Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 20 Apr 2012 08:26:05 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r234485 - head/sys/mips/atheros
Message-ID:  <201204200826.q3K8Q5bY029779@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Fri Apr 20 08:26:05 2012
New Revision: 234485
URL: http://svn.freebsd.org/changeset/base/234485

Log:
  Introduce the matching PCI ath(4) fixup code from ar71xx_pci into
  ar724x_pci.c.
  
  * Move out the code which populates the firmware into ar71xx_fixup.c
  * Shuffle around the ar724x fixup code to match what the ar71xx fixup
    code does.
  
  I've validated this on an AR7240 with AR9285 on-board NIC. It doesn't
  yet load, as the AR9285 EEPROM code needs to be made "flash aware."
  
  TODO:
  
  * Validate that I haven't broken AR71xx
  * Test AR9285/AR9287 onboard NICs, complete with EEPROM code changes
  * Port over the needed BAR hacks for AR7240, AR7241 and AR7242 from
    Linux OpenWRT.  The current WAR has only been tested on the AR7240
    and I'm not sure the way the BAR register is treated is "right".
    The "fixup" method here is right when setting the BAR for local access -
    ie, the BAR address is either 0xffff (AR7240) or 0x1000ffff (AR7241/AR7242),
    but the ath9k-fixup.c code (Linux OpenWRT) does this when setting the
    initial "fixup" BAR.  It then restores the original BAR.
    I'll have to read the ar724x PCI bus glue to see what other special cases
    await.

Added:
  head/sys/mips/atheros/ar71xx_fixup.c   (contents, props changed)
  head/sys/mips/atheros/ar71xx_fixup.h   (contents, props changed)
Modified:
  head/sys/mips/atheros/ar71xx_pci.c
  head/sys/mips/atheros/ar724x_pci.c
  head/sys/mips/atheros/files.ar71xx

Added: head/sys/mips/atheros/ar71xx_fixup.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/mips/atheros/ar71xx_fixup.c	Fri Apr 20 08:26:05 2012	(r234485)
@@ -0,0 +1,153 @@
+/*-
+ * Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_ar71xx.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <sys/bus.h>
+#include <sys/interrupt.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr_machdep.h>
+#include <machine/pmap.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+
+#include <dev/pci/pcib_private.h>
+#include "pcib_if.h"
+
+#include <mips/atheros/ar71xxreg.h>
+#include <mips/atheros/ar71xx_pci_bus_space.h>
+
+#include <mips/atheros/ar71xx_cpudef.h>
+
+#include <sys/linker.h>
+#include <sys/firmware.h>
+
+#include <mips/atheros/ar71xx_fixup.h>
+
+/*
+ * Take a copy of the EEPROM contents and squirrel it away in a firmware.
+ * The SPI flash will eventually cease to be memory-mapped, so we need
+ * to take a copy of this before the SPI driver initialises.
+ */
+void
+ar71xx_pci_slot_create_eeprom_firmware(device_t dev, u_int bus, u_int slot,
+    u_int func, long int flash_addr, int size)
+{
+	char buf[64];
+	uint16_t *cal_data = (uint16_t *) MIPS_PHYS_TO_KSEG1(flash_addr);
+	void *eeprom = NULL;
+	const struct firmware *fw = NULL;
+
+	device_printf(dev, "EEPROM firmware: 0x%lx @ %d bytes\n",
+	    flash_addr, size);
+
+	eeprom = malloc(size, M_DEVBUF, M_WAITOK | M_ZERO);
+	if (! eeprom) {
+		device_printf(dev,
+			    "%s: malloc failed for '%s', aborting EEPROM\n",
+			    __func__, buf);
+			return;
+	}
+
+	memcpy(eeprom, cal_data, size);
+
+	/*
+	 * Generate a flash EEPROM 'firmware' from the given memory
+	 * region.  Since the SPI controller will eventually
+	 * go into port-IO mode instead of memory-mapped IO
+	 * mode, a copy of the EEPROM contents is required.
+	 */
+	snprintf(buf, sizeof(buf), "%s.%d.bus.%d.%d.%d.eeprom_firmware",
+	    device_get_name(dev), device_get_unit(dev), bus, slot, func);
+	fw = firmware_register(buf, eeprom, size, 1, NULL);
+	if (fw == NULL) {
+		device_printf(dev, "%s: firmware_register (%s) failed\n",
+		    __func__, buf);
+		free(eeprom, M_DEVBUF);
+		return;
+	}
+	device_printf(dev, "device EEPROM '%s' registered\n", buf);
+}
+
+#if 0
+static void
+ar71xx_pci_slot_fixup(device_t dev, u_int bus, u_int slot, u_int func)
+{
+	long int flash_addr;
+	char buf[64];
+	int size;
+
+	/*
+	 * Check whether the given slot has a hint to poke.
+	 */
+	if (bootverbose)
+	device_printf(dev, "%s: checking dev %s, %d/%d/%d\n",
+	    __func__, device_get_nameunit(dev), bus, slot, func);
+
+	snprintf(buf, sizeof(buf), "bus.%d.%d.%d.ath_fixup_addr",
+	    bus, slot, func);
+
+	if (resource_long_value(device_get_name(dev), device_get_unit(dev),
+	    buf, &flash_addr) == 0) {
+		snprintf(buf, sizeof(buf), "bus.%d.%d.%d.ath_fixup_size",
+		    bus, slot, func);
+		if (resource_int_value(device_get_name(dev),
+		    device_get_unit(dev), buf, &size) != 0) {
+			device_printf(dev,
+			    "%s: missing hint '%s', aborting EEPROM\n",
+			    __func__, buf);
+			return;
+		}
+
+
+		device_printf(dev, "found EEPROM at 0x%lx on %d.%d.%d\n",
+		    flash_addr, bus, slot, func);
+		ar71xx_pci_fixup(dev, bus, slot, func, flash_addr, size);
+		ar71xx_pci_slot_create_eeprom_firmware(dev, bus, slot, func,
+		    flash_addr, size);
+	}
+}
+#endif /* 0 */

