summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2012-04-13 08:48:38 +0000
committeradrian <adrian@FreeBSD.org>2012-04-13 08:48:38 +0000
commit7f1f1b94c1be67023229ac71dc2d980b4c414c20 (patch)
treebc5836ed8e309c661fc9699343b8ebd45a7184de
parent6b1a85efd5f030085520e61c4fd16d57d3ff063f (diff)
downloadFreeBSD-src-7f1f1b94c1be67023229ac71dc2d980b4c414c20.zip
FreeBSD-src-7f1f1b94c1be67023229ac71dc2d980b4c414c20.tar.gz
Introduce the ability to grab local EEPROM data from the firmware(9)
interface. * Introduce a device hint, 'eeprom_firmware', which is the name of firmware to lookup. * If the lookup succeeds, take a copy of it and use it as the eeprom data. This isn't enabled by default - you have to define ATH_EEPROM_FIRMWARE. I'll add it to the configuration variables in a later commit. TODO: * just keep a firmware reference in ath_softc, and remove the need to waste the extra memory in having sc_eepromdata be a malloc()ed block.
-rw-r--r--sys/dev/ath/if_ath_pci.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/sys/dev/ath/if_ath_pci.c b/sys/dev/ath/if_ath_pci.c
index 536930b..9b0f853 100644
--- a/sys/dev/ath/if_ath_pci.c
+++ b/sys/dev/ath/if_ath_pci.c
@@ -60,6 +60,14 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
+/* #define ATH_EEPROM_FIRMWARE */
+
+/* For EEPROM firmware */
+#ifdef ATH_EEPROM_FIRMWARE
+#include <sys/linker.h>
+#include <sys/firmware.h>
+#endif /* ATH_EEPROM_FIRMWARE */
+
/*
* PCI glue.
*/
@@ -123,6 +131,10 @@ ath_pci_attach(device_t dev)
struct ath_softc *sc = &psc->sc_sc;
int error = ENXIO;
int rid;
+#ifdef ATH_EEPROM_FIRMWARE
+ const struct firmware *fw = NULL;
+ const char *buf;
+#endif
sc->sc_dev = dev;
@@ -191,6 +203,37 @@ ath_pci_attach(device_t dev)
goto bad3;
}
+#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) {
+ if (bootverbose)
+ 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 bad3;
+ }
+
+ 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 bad3;
+ }
+ memcpy(sc->sc_eepromdata, fw->data, fw->datasize);
+ firmware_put(fw, 0);
+ }
+#endif /* ATH_EEPROM_FIRMWARE */
+
ATH_LOCK_INIT(sc);
ATH_PCU_LOCK_INIT(sc);
@@ -234,6 +277,9 @@ ath_pci_detach(device_t dev)
bus_dma_tag_destroy(sc->sc_dmat);
bus_release_resource(dev, SYS_RES_MEMORY, BS_BAR, psc->sc_sr);
+ if (sc->sc_eepromdata)
+ free(sc->sc_eepromdata, M_TEMP);
+
ATH_PCU_LOCK_DESTROY(sc);
ATH_LOCK_DESTROY(sc);
OpenPOWER on IntegriCloud