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