aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/common.c
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2010-05-25 13:42:45 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-06-03 14:10:44 -0400
commiteed8e22f0133e8278b1f8079fcb452f1f9692f9d (patch)
tree74e439849bb490805ebfa799ccc9e05e25e695c9 /drivers/net/wireless/ath/ath9k/common.c
parent1d0bb42d5eee20bd70f237d0a32cfe3b079849e2 (diff)
ath9k_common: use allocated key cache entries for multi BSS crypto support
This patch replaces the buggy 'ath9k: Group Key fix for VAPs' change. For AP mode group keys, use the BSSID as lookup mac address, with the multicast keysearch bit set. For IBSS mode, use the peer's MAC address with multicast keysearch. For STA mode, keep using the group key slots. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/common.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index 27f9ae56f96c..03590f048fb8 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -211,10 +211,14 @@ static int ath_reserve_key_cache_slot_tkip(struct ath_common *common)
211 return -1; 211 return -1;
212} 212}
213 213
214static int ath_reserve_key_cache_slot(struct ath_common *common) 214static int ath_reserve_key_cache_slot(struct ath_common *common,
215 enum ieee80211_key_alg alg)
215{ 216{
216 int i; 217 int i;
217 218
219 if (alg == ALG_TKIP)
220 return ath_reserve_key_cache_slot_tkip(common);
221
218 /* First, try to find slots that would not be available for TKIP. */ 222 /* First, try to find slots that would not be available for TKIP. */
219 if (common->splitmic) { 223 if (common->splitmic) {
220 for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) { 224 for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) {
@@ -283,6 +287,7 @@ int ath9k_cmn_key_config(struct ath_common *common,
283 struct ath_hw *ah = common->ah; 287 struct ath_hw *ah = common->ah;
284 struct ath9k_keyval hk; 288 struct ath9k_keyval hk;
285 const u8 *mac = NULL; 289 const u8 *mac = NULL;
290 u8 gmac[ETH_ALEN];
286 int ret = 0; 291 int ret = 0;
287 int idx; 292 int idx;
288 293
@@ -306,9 +311,23 @@ int ath9k_cmn_key_config(struct ath_common *common,
306 memcpy(hk.kv_val, key->key, key->keylen); 311 memcpy(hk.kv_val, key->key, key->keylen);
307 312
308 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { 313 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
309 /* For now, use the default keys for broadcast keys. This may 314 switch (vif->type) {
310 * need to change with virtual interfaces. */ 315 case NL80211_IFTYPE_AP:
311 idx = key->keyidx; 316 memcpy(gmac, vif->addr, ETH_ALEN);
317 gmac[0] |= 0x01;
318 mac = gmac;
319 idx = ath_reserve_key_cache_slot(common, key->alg);
320 break;
321 case NL80211_IFTYPE_ADHOC:
322 memcpy(gmac, sta->addr, ETH_ALEN);
323 gmac[0] |= 0x01;
324 mac = gmac;
325 idx = ath_reserve_key_cache_slot(common, key->alg);
326 break;
327 default:
328 idx = key->keyidx;
329 break;
330 }
312 } else if (key->keyidx) { 331 } else if (key->keyidx) {
313 if (WARN_ON(!sta)) 332 if (WARN_ON(!sta))
314 return -EOPNOTSUPP; 333 return -EOPNOTSUPP;
@@ -325,14 +344,12 @@ int ath9k_cmn_key_config(struct ath_common *common,
325 return -EOPNOTSUPP; 344 return -EOPNOTSUPP;
326 mac = sta->addr; 345 mac = sta->addr;
327 346
328 if (key->alg == ALG_TKIP) 347 idx = ath_reserve_key_cache_slot(common, key->alg);
329 idx = ath_reserve_key_cache_slot_tkip(common);
330 else
331 idx = ath_reserve_key_cache_slot(common);
332 if (idx < 0)
333 return -ENOSPC; /* no free key cache entries */
334 } 348 }
335 349
350 if (idx < 0)
351 return -ENOSPC; /* no free key cache entries */
352
336 if (key->alg == ALG_TKIP) 353 if (key->alg == ALG_TKIP)
337 ret = ath_setkey_tkip(common, idx, key->key, &hk, mac, 354 ret = ath_setkey_tkip(common, idx, key->key, &hk, mac,
338 vif->type == NL80211_IFTYPE_AP); 355 vif->type == NL80211_IFTYPE_AP);