diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/cfg.c | 15 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 226 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 3 | ||||
-rw-r--r-- | net/mac80211/iface.c | 19 | ||||
-rw-r--r-- | net/mac80211/key.c | 154 | ||||
-rw-r--r-- | net/mac80211/main.c | 3 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 3 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 20 | ||||
-rw-r--r-- | net/mac80211/rate.c | 23 | ||||
-rw-r--r-- | net/mac80211/rc80211_minstrel_ht.c | 5 | ||||
-rw-r--r-- | net/mac80211/rx.c | 407 | ||||
-rw-r--r-- | net/mac80211/tx.c | 14 | ||||
-rw-r--r-- | net/mac80211/util.c | 2 |
13 files changed, 567 insertions, 327 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 31fc2247bc37..2e7855a1b10d 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -2302,14 +2302,25 @@ static void ieee80211_rfkill_poll(struct wiphy *wiphy) | |||
2302 | } | 2302 | } |
2303 | 2303 | ||
2304 | #ifdef CONFIG_NL80211_TESTMODE | 2304 | #ifdef CONFIG_NL80211_TESTMODE |
2305 | static int ieee80211_testmode_cmd(struct wiphy *wiphy, void *data, int len) | 2305 | static int ieee80211_testmode_cmd(struct wiphy *wiphy, |
2306 | struct wireless_dev *wdev, | ||
2307 | void *data, int len) | ||
2306 | { | 2308 | { |
2307 | struct ieee80211_local *local = wiphy_priv(wiphy); | 2309 | struct ieee80211_local *local = wiphy_priv(wiphy); |
2310 | struct ieee80211_vif *vif = NULL; | ||
2308 | 2311 | ||
2309 | if (!local->ops->testmode_cmd) | 2312 | if (!local->ops->testmode_cmd) |
2310 | return -EOPNOTSUPP; | 2313 | return -EOPNOTSUPP; |
2311 | 2314 | ||
2312 | return local->ops->testmode_cmd(&local->hw, data, len); | 2315 | if (wdev) { |
2316 | struct ieee80211_sub_if_data *sdata; | ||
2317 | |||
2318 | sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); | ||
2319 | if (sdata->flags & IEEE80211_SDATA_IN_DRIVER) | ||
2320 | vif = &sdata->vif; | ||
2321 | } | ||
2322 | |||
2323 | return local->ops->testmode_cmd(&local->hw, vif, data, len); | ||
2313 | } | 2324 | } |
2314 | 2325 | ||
2315 | static int ieee80211_testmode_dump(struct wiphy *wiphy, | 2326 | static int ieee80211_testmode_dump(struct wiphy *wiphy, |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index e08387cdc8fd..a12afe77bb26 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -34,13 +34,12 @@ | |||
34 | 34 | ||
35 | #define IEEE80211_IBSS_MAX_STA_ENTRIES 128 | 35 | #define IEEE80211_IBSS_MAX_STA_ENTRIES 128 |
36 | 36 | ||
37 | 37 | static struct beacon_data * | |
38 | static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | 38 | ieee80211_ibss_build_presp(struct ieee80211_sub_if_data *sdata, |
39 | const u8 *bssid, const int beacon_int, | 39 | const int beacon_int, const u32 basic_rates, |
40 | struct ieee80211_channel *chan, | 40 | const u16 capability, u64 tsf, |
41 | const u32 basic_rates, | 41 | struct cfg80211_chan_def *chandef, |
42 | const u16 capability, u64 tsf, | 42 | bool *have_higher_than_11mbit) |
43 | bool creator) | ||
44 | { | 43 | { |
45 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 44 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
46 | struct ieee80211_local *local = sdata->local; | 45 | struct ieee80211_local *local = sdata->local; |
@@ -48,70 +47,11 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
48 | struct ieee80211_mgmt *mgmt; | 47 | struct ieee80211_mgmt *mgmt; |
49 | u8 *pos; | 48 | u8 *pos; |
50 | struct ieee80211_supported_band *sband; | 49 | struct ieee80211_supported_band *sband; |
51 | struct cfg80211_bss *bss; | 50 | u32 rate_flags, rates = 0, rates_added = 0; |
52 | u32 bss_change, rate_flags, rates = 0, rates_added = 0; | ||
53 | struct cfg80211_chan_def chandef; | ||
54 | enum nl80211_bss_scan_width scan_width; | ||
55 | bool have_higher_than_11mbit = false; | ||
56 | struct beacon_data *presp; | 51 | struct beacon_data *presp; |
57 | int frame_len; | 52 | int frame_len; |
58 | int shift; | 53 | int shift; |
59 | 54 | ||
60 | sdata_assert_lock(sdata); | ||
61 | |||
62 | /* Reset own TSF to allow time synchronization work. */ | ||
63 | drv_reset_tsf(local, sdata); | ||
64 | |||
65 | if (!ether_addr_equal(ifibss->bssid, bssid)) | ||
66 | sta_info_flush(sdata); | ||
67 | |||
68 | /* if merging, indicate to driver that we leave the old IBSS */ | ||
69 | if (sdata->vif.bss_conf.ibss_joined) { | ||
70 | sdata->vif.bss_conf.ibss_joined = false; | ||
71 | sdata->vif.bss_conf.ibss_creator = false; | ||
72 | sdata->vif.bss_conf.enable_beacon = false; | ||
73 | netif_carrier_off(sdata->dev); | ||
74 | ieee80211_bss_info_change_notify(sdata, | ||
75 | BSS_CHANGED_IBSS | | ||
76 | BSS_CHANGED_BEACON_ENABLED); | ||
77 | } | ||
78 | |||
79 | presp = rcu_dereference_protected(ifibss->presp, | ||
80 | lockdep_is_held(&sdata->wdev.mtx)); | ||
81 | rcu_assign_pointer(ifibss->presp, NULL); | ||
82 | if (presp) | ||
83 | kfree_rcu(presp, rcu_head); | ||
84 | |||
85 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; | ||
86 | |||
87 | chandef = ifibss->chandef; | ||
88 | if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) { | ||
89 | if (chandef.width == NL80211_CHAN_WIDTH_5 || | ||
90 | chandef.width == NL80211_CHAN_WIDTH_10 || | ||
91 | chandef.width == NL80211_CHAN_WIDTH_20_NOHT || | ||
92 | chandef.width == NL80211_CHAN_WIDTH_20) { | ||
93 | sdata_info(sdata, | ||
94 | "Failed to join IBSS, beacons forbidden\n"); | ||
95 | return; | ||
96 | } | ||
97 | chandef.width = NL80211_CHAN_WIDTH_20; | ||
98 | chandef.center_freq1 = chan->center_freq; | ||
99 | } | ||
100 | |||
101 | ieee80211_vif_release_channel(sdata); | ||
102 | if (ieee80211_vif_use_channel(sdata, &chandef, | ||
103 | ifibss->fixed_channel ? | ||
104 | IEEE80211_CHANCTX_SHARED : | ||
105 | IEEE80211_CHANCTX_EXCLUSIVE)) { | ||
106 | sdata_info(sdata, "Failed to join IBSS, no channel context\n"); | ||
107 | return; | ||
108 | } | ||
109 | |||
110 | memcpy(ifibss->bssid, bssid, ETH_ALEN); | ||
111 | |||
112 | sband = local->hw.wiphy->bands[chan->band]; | ||
113 | shift = ieee80211_vif_get_shift(&sdata->vif); | ||
114 | |||
115 | /* Build IBSS probe response */ | 55 | /* Build IBSS probe response */ |
116 | frame_len = sizeof(struct ieee80211_hdr_3addr) + | 56 | frame_len = sizeof(struct ieee80211_hdr_3addr) + |
117 | 12 /* struct ieee80211_mgmt.u.beacon */ + | 57 | 12 /* struct ieee80211_mgmt.u.beacon */ + |
@@ -125,7 +65,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
125 | ifibss->ie_len; | 65 | ifibss->ie_len; |
126 | presp = kzalloc(sizeof(*presp) + frame_len, GFP_KERNEL); | 66 | presp = kzalloc(sizeof(*presp) + frame_len, GFP_KERNEL); |
127 | if (!presp) | 67 | if (!presp) |
128 | return; | 68 | return NULL; |
129 | 69 | ||
130 | presp->head = (void *)(presp + 1); | 70 | presp->head = (void *)(presp + 1); |
131 | 71 | ||
@@ -146,12 +86,19 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
146 | memcpy(pos, ifibss->ssid, ifibss->ssid_len); | 86 | memcpy(pos, ifibss->ssid, ifibss->ssid_len); |
147 | pos += ifibss->ssid_len; | 87 | pos += ifibss->ssid_len; |
148 | 88 | ||
149 | rate_flags = ieee80211_chandef_rate_flags(&chandef); | 89 | sband = local->hw.wiphy->bands[chandef->chan->band]; |
90 | rate_flags = ieee80211_chandef_rate_flags(chandef); | ||
91 | shift = ieee80211_chandef_get_shift(chandef); | ||
92 | rates_n = 0; | ||
93 | if (have_higher_than_11mbit) | ||
94 | *have_higher_than_11mbit = false; | ||
95 | |||
150 | for (i = 0; i < sband->n_bitrates; i++) { | 96 | for (i = 0; i < sband->n_bitrates; i++) { |
151 | if ((rate_flags & sband->bitrates[i].flags) != rate_flags) | 97 | if ((rate_flags & sband->bitrates[i].flags) != rate_flags) |
152 | continue; | 98 | continue; |
153 | if (sband->bitrates[i].bitrate > 110) | 99 | if (sband->bitrates[i].bitrate > 110 && |
154 | have_higher_than_11mbit = true; | 100 | have_higher_than_11mbit) |
101 | *have_higher_than_11mbit = true; | ||
155 | 102 | ||
156 | rates |= BIT(i); | 103 | rates |= BIT(i); |
157 | rates_n++; | 104 | rates_n++; |
@@ -178,7 +125,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
178 | if (sband->band == IEEE80211_BAND_2GHZ) { | 125 | if (sband->band == IEEE80211_BAND_2GHZ) { |
179 | *pos++ = WLAN_EID_DS_PARAMS; | 126 | *pos++ = WLAN_EID_DS_PARAMS; |
180 | *pos++ = 1; | 127 | *pos++ = 1; |
181 | *pos++ = ieee80211_frequency_to_channel(chan->center_freq); | 128 | *pos++ = ieee80211_frequency_to_channel( |
129 | chandef->chan->center_freq); | ||
182 | } | 130 | } |
183 | 131 | ||
184 | *pos++ = WLAN_EID_IBSS_PARAMS; | 132 | *pos++ = WLAN_EID_IBSS_PARAMS; |
@@ -210,9 +158,9 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
210 | } | 158 | } |
211 | 159 | ||
212 | /* add HT capability and information IEs */ | 160 | /* add HT capability and information IEs */ |
213 | if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT && | 161 | if (chandef->width != NL80211_CHAN_WIDTH_20_NOHT && |
214 | chandef.width != NL80211_CHAN_WIDTH_5 && | 162 | chandef->width != NL80211_CHAN_WIDTH_5 && |
215 | chandef.width != NL80211_CHAN_WIDTH_10 && | 163 | chandef->width != NL80211_CHAN_WIDTH_10 && |
216 | sband->ht_cap.ht_supported) { | 164 | sband->ht_cap.ht_supported) { |
217 | struct ieee80211_sta_ht_cap ht_cap; | 165 | struct ieee80211_sta_ht_cap ht_cap; |
218 | 166 | ||
@@ -226,7 +174,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
226 | * keep them at 0 | 174 | * keep them at 0 |
227 | */ | 175 | */ |
228 | pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap, | 176 | pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap, |
229 | &chandef, 0); | 177 | chandef, 0); |
230 | } | 178 | } |
231 | 179 | ||
232 | if (local->hw.queues >= IEEE80211_NUM_ACS) { | 180 | if (local->hw.queues >= IEEE80211_NUM_ACS) { |
@@ -243,9 +191,97 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
243 | 191 | ||
244 | presp->head_len = pos - presp->head; | 192 | presp->head_len = pos - presp->head; |
245 | if (WARN_ON(presp->head_len > frame_len)) | 193 | if (WARN_ON(presp->head_len > frame_len)) |
194 | goto error; | ||
195 | |||
196 | return presp; | ||
197 | error: | ||
198 | kfree(presp); | ||
199 | return NULL; | ||
200 | } | ||
201 | |||
202 | static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | ||
203 | const u8 *bssid, const int beacon_int, | ||
204 | struct cfg80211_chan_def *req_chandef, | ||
205 | const u32 basic_rates, | ||
206 | const u16 capability, u64 tsf, | ||
207 | bool creator) | ||
208 | { | ||
209 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | ||
210 | struct ieee80211_local *local = sdata->local; | ||
211 | struct ieee80211_supported_band *sband; | ||
212 | struct ieee80211_mgmt *mgmt; | ||
213 | struct cfg80211_bss *bss; | ||
214 | u32 bss_change; | ||
215 | struct cfg80211_chan_def chandef; | ||
216 | struct ieee80211_channel *chan; | ||
217 | struct beacon_data *presp; | ||
218 | enum nl80211_bss_scan_width scan_width; | ||
219 | bool have_higher_than_11mbit; | ||
220 | |||
221 | sdata_assert_lock(sdata); | ||
222 | |||
223 | /* Reset own TSF to allow time synchronization work. */ | ||
224 | drv_reset_tsf(local, sdata); | ||
225 | |||
226 | if (!ether_addr_equal(ifibss->bssid, bssid)) | ||
227 | sta_info_flush(sdata); | ||
228 | |||
229 | /* if merging, indicate to driver that we leave the old IBSS */ | ||
230 | if (sdata->vif.bss_conf.ibss_joined) { | ||
231 | sdata->vif.bss_conf.ibss_joined = false; | ||
232 | sdata->vif.bss_conf.ibss_creator = false; | ||
233 | sdata->vif.bss_conf.enable_beacon = false; | ||
234 | netif_carrier_off(sdata->dev); | ||
235 | ieee80211_bss_info_change_notify(sdata, | ||
236 | BSS_CHANGED_IBSS | | ||
237 | BSS_CHANGED_BEACON_ENABLED); | ||
238 | } | ||
239 | |||
240 | presp = rcu_dereference_protected(ifibss->presp, | ||
241 | lockdep_is_held(&sdata->wdev.mtx)); | ||
242 | rcu_assign_pointer(ifibss->presp, NULL); | ||
243 | if (presp) | ||
244 | kfree_rcu(presp, rcu_head); | ||
245 | |||
246 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; | ||
247 | |||
248 | /* make a copy of the chandef, it could be modified below. */ | ||
249 | chandef = *req_chandef; | ||
250 | chan = chandef.chan; | ||
251 | if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) { | ||
252 | if (chandef.width == NL80211_CHAN_WIDTH_5 || | ||
253 | chandef.width == NL80211_CHAN_WIDTH_10 || | ||
254 | chandef.width == NL80211_CHAN_WIDTH_20_NOHT || | ||
255 | chandef.width == NL80211_CHAN_WIDTH_20) { | ||
256 | sdata_info(sdata, | ||
257 | "Failed to join IBSS, beacons forbidden\n"); | ||
258 | return; | ||
259 | } | ||
260 | chandef.width = NL80211_CHAN_WIDTH_20; | ||
261 | chandef.center_freq1 = chan->center_freq; | ||
262 | } | ||
263 | |||
264 | ieee80211_vif_release_channel(sdata); | ||
265 | if (ieee80211_vif_use_channel(sdata, &chandef, | ||
266 | ifibss->fixed_channel ? | ||
267 | IEEE80211_CHANCTX_SHARED : | ||
268 | IEEE80211_CHANCTX_EXCLUSIVE)) { | ||
269 | sdata_info(sdata, "Failed to join IBSS, no channel context\n"); | ||
270 | return; | ||
271 | } | ||
272 | |||
273 | memcpy(ifibss->bssid, bssid, ETH_ALEN); | ||
274 | |||
275 | sband = local->hw.wiphy->bands[chan->band]; | ||
276 | |||
277 | presp = ieee80211_ibss_build_presp(sdata, beacon_int, basic_rates, | ||
278 | capability, tsf, &chandef, | ||
279 | &have_higher_than_11mbit); | ||
280 | if (!presp) | ||
246 | return; | 281 | return; |
247 | 282 | ||
248 | rcu_assign_pointer(ifibss->presp, presp); | 283 | rcu_assign_pointer(ifibss->presp, presp); |
284 | mgmt = (void *)presp->head; | ||
249 | 285 | ||
250 | sdata->vif.bss_conf.enable_beacon = true; | 286 | sdata->vif.bss_conf.enable_beacon = true; |
251 | sdata->vif.bss_conf.beacon_int = beacon_int; | 287 | sdata->vif.bss_conf.beacon_int = beacon_int; |
@@ -306,10 +342,12 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
306 | struct cfg80211_bss *cbss = | 342 | struct cfg80211_bss *cbss = |
307 | container_of((void *)bss, struct cfg80211_bss, priv); | 343 | container_of((void *)bss, struct cfg80211_bss, priv); |
308 | struct ieee80211_supported_band *sband; | 344 | struct ieee80211_supported_band *sband; |
345 | struct cfg80211_chan_def chandef; | ||
309 | u32 basic_rates; | 346 | u32 basic_rates; |
310 | int i, j; | 347 | int i, j; |
311 | u16 beacon_int = cbss->beacon_interval; | 348 | u16 beacon_int = cbss->beacon_interval; |
312 | const struct cfg80211_bss_ies *ies; | 349 | const struct cfg80211_bss_ies *ies; |
350 | enum nl80211_channel_type chan_type; | ||
313 | u64 tsf; | 351 | u64 tsf; |
314 | u32 rate_flags; | 352 | u32 rate_flags; |
315 | int shift; | 353 | int shift; |
@@ -319,6 +357,26 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
319 | if (beacon_int < 10) | 357 | if (beacon_int < 10) |
320 | beacon_int = 10; | 358 | beacon_int = 10; |
321 | 359 | ||
360 | switch (sdata->u.ibss.chandef.width) { | ||
361 | case NL80211_CHAN_WIDTH_20_NOHT: | ||
362 | case NL80211_CHAN_WIDTH_20: | ||
363 | case NL80211_CHAN_WIDTH_40: | ||
364 | chan_type = cfg80211_get_chandef_type(&sdata->u.ibss.chandef); | ||
365 | cfg80211_chandef_create(&chandef, cbss->channel, chan_type); | ||
366 | break; | ||
367 | case NL80211_CHAN_WIDTH_5: | ||
368 | case NL80211_CHAN_WIDTH_10: | ||
369 | cfg80211_chandef_create(&chandef, cbss->channel, | ||
370 | NL80211_CHAN_WIDTH_20_NOHT); | ||
371 | chandef.width = sdata->u.ibss.chandef.width; | ||
372 | break; | ||
373 | default: | ||
374 | /* fall back to 20 MHz for unsupported modes */ | ||
375 | cfg80211_chandef_create(&chandef, cbss->channel, | ||
376 | NL80211_CHAN_WIDTH_20_NOHT); | ||
377 | break; | ||
378 | } | ||
379 | |||
322 | sband = sdata->local->hw.wiphy->bands[cbss->channel->band]; | 380 | sband = sdata->local->hw.wiphy->bands[cbss->channel->band]; |
323 | rate_flags = ieee80211_chandef_rate_flags(&sdata->u.ibss.chandef); | 381 | rate_flags = ieee80211_chandef_rate_flags(&sdata->u.ibss.chandef); |
324 | shift = ieee80211_vif_get_shift(&sdata->vif); | 382 | shift = ieee80211_vif_get_shift(&sdata->vif); |
@@ -352,7 +410,7 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
352 | 410 | ||
353 | __ieee80211_sta_join_ibss(sdata, cbss->bssid, | 411 | __ieee80211_sta_join_ibss(sdata, cbss->bssid, |
354 | beacon_int, | 412 | beacon_int, |
355 | cbss->channel, | 413 | &chandef, |
356 | basic_rates, | 414 | basic_rates, |
357 | cbss->capability, | 415 | cbss->capability, |
358 | tsf, false); | 416 | tsf, false); |
@@ -834,7 +892,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) | |||
834 | sdata->drop_unencrypted = 0; | 892 | sdata->drop_unencrypted = 0; |
835 | 893 | ||
836 | __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, | 894 | __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, |
837 | ifibss->chandef.chan, ifibss->basic_rates, | 895 | &ifibss->chandef, ifibss->basic_rates, |
838 | capability, 0, true); | 896 | capability, 0, true); |
839 | } | 897 | } |
840 | 898 | ||
@@ -891,6 +949,17 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
891 | return; | 949 | return; |
892 | } | 950 | } |
893 | 951 | ||
952 | /* if a fixed bssid and a fixed freq have been provided create the IBSS | ||
953 | * directly and do not waste time scanning | ||
954 | */ | ||
955 | if (ifibss->fixed_bssid && ifibss->fixed_channel) { | ||
956 | sdata_info(sdata, "Created IBSS using preconfigured BSSID %pM\n", | ||
957 | bssid); | ||
958 | ieee80211_sta_create_ibss(sdata); | ||
959 | return; | ||
960 | } | ||
961 | |||
962 | |||
894 | ibss_dbg(sdata, "sta_find_ibss: did not try to join ibss\n"); | 963 | ibss_dbg(sdata, "sta_find_ibss: did not try to join ibss\n"); |
895 | 964 | ||
896 | /* Selected IBSS not found in current scan results - try to scan */ | 965 | /* Selected IBSS not found in current scan results - try to scan */ |
@@ -1260,6 +1329,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
1260 | clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); | 1329 | clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); |
1261 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | | 1330 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | |
1262 | BSS_CHANGED_IBSS); | 1331 | BSS_CHANGED_IBSS); |
1332 | ieee80211_vif_release_channel(sdata); | ||
1263 | synchronize_rcu(); | 1333 | synchronize_rcu(); |
1264 | kfree(presp); | 1334 | kfree(presp); |
1265 | 1335 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index e94c84050e9c..b6186517ec56 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -53,9 +53,6 @@ struct ieee80211_local; | |||
53 | * increased memory use (about 2 kB of RAM per entry). */ | 53 | * increased memory use (about 2 kB of RAM per entry). */ |
54 | #define IEEE80211_FRAGMENT_MAX 4 | 54 | #define IEEE80211_FRAGMENT_MAX 4 |
55 | 55 | ||
56 | #define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024)) | ||
57 | #define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x)) | ||
58 | |||
59 | /* power level hasn't been configured (or set to automatic) */ | 56 | /* power level hasn't been configured (or set to automatic) */ |
60 | #define IEEE80211_UNSET_POWER_LEVEL INT_MIN | 57 | #define IEEE80211_UNSET_POWER_LEVEL INT_MIN |
61 | 58 | ||
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 7ca534bf4cea..fcecd633514e 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -308,12 +308,13 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, | |||
308 | return 0; | 308 | return 0; |
309 | } | 309 | } |
310 | 310 | ||
311 | static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata) | 311 | static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata, |
312 | enum nl80211_iftype iftype) | ||
312 | { | 313 | { |
313 | int n_queues = sdata->local->hw.queues; | 314 | int n_queues = sdata->local->hw.queues; |
314 | int i; | 315 | int i; |
315 | 316 | ||
316 | if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE) { | 317 | if (iftype != NL80211_IFTYPE_P2P_DEVICE) { |
317 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { | 318 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { |
318 | if (WARN_ON_ONCE(sdata->vif.hw_queue[i] == | 319 | if (WARN_ON_ONCE(sdata->vif.hw_queue[i] == |
319 | IEEE80211_INVAL_HW_QUEUE)) | 320 | IEEE80211_INVAL_HW_QUEUE)) |
@@ -324,8 +325,9 @@ static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata) | |||
324 | } | 325 | } |
325 | } | 326 | } |
326 | 327 | ||
327 | if ((sdata->vif.type != NL80211_IFTYPE_AP && | 328 | if ((iftype != NL80211_IFTYPE_AP && |
328 | sdata->vif.type != NL80211_IFTYPE_MESH_POINT) || | 329 | iftype != NL80211_IFTYPE_P2P_GO && |
330 | iftype != NL80211_IFTYPE_MESH_POINT) || | ||
329 | !(sdata->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)) { | 331 | !(sdata->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)) { |
330 | sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE; | 332 | sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE; |
331 | return 0; | 333 | return 0; |
@@ -408,7 +410,7 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local) | |||
408 | return ret; | 410 | return ret; |
409 | } | 411 | } |
410 | 412 | ||
411 | ret = ieee80211_check_queues(sdata); | 413 | ret = ieee80211_check_queues(sdata, NL80211_IFTYPE_MONITOR); |
412 | if (ret) { | 414 | if (ret) { |
413 | kfree(sdata); | 415 | kfree(sdata); |
414 | return ret; | 416 | return ret; |
@@ -592,7 +594,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) | |||
592 | res = drv_add_interface(local, sdata); | 594 | res = drv_add_interface(local, sdata); |
593 | if (res) | 595 | if (res) |
594 | goto err_stop; | 596 | goto err_stop; |
595 | res = ieee80211_check_queues(sdata); | 597 | res = ieee80211_check_queues(sdata, |
598 | ieee80211_vif_type_p2p(&sdata->vif)); | ||
596 | if (res) | 599 | if (res) |
597 | goto err_del_interface; | 600 | goto err_del_interface; |
598 | } | 601 | } |
@@ -1389,14 +1392,14 @@ static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, | |||
1389 | 1392 | ||
1390 | ret = drv_change_interface(local, sdata, internal_type, p2p); | 1393 | ret = drv_change_interface(local, sdata, internal_type, p2p); |
1391 | if (ret) | 1394 | if (ret) |
1392 | type = sdata->vif.type; | 1395 | type = ieee80211_vif_type_p2p(&sdata->vif); |
1393 | 1396 | ||
1394 | /* | 1397 | /* |
1395 | * Ignore return value here, there's not much we can do since | 1398 | * Ignore return value here, there's not much we can do since |
1396 | * the driver changed the interface type internally already. | 1399 | * the driver changed the interface type internally already. |
1397 | * The warnings will hopefully make driver authors fix it :-) | 1400 | * The warnings will hopefully make driver authors fix it :-) |
1398 | */ | 1401 | */ |
1399 | ieee80211_check_queues(sdata); | 1402 | ieee80211_check_queues(sdata, type); |
1400 | 1403 | ||
1401 | ieee80211_setup_sdata(sdata, type); | 1404 | ieee80211_setup_sdata(sdata, type); |
1402 | 1405 | ||
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index e39cc91d0cf1..620677e897bd 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -93,6 +93,9 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
93 | 93 | ||
94 | might_sleep(); | 94 | might_sleep(); |
95 | 95 | ||
96 | if (key->flags & KEY_FLAG_TAINTED) | ||
97 | return -EINVAL; | ||
98 | |||
96 | if (!key->local->ops->set_key) | 99 | if (!key->local->ops->set_key) |
97 | goto out_unsupported; | 100 | goto out_unsupported; |
98 | 101 | ||
@@ -455,6 +458,7 @@ int ieee80211_key_link(struct ieee80211_key *key, | |||
455 | struct ieee80211_sub_if_data *sdata, | 458 | struct ieee80211_sub_if_data *sdata, |
456 | struct sta_info *sta) | 459 | struct sta_info *sta) |
457 | { | 460 | { |
461 | struct ieee80211_local *local = sdata->local; | ||
458 | struct ieee80211_key *old_key; | 462 | struct ieee80211_key *old_key; |
459 | int idx, ret; | 463 | int idx, ret; |
460 | bool pairwise; | 464 | bool pairwise; |
@@ -484,10 +488,13 @@ int ieee80211_key_link(struct ieee80211_key *key, | |||
484 | 488 | ||
485 | ieee80211_debugfs_key_add(key); | 489 | ieee80211_debugfs_key_add(key); |
486 | 490 | ||
487 | ret = ieee80211_key_enable_hw_accel(key); | 491 | if (!local->wowlan) { |
488 | 492 | ret = ieee80211_key_enable_hw_accel(key); | |
489 | if (ret) | 493 | if (ret) |
490 | ieee80211_key_free(key, true); | 494 | ieee80211_key_free(key, true); |
495 | } else { | ||
496 | ret = 0; | ||
497 | } | ||
491 | 498 | ||
492 | mutex_unlock(&sdata->local->key_mtx); | 499 | mutex_unlock(&sdata->local->key_mtx); |
493 | 500 | ||
@@ -540,7 +547,7 @@ void ieee80211_iter_keys(struct ieee80211_hw *hw, | |||
540 | void *iter_data) | 547 | void *iter_data) |
541 | { | 548 | { |
542 | struct ieee80211_local *local = hw_to_local(hw); | 549 | struct ieee80211_local *local = hw_to_local(hw); |
543 | struct ieee80211_key *key; | 550 | struct ieee80211_key *key, *tmp; |
544 | struct ieee80211_sub_if_data *sdata; | 551 | struct ieee80211_sub_if_data *sdata; |
545 | 552 | ||
546 | ASSERT_RTNL(); | 553 | ASSERT_RTNL(); |
@@ -548,13 +555,14 @@ void ieee80211_iter_keys(struct ieee80211_hw *hw, | |||
548 | mutex_lock(&local->key_mtx); | 555 | mutex_lock(&local->key_mtx); |
549 | if (vif) { | 556 | if (vif) { |
550 | sdata = vif_to_sdata(vif); | 557 | sdata = vif_to_sdata(vif); |
551 | list_for_each_entry(key, &sdata->key_list, list) | 558 | list_for_each_entry_safe(key, tmp, &sdata->key_list, list) |
552 | iter(hw, &sdata->vif, | 559 | iter(hw, &sdata->vif, |
553 | key->sta ? &key->sta->sta : NULL, | 560 | key->sta ? &key->sta->sta : NULL, |
554 | &key->conf, iter_data); | 561 | &key->conf, iter_data); |
555 | } else { | 562 | } else { |
556 | list_for_each_entry(sdata, &local->interfaces, list) | 563 | list_for_each_entry(sdata, &local->interfaces, list) |
557 | list_for_each_entry(key, &sdata->key_list, list) | 564 | list_for_each_entry_safe(key, tmp, |
565 | &sdata->key_list, list) | ||
558 | iter(hw, &sdata->vif, | 566 | iter(hw, &sdata->vif, |
559 | key->sta ? &key->sta->sta : NULL, | 567 | key->sta ? &key->sta->sta : NULL, |
560 | &key->conf, iter_data); | 568 | &key->conf, iter_data); |
@@ -751,3 +759,135 @@ void ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf, | |||
751 | } | 759 | } |
752 | } | 760 | } |
753 | EXPORT_SYMBOL(ieee80211_get_key_rx_seq); | 761 | EXPORT_SYMBOL(ieee80211_get_key_rx_seq); |
762 | |||
763 | void ieee80211_set_key_tx_seq(struct ieee80211_key_conf *keyconf, | ||
764 | struct ieee80211_key_seq *seq) | ||
765 | { | ||
766 | struct ieee80211_key *key; | ||
767 | u64 pn64; | ||
768 | |||
769 | key = container_of(keyconf, struct ieee80211_key, conf); | ||
770 | |||
771 | switch (key->conf.cipher) { | ||
772 | case WLAN_CIPHER_SUITE_TKIP: | ||
773 | key->u.tkip.tx.iv32 = seq->tkip.iv32; | ||
774 | key->u.tkip.tx.iv16 = seq->tkip.iv16; | ||
775 | break; | ||
776 | case WLAN_CIPHER_SUITE_CCMP: | ||
777 | pn64 = (u64)seq->ccmp.pn[5] | | ||
778 | ((u64)seq->ccmp.pn[4] << 8) | | ||
779 | ((u64)seq->ccmp.pn[3] << 16) | | ||
780 | ((u64)seq->ccmp.pn[2] << 24) | | ||
781 | ((u64)seq->ccmp.pn[1] << 32) | | ||
782 | ((u64)seq->ccmp.pn[0] << 40); | ||
783 | atomic64_set(&key->u.ccmp.tx_pn, pn64); | ||
784 | break; | ||
785 | case WLAN_CIPHER_SUITE_AES_CMAC: | ||
786 | pn64 = (u64)seq->aes_cmac.pn[5] | | ||
787 | ((u64)seq->aes_cmac.pn[4] << 8) | | ||
788 | ((u64)seq->aes_cmac.pn[3] << 16) | | ||
789 | ((u64)seq->aes_cmac.pn[2] << 24) | | ||
790 | ((u64)seq->aes_cmac.pn[1] << 32) | | ||
791 | ((u64)seq->aes_cmac.pn[0] << 40); | ||
792 | atomic64_set(&key->u.aes_cmac.tx_pn, pn64); | ||
793 | break; | ||
794 | default: | ||
795 | WARN_ON(1); | ||
796 | break; | ||
797 | } | ||
798 | } | ||
799 | EXPORT_SYMBOL_GPL(ieee80211_set_key_tx_seq); | ||
800 | |||
801 | void ieee80211_set_key_rx_seq(struct ieee80211_key_conf *keyconf, | ||
802 | int tid, struct ieee80211_key_seq *seq) | ||
803 | { | ||
804 | struct ieee80211_key *key; | ||
805 | u8 *pn; | ||
806 | |||
807 | key = container_of(keyconf, struct ieee80211_key, conf); | ||
808 | |||
809 | switch (key->conf.cipher) { | ||
810 | case WLAN_CIPHER_SUITE_TKIP: | ||
811 | if (WARN_ON(tid < 0 || tid >= IEEE80211_NUM_TIDS)) | ||
812 | return; | ||
813 | key->u.tkip.rx[tid].iv32 = seq->tkip.iv32; | ||
814 | key->u.tkip.rx[tid].iv16 = seq->tkip.iv16; | ||
815 | break; | ||
816 | case WLAN_CIPHER_SUITE_CCMP: | ||
817 | if (WARN_ON(tid < -1 || tid >= IEEE80211_NUM_TIDS)) | ||
818 | return; | ||
819 | if (tid < 0) | ||
820 | pn = key->u.ccmp.rx_pn[IEEE80211_NUM_TIDS]; | ||
821 | else | ||
822 | pn = key->u.ccmp.rx_pn[tid]; | ||
823 | memcpy(pn, seq->ccmp.pn, IEEE80211_CCMP_PN_LEN); | ||
824 | break; | ||
825 | case WLAN_CIPHER_SUITE_AES_CMAC: | ||
826 | if (WARN_ON(tid != 0)) | ||
827 | return; | ||
828 | pn = key->u.aes_cmac.rx_pn; | ||
829 | memcpy(pn, seq->aes_cmac.pn, IEEE80211_CMAC_PN_LEN); | ||
830 | break; | ||
831 | default: | ||
832 | WARN_ON(1); | ||
833 | break; | ||
834 | } | ||
835 | } | ||
836 | EXPORT_SYMBOL_GPL(ieee80211_set_key_rx_seq); | ||
837 | |||
838 | void ieee80211_remove_key(struct ieee80211_key_conf *keyconf) | ||
839 | { | ||
840 | struct ieee80211_key *key; | ||
841 | |||
842 | key = container_of(keyconf, struct ieee80211_key, conf); | ||
843 | |||
844 | assert_key_lock(key->local); | ||
845 | |||
846 | /* | ||
847 | * if key was uploaded, we assume the driver will/has remove(d) | ||
848 | * it, so adjust bookkeeping accordingly | ||
849 | */ | ||
850 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | ||
851 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; | ||
852 | |||
853 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || | ||
854 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) || | ||
855 | (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))) | ||
856 | increment_tailroom_need_count(key->sdata); | ||
857 | } | ||
858 | |||
859 | ieee80211_key_free(key, false); | ||
860 | } | ||
861 | EXPORT_SYMBOL_GPL(ieee80211_remove_key); | ||
862 | |||
863 | struct ieee80211_key_conf * | ||
864 | ieee80211_gtk_rekey_add(struct ieee80211_vif *vif, | ||
865 | struct ieee80211_key_conf *keyconf) | ||
866 | { | ||
867 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
868 | struct ieee80211_local *local = sdata->local; | ||
869 | struct ieee80211_key *key; | ||
870 | int err; | ||
871 | |||
872 | if (WARN_ON(!local->wowlan)) | ||
873 | return ERR_PTR(-EINVAL); | ||
874 | |||
875 | if (WARN_ON(vif->type != NL80211_IFTYPE_STATION)) | ||
876 | return ERR_PTR(-EINVAL); | ||
877 | |||
878 | key = ieee80211_key_alloc(keyconf->cipher, keyconf->keyidx, | ||
879 | keyconf->keylen, keyconf->key, | ||
880 | 0, NULL); | ||
881 | if (IS_ERR(key)) | ||
882 | return ERR_PTR(PTR_ERR(key)); | ||
883 | |||
884 | if (sdata->u.mgd.mfp != IEEE80211_MFP_DISABLED) | ||
885 | key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT; | ||
886 | |||
887 | err = ieee80211_key_link(key, sdata, NULL); | ||
888 | if (err) | ||
889 | return ERR_PTR(err); | ||
890 | |||
891 | return &key->conf; | ||
892 | } | ||
893 | EXPORT_SYMBOL_GPL(ieee80211_gtk_rekey_add); | ||
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 25eb35b01938..21d5d44444d0 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -892,9 +892,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
892 | if (!local->ops->remain_on_channel) | 892 | if (!local->ops->remain_on_channel) |
893 | local->hw.wiphy->max_remain_on_channel_duration = 5000; | 893 | local->hw.wiphy->max_remain_on_channel_duration = 5000; |
894 | 894 | ||
895 | if (local->ops->sched_scan_start) | ||
896 | local->hw.wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; | ||
897 | |||
898 | /* mac80211 based drivers don't support internal TDLS setup */ | 895 | /* mac80211 based drivers don't support internal TDLS setup */ |
899 | if (local->hw.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) | 896 | if (local->hw.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) |
900 | local->hw.wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP; | 897 | local->hw.wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP; |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 885a5f6e2c21..707ac61d63e5 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -832,6 +832,9 @@ ieee80211_mesh_rx_probe_req(struct ieee80211_sub_if_data *sdata, | |||
832 | 832 | ||
833 | ieee802_11_parse_elems(pos, len - baselen, false, &elems); | 833 | ieee802_11_parse_elems(pos, len - baselen, false, &elems); |
834 | 834 | ||
835 | if (!elems.mesh_id) | ||
836 | return; | ||
837 | |||
835 | /* 802.11-2012 10.1.4.3.2 */ | 838 | /* 802.11-2012 10.1.4.3.2 */ |
836 | if ((!ether_addr_equal(mgmt->da, sdata->vif.addr) && | 839 | if ((!ether_addr_equal(mgmt->da, sdata->vif.addr) && |
837 | !is_broadcast_ether_addr(mgmt->da)) || | 840 | !is_broadcast_ether_addr(mgmt->da)) || |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 21bccd849b3f..86e4ad56b573 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1113,6 +1113,15 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
1113 | case -1: | 1113 | case -1: |
1114 | cfg80211_chandef_create(&new_chandef, new_chan, | 1114 | cfg80211_chandef_create(&new_chandef, new_chan, |
1115 | NL80211_CHAN_NO_HT); | 1115 | NL80211_CHAN_NO_HT); |
1116 | /* keep width for 5/10 MHz channels */ | ||
1117 | switch (sdata->vif.bss_conf.chandef.width) { | ||
1118 | case NL80211_CHAN_WIDTH_5: | ||
1119 | case NL80211_CHAN_WIDTH_10: | ||
1120 | new_chandef.width = sdata->vif.bss_conf.chandef.width; | ||
1121 | break; | ||
1122 | default: | ||
1123 | break; | ||
1124 | } | ||
1116 | break; | 1125 | break; |
1117 | } | 1126 | } |
1118 | 1127 | ||
@@ -2852,14 +2861,6 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
2852 | ieee80211_rx_bss_put(local, bss); | 2861 | ieee80211_rx_bss_put(local, bss); |
2853 | sdata->vif.bss_conf.beacon_rate = bss->beacon_rate; | 2862 | sdata->vif.bss_conf.beacon_rate = bss->beacon_rate; |
2854 | } | 2863 | } |
2855 | |||
2856 | if (!sdata->u.mgd.associated || | ||
2857 | !ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) | ||
2858 | return; | ||
2859 | |||
2860 | ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, | ||
2861 | elems, true); | ||
2862 | |||
2863 | } | 2864 | } |
2864 | 2865 | ||
2865 | 2866 | ||
@@ -3148,6 +3149,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
3148 | 3149 | ||
3149 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); | 3150 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); |
3150 | 3151 | ||
3152 | ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, | ||
3153 | &elems, true); | ||
3154 | |||
3151 | if (ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, | 3155 | if (ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, |
3152 | elems.wmm_param_len)) | 3156 | elems.wmm_param_len)) |
3153 | changed |= BSS_CHANGED_QOS; | 3157 | changed |= BSS_CHANGED_QOS; |
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index ba63ac851c2b..e126605cec66 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
@@ -210,7 +210,7 @@ static bool rc_no_data_or_no_ack_use_min(struct ieee80211_tx_rate_control *txrc) | |||
210 | !ieee80211_is_data(fc); | 210 | !ieee80211_is_data(fc); |
211 | } | 211 | } |
212 | 212 | ||
213 | static void rc_send_low_broadcast(s8 *idx, u32 basic_rates, | 213 | static void rc_send_low_basicrate(s8 *idx, u32 basic_rates, |
214 | struct ieee80211_supported_band *sband) | 214 | struct ieee80211_supported_band *sband) |
215 | { | 215 | { |
216 | u8 i; | 216 | u8 i; |
@@ -263,28 +263,37 @@ static void __rate_control_send_low(struct ieee80211_hw *hw, | |||
263 | } | 263 | } |
264 | 264 | ||
265 | 265 | ||
266 | bool rate_control_send_low(struct ieee80211_sta *sta, | 266 | bool rate_control_send_low(struct ieee80211_sta *pubsta, |
267 | void *priv_sta, | 267 | void *priv_sta, |
268 | struct ieee80211_tx_rate_control *txrc) | 268 | struct ieee80211_tx_rate_control *txrc) |
269 | { | 269 | { |
270 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); | 270 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); |
271 | struct ieee80211_supported_band *sband = txrc->sband; | 271 | struct ieee80211_supported_band *sband = txrc->sband; |
272 | struct sta_info *sta; | ||
272 | int mcast_rate; | 273 | int mcast_rate; |
274 | bool use_basicrate = false; | ||
273 | 275 | ||
274 | if (!sta || !priv_sta || rc_no_data_or_no_ack_use_min(txrc)) { | 276 | if (!pubsta || !priv_sta || rc_no_data_or_no_ack_use_min(txrc)) { |
275 | __rate_control_send_low(txrc->hw, sband, sta, info); | 277 | __rate_control_send_low(txrc->hw, sband, pubsta, info); |
276 | 278 | ||
277 | if (!sta && txrc->bss) { | 279 | if (!pubsta && txrc->bss) { |
278 | mcast_rate = txrc->bss_conf->mcast_rate[sband->band]; | 280 | mcast_rate = txrc->bss_conf->mcast_rate[sband->band]; |
279 | if (mcast_rate > 0) { | 281 | if (mcast_rate > 0) { |
280 | info->control.rates[0].idx = mcast_rate - 1; | 282 | info->control.rates[0].idx = mcast_rate - 1; |
281 | return true; | 283 | return true; |
282 | } | 284 | } |
285 | use_basicrate = true; | ||
286 | } else if (pubsta) { | ||
287 | sta = container_of(pubsta, struct sta_info, sta); | ||
288 | if (ieee80211_vif_is_mesh(&sta->sdata->vif)) | ||
289 | use_basicrate = true; | ||
290 | } | ||
283 | 291 | ||
284 | rc_send_low_broadcast(&info->control.rates[0].idx, | 292 | if (use_basicrate) |
293 | rc_send_low_basicrate(&info->control.rates[0].idx, | ||
285 | txrc->bss_conf->basic_rates, | 294 | txrc->bss_conf->basic_rates, |
286 | sband); | 295 | sband); |
287 | } | 296 | |
288 | return true; | 297 | return true; |
289 | } | 298 | } |
290 | return false; | 299 | return false; |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 61569425b723..7c323f27ba23 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
@@ -776,7 +776,7 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
776 | 776 | ||
777 | /* Don't use EAPOL frames for sampling on non-mrr hw */ | 777 | /* Don't use EAPOL frames for sampling on non-mrr hw */ |
778 | if (mp->hw->max_rates == 1 && | 778 | if (mp->hw->max_rates == 1 && |
779 | txrc->skb->protocol == cpu_to_be16(ETH_P_PAE)) | 779 | (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)) |
780 | sample_idx = -1; | 780 | sample_idx = -1; |
781 | else | 781 | else |
782 | sample_idx = minstrel_get_sample_rate(mp, mi); | 782 | sample_idx = minstrel_get_sample_rate(mp, mi); |
@@ -828,6 +828,9 @@ minstrel_ht_update_cck(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, | |||
828 | if (sband->band != IEEE80211_BAND_2GHZ) | 828 | if (sband->band != IEEE80211_BAND_2GHZ) |
829 | return; | 829 | return; |
830 | 830 | ||
831 | if (!(mp->hw->flags & IEEE80211_HW_SUPPORTS_HT_CCK_RATES)) | ||
832 | return; | ||
833 | |||
831 | mi->cck_supported = 0; | 834 | mi->cck_supported = 0; |
832 | mi->cck_supported_short = 0; | 835 | mi->cck_supported_short = 0; |
833 | for (i = 0; i < 4; i++) { | 836 | for (i = 0; i < 4; i++) { |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 6b85f95b9ba1..54395d7583ba 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1055,207 +1055,6 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
1055 | 1055 | ||
1056 | 1056 | ||
1057 | static ieee80211_rx_result debug_noinline | 1057 | static ieee80211_rx_result debug_noinline |
1058 | ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | ||
1059 | { | ||
1060 | struct sk_buff *skb = rx->skb; | ||
1061 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
1062 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
1063 | int keyidx; | ||
1064 | int hdrlen; | ||
1065 | ieee80211_rx_result result = RX_DROP_UNUSABLE; | ||
1066 | struct ieee80211_key *sta_ptk = NULL; | ||
1067 | int mmie_keyidx = -1; | ||
1068 | __le16 fc; | ||
1069 | |||
1070 | /* | ||
1071 | * Key selection 101 | ||
1072 | * | ||
1073 | * There are four types of keys: | ||
1074 | * - GTK (group keys) | ||
1075 | * - IGTK (group keys for management frames) | ||
1076 | * - PTK (pairwise keys) | ||
1077 | * - STK (station-to-station pairwise keys) | ||
1078 | * | ||
1079 | * When selecting a key, we have to distinguish between multicast | ||
1080 | * (including broadcast) and unicast frames, the latter can only | ||
1081 | * use PTKs and STKs while the former always use GTKs and IGTKs. | ||
1082 | * Unless, of course, actual WEP keys ("pre-RSNA") are used, then | ||
1083 | * unicast frames can also use key indices like GTKs. Hence, if we | ||
1084 | * don't have a PTK/STK we check the key index for a WEP key. | ||
1085 | * | ||
1086 | * Note that in a regular BSS, multicast frames are sent by the | ||
1087 | * AP only, associated stations unicast the frame to the AP first | ||
1088 | * which then multicasts it on their behalf. | ||
1089 | * | ||
1090 | * There is also a slight problem in IBSS mode: GTKs are negotiated | ||
1091 | * with each station, that is something we don't currently handle. | ||
1092 | * The spec seems to expect that one negotiates the same key with | ||
1093 | * every station but there's no such requirement; VLANs could be | ||
1094 | * possible. | ||
1095 | */ | ||
1096 | |||
1097 | /* | ||
1098 | * No point in finding a key and decrypting if the frame is neither | ||
1099 | * addressed to us nor a multicast frame. | ||
1100 | */ | ||
1101 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) | ||
1102 | return RX_CONTINUE; | ||
1103 | |||
1104 | /* start without a key */ | ||
1105 | rx->key = NULL; | ||
1106 | |||
1107 | if (rx->sta) | ||
1108 | sta_ptk = rcu_dereference(rx->sta->ptk); | ||
1109 | |||
1110 | fc = hdr->frame_control; | ||
1111 | |||
1112 | if (!ieee80211_has_protected(fc)) | ||
1113 | mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); | ||
1114 | |||
1115 | if (!is_multicast_ether_addr(hdr->addr1) && sta_ptk) { | ||
1116 | rx->key = sta_ptk; | ||
1117 | if ((status->flag & RX_FLAG_DECRYPTED) && | ||
1118 | (status->flag & RX_FLAG_IV_STRIPPED)) | ||
1119 | return RX_CONTINUE; | ||
1120 | /* Skip decryption if the frame is not protected. */ | ||
1121 | if (!ieee80211_has_protected(fc)) | ||
1122 | return RX_CONTINUE; | ||
1123 | } else if (mmie_keyidx >= 0) { | ||
1124 | /* Broadcast/multicast robust management frame / BIP */ | ||
1125 | if ((status->flag & RX_FLAG_DECRYPTED) && | ||
1126 | (status->flag & RX_FLAG_IV_STRIPPED)) | ||
1127 | return RX_CONTINUE; | ||
1128 | |||
1129 | if (mmie_keyidx < NUM_DEFAULT_KEYS || | ||
1130 | mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) | ||
1131 | return RX_DROP_MONITOR; /* unexpected BIP keyidx */ | ||
1132 | if (rx->sta) | ||
1133 | rx->key = rcu_dereference(rx->sta->gtk[mmie_keyidx]); | ||
1134 | if (!rx->key) | ||
1135 | rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); | ||
1136 | } else if (!ieee80211_has_protected(fc)) { | ||
1137 | /* | ||
1138 | * The frame was not protected, so skip decryption. However, we | ||
1139 | * need to set rx->key if there is a key that could have been | ||
1140 | * used so that the frame may be dropped if encryption would | ||
1141 | * have been expected. | ||
1142 | */ | ||
1143 | struct ieee80211_key *key = NULL; | ||
1144 | struct ieee80211_sub_if_data *sdata = rx->sdata; | ||
1145 | int i; | ||
1146 | |||
1147 | if (ieee80211_is_mgmt(fc) && | ||
1148 | is_multicast_ether_addr(hdr->addr1) && | ||
1149 | (key = rcu_dereference(rx->sdata->default_mgmt_key))) | ||
1150 | rx->key = key; | ||
1151 | else { | ||
1152 | if (rx->sta) { | ||
1153 | for (i = 0; i < NUM_DEFAULT_KEYS; i++) { | ||
1154 | key = rcu_dereference(rx->sta->gtk[i]); | ||
1155 | if (key) | ||
1156 | break; | ||
1157 | } | ||
1158 | } | ||
1159 | if (!key) { | ||
1160 | for (i = 0; i < NUM_DEFAULT_KEYS; i++) { | ||
1161 | key = rcu_dereference(sdata->keys[i]); | ||
1162 | if (key) | ||
1163 | break; | ||
1164 | } | ||
1165 | } | ||
1166 | if (key) | ||
1167 | rx->key = key; | ||
1168 | } | ||
1169 | return RX_CONTINUE; | ||
1170 | } else { | ||
1171 | u8 keyid; | ||
1172 | /* | ||
1173 | * The device doesn't give us the IV so we won't be | ||
1174 | * able to look up the key. That's ok though, we | ||
1175 | * don't need to decrypt the frame, we just won't | ||
1176 | * be able to keep statistics accurate. | ||
1177 | * Except for key threshold notifications, should | ||
1178 | * we somehow allow the driver to tell us which key | ||
1179 | * the hardware used if this flag is set? | ||
1180 | */ | ||
1181 | if ((status->flag & RX_FLAG_DECRYPTED) && | ||
1182 | (status->flag & RX_FLAG_IV_STRIPPED)) | ||
1183 | return RX_CONTINUE; | ||
1184 | |||
1185 | hdrlen = ieee80211_hdrlen(fc); | ||
1186 | |||
1187 | if (rx->skb->len < 8 + hdrlen) | ||
1188 | return RX_DROP_UNUSABLE; /* TODO: count this? */ | ||
1189 | |||
1190 | /* | ||
1191 | * no need to call ieee80211_wep_get_keyidx, | ||
1192 | * it verifies a bunch of things we've done already | ||
1193 | */ | ||
1194 | skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1); | ||
1195 | keyidx = keyid >> 6; | ||
1196 | |||
1197 | /* check per-station GTK first, if multicast packet */ | ||
1198 | if (is_multicast_ether_addr(hdr->addr1) && rx->sta) | ||
1199 | rx->key = rcu_dereference(rx->sta->gtk[keyidx]); | ||
1200 | |||
1201 | /* if not found, try default key */ | ||
1202 | if (!rx->key) { | ||
1203 | rx->key = rcu_dereference(rx->sdata->keys[keyidx]); | ||
1204 | |||
1205 | /* | ||
1206 | * RSNA-protected unicast frames should always be | ||
1207 | * sent with pairwise or station-to-station keys, | ||
1208 | * but for WEP we allow using a key index as well. | ||
1209 | */ | ||
1210 | if (rx->key && | ||
1211 | rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 && | ||
1212 | rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 && | ||
1213 | !is_multicast_ether_addr(hdr->addr1)) | ||
1214 | rx->key = NULL; | ||
1215 | } | ||
1216 | } | ||
1217 | |||
1218 | if (rx->key) { | ||
1219 | if (unlikely(rx->key->flags & KEY_FLAG_TAINTED)) | ||
1220 | return RX_DROP_MONITOR; | ||
1221 | |||
1222 | rx->key->tx_rx_count++; | ||
1223 | /* TODO: add threshold stuff again */ | ||
1224 | } else { | ||
1225 | return RX_DROP_MONITOR; | ||
1226 | } | ||
1227 | |||
1228 | switch (rx->key->conf.cipher) { | ||
1229 | case WLAN_CIPHER_SUITE_WEP40: | ||
1230 | case WLAN_CIPHER_SUITE_WEP104: | ||
1231 | result = ieee80211_crypto_wep_decrypt(rx); | ||
1232 | break; | ||
1233 | case WLAN_CIPHER_SUITE_TKIP: | ||
1234 | result = ieee80211_crypto_tkip_decrypt(rx); | ||
1235 | break; | ||
1236 | case WLAN_CIPHER_SUITE_CCMP: | ||
1237 | result = ieee80211_crypto_ccmp_decrypt(rx); | ||
1238 | break; | ||
1239 | case WLAN_CIPHER_SUITE_AES_CMAC: | ||
1240 | result = ieee80211_crypto_aes_cmac_decrypt(rx); | ||
1241 | break; | ||
1242 | default: | ||
1243 | /* | ||
1244 | * We can reach here only with HW-only algorithms | ||
1245 | * but why didn't it decrypt the frame?! | ||
1246 | */ | ||
1247 | return RX_DROP_UNUSABLE; | ||
1248 | } | ||
1249 | |||
1250 | /* the hdr variable is invalid after the decrypt handlers */ | ||
1251 | |||
1252 | /* either the frame has been decrypted or will be dropped */ | ||
1253 | status->flag |= RX_FLAG_DECRYPTED; | ||
1254 | |||
1255 | return result; | ||
1256 | } | ||
1257 | |||
1258 | static ieee80211_rx_result debug_noinline | ||
1259 | ieee80211_rx_h_check_more_data(struct ieee80211_rx_data *rx) | 1058 | ieee80211_rx_h_check_more_data(struct ieee80211_rx_data *rx) |
1260 | { | 1059 | { |
1261 | struct ieee80211_local *local; | 1060 | struct ieee80211_local *local; |
@@ -1556,6 +1355,207 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
1556 | return RX_CONTINUE; | 1355 | return RX_CONTINUE; |
1557 | } /* ieee80211_rx_h_sta_process */ | 1356 | } /* ieee80211_rx_h_sta_process */ |
1558 | 1357 | ||
1358 | static ieee80211_rx_result debug_noinline | ||
1359 | ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | ||
1360 | { | ||
1361 | struct sk_buff *skb = rx->skb; | ||
1362 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
1363 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
1364 | int keyidx; | ||
1365 | int hdrlen; | ||
1366 | ieee80211_rx_result result = RX_DROP_UNUSABLE; | ||
1367 | struct ieee80211_key *sta_ptk = NULL; | ||
1368 | int mmie_keyidx = -1; | ||
1369 | __le16 fc; | ||
1370 | |||
1371 | /* | ||
1372 | * Key selection 101 | ||
1373 | * | ||
1374 | * There are four types of keys: | ||
1375 | * - GTK (group keys) | ||
1376 | * - IGTK (group keys for management frames) | ||
1377 | * - PTK (pairwise keys) | ||
1378 | * - STK (station-to-station pairwise keys) | ||
1379 | * | ||
1380 | * When selecting a key, we have to distinguish between multicast | ||
1381 | * (including broadcast) and unicast frames, the latter can only | ||
1382 | * use PTKs and STKs while the former always use GTKs and IGTKs. | ||
1383 | * Unless, of course, actual WEP keys ("pre-RSNA") are used, then | ||
1384 | * unicast frames can also use key indices like GTKs. Hence, if we | ||
1385 | * don't have a PTK/STK we check the key index for a WEP key. | ||
1386 | * | ||
1387 | * Note that in a regular BSS, multicast frames are sent by the | ||
1388 | * AP only, associated stations unicast the frame to the AP first | ||
1389 | * which then multicasts it on their behalf. | ||
1390 | * | ||
1391 | * There is also a slight problem in IBSS mode: GTKs are negotiated | ||
1392 | * with each station, that is something we don't currently handle. | ||
1393 | * The spec seems to expect that one negotiates the same key with | ||
1394 | * every station but there's no such requirement; VLANs could be | ||
1395 | * possible. | ||
1396 | */ | ||
1397 | |||
1398 | /* | ||
1399 | * No point in finding a key and decrypting if the frame is neither | ||
1400 | * addressed to us nor a multicast frame. | ||
1401 | */ | ||
1402 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) | ||
1403 | return RX_CONTINUE; | ||
1404 | |||
1405 | /* start without a key */ | ||
1406 | rx->key = NULL; | ||
1407 | |||
1408 | if (rx->sta) | ||
1409 | sta_ptk = rcu_dereference(rx->sta->ptk); | ||
1410 | |||
1411 | fc = hdr->frame_control; | ||
1412 | |||
1413 | if (!ieee80211_has_protected(fc)) | ||
1414 | mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); | ||
1415 | |||
1416 | if (!is_multicast_ether_addr(hdr->addr1) && sta_ptk) { | ||
1417 | rx->key = sta_ptk; | ||
1418 | if ((status->flag & RX_FLAG_DECRYPTED) && | ||
1419 | (status->flag & RX_FLAG_IV_STRIPPED)) | ||
1420 | return RX_CONTINUE; | ||
1421 | /* Skip decryption if the frame is not protected. */ | ||
1422 | if (!ieee80211_has_protected(fc)) | ||
1423 | return RX_CONTINUE; | ||
1424 | } else if (mmie_keyidx >= 0) { | ||
1425 | /* Broadcast/multicast robust management frame / BIP */ | ||
1426 | if ((status->flag & RX_FLAG_DECRYPTED) && | ||
1427 | (status->flag & RX_FLAG_IV_STRIPPED)) | ||
1428 | return RX_CONTINUE; | ||
1429 | |||
1430 | if (mmie_keyidx < NUM_DEFAULT_KEYS || | ||
1431 | mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) | ||
1432 | return RX_DROP_MONITOR; /* unexpected BIP keyidx */ | ||
1433 | if (rx->sta) | ||
1434 | rx->key = rcu_dereference(rx->sta->gtk[mmie_keyidx]); | ||
1435 | if (!rx->key) | ||
1436 | rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); | ||
1437 | } else if (!ieee80211_has_protected(fc)) { | ||
1438 | /* | ||
1439 | * The frame was not protected, so skip decryption. However, we | ||
1440 | * need to set rx->key if there is a key that could have been | ||
1441 | * used so that the frame may be dropped if encryption would | ||
1442 | * have been expected. | ||
1443 | */ | ||
1444 | struct ieee80211_key *key = NULL; | ||
1445 | struct ieee80211_sub_if_data *sdata = rx->sdata; | ||
1446 | int i; | ||
1447 | |||
1448 | if (ieee80211_is_mgmt(fc) && | ||
1449 | is_multicast_ether_addr(hdr->addr1) && | ||
1450 | (key = rcu_dereference(rx->sdata->default_mgmt_key))) | ||
1451 | rx->key = key; | ||
1452 | else { | ||
1453 | if (rx->sta) { | ||
1454 | for (i = 0; i < NUM_DEFAULT_KEYS; i++) { | ||
1455 | key = rcu_dereference(rx->sta->gtk[i]); | ||
1456 | if (key) | ||
1457 | break; | ||
1458 | } | ||
1459 | } | ||
1460 | if (!key) { | ||
1461 | for (i = 0; i < NUM_DEFAULT_KEYS; i++) { | ||
1462 | key = rcu_dereference(sdata->keys[i]); | ||
1463 | if (key) | ||
1464 | break; | ||
1465 | } | ||
1466 | } | ||
1467 | if (key) | ||
1468 | rx->key = key; | ||
1469 | } | ||
1470 | return RX_CONTINUE; | ||
1471 | } else { | ||
1472 | u8 keyid; | ||
1473 | /* | ||
1474 | * The device doesn't give us the IV so we won't be | ||
1475 | * able to look up the key. That's ok though, we | ||
1476 | * don't need to decrypt the frame, we just won't | ||
1477 | * be able to keep statistics accurate. | ||
1478 | * Except for key threshold notifications, should | ||
1479 | * we somehow allow the driver to tell us which key | ||
1480 | * the hardware used if this flag is set? | ||
1481 | */ | ||
1482 | if ((status->flag & RX_FLAG_DECRYPTED) && | ||
1483 | (status->flag & RX_FLAG_IV_STRIPPED)) | ||
1484 | return RX_CONTINUE; | ||
1485 | |||
1486 | hdrlen = ieee80211_hdrlen(fc); | ||
1487 | |||
1488 | if (rx->skb->len < 8 + hdrlen) | ||
1489 | return RX_DROP_UNUSABLE; /* TODO: count this? */ | ||
1490 | |||
1491 | /* | ||
1492 | * no need to call ieee80211_wep_get_keyidx, | ||
1493 | * it verifies a bunch of things we've done already | ||
1494 | */ | ||
1495 | skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1); | ||
1496 | keyidx = keyid >> 6; | ||
1497 | |||
1498 | /* check per-station GTK first, if multicast packet */ | ||
1499 | if (is_multicast_ether_addr(hdr->addr1) && rx->sta) | ||
1500 | rx->key = rcu_dereference(rx->sta->gtk[keyidx]); | ||
1501 | |||
1502 | /* if not found, try default key */ | ||
1503 | if (!rx->key) { | ||
1504 | rx->key = rcu_dereference(rx->sdata->keys[keyidx]); | ||
1505 | |||
1506 | /* | ||
1507 | * RSNA-protected unicast frames should always be | ||
1508 | * sent with pairwise or station-to-station keys, | ||
1509 | * but for WEP we allow using a key index as well. | ||
1510 | */ | ||
1511 | if (rx->key && | ||
1512 | rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 && | ||
1513 | rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 && | ||
1514 | !is_multicast_ether_addr(hdr->addr1)) | ||
1515 | rx->key = NULL; | ||
1516 | } | ||
1517 | } | ||
1518 | |||
1519 | if (rx->key) { | ||
1520 | if (unlikely(rx->key->flags & KEY_FLAG_TAINTED)) | ||
1521 | return RX_DROP_MONITOR; | ||
1522 | |||
1523 | rx->key->tx_rx_count++; | ||
1524 | /* TODO: add threshold stuff again */ | ||
1525 | } else { | ||
1526 | return RX_DROP_MONITOR; | ||
1527 | } | ||
1528 | |||
1529 | switch (rx->key->conf.cipher) { | ||
1530 | case WLAN_CIPHER_SUITE_WEP40: | ||
1531 | case WLAN_CIPHER_SUITE_WEP104: | ||
1532 | result = ieee80211_crypto_wep_decrypt(rx); | ||
1533 | break; | ||
1534 | case WLAN_CIPHER_SUITE_TKIP: | ||
1535 | result = ieee80211_crypto_tkip_decrypt(rx); | ||
1536 | break; | ||
1537 | case WLAN_CIPHER_SUITE_CCMP: | ||
1538 | result = ieee80211_crypto_ccmp_decrypt(rx); | ||
1539 | break; | ||
1540 | case WLAN_CIPHER_SUITE_AES_CMAC: | ||
1541 | result = ieee80211_crypto_aes_cmac_decrypt(rx); | ||
1542 | break; | ||
1543 | default: | ||
1544 | /* | ||
1545 | * We can reach here only with HW-only algorithms | ||
1546 | * but why didn't it decrypt the frame?! | ||
1547 | */ | ||
1548 | return RX_DROP_UNUSABLE; | ||
1549 | } | ||
1550 | |||
1551 | /* the hdr variable is invalid after the decrypt handlers */ | ||
1552 | |||
1553 | /* either the frame has been decrypted or will be dropped */ | ||
1554 | status->flag |= RX_FLAG_DECRYPTED; | ||
1555 | |||
1556 | return result; | ||
1557 | } | ||
1558 | |||
1559 | static inline struct ieee80211_fragment_entry * | 1559 | static inline struct ieee80211_fragment_entry * |
1560 | ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, | 1560 | ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, |
1561 | unsigned int frag, unsigned int seq, int rx_queue, | 1561 | unsigned int frag, unsigned int seq, int rx_queue, |
@@ -2684,8 +2684,7 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) | |||
2684 | sig = status->signal; | 2684 | sig = status->signal; |
2685 | 2685 | ||
2686 | if (cfg80211_rx_mgmt(&rx->sdata->wdev, status->freq, sig, | 2686 | if (cfg80211_rx_mgmt(&rx->sdata->wdev, status->freq, sig, |
2687 | rx->skb->data, rx->skb->len, | 2687 | rx->skb->data, rx->skb->len, 0, GFP_ATOMIC)) { |
2688 | GFP_ATOMIC)) { | ||
2689 | if (rx->sta) | 2688 | if (rx->sta) |
2690 | rx->sta->rx_packets++; | 2689 | rx->sta->rx_packets++; |
2691 | dev_kfree_skb(rx->skb); | 2690 | dev_kfree_skb(rx->skb); |
@@ -2939,10 +2938,10 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx, | |||
2939 | */ | 2938 | */ |
2940 | rx->skb = skb; | 2939 | rx->skb = skb; |
2941 | 2940 | ||
2942 | CALL_RXH(ieee80211_rx_h_decrypt) | ||
2943 | CALL_RXH(ieee80211_rx_h_check_more_data) | 2941 | CALL_RXH(ieee80211_rx_h_check_more_data) |
2944 | CALL_RXH(ieee80211_rx_h_uapsd_and_pspoll) | 2942 | CALL_RXH(ieee80211_rx_h_uapsd_and_pspoll) |
2945 | CALL_RXH(ieee80211_rx_h_sta_process) | 2943 | CALL_RXH(ieee80211_rx_h_sta_process) |
2944 | CALL_RXH(ieee80211_rx_h_decrypt) | ||
2946 | CALL_RXH(ieee80211_rx_h_defragment) | 2945 | CALL_RXH(ieee80211_rx_h_defragment) |
2947 | CALL_RXH(ieee80211_rx_h_michael_mic_verify) | 2946 | CALL_RXH(ieee80211_rx_h_michael_mic_verify) |
2948 | /* must be after MMIC verify so header is counted in MPDU mic */ | 2947 | /* must be after MMIC verify so header is counted in MPDU mic */ |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 0e42322aa6b1..3456c0486b48 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -539,9 +539,11 @@ ieee80211_tx_h_check_control_port_protocol(struct ieee80211_tx_data *tx) | |||
539 | { | 539 | { |
540 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 540 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
541 | 541 | ||
542 | if (unlikely(tx->sdata->control_port_protocol == tx->skb->protocol && | 542 | if (unlikely(tx->sdata->control_port_protocol == tx->skb->protocol)) { |
543 | tx->sdata->control_port_no_encrypt)) | 543 | if (tx->sdata->control_port_no_encrypt) |
544 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 544 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
545 | info->control.flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO; | ||
546 | } | ||
545 | 547 | ||
546 | return TX_CONTINUE; | 548 | return TX_CONTINUE; |
547 | } | 549 | } |
@@ -779,9 +781,11 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) | |||
779 | /* | 781 | /* |
780 | * Anything but QoS data that has a sequence number field | 782 | * Anything but QoS data that has a sequence number field |
781 | * (is long enough) gets a sequence number from the global | 783 | * (is long enough) gets a sequence number from the global |
782 | * counter. | 784 | * counter. QoS data frames with a multicast destination |
785 | * also use the global counter (802.11-2012 9.3.2.10). | ||
783 | */ | 786 | */ |
784 | if (!ieee80211_is_data_qos(hdr->frame_control)) { | 787 | if (!ieee80211_is_data_qos(hdr->frame_control) || |
788 | is_multicast_ether_addr(hdr->addr1)) { | ||
785 | /* driver should assign sequence number */ | 789 | /* driver should assign sequence number */ |
786 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; | 790 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; |
787 | /* for pure STA mode without beacons, we can do it */ | 791 | /* for pure STA mode without beacons, we can do it */ |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index d23c5a705a68..e1b34a18b243 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1453,8 +1453,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1453 | local->resuming = true; | 1453 | local->resuming = true; |
1454 | 1454 | ||
1455 | if (local->wowlan) { | 1455 | if (local->wowlan) { |
1456 | local->wowlan = false; | ||
1457 | res = drv_resume(local); | 1456 | res = drv_resume(local); |
1457 | local->wowlan = false; | ||
1458 | if (res < 0) { | 1458 | if (res < 0) { |
1459 | local->resuming = false; | 1459 | local->resuming = false; |
1460 | return res; | 1460 | return res; |