summaryrefslogtreecommitdiffstats
path: root/sys/mips/atheros/ar71xx_pci.c
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2012-04-20 08:26:05 +0000
committeradrian <adrian@FreeBSD.org>2012-04-20 08:26:05 +0000
commit6152dc39f23cf9b5f8db831ea0d2de2e59e9feea (patch)
treeba57b3f3aab8e5919d290c7481fe4840bc6a74f4 /sys/mips/atheros/ar71xx_pci.c
parentd9895ac1fe988335e2619f56d942d954d835bb07 (diff)
downloadFreeBSD-src-6152dc39f23cf9b5f8db831ea0d2de2e59e9feea.zip
FreeBSD-src-6152dc39f23cf9b5f8db831ea0d2de2e59e9feea.tar.gz
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.
Diffstat (limited to 'sys/mips/atheros/ar71xx_pci.c')
-rw-r--r--sys/mips/atheros/ar71xx_pci.c80
1 files changed, 18 insertions, 62 deletions
diff --git a/sys/mips/atheros/ar71xx_pci.c b/sys/mips/atheros/ar71xx_pci.c
index 25cc810..126537c 100644
--- a/sys/mips/atheros/ar71xx_pci.c
+++ b/sys/mips/atheros/ar71xx_pci.c
@@ -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_int bus, u_int slot, u_int func,
*/
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, u_int slot, u_int func,
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_int bus, u_int slot, u_int func)
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 */
OpenPOWER on IntegriCloud