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>