Added: head/sys/mips/atheros/ar71xx_fixup.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/mips/atheros/ar71xx_fixup.h	Fri Apr 20 08:26:05 2012	(r234485)
@@ -0,0 +1,36 @@
+/*-
+ * Copyright (c) 2012, Adrian Chadd <adrian@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef	__ATHEROS_AR71XX_FIXUP_H__
+#define	__ATHEROS_AR71XX_FIXUP_H__
+
+extern	void ar71xx_pci_slot_create_eeprom_firmware(device_t dev,
+    u_int bus, u_int slot, u_int func, long int flash_addr, int size);
+
+#endif /* __ATHEROS_AR71XX_FIXUP_H__ */

Modified: head/sys/mips/atheros/ar71xx_pci.c
==============================================================================
--- head/sys/mips/atheros/ar71xx_pci.c	Fri Apr 20 07:24:54 2012	(r234484)
+++ head/sys/mips/atheros/ar71xx_pci.c	Fri Apr 20 08:26:05 2012	(r234485)
@@ -63,8 +63,7 @@ __FBSDID("$FreeBSD$");
 #include <mips/atheros/ar71xx_cpudef.h>
 
 #ifdef	AR71XX_ATH_EEPROM
-#include <sys/linker.h>
-#include <sys/firmware.h>
+#include <mips/atheros/ar71xx_fixup.h>
 #endif	/* AR71XX_ATH_EEPROM */
 
 #undef	AR71XX_PCI_DEBUG
@@ -288,7 +287,7 @@ ar71xx_pci_write_config(device_t dev, u_
  */
 static void
 ar71xx_pci_fixup(device_t dev, u_int bus, u_int slot, u_int func,
-    long flash_addr)
+    long flash_addr, int len)
 {
 	uint16_t *cal_data = (uint16_t *) MIPS_PHYS_TO_KSEG1(flash_addr);
 	uint32_t reg, val, bar0;
@@ -328,67 +327,12 @@ ar71xx_pci_fixup(device_t dev, u_int bus
 	ar71xx_pci_write_config(dev, bus, slot, func, PCIR_BAR(0), bar0, 4);
 }
 
-/*
- * Take a copy of the EEPROM contents and squirrel it away in a firmware.
- * The SPI flash will eventually cease to be memory-mapped, so we need
- * to take a copy of this before the SPI driver initialises.
- */
-static void
-ar71xx_pci_slot_create_eeprom_firmware(device_t dev, u_int bus, u_int slot,
-    u_int func, long int flash_addr)
-{
-	char buf[64];
-	uint16_t *cal_data = (uint16_t *) MIPS_PHYS_TO_KSEG1(flash_addr);
-	void *eeprom = NULL;
-	const struct firmware *fw = NULL;
-	int len;
-
-	snprintf(buf, sizeof(buf), "bus.%d.%d.%d.ath_fixup_size",
-	    bus, slot, func);
-
-	if (resource_int_value(device_get_name(dev), device_get_unit(dev),
-	    buf, &len) != 0) {
-		device_printf(dev, "%s: missing hint '%s', aborting EEPROM\n",
-		    __func__, buf);
-		return;
-	}
-
-	device_printf(dev, "EEPROM firmware: 0x%lx @ %d bytes\n",
-	    flash_addr, len);
-
-	eeprom = malloc(len, M_DEVBUF, M_WAITOK | M_ZERO);
-	if (! eeprom) {
-		device_printf(dev,
-			    "%s: malloc failed for '%s', aborting EEPROM\n",
-			    __func__, buf);
-			return;
-	}
-
-	memcpy(eeprom, cal_data, len);
-
-	/*
-	 * Generate a flash EEPROM 'firmware' from the given memory
-	 * region.  Since the SPI controller will eventually
-	 * go into port-IO mode instead of memory-mapped IO
-	 * mode, a copy of the EEPROM contents is required.
-	 */
-	snprintf(buf, sizeof(buf), "%s.%d.bus.%d.%d.%d.eeprom_firmware",
-	    device_get_name(dev), device_get_unit(dev), bus, slot, func);
-	fw = firmware_register(buf, eeprom, len, 1, NULL);
-	if (fw == NULL) {
-		device_printf(dev, "%s: firmware_register (%s) failed\n",
-		    __func__, buf);
-		free(eeprom, M_DEVBUF);
-		return;
-	}
-	device_printf(dev, "device EEPROM '%s' registered\n", buf);
-}
-
 static void
 ar71xx_pci_slot_fixup(device_t dev, u_int bus, u_int slot, u_int func)
 {
 	long int flash_addr;
-	char buf[32];
+	char buf[64];
+	int size;
 
 	/*
 	 * Check whether the given slot has a hint to poke.
@@ -396,16 +340,28 @@ ar71xx_pci_slot_fixup(device_t dev, u_in
 	if (bootverbose)
 	device_printf(dev, "%s: checking dev %s, %d/%d/%d\n",
 	    __func__, device_get_nameunit(dev), bus, slot, func);
+
 	snprintf(buf, sizeof(buf), "bus.%d.%d.%d.ath_fixup_addr",
 	    bus, slot, func);
 
 	if (resource_long_value(device_get_name(dev), device_get_unit(dev),
 	    buf, &flash_addr) == 0) {
+		snprintf(buf, sizeof(buf), "bus.%d.%d.%d.ath_fixup_size",
+		    bus, slot, func);
+		if (resource_int_value(device_get_name(dev),
+		    device_get_unit(dev), buf, &size) != 0) {
+			device_printf(dev,
+			    "%s: missing hint '%s', aborting EEPROM\n",
+			    __func__, buf);
+			return;
+		}
+
+
 		device_printf(dev, "found EEPROM at 0x%lx on %d.%d.%d\n",
 		    flash_addr, bus, slot, func);
-		ar71xx_pci_fixup(dev, bus, slot, func, flash_addr);
+		ar71xx_pci_fixup(dev, bus, slot, func, flash_addr, size);
 		ar71xx_pci_slot_create_eeprom_firmware(dev, bus, slot, func,
-		    flash_addr);
+		    flash_addr, size);
 	}
 }
 #endif	/* AR71XX_ATH_EEPROM */

Modified: head/sys/mips/atheros/ar724x_pci.c
==============================================================================
--- head/sys/mips/atheros/ar724x_pci.c	Fri Apr 20 07:24:54 2012	(r234484)
+++ head/sys/mips/atheros/ar724x_pci.c	Fri Apr 20 08:26:05 2012	(r234485)
@@ -29,6 +29,8 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_ar71xx.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 
@@ -61,6 +63,10 @@ __FBSDID("$FreeBSD$");
 
 #include <mips/atheros/ar71xx_cpudef.h>
 
+#ifdef	AR71XX_ATH_EEPROM
+#include <mips/atheros/ar71xx_fixup.h>
+#endif	/* AR71XX_ATH_EEPROM */
+
 #undef	AR724X_PCI_DEBUG
 #ifdef AR724X_PCI_DEBUG
 #define dprintf printf
@@ -243,27 +249,21 @@ ar724x_pci_setup(device_t dev)
 	return (0);
 }
 
+#ifdef	AR71XX_ATH_EEPROM
 #define	AR5416_EEPROM_MAGIC		0xa55a
 
 /*
  * XXX - This should not be here ! And this looks like Atheros (if_ath) only.
  */
 static void
-ar724x_load_eeprom_data(device_t dev)
+ar724x_pci_fixup(device_t dev, long flash_addr, int len)
 {
-	uint32_t	bar0, hint, reg, val;
-	uint16_t	*data = NULL;
-
-	/* Search for a hint of eeprom data offset */
-	if (resource_int_value(device_get_name(dev),
-	    device_get_unit(dev), "eepromdata", &hint) != 0)
-		return;
-
-	device_printf(dev, "Loading the eeprom fixup data from %#x\n", hint);
-	data = (uint16_t *)MIPS_PHYS_TO_KSEG1(hint);
+	uint32_t bar0, reg, val;
+	uint16_t *cal_data = (uint16_t *) MIPS_PHYS_TO_KSEG1(flash_addr);
 
-	if (*data != AR5416_EEPROM_MAGIC) {
-		device_printf(dev, "Invalid calibration data from %#x\n", hint);
+	if (cal_data[0] != AR5416_EEPROM_MAGIC) {
+		device_printf(dev, "%s: Invalid calibration data from 0x%x\n",
+		    __func__, (uintptr_t) flash_addr);
 		return;
 	}
 
@@ -275,11 +275,14 @@ ar724x_load_eeprom_data(device_t dev)
 	ar724x_pci_write_config(dev, 0, 0, 0, PCIR_COMMAND, val, 2); 
 
 	/* set pointer to first reg address */
-	data += 3;
-	while (*data != 0xffff) {
-		reg = *data++;
-		val = *data++;
-		val |= (*data++) << 16;
+	cal_data += 3;
+	while (*cal_data != 0xffff) {
+		reg = *cal_data++;
+		val = *cal_data++;
+		val |= (*cal_data++) << 16;
+
+		if (bootverbose)
+			printf("    0x%08x=0x%04x\n", reg, val);
 
 		/* Write eeprom fixup data to device memory */
 		ATH_WRITE_REG(AR71XX_PCI_MEM_BASE + reg, val);
@@ -293,9 +296,51 @@ ar724x_load_eeprom_data(device_t dev)
 	/* Write the saved bar(0) address */
 	ar724x_pci_write_config(dev, 0, 0, 0, PCIR_BAR(0), bar0, 4);
 }
-
 #undef	AR5416_EEPROM_MAGIC
 
+/*
+ * XXX This is (mostly) duplicated with ar71xx_pci.c.
+ * It should at some point be fixed.
+ */
+static void
+ar724x_pci_slot_fixup(device_t dev)
+{
+	long int flash_addr;
+	char buf[64];
+	int size;
+
+	/*
+	 * Check whether the given slot has a hint to poke.
+	 */
+	if (bootverbose)
+	device_printf(dev, "%s: checking dev %s, %d/%d/%d\n",
+	    __func__, device_get_nameunit(dev), 0, 0, 0);
+
+	snprintf(buf, sizeof(buf), "bus.%d.%d.%d.ath_fixup_addr",
+	    0, 0, 0);
+
+	if (resource_long_value(device_get_name(dev), device_get_unit(dev),
+	    buf, &flash_addr) == 0) {
+		snprintf(buf, sizeof(buf), "bus.%d.%d.%d.ath_fixup_size",
+		    0, 0, 0);
+		if (resource_int_value(device_get_name(dev),
+		    device_get_unit(dev), buf, &size) != 0) {
+			device_printf(dev,
+			    "%s: missing hint '%s', aborting EEPROM\n",
+			    __func__, buf);
+			return;
+		}
+
+
+		device_printf(dev, "found EEPROM at 0x%lx on %d.%d.%d\n",
+		    flash_addr, 0, 0, 0);
+		ar724x_pci_fixup(dev, flash_addr, size);
+		ar71xx_pci_slot_create_eeprom_firmware(dev, 0, 0, 0,
+		    flash_addr, size);
+	}
+}
+#endif	/* AR71XX_ATH_EEPROM */
+
 static int
 ar724x_pci_probe(device_t dev)
 {
@@ -357,8 +402,9 @@ ar724x_pci_attach(device_t dev)
 	if (ar724x_pci_setup(dev))
 		return (ENXIO);
 
-	/* XXX - Load eeprom fixup data */
-	ar724x_load_eeprom_data(dev);
+#ifdef	AR71XX_ATH_EEPROM
+	ar724x_pci_slot_fixup(dev);
+#endif	/* AR71XX_ATH_EEPROM */
 
 	/* Fixup internal PCI bridge */
 	ar724x_pci_write_config(dev, 0, 0, 0, PCIR_COMMAND, 

Modified: head/sys/mips/atheros/files.ar71xx
==============================================================================
--- head/sys/mips/atheros/files.ar71xx	Fri Apr 20 07:24:54 2012	(r234484)
+++ head/sys/mips/atheros/files.ar71xx	Fri Apr 20 08:26:05 2012	(r234485)
@@ -21,5 +21,6 @@ mips/atheros/ar71xx_setup.c	standard
 mips/atheros/ar71xx_chip.c	standard
 mips/atheros/ar724x_chip.c	standard
 mips/atheros/ar91xx_chip.c	standard
+mips/atheros/ar71xx_fixup.c	optional ar71xx_ath_eeprom
 
 dev/hwpmc/hwpmc_mips24k.c	optional hwpmc



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201204200826.q3K8Q5bY029779>