mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
[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
This commit is contained in:
parent
c20feae640
commit
31ce00f662
1 changed files with 38 additions and 60 deletions
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue