Date: Sat, 28 Mar 2015 23:41:24 +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: r280799 - head/sys/dev/ath Message-ID: <201503282341.t2SNfOZc032386@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: adrian Date: Sat Mar 28 23:41:23 2015 New Revision: 280799 URL: https://svnweb.freebsd.org/changeset/base/280799 Log: Update if_ath(4) to check for "hint.ath.X.macaddr" for an override MAC address. This is used by the AR71xx platform code to choose a local MAC based on the "board MAC address", versus whatever potentially invalid/garbage values are stored in the Atheros calibration data. Modified: head/sys/dev/ath/if_ath.c Modified: head/sys/dev/ath/if_ath.c ============================================================================== --- head/sys/dev/ath/if_ath.c Sat Mar 28 23:40:29 2015 (r280798) +++ head/sys/dev/ath/if_ath.c Sat Mar 28 23:41:23 2015 (r280799) @@ -510,6 +510,60 @@ ath_setup_hal_config(struct ath_softc *s } +/* + * Attempt to fetch the MAC address from the kernel environment. + * + * Returns 0, macaddr in macaddr if successful; -1 otherwise. + */ +static int +ath_fetch_mac_kenv(struct ath_softc *sc, uint8_t *macaddr) +{ + char devid_str[32]; + int local_mac = 0; + char *local_macstr; + + /* + * Fetch from the kenv rather than using hints. + * + * Hints would be nice but the transition to dynamic + * hints/kenv doesn't happen early enough for this + * to work reliably (eg on anything embedded.) + */ + snprintf(devid_str, 32, "hint.%s.%d.macaddr", + device_get_name(sc->sc_dev), + device_get_unit(sc->sc_dev)); + + if ((local_macstr = kern_getenv(devid_str)) != NULL) { + uint32_t tmpmac[ETHER_ADDR_LEN]; + int count; + int i; + + /* Have a MAC address; should use it */ + device_printf(sc->sc_dev, + "Overriding MAC address from environment: '%s'\n", + local_macstr); + + /* Extract out the MAC address */ + count = sscanf(local_macstr, "%x%*c%x%*c%x%*c%x%*c%x%*c%x", + &tmpmac[0], &tmpmac[1], + &tmpmac[2], &tmpmac[3], + &tmpmac[4], &tmpmac[5]); + if (count == 6) { + /* Valid! */ + local_mac = 1; + for (i = 0; i < ETHER_ADDR_LEN; i++) + macaddr[i] = tmpmac[i]; + } + /* Done! */ + freeenv(local_macstr); + local_macstr = NULL; + } + + if (local_mac) + return (0); + return (-1); +} + #define HAL_MODE_HT20 (HAL_MODE_11NG_HT20 | HAL_MODE_11NA_HT20) #define HAL_MODE_HT40 \ (HAL_MODE_11NG_HT40PLUS | HAL_MODE_11NG_HT40MINUS | \ @@ -1149,8 +1203,10 @@ ath_attach(u_int16_t devid, struct ath_s */ sc->sc_hasveol = ath_hal_hasveol(ah); - /* get mac address from hardware */ - ath_hal_getmac(ah, macaddr); + /* get mac address from kenv first, then hardware */ + if (ath_fetch_mac_kenv(sc, macaddr) < 0) + ath_hal_getmac(ah, macaddr); + if (sc->sc_hasbmask) ath_hal_getbssidmask(ah, sc->sc_hwbssidmask);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201503282341.t2SNfOZc032386>