svn commit: r318768 - head/sys/dev/ath
Adrian Chadd
adrian at FreeBSD.org
Wed May 24 01:02:37 UTC 2017
Author: adrian
Date: Wed May 24 01:02:35 2017
New Revision: 318768
URL: https://svnweb.freebsd.org/changeset/base/318768
Log:
[ath] begin migration of AHB support to use the PCI style board data API for calibration data.
This brings the AHB support in line with the PCI support - now other "things"
can wrap up the calibration / board data into a firmware blob and have them
probe/attach after the system has finished booting.
Note that this change requires /all/ of the AHB using kernel configurations
to change - so until I drop those changes in, this breaks AHB.
Fear not, I'll do that soon.
TODO:
* the above stuff.
Tested:
* AR9331, carambola 2, loading if_ath / wlan as modules at run time
Modified:
head/sys/dev/ath/if_ath_ahb.c
Modified: head/sys/dev/ath/if_ath_ahb.c
==============================================================================
--- head/sys/dev/ath/if_ath_ahb.c Wed May 24 01:01:57 2017 (r318767)
+++ head/sys/dev/ath/if_ath_ahb.c Wed May 24 01:02:35 2017 (r318768)
@@ -66,6 +66,12 @@ __FBSDID("$FreeBSD$");
#include <mips/atheros/ar91xxreg.h>
#include <mips/atheros/ar71xx_cpudef.h>
+/* For EEPROM firmware */
+#ifdef ATH_EEPROM_FIRMWARE
+#include <sys/linker.h>
+#include <sys/firmware.h>
+#endif /* ATH_EEPROM_FIRMWARE */
+
/*
* bus glue.
*/
@@ -77,7 +83,6 @@ struct ath_ahb_softc {
struct ath_softc sc_sc;
struct resource *sc_sr; /* memory resource */
struct resource *sc_irq; /* irq resource */
- struct resource *sc_eeprom; /* eeprom location */
void *sc_ih; /* interrupt handler */
};
@@ -132,10 +137,11 @@ ath_ahb_attach(device_t dev)
struct ath_softc *sc = &psc->sc_sc;
int error = ENXIO;
int rid;
- long eepromaddr;
- int eepromsize;
- uint8_t *p;
int device_id, vendor_id;
+#ifdef ATH_EEPROM_FIRMWARE
+ const struct firmware *fw = NULL;
+ const char *buf;
+#endif
sc->sc_dev = dev;
@@ -146,44 +152,6 @@ ath_ahb_attach(device_t dev)
goto bad;
}
- if (resource_long_value(device_get_name(dev), device_get_unit(dev),
- "eepromaddr", &eepromaddr) != 0) {
- device_printf(dev, "cannot fetch 'eepromaddr' from hints\n");
- goto bad0;
- }
-
- /*
- * The default EEPROM size is 2048 * 16 bit words.
- * Later EEPROM/OTP/flash regions may be quite a bit bigger.
- */
- if (resource_int_value(device_get_name(dev), device_get_unit(dev),
- "eepromsize", &eepromsize) != 0) {
- eepromsize = ATH_EEPROM_DATA_SIZE * 2;
- }
-
- rid = 0;
- device_printf(sc->sc_dev, "eeprom @ %p (%d bytes)\n",
- (void *) eepromaddr, eepromsize);
- /*
- * XXX this assumes that the parent device is the nexus
- * and will just pass through requests for all of memory.
- *
- * Later on, when this has to attach off of the actual
- * AHB, this won't work.
- *
- * Ideally this would be done in machdep code in mips/atheros/
- * and it'd expose the EEPROM via the firmware interface,
- * so the ath/ath_ahb drivers can be loaded as modules
- * after boot-time.
- */
- psc->sc_eeprom = bus_alloc_resource(dev, SYS_RES_MEMORY,
- &rid, (uintptr_t) eepromaddr,
- (uintptr_t) eepromaddr + (uintptr_t) (eepromsize - 1), 0, RF_ACTIVE);
- if (psc->sc_eeprom == NULL) {
- device_printf(dev, "cannot map eeprom space\n");
- goto bad0;
- }
-
sc->sc_st = (HAL_BUS_TAG) rman_get_bustag(psc->sc_sr);
sc->sc_sh = (HAL_BUS_HANDLE) rman_get_bushandle(psc->sc_sr);
/*
@@ -192,22 +160,35 @@ ath_ahb_attach(device_t dev)
*/
sc->sc_invalid = 1;
- /* Copy the EEPROM data out */
- sc->sc_eepromdata = malloc(eepromsize, M_TEMP, M_NOWAIT | M_ZERO);
- if (sc->sc_eepromdata == NULL) {
- device_printf(dev, "cannot allocate memory for eeprom data\n");
- goto bad1;
+#ifdef ATH_EEPROM_FIRMWARE
+ /*
+ * If there's an EEPROM firmware image, load that in.
+ */
+ if (resource_string_value(device_get_name(dev), device_get_unit(dev),
+ "eeprom_firmware", &buf) == 0) {
+ device_printf(dev, "%s: looking up firmware @ '%s'\n",
+ __func__, buf);
+
+ fw = firmware_get(buf);
+ if (fw == NULL) {
+ device_printf(dev, "%s: couldn't find firmware\n",
+ __func__);
+ goto bad1;
+ }
+
+ device_printf(dev, "%s: EEPROM firmware @ %p\n",
+ __func__, fw->data);
+ sc->sc_eepromdata =
+ malloc(fw->datasize, M_TEMP, M_WAITOK | M_ZERO);
+ if (! sc->sc_eepromdata) {
+ device_printf(dev, "%s: can't malloc eepromdata\n",
+ __func__);
+ goto bad1;
+ }
+ memcpy(sc->sc_eepromdata, fw->data, fw->datasize);
+ firmware_put(fw, 0);
}
- device_printf(sc->sc_dev, "eeprom data @ %p\n", (void *) rman_get_bushandle(psc->sc_eeprom));
- /* XXX why doesn't this work? -adrian */
-#if 0
- bus_space_read_multi_1(
- rman_get_bustag(psc->sc_eeprom),
- rman_get_bushandle(psc->sc_eeprom),
- 0, (u_int8_t *) sc->sc_eepromdata, eepromsize);
-#endif
- p = (void *) rman_get_bushandle(psc->sc_eeprom);
- memcpy(sc->sc_eepromdata, p, eepromsize);
+#endif /* ATH_EEPROM_FIRMWARE */
/*
* Arrange interrupt line.
@@ -278,8 +259,6 @@ bad3:
bad2:
bus_release_resource(dev, SYS_RES_IRQ, 0, psc->sc_irq);
bad1:
- bus_release_resource(dev, SYS_RES_MEMORY, 0, psc->sc_eeprom);
-bad0:
bus_release_resource(dev, SYS_RES_MEMORY, 0, psc->sc_sr);
bad:
/* XXX?! */
@@ -305,7 +284,6 @@ ath_ahb_detach(device_t dev)
bus_dma_tag_destroy(sc->sc_dmat);
bus_release_resource(dev, SYS_RES_MEMORY, 0, psc->sc_sr);
- bus_release_resource(dev, SYS_RES_MEMORY, 0, psc->sc_eeprom);
/* XXX?! */
if (sc->sc_eepromdata)
free(sc->sc_eepromdata, M_TEMP);
More information about the svn-src-head
mailing list