summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrpaulo <rpaulo@FreeBSD.org>2010-02-08 20:23:20 +0000
committerrpaulo <rpaulo@FreeBSD.org>2010-02-08 20:23:20 +0000
commitdef28d2809f75a8ab70de810865728bc31f1c6cb (patch)
tree717679366c279bad9bce1f2d444f23607f8b3ebf
parent8fa59f844ebe44b567eb67de82c353348ddb4265 (diff)
downloadFreeBSD-src-def28d2809f75a8ab70de810865728bc31f1c6cb.zip
FreeBSD-src-def28d2809f75a8ab70de810865728bc31f1c6cb.tar.gz
Add multicast key search support. This fixes corrupted mcast packets
when we have more than one hostap vap. Submitted by: Russell Yount <russell.yount at gmail.com> MFC after: 2 weeks
-rw-r--r--sys/dev/ath/if_ath.c35
-rw-r--r--sys/dev/ath/if_athvar.h6
2 files changed, 30 insertions, 11 deletions
diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c
index ed69a7d..d00d469 100644
--- a/sys/dev/ath/if_ath.c
+++ b/sys/dev/ath/if_ath.c
@@ -620,6 +620,13 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
sc->sc_wmetkipmic = 1;
}
sc->sc_hasclrkey = ath_hal_ciphersupported(ah, HAL_CIPHER_CLR);
+ /*
+ * Check for multicast key sarch support.
+ */
+ if (ath_hal_hasmcastkeysearch(sc->sc_ah) &&
+ !ath_hal_getmcastkeysearch(sc->sc_ah)) {
+ ath_hal_setmcastkeysearch(sc->sc_ah, 1);
+ }
sc->sc_mcastkey = ath_hal_getmcastkeysearch(ah);
/*
* Mark key cache slots associated with global keys
@@ -2038,7 +2045,7 @@ ath_keyset(struct ath_softc *sc, const struct ieee80211_key *k,
if ((k->wk_flags & IEEE80211_KEY_GROUP) && sc->sc_mcastkey) {
/*
* Group keys on hardware that supports multicast frame
- * key search use a mac that is the sender's address with
+ * key search use a MAC that is the sender's address with
* the high bit set instead of the app-specified address.
*/
IEEE80211_ADDR_COPY(gmac, bss->ni_macaddr);
@@ -2218,8 +2225,10 @@ ath_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k,
* it permits us to support multiple users for adhoc and/or
* multi-station operation.
*/
- if (k->wk_keyix != IEEE80211_KEYIX_NONE || /* global key */
- ((k->wk_flags & IEEE80211_KEY_GROUP) && !sc->sc_mcastkey)) {
+ if (k->wk_keyix != IEEE80211_KEYIX_NONE) {
+ /*
+ * Only global keys should have key index assigned.
+ */
if (!(&vap->iv_nw_keys[0] <= k &&
k < &vap->iv_nw_keys[IEEE80211_WEP_NKID])) {
/* should not happen */
@@ -2227,12 +2236,22 @@ ath_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k,
"%s: bogus group key\n", __func__);
return 0;
}
+ */
+ if (vap->iv_opmode != IEEE80211_M_HOSTAP ||
+ !(k->wk_flags & IEEE80211_KEY_GROUP) ||
+ !sc->sc_mcastkey) {
+ /*
+ * XXX we pre-allocate the global keys so
+ * have no way to check if they've already
+ * been allocated.
+ */
+ *keyix = *rxkeyix = k - vap->iv_nw_keys;
+ return 1;
+ }
/*
- * XXX we pre-allocate the global keys so
- * have no way to check if they've already been allocated.
+ * Group key and device supports multicast key search.
*/
- *keyix = *rxkeyix = k - vap->iv_nw_keys;
- return 1;
+ k->wk_keyix = IEEE80211_KEYIX_NONE;
}
/*
@@ -6944,6 +6963,8 @@ ath_announce(struct ath_softc *sc)
if_printf(ifp, "using %u rx buffers\n", ath_rxbuf);
if (ath_txbuf != ATH_TXBUF)
if_printf(ifp, "using %u tx buffers\n", ath_txbuf);
+ if (sc->sc_mcastkey && bootverbose)
+ if_printf(ifp, "using multicast key search\n");
}
#ifdef IEEE80211_SUPPORT_TDMA
diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h
index 29efc4c..31b1d4c 100644
--- a/sys/dev/ath/if_athvar.h
+++ b/sys/dev/ath/if_athvar.h
@@ -580,14 +580,12 @@ void ath_intr(void *);
ath_hal_setcapability(_ah, HAL_CAP_TPC, 1, _v, NULL)
#define ath_hal_hasbursting(_ah) \
(ath_hal_getcapability(_ah, HAL_CAP_BURST, 0, NULL) == HAL_OK)
-#ifdef notyet
+#define ath_hal_setmcastkeysearch(_ah, _v) \
+ ath_hal_setcapability(_ah, HAL_CAP_MCAST_KEYSRCH, 0, _v, NULL)
#define ath_hal_hasmcastkeysearch(_ah) \
(ath_hal_getcapability(_ah, HAL_CAP_MCAST_KEYSRCH, 0, NULL) == HAL_OK)
#define ath_hal_getmcastkeysearch(_ah) \
(ath_hal_getcapability(_ah, HAL_CAP_MCAST_KEYSRCH, 1, NULL) == HAL_OK)
-#else
-#define ath_hal_getmcastkeysearch(_ah) 0
-#endif
#define ath_hal_hasfastframes(_ah) \
(ath_hal_getcapability(_ah, HAL_CAP_FASTFRAME, 0, NULL) == HAL_OK)
#define ath_hal_hasbssidmask(_ah) \
OpenPOWER on IntegriCloud