aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-10-05 13:39:30 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-10-06 16:30:40 -0400
commite31b82136d1adc7a599b6e99d3321e5831841f5a (patch)
treec72d78d4cccfd08587e909c7efe59956f1cbc23e /net/mac80211
parent53f73c09d64f1fa7d7e6e8b6bb7468d42eddc92d (diff)
cfg80211/mac80211: allow per-station GTKs
This adds API to allow adding per-station GTKs, updates mac80211 to support it, and also allows drivers to remove a key from hwaccel again when this may be necessary due to multiple GTKs. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c32
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/key.c95
-rw-r--r--net/mac80211/key.h3
-rw-r--r--net/mac80211/rx.c41
-rw-r--r--net/mac80211/sta_info.c10
-rw-r--r--net/mac80211/sta_info.h6
-rw-r--r--net/mac80211/tx.c2
8 files changed, 123 insertions, 68 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 94bf550bd4c9..8b0e874a3d65 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -103,7 +103,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
103} 103}
104 104
105static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, 105static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
106 u8 key_idx, const u8 *mac_addr, 106 u8 key_idx, bool pairwise, const u8 *mac_addr,
107 struct key_params *params) 107 struct key_params *params)
108{ 108{
109 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 109 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -131,6 +131,9 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
131 if (IS_ERR(key)) 131 if (IS_ERR(key))
132 return PTR_ERR(key); 132 return PTR_ERR(key);
133 133
134 if (pairwise)
135 key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE;
136
134 mutex_lock(&sdata->local->sta_mtx); 137 mutex_lock(&sdata->local->sta_mtx);
135 138
136 if (mac_addr) { 139 if (mac_addr) {
@@ -153,7 +156,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
153} 156}
154 157
155static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, 158static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
156 u8 key_idx, const u8 *mac_addr) 159 u8 key_idx, bool pairwise, const u8 *mac_addr)
157{ 160{
158 struct ieee80211_sub_if_data *sdata; 161 struct ieee80211_sub_if_data *sdata;
159 struct sta_info *sta; 162 struct sta_info *sta;
@@ -170,10 +173,17 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
170 if (!sta) 173 if (!sta)
171 goto out_unlock; 174 goto out_unlock;
172 175
173 if (sta->key) { 176 if (pairwise) {
174 ieee80211_key_free(sdata->local, sta->key); 177 if (sta->ptk) {
175 WARN_ON(sta->key); 178 ieee80211_key_free(sdata->local, sta->ptk);
176 ret = 0; 179 ret = 0;
180 }
181 } else {
182 if (sta->gtk[key_idx]) {
183 ieee80211_key_free(sdata->local,
184 sta->gtk[key_idx]);
185 ret = 0;
186 }
177 } 187 }
178 188
179 goto out_unlock; 189 goto out_unlock;
@@ -195,7 +205,8 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
195} 205}
196 206
197static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, 207static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
198 u8 key_idx, const u8 *mac_addr, void *cookie, 208 u8 key_idx, bool pairwise, const u8 *mac_addr,
209 void *cookie,
199 void (*callback)(void *cookie, 210 void (*callback)(void *cookie,
200 struct key_params *params)) 211 struct key_params *params))
201{ 212{
@@ -203,7 +214,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
203 struct sta_info *sta = NULL; 214 struct sta_info *sta = NULL;
204 u8 seq[6] = {0}; 215 u8 seq[6] = {0};
205 struct key_params params; 216 struct key_params params;
206 struct ieee80211_key *key; 217 struct ieee80211_key *key = NULL;
207 u32 iv32; 218 u32 iv32;
208 u16 iv16; 219 u16 iv16;
209 int err = -ENOENT; 220 int err = -ENOENT;
@@ -217,7 +228,10 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
217 if (!sta) 228 if (!sta)
218 goto out; 229 goto out;
219 230
220 key = sta->key; 231 if (pairwise)
232 key = sta->ptk;
233 else if (key_idx < NUM_DEFAULT_KEYS)
234 key = sta->gtk[key_idx];
221 } else 235 } else
222 key = sdata->keys[key_idx]; 236 key = sdata->keys[key_idx];
223 237
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 76c2b50ec6f8..f0610fa4fbe0 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -549,8 +549,6 @@ struct ieee80211_sub_if_data {
549 struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; 549 struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
550 unsigned int fragment_next; 550 unsigned int fragment_next;
551 551
552#define NUM_DEFAULT_KEYS 4
553#define NUM_DEFAULT_MGMT_KEYS 2
554 struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; 552 struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
555 struct ieee80211_key *default_key; 553 struct ieee80211_key *default_key;
556 struct ieee80211_key *default_mgmt_key; 554 struct ieee80211_key *default_mgmt_key;
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 6a63d1abd14d..ccd676b2f599 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -68,15 +68,21 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
68 68
69 might_sleep(); 69 might_sleep();
70 70
71 if (!key->local->ops->set_key) { 71 if (!key->local->ops->set_key)
72 ret = -EOPNOTSUPP;
73 goto out_unsupported; 72 goto out_unsupported;
74 }
75 73
76 assert_key_lock(key->local); 74 assert_key_lock(key->local);
77 75
78 sta = get_sta_for_key(key); 76 sta = get_sta_for_key(key);
79 77
78 /*
79 * If this is a per-STA GTK, check if it
80 * is supported; if not, return.
81 */
82 if (sta && !(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE) &&
83 !(key->local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK))
84 goto out_unsupported;
85
80 sdata = key->sdata; 86 sdata = key->sdata;
81 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 87 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
82 sdata = container_of(sdata->bss, 88 sdata = container_of(sdata->bss,
@@ -85,31 +91,28 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
85 91
86 ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf); 92 ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf);
87 93
88 if (!ret) 94 if (!ret) {
89 key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; 95 key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
96 return 0;
97 }
90 98
91 if (ret && ret != -ENOSPC && ret != -EOPNOTSUPP) 99 if (ret != -ENOSPC && ret != -EOPNOTSUPP)
92 wiphy_err(key->local->hw.wiphy, 100 wiphy_err(key->local->hw.wiphy,
93 "failed to set key (%d, %pM) to hardware (%d)\n", 101 "failed to set key (%d, %pM) to hardware (%d)\n",
94 key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); 102 key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
95 103
96out_unsupported: 104 out_unsupported:
97 if (ret) { 105 switch (key->conf.cipher) {
98 switch (key->conf.cipher) { 106 case WLAN_CIPHER_SUITE_WEP40:
99 case WLAN_CIPHER_SUITE_WEP40: 107 case WLAN_CIPHER_SUITE_WEP104:
100 case WLAN_CIPHER_SUITE_WEP104: 108 case WLAN_CIPHER_SUITE_TKIP:
101 case WLAN_CIPHER_SUITE_TKIP: 109 case WLAN_CIPHER_SUITE_CCMP:
102 case WLAN_CIPHER_SUITE_CCMP: 110 case WLAN_CIPHER_SUITE_AES_CMAC:
103 case WLAN_CIPHER_SUITE_AES_CMAC: 111 /* all of these we can do in software */
104 /* all of these we can do in software */ 112 return 0;
105 ret = 0; 113 default:
106 break; 114 return -EINVAL;
107 default:
108 ret = -EINVAL;
109 }
110 } 115 }
111
112 return ret;
113} 116}
114 117
115static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) 118static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
@@ -147,6 +150,26 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
147 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; 150 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
148} 151}
149 152
153void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
154{
155 struct ieee80211_key *key;
156
157 key = container_of(key_conf, struct ieee80211_key, conf);
158
159 might_sleep();
160 assert_key_lock(key->local);
161
162 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
163
164 /*
165 * Flush TX path to avoid attempts to use this key
166 * after this function returns. Until then, drivers
167 * must be prepared to handle the key.
168 */
169 synchronize_rcu();
170}
171EXPORT_SYMBOL_GPL(ieee80211_key_removed);
172
150static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, 173static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
151 int idx) 174 int idx)
152{ 175{
@@ -202,6 +225,7 @@ void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
202 225
203static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, 226static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
204 struct sta_info *sta, 227 struct sta_info *sta,
228 bool pairwise,
205 struct ieee80211_key *old, 229 struct ieee80211_key *old,
206 struct ieee80211_key *new) 230 struct ieee80211_key *new)
207{ 231{
@@ -210,8 +234,14 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
210 if (new) 234 if (new)
211 list_add(&new->list, &sdata->key_list); 235 list_add(&new->list, &sdata->key_list);
212 236
213 if (sta) { 237 if (sta && pairwise) {
214 rcu_assign_pointer(sta->key, new); 238 rcu_assign_pointer(sta->ptk, new);
239 } else if (sta) {
240 if (old)
241 idx = old->conf.keyidx;
242 else
243 idx = new->conf.keyidx;
244 rcu_assign_pointer(sta->gtk[idx], new);
215 } else { 245 } else {
216 WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx); 246 WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx);
217 247
@@ -355,6 +385,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
355{ 385{
356 struct ieee80211_key *old_key; 386 struct ieee80211_key *old_key;
357 int idx, ret; 387 int idx, ret;
388 bool pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE;
358 389
359 BUG_ON(!sdata); 390 BUG_ON(!sdata);
360 BUG_ON(!key); 391 BUG_ON(!key);
@@ -371,13 +402,6 @@ int ieee80211_key_link(struct ieee80211_key *key,
371 */ 402 */
372 if (test_sta_flags(sta, WLAN_STA_WME)) 403 if (test_sta_flags(sta, WLAN_STA_WME))
373 key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; 404 key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA;
374
375 /*
376 * This key is for a specific sta interface,
377 * inform the driver that it should try to store
378 * this key as pairwise key.
379 */
380 key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE;
381 } else { 405 } else {
382 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 406 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
383 struct sta_info *ap; 407 struct sta_info *ap;
@@ -399,12 +423,14 @@ int ieee80211_key_link(struct ieee80211_key *key,
399 423
400 mutex_lock(&sdata->local->key_mtx); 424 mutex_lock(&sdata->local->key_mtx);
401 425
402 if (sta) 426 if (sta && pairwise)
403 old_key = sta->key; 427 old_key = sta->ptk;
428 else if (sta)
429 old_key = sta->gtk[idx];
404 else 430 else
405 old_key = sdata->keys[idx]; 431 old_key = sdata->keys[idx];
406 432
407 __ieee80211_key_replace(sdata, sta, old_key, key); 433 __ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
408 __ieee80211_key_destroy(old_key); 434 __ieee80211_key_destroy(old_key);
409 435
410 ieee80211_debugfs_key_add(key); 436 ieee80211_debugfs_key_add(key);
@@ -423,7 +449,8 @@ static void __ieee80211_key_free(struct ieee80211_key *key)
423 */ 449 */
424 if (key->sdata) 450 if (key->sdata)
425 __ieee80211_key_replace(key->sdata, key->sta, 451 __ieee80211_key_replace(key->sdata, key->sta,
426 key, NULL); 452 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
453 key, NULL);
427 __ieee80211_key_destroy(key); 454 __ieee80211_key_destroy(key);
428} 455}
429 456
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index cb9a4a65cc68..0db1c0f5f697 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -16,6 +16,9 @@
16#include <linux/rcupdate.h> 16#include <linux/rcupdate.h>
17#include <net/mac80211.h> 17#include <net/mac80211.h>
18 18
19#define NUM_DEFAULT_KEYS 4
20#define NUM_DEFAULT_MGMT_KEYS 2
21
19#define WEP_IV_LEN 4 22#define WEP_IV_LEN 4
20#define WEP_ICV_LEN 4 23#define WEP_ICV_LEN 4
21#define ALG_TKIP_KEY_LEN 32 24#define ALG_TKIP_KEY_LEN 32
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b3e161ffa4b3..b67221def584 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -846,7 +846,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
846 int keyidx; 846 int keyidx;
847 int hdrlen; 847 int hdrlen;
848 ieee80211_rx_result result = RX_DROP_UNUSABLE; 848 ieee80211_rx_result result = RX_DROP_UNUSABLE;
849 struct ieee80211_key *stakey = NULL; 849 struct ieee80211_key *sta_ptk = NULL;
850 int mmie_keyidx = -1; 850 int mmie_keyidx = -1;
851 __le16 fc; 851 __le16 fc;
852 852
@@ -888,15 +888,15 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
888 rx->key = NULL; 888 rx->key = NULL;
889 889
890 if (rx->sta) 890 if (rx->sta)
891 stakey = rcu_dereference(rx->sta->key); 891 sta_ptk = rcu_dereference(rx->sta->ptk);
892 892
893 fc = hdr->frame_control; 893 fc = hdr->frame_control;
894 894
895 if (!ieee80211_has_protected(fc)) 895 if (!ieee80211_has_protected(fc))
896 mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); 896 mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);
897 897
898 if (!is_multicast_ether_addr(hdr->addr1) && stakey) { 898 if (!is_multicast_ether_addr(hdr->addr1) && sta_ptk) {
899 rx->key = stakey; 899 rx->key = sta_ptk;
900 if ((status->flag & RX_FLAG_DECRYPTED) && 900 if ((status->flag & RX_FLAG_DECRYPTED) &&
901 (status->flag & RX_FLAG_IV_STRIPPED)) 901 (status->flag & RX_FLAG_IV_STRIPPED))
902 return RX_CONTINUE; 902 return RX_CONTINUE;
@@ -912,7 +912,10 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
912 if (mmie_keyidx < NUM_DEFAULT_KEYS || 912 if (mmie_keyidx < NUM_DEFAULT_KEYS ||
913 mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) 913 mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
914 return RX_DROP_MONITOR; /* unexpected BIP keyidx */ 914 return RX_DROP_MONITOR; /* unexpected BIP keyidx */
915 rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); 915 if (rx->sta)
916 rx->key = rcu_dereference(rx->sta->gtk[mmie_keyidx]);
917 if (!rx->key)
918 rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]);
916 } else if (!ieee80211_has_protected(fc)) { 919 } else if (!ieee80211_has_protected(fc)) {
917 /* 920 /*
918 * The frame was not protected, so skip decryption. However, we 921 * The frame was not protected, so skip decryption. However, we
@@ -955,17 +958,25 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
955 skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1); 958 skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1);
956 keyidx = keyid >> 6; 959 keyidx = keyid >> 6;
957 960
958 rx->key = rcu_dereference(rx->sdata->keys[keyidx]); 961 /* check per-station GTK first, if multicast packet */
962 if (is_multicast_ether_addr(hdr->addr1) && rx->sta)
963 rx->key = rcu_dereference(rx->sta->gtk[keyidx]);
959 964
960 /* 965 /* if not found, try default key */
961 * RSNA-protected unicast frames should always be sent with 966 if (!rx->key) {
962 * pairwise or station-to-station keys, but for WEP we allow 967 rx->key = rcu_dereference(rx->sdata->keys[keyidx]);
963 * using a key index as well. 968
964 */ 969 /*
965 if (rx->key && rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 && 970 * RSNA-protected unicast frames should always be
966 rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 && 971 * sent with pairwise or station-to-station keys,
967 !is_multicast_ether_addr(hdr->addr1)) 972 * but for WEP we allow using a key index as well.
968 rx->key = NULL; 973 */
974 if (rx->key &&
975 rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 &&
976 rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 &&
977 !is_multicast_ether_addr(hdr->addr1))
978 rx->key = NULL;
979 }
969 } 980 }
970 981
971 if (rx->key) { 982 if (rx->key) {
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index aeaf2d6fccc8..6d8f897d8763 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -616,7 +616,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
616 struct ieee80211_sub_if_data *sdata; 616 struct ieee80211_sub_if_data *sdata;
617 struct sk_buff *skb; 617 struct sk_buff *skb;
618 unsigned long flags; 618 unsigned long flags;
619 int ret; 619 int ret, i;
620 620
621 might_sleep(); 621 might_sleep();
622 622
@@ -644,10 +644,10 @@ static int __must_check __sta_info_destroy(struct sta_info *sta)
644 if (ret) 644 if (ret)
645 return ret; 645 return ret;
646 646
647 if (sta->key) { 647 for (i = 0; i < NUM_DEFAULT_KEYS; i++)
648 ieee80211_key_free(local, sta->key); 648 ieee80211_key_free(local, sta->gtk[i]);
649 WARN_ON(sta->key); 649 if (sta->ptk)
650 } 650 ieee80211_key_free(local, sta->ptk);
651 651
652 sta->dead = true; 652 sta->dead = true;
653 653
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index cf21a2e8134f..9265acadef32 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -199,7 +199,8 @@ enum plink_state {
199 * @hnext: hash table linked list pointer 199 * @hnext: hash table linked list pointer
200 * @local: pointer to the global information 200 * @local: pointer to the global information
201 * @sdata: virtual interface this station belongs to 201 * @sdata: virtual interface this station belongs to
202 * @key: peer key negotiated with this station, if any 202 * @ptk: peer key negotiated with this station, if any
203 * @gtk: group keys negotiated with this station, if any
203 * @rate_ctrl: rate control algorithm reference 204 * @rate_ctrl: rate control algorithm reference
204 * @rate_ctrl_priv: rate control private per-STA pointer 205 * @rate_ctrl_priv: rate control private per-STA pointer
205 * @last_tx_rate: rate used for last transmit, to report to userspace as 206 * @last_tx_rate: rate used for last transmit, to report to userspace as
@@ -254,7 +255,8 @@ struct sta_info {
254 struct sta_info *hnext; 255 struct sta_info *hnext;
255 struct ieee80211_local *local; 256 struct ieee80211_local *local;
256 struct ieee80211_sub_if_data *sdata; 257 struct ieee80211_sub_if_data *sdata;
257 struct ieee80211_key *key; 258 struct ieee80211_key *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
259 struct ieee80211_key *ptk;
258 struct rate_control_ref *rate_ctrl; 260 struct rate_control_ref *rate_ctrl;
259 void *rate_ctrl_priv; 261 void *rate_ctrl_priv;
260 spinlock_t lock; 262 spinlock_t lock;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 258fbdbedbdf..96c594309506 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -532,7 +532,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
532 532
533 if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) 533 if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT))
534 tx->key = NULL; 534 tx->key = NULL;
535 else if (tx->sta && (key = rcu_dereference(tx->sta->key))) 535 else if (tx->sta && (key = rcu_dereference(tx->sta->ptk)))
536 tx->key = key; 536 tx->key = key;
537 else if (ieee80211_is_mgmt(hdr->frame_control) && 537 else if (ieee80211_is_mgmt(hdr->frame_control) &&
538 is_multicast_ether_addr(hdr->addr1) && 538 is_multicast_ether_addr(hdr->addr1) &&