diff options
-rw-r--r-- | drivers/net/wireless/ath5k/base.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/pcu.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/main.c | 18 | ||||
-rw-r--r-- | drivers/net/wireless/b43/main.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/p54/p54common.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00mac.c | 29 | ||||
-rw-r--r-- | include/net/mac80211.h | 20 | ||||
-rw-r--r-- | net/mac80211/key.c | 51 |
11 files changed, 89 insertions, 83 deletions
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 8ef87356e083..88618645a7e4 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
@@ -232,7 +232,7 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, | |||
232 | int mc_count, struct dev_mc_list *mclist); | 232 | int mc_count, struct dev_mc_list *mclist); |
233 | static int ath5k_set_key(struct ieee80211_hw *hw, | 233 | static int ath5k_set_key(struct ieee80211_hw *hw, |
234 | enum set_key_cmd cmd, | 234 | enum set_key_cmd cmd, |
235 | const u8 *local_addr, const u8 *addr, | 235 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, |
236 | struct ieee80211_key_conf *key); | 236 | struct ieee80211_key_conf *key); |
237 | static int ath5k_get_stats(struct ieee80211_hw *hw, | 237 | static int ath5k_get_stats(struct ieee80211_hw *hw, |
238 | struct ieee80211_low_level_stats *stats); | 238 | struct ieee80211_low_level_stats *stats); |
@@ -2991,8 +2991,8 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, | |||
2991 | 2991 | ||
2992 | static int | 2992 | static int |
2993 | ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 2993 | ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
2994 | const u8 *local_addr, const u8 *addr, | 2994 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, |
2995 | struct ieee80211_key_conf *key) | 2995 | struct ieee80211_key_conf *key) |
2996 | { | 2996 | { |
2997 | struct ath5k_softc *sc = hw->priv; | 2997 | struct ath5k_softc *sc = hw->priv; |
2998 | int ret = 0; | 2998 | int ret = 0; |
@@ -3015,7 +3015,8 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3015 | 3015 | ||
3016 | switch (cmd) { | 3016 | switch (cmd) { |
3017 | case SET_KEY: | 3017 | case SET_KEY: |
3018 | ret = ath5k_hw_set_key(sc->ah, key->keyidx, key, addr); | 3018 | ret = ath5k_hw_set_key(sc->ah, key->keyidx, key, |
3019 | sta ? sta->addr : NULL); | ||
3019 | if (ret) { | 3020 | if (ret) { |
3020 | ATH5K_ERR(sc, "can't set the key\n"); | 3021 | ATH5K_ERR(sc, "can't set the key\n"); |
3021 | goto unlock; | 3022 | goto unlock; |
diff --git a/drivers/net/wireless/ath5k/pcu.c b/drivers/net/wireless/ath5k/pcu.c index 75eb9f43c741..5b416ed65299 100644 --- a/drivers/net/wireless/ath5k/pcu.c +++ b/drivers/net/wireless/ath5k/pcu.c | |||
@@ -1139,7 +1139,7 @@ int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac) | |||
1139 | 1139 | ||
1140 | /* MAC may be NULL if it's a broadcast key. In this case no need to | 1140 | /* MAC may be NULL if it's a broadcast key. In this case no need to |
1141 | * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */ | 1141 | * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */ |
1142 | if (unlikely(mac == NULL)) { | 1142 | if (!mac) { |
1143 | low_id = 0xffffffff; | 1143 | low_id = 0xffffffff; |
1144 | high_id = 0xffff | AR5K_KEYTABLE_VALID; | 1144 | high_id = 0xffff | AR5K_KEYTABLE_VALID; |
1145 | } else { | 1145 | } else { |
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 5cbda9245560..a4046a97c016 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c | |||
@@ -794,7 +794,7 @@ static int ath_reserve_key_cache_slot(struct ath_softc *sc) | |||
794 | } | 794 | } |
795 | 795 | ||
796 | static int ath_key_config(struct ath_softc *sc, | 796 | static int ath_key_config(struct ath_softc *sc, |
797 | const u8 *addr, | 797 | struct ieee80211_sta *sta, |
798 | struct ieee80211_key_conf *key) | 798 | struct ieee80211_key_conf *key) |
799 | { | 799 | { |
800 | struct ath9k_keyval hk; | 800 | struct ath9k_keyval hk; |
@@ -828,7 +828,10 @@ static int ath_key_config(struct ath_softc *sc, | |||
828 | } else if (key->keyidx) { | 828 | } else if (key->keyidx) { |
829 | struct ieee80211_vif *vif; | 829 | struct ieee80211_vif *vif; |
830 | 830 | ||
831 | mac = addr; | 831 | if (WARN_ON(!sta)) |
832 | return -EOPNOTSUPP; | ||
833 | mac = sta->addr; | ||
834 | |||
832 | vif = sc->sc_vaps[0]; | 835 | vif = sc->sc_vaps[0]; |
833 | if (vif->type != NL80211_IFTYPE_AP) { | 836 | if (vif->type != NL80211_IFTYPE_AP) { |
834 | /* Only keyidx 0 should be used with unicast key, but | 837 | /* Only keyidx 0 should be used with unicast key, but |
@@ -837,7 +840,10 @@ static int ath_key_config(struct ath_softc *sc, | |||
837 | } else | 840 | } else |
838 | return -EIO; | 841 | return -EIO; |
839 | } else { | 842 | } else { |
840 | mac = addr; | 843 | if (WARN_ON(!sta)) |
844 | return -EOPNOTSUPP; | ||
845 | mac = sta->addr; | ||
846 | |||
841 | if (key->alg == ALG_TKIP) | 847 | if (key->alg == ALG_TKIP) |
842 | idx = ath_reserve_key_cache_slot_tkip(sc); | 848 | idx = ath_reserve_key_cache_slot_tkip(sc); |
843 | else | 849 | else |
@@ -2320,8 +2326,8 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, | |||
2320 | 2326 | ||
2321 | static int ath9k_set_key(struct ieee80211_hw *hw, | 2327 | static int ath9k_set_key(struct ieee80211_hw *hw, |
2322 | enum set_key_cmd cmd, | 2328 | enum set_key_cmd cmd, |
2323 | const u8 *local_addr, | 2329 | struct ieee80211_vif *vif, |
2324 | const u8 *addr, | 2330 | struct ieee80211_sta *sta, |
2325 | struct ieee80211_key_conf *key) | 2331 | struct ieee80211_key_conf *key) |
2326 | { | 2332 | { |
2327 | struct ath_softc *sc = hw->priv; | 2333 | struct ath_softc *sc = hw->priv; |
@@ -2331,7 +2337,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
2331 | 2337 | ||
2332 | switch (cmd) { | 2338 | switch (cmd) { |
2333 | case SET_KEY: | 2339 | case SET_KEY: |
2334 | ret = ath_key_config(sc, addr, key); | 2340 | ret = ath_key_config(sc, sta, key); |
2335 | if (ret >= 0) { | 2341 | if (ret >= 0) { |
2336 | key->hw_key_idx = ret; | 2342 | key->hw_key_idx = ret; |
2337 | /* push IV and Michael MIC generation to stack */ | 2343 | /* push IV and Michael MIC generation to stack */ |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 5ca55dcd0345..19ad5164fce7 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -3476,8 +3476,8 @@ out_unlock_mutex: | |||
3476 | } | 3476 | } |
3477 | 3477 | ||
3478 | static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 3478 | static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
3479 | const u8 *local_addr, const u8 *addr, | 3479 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, |
3480 | struct ieee80211_key_conf *key) | 3480 | struct ieee80211_key_conf *key) |
3481 | { | 3481 | { |
3482 | struct b43_wl *wl = hw_to_b43_wl(hw); | 3482 | struct b43_wl *wl = hw_to_b43_wl(hw); |
3483 | struct b43_wldev *dev; | 3483 | struct b43_wldev *dev; |
@@ -3542,9 +3542,14 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3542 | } | 3542 | } |
3543 | 3543 | ||
3544 | if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { | 3544 | if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { |
3545 | if (WARN_ON(!sta)) { | ||
3546 | err = -EOPNOTSUPP; | ||
3547 | goto out_unlock; | ||
3548 | } | ||
3545 | /* Pairwise key with an assigned MAC address. */ | 3549 | /* Pairwise key with an assigned MAC address. */ |
3546 | err = b43_key_write(dev, -1, algorithm, | 3550 | err = b43_key_write(dev, -1, algorithm, |
3547 | key->key, key->keylen, addr, key); | 3551 | key->key, key->keylen, |
3552 | sta->addr, key); | ||
3548 | } else { | 3553 | } else { |
3549 | /* Group key */ | 3554 | /* Group key */ |
3550 | err = b43_key_write(dev, index, algorithm, | 3555 | err = b43_key_write(dev, index, algorithm, |
@@ -3577,7 +3582,7 @@ out_unlock: | |||
3577 | b43dbg(wl, "%s hardware based encryption for keyidx: %d, " | 3582 | b43dbg(wl, "%s hardware based encryption for keyidx: %d, " |
3578 | "mac: %pM\n", | 3583 | "mac: %pM\n", |
3579 | cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, | 3584 | cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, |
3580 | addr); | 3585 | sta ? sta->addr : "<group key>"); |
3581 | b43_dump_keymemory(dev); | 3586 | b43_dump_keymemory(dev); |
3582 | } | 3587 | } |
3583 | write_unlock(&wl->tx_lock); | 3588 | write_unlock(&wl->tx_lock); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index f3f6dba7a673..dbfee28107a5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -3021,13 +3021,17 @@ static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw, | |||
3021 | } | 3021 | } |
3022 | 3022 | ||
3023 | static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 3023 | static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
3024 | const u8 *local_addr, const u8 *addr, | 3024 | struct ieee80211_vif *vif, |
3025 | struct ieee80211_sta *sta, | ||
3025 | struct ieee80211_key_conf *key) | 3026 | struct ieee80211_key_conf *key) |
3026 | { | 3027 | { |
3027 | struct iwl_priv *priv = hw->priv; | 3028 | struct iwl_priv *priv = hw->priv; |
3028 | int ret = 0; | 3029 | int ret = 0; |
3029 | u8 sta_id = IWL_INVALID_STATION; | 3030 | u8 sta_id = IWL_INVALID_STATION; |
3030 | u8 is_default_wep_key = 0; | 3031 | u8 is_default_wep_key = 0; |
3032 | static const u8 bcast_addr[ETH_ALEN] = | ||
3033 | { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; | ||
3034 | static const u8 *addr; | ||
3031 | 3035 | ||
3032 | IWL_DEBUG_MAC80211("enter\n"); | 3036 | IWL_DEBUG_MAC80211("enter\n"); |
3033 | 3037 | ||
@@ -3036,9 +3040,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3036 | return -EOPNOTSUPP; | 3040 | return -EOPNOTSUPP; |
3037 | } | 3041 | } |
3038 | 3042 | ||
3039 | if (is_zero_ether_addr(addr)) | 3043 | addr = sta ? sta->addr : bcast_addr; |
3040 | /* only support pairwise keys */ | ||
3041 | return -EOPNOTSUPP; | ||
3042 | 3044 | ||
3043 | sta_id = iwl_find_station(priv, addr); | 3045 | sta_id = iwl_find_station(priv, addr); |
3044 | if (sta_id == IWL_INVALID_STATION) { | 3046 | if (sta_id == IWL_INVALID_STATION) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index a176f42fd7cf..43cfc6ec5163 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -6546,12 +6546,16 @@ out_unlock: | |||
6546 | } | 6546 | } |
6547 | 6547 | ||
6548 | static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 6548 | static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
6549 | const u8 *local_addr, const u8 *addr, | 6549 | struct ieee80211_vif *vif, |
6550 | struct ieee80211_key_conf *key) | 6550 | struct ieee80211_sta *sta, |
6551 | struct ieee80211_key_conf *key) | ||
6551 | { | 6552 | { |
6552 | struct iwl_priv *priv = hw->priv; | 6553 | struct iwl_priv *priv = hw->priv; |
6554 | const u8 *addr; | ||
6553 | int rc = 0; | 6555 | int rc = 0; |
6554 | u8 sta_id; | 6556 | u8 sta_id; |
6557 | static const u8 bcast_addr[ETH_ALEN] = | ||
6558 | { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | ||
6555 | 6559 | ||
6556 | IWL_DEBUG_MAC80211("enter\n"); | 6560 | IWL_DEBUG_MAC80211("enter\n"); |
6557 | 6561 | ||
@@ -6560,9 +6564,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
6560 | return -EOPNOTSUPP; | 6564 | return -EOPNOTSUPP; |
6561 | } | 6565 | } |
6562 | 6566 | ||
6563 | if (is_zero_ether_addr(addr)) | 6567 | addr = sta ? sta->addr : bcast_addr; |
6564 | /* only support pairwise keys */ | ||
6565 | return -EOPNOTSUPP; | ||
6566 | 6568 | ||
6567 | sta_id = iwl3945_hw_find_station(priv, addr); | 6569 | sta_id = iwl3945_hw_find_station(priv, addr); |
6568 | if (sta_id == IWL_INVALID_STATION) { | 6570 | if (sta_id == IWL_INVALID_STATION) { |
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 8d2df5b6ecbf..0907e6f246e6 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c | |||
@@ -2127,7 +2127,7 @@ static void p54_bss_info_changed(struct ieee80211_hw *dev, | |||
2127 | } | 2127 | } |
2128 | 2128 | ||
2129 | static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, | 2129 | static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, |
2130 | const u8 *local_address, const u8 *address, | 2130 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, |
2131 | struct ieee80211_key_conf *key) | 2131 | struct ieee80211_key_conf *key) |
2132 | { | 2132 | { |
2133 | struct p54_common *priv = dev->priv; | 2133 | struct p54_common *priv = dev->priv; |
@@ -2191,8 +2191,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, | |||
2191 | rxkey->entry = key->keyidx; | 2191 | rxkey->entry = key->keyidx; |
2192 | rxkey->key_id = key->keyidx; | 2192 | rxkey->key_id = key->keyidx; |
2193 | rxkey->key_type = algo; | 2193 | rxkey->key_type = algo; |
2194 | if (address) | 2194 | if (sta) |
2195 | memcpy(rxkey->mac, address, ETH_ALEN); | 2195 | memcpy(rxkey->mac, sta->addr, ETH_ALEN); |
2196 | else | 2196 | else |
2197 | memset(rxkey->mac, ~0, ETH_ALEN); | 2197 | memset(rxkey->mac, ~0, ETH_ALEN); |
2198 | if (key->alg != ALG_TKIP) { | 2198 | if (key->alg != ALG_TKIP) { |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 1ef3434a2bae..890c7216cf38 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -931,7 +931,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw, | |||
931 | int mc_count, struct dev_addr_list *mc_list); | 931 | int mc_count, struct dev_addr_list *mc_list); |
932 | #ifdef CONFIG_RT2X00_LIB_CRYPTO | 932 | #ifdef CONFIG_RT2X00_LIB_CRYPTO |
933 | int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 933 | int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
934 | const u8 *local_address, const u8 *address, | 934 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, |
935 | struct ieee80211_key_conf *key); | 935 | struct ieee80211_key_conf *key); |
936 | #else | 936 | #else |
937 | #define rt2x00mac_set_key NULL | 937 | #define rt2x00mac_set_key NULL |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index bf7755a21645..3e204406f44f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -502,15 +502,17 @@ static void memcpy_tkip(struct rt2x00lib_crypto *crypto, u8 *key, u8 key_len) | |||
502 | } | 502 | } |
503 | 503 | ||
504 | int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 504 | int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
505 | const u8 *local_address, const u8 *address, | 505 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, |
506 | struct ieee80211_key_conf *key) | 506 | struct ieee80211_key_conf *key) |
507 | { | 507 | { |
508 | struct rt2x00_dev *rt2x00dev = hw->priv; | 508 | struct rt2x00_dev *rt2x00dev = hw->priv; |
509 | struct ieee80211_sta *sta; | 509 | struct rt2x00_intf *intf = vif_to_intf(vif); |
510 | int (*set_key) (struct rt2x00_dev *rt2x00dev, | 510 | int (*set_key) (struct rt2x00_dev *rt2x00dev, |
511 | struct rt2x00lib_crypto *crypto, | 511 | struct rt2x00lib_crypto *crypto, |
512 | struct ieee80211_key_conf *key); | 512 | struct ieee80211_key_conf *key); |
513 | struct rt2x00lib_crypto crypto; | 513 | struct rt2x00lib_crypto crypto; |
514 | static const u8 bcast_addr[ETH_ALEN] = | ||
515 | { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; | ||
514 | 516 | ||
515 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) | 517 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) |
516 | return 0; | 518 | return 0; |
@@ -528,32 +530,25 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
528 | if (rt2x00dev->intf_sta_count) | 530 | if (rt2x00dev->intf_sta_count) |
529 | crypto.bssidx = 0; | 531 | crypto.bssidx = 0; |
530 | else | 532 | else |
531 | crypto.bssidx = | 533 | crypto.bssidx = intf->mac[5] & (rt2x00dev->ops->max_ap_intf - 1); |
532 | local_address[5] & (rt2x00dev->ops->max_ap_intf - 1); | ||
533 | 534 | ||
534 | crypto.cipher = rt2x00crypto_key_to_cipher(key); | 535 | crypto.cipher = rt2x00crypto_key_to_cipher(key); |
535 | if (crypto.cipher == CIPHER_NONE) | 536 | if (crypto.cipher == CIPHER_NONE) |
536 | return -EOPNOTSUPP; | 537 | return -EOPNOTSUPP; |
537 | 538 | ||
538 | crypto.cmd = cmd; | 539 | crypto.cmd = cmd; |
539 | crypto.address = address; | 540 | |
541 | if (sta) { | ||
542 | /* some drivers need the AID */ | ||
543 | crypto.aid = sta->aid; | ||
544 | crypto.address = sta->addr; | ||
545 | } else | ||
546 | crypto.address = bcast_addr; | ||
540 | 547 | ||
541 | if (crypto.cipher == CIPHER_TKIP) | 548 | if (crypto.cipher == CIPHER_TKIP) |
542 | memcpy_tkip(&crypto, &key->key[0], key->keylen); | 549 | memcpy_tkip(&crypto, &key->key[0], key->keylen); |
543 | else | 550 | else |
544 | memcpy(&crypto.key, &key->key[0], key->keylen); | 551 | memcpy(&crypto.key, &key->key[0], key->keylen); |
545 | |||
546 | /* | ||
547 | * Discover the Association ID from mac80211. | ||
548 | * Some drivers need this information when updating the | ||
549 | * hardware key (either adding or removing). | ||
550 | */ | ||
551 | rcu_read_lock(); | ||
552 | sta = ieee80211_find_sta(hw, address); | ||
553 | if (sta) | ||
554 | crypto.aid = sta->aid; | ||
555 | rcu_read_unlock(); | ||
556 | |||
557 | /* | 552 | /* |
558 | * Each BSS has a maximum of 4 shared keys. | 553 | * Each BSS has a maximum of 4 shared keys. |
559 | * Shared key index values: | 554 | * Shared key index values: |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index ffcbd12775a4..9215b1ec90ec 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -715,8 +715,8 @@ enum ieee80211_key_flags { | |||
715 | * - Temporal Encryption Key (128 bits) | 715 | * - Temporal Encryption Key (128 bits) |
716 | * - Temporal Authenticator Tx MIC Key (64 bits) | 716 | * - Temporal Authenticator Tx MIC Key (64 bits) |
717 | * - Temporal Authenticator Rx MIC Key (64 bits) | 717 | * - Temporal Authenticator Rx MIC Key (64 bits) |
718 | * @icv_len: FIXME | 718 | * @icv_len: The ICV length for this key type |
719 | * @iv_len: FIXME | 719 | * @iv_len: The IV length for this key type |
720 | */ | 720 | */ |
721 | struct ieee80211_key_conf { | 721 | struct ieee80211_key_conf { |
722 | enum ieee80211_key_alg alg; | 722 | enum ieee80211_key_alg alg; |
@@ -1019,16 +1019,12 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, | |||
1019 | * | 1019 | * |
1020 | * The set_key() callback in the &struct ieee80211_ops for a given | 1020 | * The set_key() callback in the &struct ieee80211_ops for a given |
1021 | * device is called to enable hardware acceleration of encryption and | 1021 | * device is called to enable hardware acceleration of encryption and |
1022 | * decryption. The callback takes an @address parameter that will be | 1022 | * decryption. The callback takes a @sta parameter that will be NULL |
1023 | * the broadcast address for default keys, the other station's hardware | 1023 | * for default keys or keys used for transmission only, or point to |
1024 | * address for individual keys or the zero address for keys that will | 1024 | * the station information for the peer for individual keys. |
1025 | * be used only for transmission. | ||
1026 | * Multiple transmission keys with the same key index may be used when | 1025 | * Multiple transmission keys with the same key index may be used when |
1027 | * VLANs are configured for an access point. | 1026 | * VLANs are configured for an access point. |
1028 | * | 1027 | * |
1029 | * The @local_address parameter will always be set to our own address, | ||
1030 | * this is only relevant if you support multiple local addresses. | ||
1031 | * | ||
1032 | * When transmitting, the TX control data will use the @hw_key_idx | 1028 | * When transmitting, the TX control data will use the @hw_key_idx |
1033 | * selected by the driver by modifying the &struct ieee80211_key_conf | 1029 | * selected by the driver by modifying the &struct ieee80211_key_conf |
1034 | * pointed to by the @key parameter to the set_key() function. | 1030 | * pointed to by the @key parameter to the set_key() function. |
@@ -1233,8 +1229,8 @@ enum ieee80211_ampdu_mlme_action { | |||
1233 | * | 1229 | * |
1234 | * @set_key: See the section "Hardware crypto acceleration" | 1230 | * @set_key: See the section "Hardware crypto acceleration" |
1235 | * This callback can sleep, and is only called between add_interface | 1231 | * This callback can sleep, and is only called between add_interface |
1236 | * and remove_interface calls, i.e. while the interface with the | 1232 | * and remove_interface calls, i.e. while the given virtual interface |
1237 | * given local_address is enabled. | 1233 | * is enabled. |
1238 | * | 1234 | * |
1239 | * @update_tkip_key: See the section "Hardware crypto acceleration" | 1235 | * @update_tkip_key: See the section "Hardware crypto acceleration" |
1240 | * This callback will be called in the context of Rx. Called for drivers | 1236 | * This callback will be called in the context of Rx. Called for drivers |
@@ -1311,7 +1307,7 @@ struct ieee80211_ops { | |||
1311 | int (*set_tim)(struct ieee80211_hw *hw, struct ieee80211_sta *sta, | 1307 | int (*set_tim)(struct ieee80211_hw *hw, struct ieee80211_sta *sta, |
1312 | bool set); | 1308 | bool set); |
1313 | int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 1309 | int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
1314 | const u8 *local_address, const u8 *address, | 1310 | struct ieee80211_vif *vif, struct ieee80211_sta *sta, |
1315 | struct ieee80211_key_conf *key); | 1311 | struct ieee80211_key_conf *key); |
1316 | void (*update_tkip_key)(struct ieee80211_hw *hw, | 1312 | void (*update_tkip_key)(struct ieee80211_hw *hw, |
1317 | struct ieee80211_key_conf *conf, const u8 *address, | 1313 | struct ieee80211_key_conf *conf, const u8 *address, |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 999f7aa42326..b0a025c9b615 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -47,7 +47,6 @@ | |||
47 | */ | 47 | */ |
48 | 48 | ||
49 | static const u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 49 | static const u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
50 | static const u8 zero_addr[ETH_ALEN]; | ||
51 | 50 | ||
52 | /* key mutex: used to synchronise todo runners */ | 51 | /* key mutex: used to synchronise todo runners */ |
53 | static DEFINE_MUTEX(key_mutex); | 52 | static DEFINE_MUTEX(key_mutex); |
@@ -108,29 +107,18 @@ static void assert_key_lock(void) | |||
108 | WARN_ON(!mutex_is_locked(&key_mutex)); | 107 | WARN_ON(!mutex_is_locked(&key_mutex)); |
109 | } | 108 | } |
110 | 109 | ||
111 | static const u8 *get_mac_for_key(struct ieee80211_key *key) | 110 | static struct ieee80211_sta *get_sta_for_key(struct ieee80211_key *key) |
112 | { | 111 | { |
113 | const u8 *addr = bcast_addr; | ||
114 | |||
115 | /* | ||
116 | * If we're an AP we won't ever receive frames with a non-WEP | ||
117 | * group key so we tell the driver that by using the zero MAC | ||
118 | * address to indicate a transmit-only key. | ||
119 | */ | ||
120 | if (key->conf.alg != ALG_WEP && | ||
121 | (key->sdata->vif.type == NL80211_IFTYPE_AP || | ||
122 | key->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) | ||
123 | addr = zero_addr; | ||
124 | |||
125 | if (key->sta) | 112 | if (key->sta) |
126 | addr = key->sta->sta.addr; | 113 | return &key->sta->sta; |
127 | 114 | ||
128 | return addr; | 115 | return NULL; |
129 | } | 116 | } |
130 | 117 | ||
131 | static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | 118 | static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) |
132 | { | 119 | { |
133 | const u8 *addr; | 120 | struct ieee80211_sub_if_data *sdata; |
121 | struct ieee80211_sta *sta; | ||
134 | int ret; | 122 | int ret; |
135 | 123 | ||
136 | assert_key_lock(); | 124 | assert_key_lock(); |
@@ -139,11 +127,16 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
139 | if (!key->local->ops->set_key) | 127 | if (!key->local->ops->set_key) |
140 | return; | 128 | return; |
141 | 129 | ||
142 | addr = get_mac_for_key(key); | 130 | sta = get_sta_for_key(key); |
131 | |||
132 | sdata = key->sdata; | ||
133 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
134 | sdata = container_of(sdata->bss, | ||
135 | struct ieee80211_sub_if_data, | ||
136 | u.ap); | ||
143 | 137 | ||
144 | ret = key->local->ops->set_key(local_to_hw(key->local), SET_KEY, | 138 | ret = key->local->ops->set_key(local_to_hw(key->local), SET_KEY, |
145 | key->sdata->dev->dev_addr, addr, | 139 | &sdata->vif, sta, &key->conf); |
146 | &key->conf); | ||
147 | 140 | ||
148 | if (!ret) { | 141 | if (!ret) { |
149 | spin_lock(&todo_lock); | 142 | spin_lock(&todo_lock); |
@@ -155,12 +148,13 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
155 | printk(KERN_ERR "mac80211-%s: failed to set key " | 148 | printk(KERN_ERR "mac80211-%s: failed to set key " |
156 | "(%d, %pM) to hardware (%d)\n", | 149 | "(%d, %pM) to hardware (%d)\n", |
157 | wiphy_name(key->local->hw.wiphy), | 150 | wiphy_name(key->local->hw.wiphy), |
158 | key->conf.keyidx, addr, ret); | 151 | key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); |
159 | } | 152 | } |
160 | 153 | ||
161 | static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) | 154 | static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) |
162 | { | 155 | { |
163 | const u8 *addr; | 156 | struct ieee80211_sub_if_data *sdata; |
157 | struct ieee80211_sta *sta; | ||
164 | int ret; | 158 | int ret; |
165 | 159 | ||
166 | assert_key_lock(); | 160 | assert_key_lock(); |
@@ -176,17 +170,22 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) | |||
176 | } | 170 | } |
177 | spin_unlock(&todo_lock); | 171 | spin_unlock(&todo_lock); |
178 | 172 | ||
179 | addr = get_mac_for_key(key); | 173 | sta = get_sta_for_key(key); |
174 | sdata = key->sdata; | ||
175 | |||
176 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
177 | sdata = container_of(sdata->bss, | ||
178 | struct ieee80211_sub_if_data, | ||
179 | u.ap); | ||
180 | 180 | ||
181 | ret = key->local->ops->set_key(local_to_hw(key->local), DISABLE_KEY, | 181 | ret = key->local->ops->set_key(local_to_hw(key->local), DISABLE_KEY, |
182 | key->sdata->dev->dev_addr, addr, | 182 | &sdata->vif, sta, &key->conf); |
183 | &key->conf); | ||
184 | 183 | ||
185 | if (ret) | 184 | if (ret) |
186 | printk(KERN_ERR "mac80211-%s: failed to remove key " | 185 | printk(KERN_ERR "mac80211-%s: failed to remove key " |
187 | "(%d, %pM) from hardware (%d)\n", | 186 | "(%d, %pM) from hardware (%d)\n", |
188 | wiphy_name(key->local->hw.wiphy), | 187 | wiphy_name(key->local->hw.wiphy), |
189 | key->conf.keyidx, addr, ret); | 188 | key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); |
190 | 189 | ||
191 | spin_lock(&todo_lock); | 190 | spin_lock(&todo_lock); |
192 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; | 191 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; |