PERFORCE change 139245 for review

Sam Leffler sam at FreeBSD.org
Wed Apr 2 15:06:31 PDT 2008


http://perforce.freebsd.org/chv.cgi?CH=139245

Change 139245 by sam at 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) \


More information about the p4-projects mailing list