Date: Wed, 2 Apr 2008 22:06:30 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 139245 for review Message-ID: <200804022206.m32M6Uas071941@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=139245 Change 139245 by sam@sam_ebb on 2008/04/02 22:06:16 Handle older parts that cannot do TKIP MIC in hardware together with WME: o when WME is enabled for use and the device is incapable of doing TKIP MIC in hardware disable it and disable the capability in ic_cryptocaps so net80211 will setup keys to use s/w MIC support o do above work on callbacks through iv_reset so dynamic changes to wme use are handled o re-renable use of WME by default now that we don't silently break Affected files ... .. //depot/projects/vap/sys/dev/ath/if_ath.c#57 edit .. //depot/projects/vap/sys/dev/ath/if_athvar.h#19 edit Differences ... ==== //depot/projects/vap/sys/dev/ath/if_ath.c#57 (text+ko) ==== @@ -547,6 +547,13 @@ if (ath_hal_hastkipsplit(ah) || !ath_hal_settkipsplit(ah, AH_FALSE)) sc->sc_splitmic = 1; + /* + * If the h/w can do TKIP MIC together with WME then + * we use it; otherwise we force the MIC to be done + * in software by the net80211 layer. + */ + if (ath_hal_haswmetkipmic(ah)) + sc->sc_wmetkipmic = 1; } sc->sc_hasclrkey = ath_hal_ciphersupported(ah, HAL_CIPHER_CLR); sc->sc_mcastkey = ath_hal_getmcastkeysearch(ah); @@ -862,9 +869,6 @@ ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); ATH_LOCK(sc); - /* XXX turn off WME until we fix WME+TKIP for older chips */ - vap->iv_flags &= ~IEEE80211_F_WME; - /* h/w crypto support */ vap->iv_key_alloc = ath_key_alloc; vap->iv_key_delete = ath_key_delete; @@ -1280,6 +1284,28 @@ #undef N } +/* + * Handle TKIP MIC setup to deal hardware that doesn't do MIC + * calcs together with WME. If necessary disable the crypto + * hardware and mark the 802.11 state so keys will be setup + * with the MIC work done in software. + */ +static void +ath_settkipmic(struct ath_softc *sc) +{ + struct ieee80211com *ic = &sc->sc_ic; + + if ((ic->ic_cryptocaps & IEEE80211_CRYPTO_TKIP) && !sc->sc_wmetkipmic) { + if (ic->ic_flags & IEEE80211_F_WME) { + ath_hal_settkipmic(sc->sc_ah, AH_FALSE); + ic->ic_cryptocaps &= ~IEEE80211_CRYPTO_TKIPMIC; + } else { + ath_hal_settkipmic(sc->sc_ah, AH_TRUE); + ic->ic_cryptocaps |= IEEE80211_CRYPTO_TKIPMIC; + } + } +} + static void ath_init(void *arg) { @@ -1307,6 +1333,7 @@ * and then setup of the interrupt mask. */ ath_mapchan(&sc->sc_curchan, ic->ic_curchan); + ath_settkipmic(sc); if (!ath_hal_reset(ah, sc->sc_opmode, &sc->sc_curchan, AH_FALSE, &status)) { if_printf(ifp, "unable to reset hardware; hal status %u\n", status); @@ -1457,6 +1484,7 @@ ath_hal_intrset(ah, 0); /* disable interrupts */ ath_draintxq(sc); /* stop xmit side */ ath_stoprecv(sc); /* stop recv side */ + ath_settkipmic(sc); /* configure TKIP MIC handling */ /* NB: indicate channel change so we do a full reset */ if (!ath_hal_reset(ah, sc->sc_opmode, &sc->sc_curchan, AH_TRUE, &status)) if_printf(ifp, "%s: unable to reset hardware; hal status %u\n", ==== //depot/projects/vap/sys/dev/ath/if_athvar.h#19 (text+ko) ==== @@ -245,7 +245,8 @@ sc_hastsfadd: 1,/* tsf adjust support */ sc_beacons : 1,/* beacons running */ sc_swbmiss : 1,/* sta mode using sw bmiss */ - sc_stagbeacons:1;/* use staggered beacons */ + sc_stagbeacons:1,/* use staggered beacons */ + sc_wmetkipmic:1;/* can do WME+TKIP MIC */ /* rate tables */ #define IEEE80211_MODE_HALF (IEEE80211_MODE_MAX+0) #define IEEE80211_MODE_QUARTER (IEEE80211_MODE_MAX+1) @@ -506,12 +507,18 @@ (*(uint16_t *)(((uint8_t *)(_ah)) + 520) = (_rd)) #define ath_hal_getcountrycode(_ah, _pcc) \ (*(_pcc) = (_ah)->ah_countryCode) +#define ath_hal_gettkipmic(_ah) \ + (ath_hal_getcapability(_ah, HAL_CAP_TKIP_MIC, 1, NULL) == HAL_OK) +#define ath_hal_settkipmic(_ah, _v) \ + ath_hal_setcapability(_ah, HAL_CAP_TKIP_MIC, 1, _v, NULL) #define ath_hal_hastkipsplit(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_TKIP_SPLIT, 0, NULL) == HAL_OK) #define ath_hal_gettkipsplit(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_TKIP_SPLIT, 1, NULL) == HAL_OK) #define ath_hal_settkipsplit(_ah, _v) \ ath_hal_setcapability(_ah, HAL_CAP_TKIP_SPLIT, 1, _v, NULL) +#define ath_hal_haswmetkipmic(_ah) \ + (ath_hal_getcapability(_ah, HAL_CAP_WME_TKIPMIC, 0, NULL) == HAL_OK) #define ath_hal_hwphycounters(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_PHYCOUNTERS, 0, NULL) == HAL_OK) #define ath_hal_hasdiversity(_ah) \
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200804022206.m32M6Uas071941>