aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-12-23 07:15:35 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-12-28 16:54:55 -0500
commitaf6b63741cc4e4dfd575d06beb333b11a8a6e0c0 (patch)
treea2c1a27b6b6b0fb171606f3653b5c280537b32a3
parentf679f65d417c3ea3f91b4bbfb68e3951c9eb8f04 (diff)
mac80211: generalise work handling
In order to use auth/assoc for different purposes other than MLME, it needs to be split up. For other purposes, a generic work handling (potentially on another channel) will be useful. To achieve that, this patch moves much of the MLME work handling out of mlme into a new work API. The API can currently handle probing a specific AP, authentication and association. The MLME previously handled probe/authentication as one step and will continue to do so, but they are separate in the new work handling. Work items are RCU-managed to be able to check for existence of an item for a specific frame in the RX path, but they can be re-used which the MLME right now will do for its combined probe/auth step. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/mac80211/Makefile2
-rw-r--r--net/mac80211/debugfs_netdev.c2
-rw-r--r--net/mac80211/ieee80211_i.h59
-rw-r--r--net/mac80211/iface.c11
-rw-r--r--net/mac80211/main.c2
-rw-r--r--net/mac80211/mlme.c956
-rw-r--r--net/mac80211/rx.c5
-rw-r--r--net/mac80211/scan.c8
-rw-r--r--net/mac80211/work.c902
9 files changed, 1112 insertions, 835 deletions
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index 298cfcc1bf8d..5a1f57df7cd6 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -9,7 +9,7 @@ mac80211-y := \
9 scan.o \ 9 scan.o \
10 ht.o agg-tx.o agg-rx.o \ 10 ht.o agg-tx.o agg-rx.o \
11 ibss.o \ 11 ibss.o \
12 mlme.o \ 12 mlme.o work.o \
13 iface.o \ 13 iface.o \
14 rate.o \ 14 rate.o \
15 michael.o \ 15 michael.o \
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 355983503885..59f6e3bcbd09 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -133,7 +133,6 @@ IEEE80211_IF_FILE(max_ratectrl_rateidx, max_ratectrl_rateidx, DEC);
133/* STA attributes */ 133/* STA attributes */
134IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC); 134IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC);
135IEEE80211_IF_FILE(aid, u.mgd.aid, DEC); 135IEEE80211_IF_FILE(aid, u.mgd.aid, DEC);
136IEEE80211_IF_FILE(capab, u.mgd.capab, HEX);
137 136
138static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata, 137static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
139 enum ieee80211_smps_mode smps_mode) 138 enum ieee80211_smps_mode smps_mode)
@@ -270,7 +269,6 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
270 269
271 DEBUGFS_ADD(bssid, sta); 270 DEBUGFS_ADD(bssid, sta);
272 DEBUGFS_ADD(aid, sta); 271 DEBUGFS_ADD(aid, sta);
273 DEBUGFS_ADD(capab, sta);
274 DEBUGFS_ADD_MODE(smps, 0600); 272 DEBUGFS_ADD_MODE(smps, 0600);
275} 273}
276 274
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 0339e909e0c4..97b6076b492e 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -228,41 +228,63 @@ struct mesh_preq_queue {
228}; 228};
229 229
230enum ieee80211_work_type { 230enum ieee80211_work_type {
231 IEEE80211_WORK_AUTH_PROBE, 231 IEEE80211_WORK_DIRECT_PROBE,
232 IEEE80211_WORK_AUTH, 232 IEEE80211_WORK_AUTH,
233 IEEE80211_WORK_ASSOC, 233 IEEE80211_WORK_ASSOC,
234}; 234};
235 235
236/**
237 * enum work_done_result - indicates what to do after work was done
238 *
239 * @WORK_DONE_DESTROY: This work item is no longer needed, destroy.
240 * @WORK_DONE_REQUEUE: This work item was reset to be reused, and
241 * should be requeued.
242 */
243enum work_done_result {
244 WORK_DONE_DESTROY,
245 WORK_DONE_REQUEUE,
246};
247
236struct ieee80211_work { 248struct ieee80211_work {
237 struct list_head list; 249 struct list_head list;
238 250
251 struct rcu_head rcu_head;
252
253 struct ieee80211_sub_if_data *sdata;
254
255 enum work_done_result (*done)(struct ieee80211_work *wk,
256 struct sk_buff *skb);
257
239 struct ieee80211_channel *chan; 258 struct ieee80211_channel *chan;
240 /* XXX: chan type? -- right now not really needed */ 259 /* XXX: chan type? -- right now not really needed */
260
241 unsigned long timeout; 261 unsigned long timeout;
242 enum ieee80211_work_type type; 262 enum ieee80211_work_type type;
243 263
264 u8 filter_ta[ETH_ALEN];
265
244 union { 266 union {
245 struct { 267 struct {
246 int tries; 268 int tries;
247 u16 algorithm, transaction; 269 u16 algorithm, transaction;
248 u8 ssid[IEEE80211_MAX_SSID_LEN]; 270 u8 ssid[IEEE80211_MAX_SSID_LEN];
249 u8 ssid_len; 271 u8 ssid_len;
250 u8 bssid[ETH_ALEN];
251 u8 key[WLAN_KEY_LEN_WEP104]; 272 u8 key[WLAN_KEY_LEN_WEP104];
252 u8 key_len, key_idx; 273 u8 key_len, key_idx;
253 bool privacy; 274 bool privacy;
254 } auth; 275 } probe_auth;
255 struct { 276 struct {
256 struct ieee80211_bss *bss; 277 struct ieee80211_bss *bss;
257 const u8 *supp_rates; 278 const u8 *supp_rates;
258 const u8 *ht_information_ie; 279 const u8 *ht_information_ie;
280 enum ieee80211_smps_mode smps;
259 int tries; 281 int tries;
260 u16 capability; 282 u16 capability;
261 u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; 283 u8 prev_bssid[ETH_ALEN];
262 u8 ssid[IEEE80211_MAX_SSID_LEN]; 284 u8 ssid[IEEE80211_MAX_SSID_LEN];
263 u8 ssid_len; 285 u8 ssid_len;
264 u8 supp_rates_len; 286 u8 supp_rates_len;
265 bool wmm_used; 287 bool wmm_used, use_11n;
266 } assoc; 288 } assoc;
267 }; 289 };
268 290
@@ -276,17 +298,11 @@ enum ieee80211_sta_flags {
276 IEEE80211_STA_BEACON_POLL = BIT(0), 298 IEEE80211_STA_BEACON_POLL = BIT(0),
277 IEEE80211_STA_CONNECTION_POLL = BIT(1), 299 IEEE80211_STA_CONNECTION_POLL = BIT(1),
278 IEEE80211_STA_CONTROL_PORT = BIT(2), 300 IEEE80211_STA_CONTROL_PORT = BIT(2),
279 IEEE80211_STA_WMM_ENABLED = BIT(3),
280 IEEE80211_STA_DISABLE_11N = BIT(4), 301 IEEE80211_STA_DISABLE_11N = BIT(4),
281 IEEE80211_STA_CSA_RECEIVED = BIT(5), 302 IEEE80211_STA_CSA_RECEIVED = BIT(5),
282 IEEE80211_STA_MFP_ENABLED = BIT(6), 303 IEEE80211_STA_MFP_ENABLED = BIT(6),
283}; 304};
284 305
285/* flags for MLME request */
286enum ieee80211_sta_request {
287 IEEE80211_STA_REQ_SCAN,
288};
289
290struct ieee80211_if_managed { 306struct ieee80211_if_managed {
291 struct timer_list timer; 307 struct timer_list timer;
292 struct timer_list conn_mon_timer; 308 struct timer_list conn_mon_timer;
@@ -302,12 +318,10 @@ struct ieee80211_if_managed {
302 318
303 struct mutex mtx; 319 struct mutex mtx;
304 struct ieee80211_bss *associated; 320 struct ieee80211_bss *associated;
305 struct list_head work_list;
306 321
307 u8 bssid[ETH_ALEN]; 322 u8 bssid[ETH_ALEN];
308 323
309 u16 aid; 324 u16 aid;
310 u16 capab;
311 325
312 struct sk_buff_head skb_queue; 326 struct sk_buff_head skb_queue;
313 327
@@ -316,8 +330,6 @@ struct ieee80211_if_managed {
316 enum ieee80211_smps_mode req_smps, /* requested smps mode */ 330 enum ieee80211_smps_mode req_smps, /* requested smps mode */
317 ap_smps; /* smps mode AP thinks we're in */ 331 ap_smps; /* smps mode AP thinks we're in */
318 332
319 unsigned long request;
320
321 unsigned int flags; 333 unsigned int flags;
322 334
323 u32 beacon_crc; 335 u32 beacon_crc;
@@ -584,6 +596,15 @@ struct ieee80211_local {
584 const struct ieee80211_ops *ops; 596 const struct ieee80211_ops *ops;
585 597
586 /* 598 /*
599 * work stuff, potentially off-channel (in the future)
600 */
601 struct mutex work_mtx;
602 struct list_head work_list;
603 struct timer_list work_timer;
604 struct work_struct work_work;
605 struct sk_buff_head work_skb_queue;
606
607 /*
587 * private workqueue to mac80211. mac80211 makes this accessible 608 * private workqueue to mac80211. mac80211 makes this accessible
588 * via ieee80211_queue_work() 609 * via ieee80211_queue_work()
589 */ 610 */
@@ -1127,6 +1148,14 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
1127void ieee80211_recalc_smps(struct ieee80211_local *local, 1148void ieee80211_recalc_smps(struct ieee80211_local *local,
1128 struct ieee80211_sub_if_data *forsdata); 1149 struct ieee80211_sub_if_data *forsdata);
1129 1150
1151/* internal work items */
1152void ieee80211_work_init(struct ieee80211_local *local);
1153void ieee80211_add_work(struct ieee80211_work *wk);
1154void free_work(struct ieee80211_work *wk);
1155void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata);
1156ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata,
1157 struct sk_buff *skb);
1158
1130#ifdef CONFIG_MAC80211_NOINLINE 1159#ifdef CONFIG_MAC80211_NOINLINE
1131#define debug_noinline noinline 1160#define debug_noinline noinline
1132#else 1161#else
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 389dc8d880f3..7d410f15281a 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -362,6 +362,11 @@ static int ieee80211_stop(struct net_device *dev)
362 netif_stop_queue(dev); 362 netif_stop_queue(dev);
363 363
364 /* 364 /*
365 * Purge work for this interface.
366 */
367 ieee80211_work_purge(sdata);
368
369 /*
365 * Now delete all active aggregation sessions. 370 * Now delete all active aggregation sessions.
366 */ 371 */
367 rcu_read_lock(); 372 rcu_read_lock();
@@ -928,6 +933,9 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
928 struct ieee80211_sub_if_data *sdata; 933 struct ieee80211_sub_if_data *sdata;
929 int count = 0; 934 int count = 0;
930 935
936 if (!list_empty(&local->work_list))
937 return ieee80211_idle_off(local, "working");
938
931 if (local->scanning) 939 if (local->scanning)
932 return ieee80211_idle_off(local, "scanning"); 940 return ieee80211_idle_off(local, "scanning");
933 941
@@ -936,8 +944,7 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
936 continue; 944 continue;
937 /* do not count disabled managed interfaces */ 945 /* do not count disabled managed interfaces */
938 if (sdata->vif.type == NL80211_IFTYPE_STATION && 946 if (sdata->vif.type == NL80211_IFTYPE_STATION &&
939 !sdata->u.mgd.associated && 947 !sdata->u.mgd.associated)
940 list_empty(&sdata->u.mgd.work_list))
941 continue; 948 continue;
942 /* do not count unused IBSS interfaces */ 949 /* do not count unused IBSS interfaces */
943 if (sdata->vif.type == NL80211_IFTYPE_ADHOC && 950 if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index e93bc558d785..d35023ce7fa1 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -395,6 +395,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
395 395
396 INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); 396 INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
397 397
398 ieee80211_work_init(local);
399
398 INIT_WORK(&local->restart_work, ieee80211_restart_work); 400 INIT_WORK(&local->restart_work, ieee80211_restart_work);
399 401
400 INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter); 402 INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index c65225f29bb6..7c1f91bcc834 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -77,12 +77,6 @@ enum rx_mgmt_action {
77 77
78 /* caller must tell cfg80211 about internal error */ 78 /* caller must tell cfg80211 about internal error */
79 RX_MGMT_CFG80211_ASSOC_ERROR, 79 RX_MGMT_CFG80211_ASSOC_ERROR,
80
81 /* caller must call cfg80211_auth_timeout() & free work */
82 RX_MGMT_CFG80211_AUTH_TO,
83
84 /* caller must call cfg80211_assoc_timeout() & free work */
85 RX_MGMT_CFG80211_ASSOC_TO,
86}; 80};
87 81
88/* utils */ 82/* utils */
@@ -125,27 +119,6 @@ static int ecw2cw(int ecw)
125 return (1 << ecw) - 1; 119 return (1 << ecw) - 1;
126} 120}
127 121
128static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len,
129 struct ieee80211_supported_band *sband,
130 u32 *rates)
131{
132 int i, j, count;
133 *rates = 0;
134 count = 0;
135 for (i = 0; i < supp_rates_len; i++) {
136 int rate = (supp_rates[i] & 0x7F) * 5;
137
138 for (j = 0; j < sband->n_bitrates; j++)
139 if (sband->bitrates[j].bitrate == rate) {
140 *rates |= BIT(j);
141 count++;
142 break;
143 }
144 }
145
146 return count;
147}
148
149/* 122/*
150 * ieee80211_enable_ht should be called only after the operating band 123 * ieee80211_enable_ht should be called only after the operating band
151 * has been determined as ht configuration depends on the hw's 124 * has been determined as ht configuration depends on the hw's
@@ -231,266 +204,6 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
231 204
232/* frame sending functions */ 205/* frame sending functions */
233 206
234static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
235 struct ieee80211_work *wk)
236{
237 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
238 struct ieee80211_local *local = sdata->local;
239 struct sk_buff *skb;
240 struct ieee80211_mgmt *mgmt;
241 u8 *pos;
242 const u8 *ies, *ht_ie;
243 int i, len, count, rates_len, supp_rates_len;
244 u16 capab;
245 int wmm = 0;
246 struct ieee80211_supported_band *sband;
247 u32 rates = 0;
248
249 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
250 sizeof(*mgmt) + 200 + wk->ie_len +
251 wk->assoc.ssid_len);
252 if (!skb) {
253 printk(KERN_DEBUG "%s: failed to allocate buffer for assoc "
254 "frame\n", sdata->name);
255 return;
256 }
257 skb_reserve(skb, local->hw.extra_tx_headroom);
258
259 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
260
261 capab = ifmgd->capab;
262
263 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) {
264 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
265 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
266 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
267 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
268 }
269
270 if (wk->assoc.capability & WLAN_CAPABILITY_PRIVACY)
271 capab |= WLAN_CAPABILITY_PRIVACY;
272 if (wk->assoc.wmm_used)
273 wmm = 1;
274
275 /* get all rates supported by the device and the AP as
276 * some APs don't like getting a superset of their rates
277 * in the association request (e.g. D-Link DAP 1353 in
278 * b-only mode) */
279 rates_len = ieee80211_compatible_rates(wk->assoc.supp_rates,
280 wk->assoc.supp_rates_len,
281 sband, &rates);
282
283 if ((wk->assoc.capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
284 (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
285 capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
286
287 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
288 memset(mgmt, 0, 24);
289 memcpy(mgmt->da, wk->assoc.bssid, ETH_ALEN);
290 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
291 memcpy(mgmt->bssid, wk->assoc.bssid, ETH_ALEN);
292
293 if (!is_zero_ether_addr(wk->assoc.prev_bssid)) {
294 skb_put(skb, 10);
295 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
296 IEEE80211_STYPE_REASSOC_REQ);
297 mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
298 mgmt->u.reassoc_req.listen_interval =
299 cpu_to_le16(local->hw.conf.listen_interval);
300 memcpy(mgmt->u.reassoc_req.current_ap, wk->assoc.prev_bssid,
301 ETH_ALEN);
302 } else {
303 skb_put(skb, 4);
304 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
305 IEEE80211_STYPE_ASSOC_REQ);
306 mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
307 mgmt->u.assoc_req.listen_interval =
308 cpu_to_le16(local->hw.conf.listen_interval);
309 }
310
311 /* SSID */
312 ies = pos = skb_put(skb, 2 + wk->assoc.ssid_len);
313 *pos++ = WLAN_EID_SSID;
314 *pos++ = wk->assoc.ssid_len;
315 memcpy(pos, wk->assoc.ssid, wk->assoc.ssid_len);
316
317 /* add all rates which were marked to be used above */
318 supp_rates_len = rates_len;
319 if (supp_rates_len > 8)
320 supp_rates_len = 8;
321
322 len = sband->n_bitrates;
323 pos = skb_put(skb, supp_rates_len + 2);
324 *pos++ = WLAN_EID_SUPP_RATES;
325 *pos++ = supp_rates_len;
326
327 count = 0;
328 for (i = 0; i < sband->n_bitrates; i++) {
329 if (BIT(i) & rates) {
330 int rate = sband->bitrates[i].bitrate;
331 *pos++ = (u8) (rate / 5);
332 if (++count == 8)
333 break;
334 }
335 }
336
337 if (rates_len > count) {
338 pos = skb_put(skb, rates_len - count + 2);
339 *pos++ = WLAN_EID_EXT_SUPP_RATES;
340 *pos++ = rates_len - count;
341
342 for (i++; i < sband->n_bitrates; i++) {
343 if (BIT(i) & rates) {
344 int rate = sband->bitrates[i].bitrate;
345 *pos++ = (u8) (rate / 5);
346 }
347 }
348 }
349
350 if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) {
351 /* 1. power capabilities */
352 pos = skb_put(skb, 4);
353 *pos++ = WLAN_EID_PWR_CAPABILITY;
354 *pos++ = 2;
355 *pos++ = 0; /* min tx power */
356 *pos++ = local->hw.conf.channel->max_power; /* max tx power */
357
358 /* 2. supported channels */
359 /* TODO: get this in reg domain format */
360 pos = skb_put(skb, 2 * sband->n_channels + 2);
361 *pos++ = WLAN_EID_SUPPORTED_CHANNELS;
362 *pos++ = 2 * sband->n_channels;
363 for (i = 0; i < sband->n_channels; i++) {
364 *pos++ = ieee80211_frequency_to_channel(
365 sband->channels[i].center_freq);
366 *pos++ = 1; /* one channel in the subband*/
367 }
368 }
369
370 if (wk->ie_len && wk->ie) {
371 pos = skb_put(skb, wk->ie_len);
372 memcpy(pos, wk->ie, wk->ie_len);
373 }
374
375 if (wmm && (ifmgd->flags & IEEE80211_STA_WMM_ENABLED)) {
376 pos = skb_put(skb, 9);
377 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
378 *pos++ = 7; /* len */
379 *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
380 *pos++ = 0x50;
381 *pos++ = 0xf2;
382 *pos++ = 2; /* WME */
383 *pos++ = 0; /* WME info */
384 *pos++ = 1; /* WME ver */
385 *pos++ = 0;
386 }
387
388 /* wmm support is a must to HT */
389 /*
390 * IEEE802.11n does not allow TKIP/WEP as pairwise
391 * ciphers in HT mode. We still associate in non-ht
392 * mode (11a/b/g) if any one of these ciphers is
393 * configured as pairwise.
394 */
395 if (wmm && (ifmgd->flags & IEEE80211_STA_WMM_ENABLED) &&
396 sband->ht_cap.ht_supported &&
397 (ht_ie = wk->assoc.ht_information_ie) &&
398 ht_ie[1] >= sizeof(struct ieee80211_ht_info) &&
399 (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N))) {
400 struct ieee80211_ht_info *ht_info =
401 (struct ieee80211_ht_info *)(ht_ie + 2);
402 u16 cap = sband->ht_cap.cap;
403 __le16 tmp;
404 u32 flags = local->hw.conf.channel->flags;
405
406 /* determine capability flags */
407
408 if (ieee80211_disable_40mhz_24ghz &&
409 sband->band == IEEE80211_BAND_2GHZ) {
410 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
411 cap &= ~IEEE80211_HT_CAP_SGI_40;
412 }
413
414 switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
415 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
416 if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
417 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
418 cap &= ~IEEE80211_HT_CAP_SGI_40;
419 }
420 break;
421 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
422 if (flags & IEEE80211_CHAN_NO_HT40MINUS) {
423 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
424 cap &= ~IEEE80211_HT_CAP_SGI_40;
425 }
426 break;
427 }
428
429 /* set SM PS mode properly */
430 cap &= ~IEEE80211_HT_CAP_SM_PS;
431 /* new association always uses requested smps mode */
432 if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) {
433 if (ifmgd->powersave)
434 ifmgd->ap_smps = IEEE80211_SMPS_DYNAMIC;
435 else
436 ifmgd->ap_smps = IEEE80211_SMPS_OFF;
437 } else
438 ifmgd->ap_smps = ifmgd->req_smps;
439
440 switch (ifmgd->ap_smps) {
441 case IEEE80211_SMPS_AUTOMATIC:
442 case IEEE80211_SMPS_NUM_MODES:
443 WARN_ON(1);
444 case IEEE80211_SMPS_OFF:
445 cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
446 IEEE80211_HT_CAP_SM_PS_SHIFT;
447 break;
448 case IEEE80211_SMPS_STATIC:
449 cap |= WLAN_HT_CAP_SM_PS_STATIC <<
450 IEEE80211_HT_CAP_SM_PS_SHIFT;
451 break;
452 case IEEE80211_SMPS_DYNAMIC:
453 cap |= WLAN_HT_CAP_SM_PS_DYNAMIC <<
454 IEEE80211_HT_CAP_SM_PS_SHIFT;
455 break;
456 }
457
458 /* reserve and fill IE */
459
460 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
461 *pos++ = WLAN_EID_HT_CAPABILITY;
462 *pos++ = sizeof(struct ieee80211_ht_cap);
463 memset(pos, 0, sizeof(struct ieee80211_ht_cap));
464
465 /* capability flags */
466 tmp = cpu_to_le16(cap);
467 memcpy(pos, &tmp, sizeof(u16));
468 pos += sizeof(u16);
469
470 /* AMPDU parameters */
471 *pos++ = sband->ht_cap.ampdu_factor |
472 (sband->ht_cap.ampdu_density <<
473 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
474
475 /* MCS set */
476 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
477 pos += sizeof(sband->ht_cap.mcs);
478
479 /* extended capabilities */
480 pos += sizeof(__le16);
481
482 /* BF capabilities */
483 pos += sizeof(__le32);
484
485 /* antenna selection */
486 pos += sizeof(u8);
487 }
488
489 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
490 ieee80211_tx_skb(sdata, skb);
491}
492
493
494static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, 207static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
495 const u8 *bssid, u16 stype, u16 reason, 208 const u8 *bssid, u16 stype, u16 reason,
496 void *cookie) 209 void *cookie)
@@ -751,6 +464,11 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
751 return; 464 return;
752 } 465 }
753 466
467 if (!list_empty(&local->work_list)) {
468 local->ps_sdata = NULL;
469 goto change;
470 }
471
754 list_for_each_entry(sdata, &local->interfaces, list) { 472 list_for_each_entry(sdata, &local->interfaces, list) {
755 if (!ieee80211_sdata_running(sdata)) 473 if (!ieee80211_sdata_running(sdata))
756 continue; 474 continue;
@@ -761,7 +479,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
761 } 479 }
762 480
763 if (count == 1 && found->u.mgd.powersave && 481 if (count == 1 && found->u.mgd.powersave &&
764 found->u.mgd.associated && list_empty(&found->u.mgd.work_list) && 482 found->u.mgd.associated &&
765 !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL | 483 !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL |
766 IEEE80211_STA_CONNECTION_POLL))) { 484 IEEE80211_STA_CONNECTION_POLL))) {
767 s32 beaconint_us; 485 s32 beaconint_us;
@@ -789,6 +507,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
789 local->ps_sdata = NULL; 507 local->ps_sdata = NULL;
790 } 508 }
791 509
510 change:
792 ieee80211_change_ps(local); 511 ieee80211_change_ps(local);
793} 512}
794 513
@@ -848,7 +567,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
848 int count; 567 int count;
849 u8 *pos; 568 u8 *pos;
850 569
851 if (!(ifmgd->flags & IEEE80211_STA_WMM_ENABLED)) 570 if (local->hw.queues < 4)
852 return; 571 return;
853 572
854 if (!wmm_param) 573 if (!wmm_param)
@@ -1005,110 +724,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
1005 netif_carrier_on(sdata->dev); 724 netif_carrier_on(sdata->dev);
1006} 725}
1007 726
1008static void ieee80211_remove_auth_bss(struct ieee80211_local *local,
1009 struct ieee80211_work *wk)
1010{
1011 struct cfg80211_bss *cbss;
1012 u16 capa_val = WLAN_CAPABILITY_ESS;
1013
1014 if (wk->auth.privacy)
1015 capa_val |= WLAN_CAPABILITY_PRIVACY;
1016
1017 cbss = cfg80211_get_bss(local->hw.wiphy, wk->chan, wk->auth.bssid,
1018 wk->auth.ssid, wk->auth.ssid_len,
1019 WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY,
1020 capa_val);
1021 if (!cbss)
1022 return;
1023
1024 cfg80211_unlink_bss(local->hw.wiphy, cbss);
1025 cfg80211_put_bss(cbss);
1026}
1027
1028static enum rx_mgmt_action __must_check
1029ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata,
1030 struct ieee80211_work *wk)
1031{
1032 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1033 struct ieee80211_local *local = sdata->local;
1034
1035 wk->auth.tries++;
1036 if (wk->auth.tries > IEEE80211_AUTH_MAX_TRIES) {
1037 printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n",
1038 sdata->name, wk->auth.bssid);
1039
1040 /*
1041 * Most likely AP is not in the range so remove the
1042 * bss struct for that AP.
1043 */
1044 ieee80211_remove_auth_bss(local, wk);
1045
1046 /*
1047 * We might have a pending scan which had no chance to run yet
1048 * due to work needing to be done. Hence, queue the STAs work
1049 * again for that.
1050 */
1051 ieee80211_queue_work(&local->hw, &ifmgd->work);
1052 return RX_MGMT_CFG80211_AUTH_TO;
1053 }
1054
1055 printk(KERN_DEBUG "%s: direct probe to AP %pM (try %d)\n",
1056 sdata->name, wk->auth.bssid, wk->auth.tries);
1057
1058 /*
1059 * Direct probe is sent to broadcast address as some APs
1060 * will not answer to direct packet in unassociated state.
1061 */
1062 ieee80211_send_probe_req(sdata, NULL, wk->auth.ssid, wk->auth.ssid_len,
1063 NULL, 0);
1064
1065 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
1066 run_again(ifmgd, wk->timeout);
1067
1068 return RX_MGMT_NONE;
1069}
1070
1071
1072static enum rx_mgmt_action __must_check
1073ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
1074 struct ieee80211_work *wk)
1075{
1076 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1077 struct ieee80211_local *local = sdata->local;
1078
1079 wk->auth.tries++;
1080 if (wk->auth.tries > IEEE80211_AUTH_MAX_TRIES) {
1081 printk(KERN_DEBUG "%s: authentication with AP %pM"
1082 " timed out\n", sdata->name, wk->auth.bssid);
1083
1084 /*
1085 * Most likely AP is not in the range so remove the
1086 * bss struct for that AP.
1087 */
1088 ieee80211_remove_auth_bss(local, wk);
1089
1090 /*
1091 * We might have a pending scan which had no chance to run yet
1092 * due to work needing to be done. Hence, queue the STAs work
1093 * again for that.
1094 */
1095 ieee80211_queue_work(&local->hw, &ifmgd->work);
1096 return RX_MGMT_CFG80211_AUTH_TO;
1097 }
1098
1099 printk(KERN_DEBUG "%s: authenticate with AP %pM (try %d)\n",
1100 sdata->name, wk->auth.bssid, wk->auth.tries);
1101
1102 ieee80211_send_auth(sdata, 1, wk->auth.algorithm, wk->ie, wk->ie_len,
1103 wk->auth.bssid, NULL, 0, 0);
1104 wk->auth.transaction = 2;
1105
1106 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
1107 run_again(ifmgd, wk->timeout);
1108
1109 return RX_MGMT_NONE;
1110}
1111
1112static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata) 727static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata)
1113{ 728{
1114 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 729 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
@@ -1195,44 +810,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata)
1195 sta_info_destroy(sta); 810 sta_info_destroy(sta);
1196} 811}
1197 812
1198static enum rx_mgmt_action __must_check
1199ieee80211_associate(struct ieee80211_sub_if_data *sdata,
1200 struct ieee80211_work *wk)
1201{
1202 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1203 struct ieee80211_local *local = sdata->local;
1204
1205 wk->assoc.tries++;
1206 if (wk->assoc.tries > IEEE80211_ASSOC_MAX_TRIES) {
1207 printk(KERN_DEBUG "%s: association with AP %pM"
1208 " timed out\n",
1209 sdata->name, wk->assoc.bssid);
1210
1211 /*
1212 * Most likely AP is not in the range so remove the
1213 * bss struct for that AP.
1214 */
1215 cfg80211_unlink_bss(local->hw.wiphy, &wk->assoc.bss->cbss);
1216
1217 /*
1218 * We might have a pending scan which had no chance to run yet
1219 * due to work needing to be done. Hence, queue the STAs work
1220 * again for that.
1221 */
1222 ieee80211_queue_work(&local->hw, &ifmgd->work);
1223 return RX_MGMT_CFG80211_ASSOC_TO;
1224 }
1225
1226 printk(KERN_DEBUG "%s: associate with AP %pM (try %d)\n",
1227 sdata->name, wk->assoc.bssid, wk->assoc.tries);
1228 ieee80211_send_assoc(sdata, wk);
1229
1230 wk->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
1231 run_again(ifmgd, wk->timeout);
1232
1233 return RX_MGMT_NONE;
1234}
1235
1236void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 813void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
1237 struct ieee80211_hdr *hdr) 814 struct ieee80211_hdr *hdr)
1238{ 815{
@@ -1338,86 +915,6 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif)
1338} 915}
1339EXPORT_SYMBOL(ieee80211_beacon_loss); 916EXPORT_SYMBOL(ieee80211_beacon_loss);
1340 917
1341static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata,
1342 struct ieee80211_work *wk)
1343{
1344 list_del(&wk->list);
1345 kfree(wk);
1346 printk(KERN_DEBUG "%s: authenticated\n", sdata->name);
1347}
1348
1349
1350static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
1351 struct ieee80211_work *wk,
1352 struct ieee80211_mgmt *mgmt,
1353 size_t len)
1354{
1355 u8 *pos;
1356 struct ieee802_11_elems elems;
1357
1358 pos = mgmt->u.auth.variable;
1359 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1360 if (!elems.challenge)
1361 return;
1362 ieee80211_send_auth(sdata, 3, wk->auth.algorithm,
1363 elems.challenge - 2, elems.challenge_len + 2,
1364 wk->auth.bssid, wk->auth.key, wk->auth.key_len,
1365 wk->auth.key_idx);
1366 wk->auth.transaction = 4;
1367}
1368
1369static enum rx_mgmt_action __must_check
1370ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1371 struct ieee80211_work *wk,
1372 struct ieee80211_mgmt *mgmt, size_t len)
1373{
1374 u16 auth_alg, auth_transaction, status_code;
1375
1376 if (wk->type != IEEE80211_WORK_AUTH)
1377 return RX_MGMT_NONE;
1378
1379 if (len < 24 + 6)
1380 return RX_MGMT_NONE;
1381
1382 if (memcmp(wk->auth.bssid, mgmt->sa, ETH_ALEN) != 0)
1383 return RX_MGMT_NONE;
1384
1385 if (memcmp(wk->auth.bssid, mgmt->bssid, ETH_ALEN) != 0)
1386 return RX_MGMT_NONE;
1387
1388 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
1389 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
1390 status_code = le16_to_cpu(mgmt->u.auth.status_code);
1391
1392 if (auth_alg != wk->auth.algorithm ||
1393 auth_transaction != wk->auth.transaction)
1394 return RX_MGMT_NONE;
1395
1396 if (status_code != WLAN_STATUS_SUCCESS) {
1397 list_del(&wk->list);
1398 kfree(wk);
1399 return RX_MGMT_CFG80211_AUTH;
1400 }
1401
1402 switch (wk->auth.algorithm) {
1403 case WLAN_AUTH_OPEN:
1404 case WLAN_AUTH_LEAP:
1405 case WLAN_AUTH_FT:
1406 ieee80211_auth_completed(sdata, wk);
1407 return RX_MGMT_CFG80211_AUTH;
1408 case WLAN_AUTH_SHARED_KEY:
1409 if (wk->auth.transaction == 4) {
1410 ieee80211_auth_completed(sdata, wk);
1411 return RX_MGMT_CFG80211_AUTH;
1412 } else
1413 ieee80211_auth_challenge(sdata, wk, mgmt, len);
1414 break;
1415 }
1416
1417 return RX_MGMT_NONE;
1418}
1419
1420
1421static enum rx_mgmt_action __must_check 918static enum rx_mgmt_action __must_check
1422ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, 919ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1423 struct ieee80211_mgmt *mgmt, size_t len) 920 struct ieee80211_mgmt *mgmt, size_t len)
@@ -1474,98 +971,51 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1474} 971}
1475 972
1476 973
1477static enum rx_mgmt_action __must_check 974static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1478ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, 975 struct ieee80211_mgmt *mgmt, size_t len)
1479 struct ieee80211_work *wk,
1480 struct ieee80211_mgmt *mgmt, size_t len,
1481 bool reassoc)
1482{ 976{
977 struct ieee80211_sub_if_data *sdata = wk->sdata;
1483 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 978 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1484 struct ieee80211_local *local = sdata->local; 979 struct ieee80211_local *local = sdata->local;
1485 struct ieee80211_supported_band *sband; 980 struct ieee80211_supported_band *sband;
1486 struct sta_info *sta; 981 struct sta_info *sta;
1487 struct ieee80211_bss *bss = wk->assoc.bss; 982 struct ieee80211_bss *bss = wk->assoc.bss;
983 u8 *pos;
1488 u32 rates, basic_rates; 984 u32 rates, basic_rates;
1489 u16 capab_info, status_code, aid; 985 u16 capab_info, aid;
1490 struct ieee802_11_elems elems; 986 struct ieee802_11_elems elems;
1491 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; 987 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
1492 u8 *pos;
1493 u32 changed = 0; 988 u32 changed = 0;
1494 int i, j, err; 989 int i, j, err;
1495 bool have_higher_than_11mbit = false; 990 bool have_higher_than_11mbit = false;
1496 u16 ap_ht_cap_flags; 991 u16 ap_ht_cap_flags;
1497 992
1498 /* 993 /* AssocResp and ReassocResp have identical structure */
1499 * AssocResp and ReassocResp have identical structure, so process both
1500 * of them in this function.
1501 */
1502
1503 if (len < 24 + 6)
1504 return RX_MGMT_NONE;
1505 994
1506 if (memcmp(bss->cbss.bssid, mgmt->sa, ETH_ALEN) != 0)
1507 return RX_MGMT_NONE;
1508
1509 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
1510 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
1511 aid = le16_to_cpu(mgmt->u.assoc_resp.aid); 995 aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
1512 996 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
1513 printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x "
1514 "status=%d aid=%d)\n",
1515 sdata->name, reassoc ? "Rea" : "A", mgmt->sa,
1516 capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
1517
1518 pos = mgmt->u.assoc_resp.variable;
1519 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1520
1521 if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
1522 elems.timeout_int && elems.timeout_int_len == 5 &&
1523 elems.timeout_int[0] == WLAN_TIMEOUT_ASSOC_COMEBACK) {
1524 u32 tu, ms;
1525 tu = get_unaligned_le32(elems.timeout_int + 1);
1526 ms = tu * 1024 / 1000;
1527 printk(KERN_DEBUG "%s: AP rejected association temporarily; "
1528 "comeback duration %u TU (%u ms)\n",
1529 sdata->name, tu, ms);
1530 wk->timeout = jiffies + msecs_to_jiffies(ms);
1531 if (ms > IEEE80211_ASSOC_TIMEOUT)
1532 run_again(ifmgd, jiffies + msecs_to_jiffies(ms));
1533 return RX_MGMT_NONE;
1534 }
1535
1536 /*
1537 * Here the association was either successful or not.
1538 */
1539
1540 /* delete work item -- must be before set_associated for PS */
1541 list_del(&wk->list);
1542 kfree(wk);
1543
1544 if (status_code != WLAN_STATUS_SUCCESS) {
1545 printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
1546 sdata->name, status_code);
1547 return RX_MGMT_CFG80211_ASSOC;
1548 }
1549 997
1550 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) 998 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
1551 printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not " 999 printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
1552 "set\n", sdata->name, aid); 1000 "set\n", sdata->name, aid);
1553 aid &= ~(BIT(15) | BIT(14)); 1001 aid &= ~(BIT(15) | BIT(14));
1554 1002
1003 pos = mgmt->u.assoc_resp.variable;
1004 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1005
1555 if (!elems.supp_rates) { 1006 if (!elems.supp_rates) {
1556 printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n", 1007 printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
1557 sdata->name); 1008 sdata->name);
1558 return RX_MGMT_NONE; 1009 return false;
1559 } 1010 }
1560 1011
1561 printk(KERN_DEBUG "%s: associated\n", sdata->name);
1562 ifmgd->aid = aid; 1012 ifmgd->aid = aid;
1563 1013
1564 sta = sta_info_alloc(sdata, bss->cbss.bssid, GFP_KERNEL); 1014 sta = sta_info_alloc(sdata, bss->cbss.bssid, GFP_KERNEL);
1565 if (!sta) { 1015 if (!sta) {
1566 printk(KERN_DEBUG "%s: failed to alloc STA entry for" 1016 printk(KERN_DEBUG "%s: failed to alloc STA entry for"
1567 " the AP\n", sdata->name); 1017 " the AP\n", sdata->name);
1568 return RX_MGMT_CFG80211_ASSOC_ERROR; 1018 return false;
1569 } 1019 }
1570 1020
1571 set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | 1021 set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC |
@@ -1650,7 +1100,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1650 ieee80211_set_wmm_default(sdata); 1100 ieee80211_set_wmm_default(sdata);
1651 1101
1652 if (elems.ht_info_elem && elems.wmm_param && 1102 if (elems.ht_info_elem && elems.wmm_param &&
1653 (ifmgd->flags & IEEE80211_STA_WMM_ENABLED) && 1103 (sdata->local->hw.queues >= 4) &&
1654 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 1104 !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
1655 changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, 1105 changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem,
1656 bss->cbss.bssid, 1106 bss->cbss.bssid,
@@ -1669,7 +1119,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1669 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); 1119 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
1670 mod_beacon_timer(sdata); 1120 mod_beacon_timer(sdata);
1671 1121
1672 return RX_MGMT_CFG80211_ASSOC; 1122 return true;
1673} 1123}
1674 1124
1675 1125
@@ -1714,12 +1164,12 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
1714 1164
1715 1165
1716static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, 1166static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1717 struct ieee80211_work *wk, 1167 struct sk_buff *skb)
1718 struct ieee80211_mgmt *mgmt, size_t len,
1719 struct ieee80211_rx_status *rx_status)
1720{ 1168{
1169 struct ieee80211_mgmt *mgmt = (void *)skb->data;
1721 struct ieee80211_if_managed *ifmgd; 1170 struct ieee80211_if_managed *ifmgd;
1722 size_t baselen; 1171 struct ieee80211_rx_status *rx_status = (void *) skb->cb;
1172 size_t baselen, len = skb->len;
1723 struct ieee802_11_elems elems; 1173 struct ieee802_11_elems elems;
1724 1174
1725 ifmgd = &sdata->u.mgd; 1175 ifmgd = &sdata->u.mgd;
@@ -1738,15 +1188,6 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1738 1188
1739 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false); 1189 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
1740 1190
1741 /* direct probe may be part of the association flow */
1742 if (wk && wk->type == IEEE80211_WORK_AUTH_PROBE) {
1743 printk(KERN_DEBUG "%s: direct probe responded\n",
1744 sdata->name);
1745 wk->auth.tries = 0;
1746 wk->type = IEEE80211_WORK_AUTH;
1747 WARN_ON(ieee80211_authenticate(sdata, wk) != RX_MGMT_NONE);
1748 }
1749
1750 if (ifmgd->associated && 1191 if (ifmgd->associated &&
1751 memcmp(mgmt->bssid, ifmgd->associated->cbss.bssid, ETH_ALEN) == 0 && 1192 memcmp(mgmt->bssid, ifmgd->associated->cbss.bssid, ETH_ALEN) == 0 &&
1752 ifmgd->flags & (IEEE80211_STA_BEACON_POLL | 1193 ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
@@ -1960,9 +1401,6 @@ ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
1960 switch (fc & IEEE80211_FCTL_STYPE) { 1401 switch (fc & IEEE80211_FCTL_STYPE) {
1961 case IEEE80211_STYPE_PROBE_RESP: 1402 case IEEE80211_STYPE_PROBE_RESP:
1962 case IEEE80211_STYPE_BEACON: 1403 case IEEE80211_STYPE_BEACON:
1963 case IEEE80211_STYPE_AUTH:
1964 case IEEE80211_STYPE_ASSOC_RESP:
1965 case IEEE80211_STYPE_REASSOC_RESP:
1966 case IEEE80211_STYPE_DEAUTH: 1404 case IEEE80211_STYPE_DEAUTH:
1967 case IEEE80211_STYPE_DISASSOC: 1405 case IEEE80211_STYPE_DISASSOC:
1968 case IEEE80211_STYPE_ACTION: 1406 case IEEE80211_STYPE_ACTION:
@@ -1980,7 +1418,6 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1980 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1418 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1981 struct ieee80211_rx_status *rx_status; 1419 struct ieee80211_rx_status *rx_status;
1982 struct ieee80211_mgmt *mgmt; 1420 struct ieee80211_mgmt *mgmt;
1983 struct ieee80211_work *wk;
1984 enum rx_mgmt_action rma = RX_MGMT_NONE; 1421 enum rx_mgmt_action rma = RX_MGMT_NONE;
1985 u16 fc; 1422 u16 fc;
1986 1423
@@ -1999,8 +1436,7 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1999 rx_status); 1436 rx_status);
2000 break; 1437 break;
2001 case IEEE80211_STYPE_PROBE_RESP: 1438 case IEEE80211_STYPE_PROBE_RESP:
2002 ieee80211_rx_mgmt_probe_resp(sdata, NULL, mgmt, 1439 ieee80211_rx_mgmt_probe_resp(sdata, skb);
2003 skb->len, rx_status);
2004 break; 1440 break;
2005 case IEEE80211_STYPE_DEAUTH: 1441 case IEEE80211_STYPE_DEAUTH:
2006 rma = ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len); 1442 rma = ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len);
@@ -2033,88 +1469,11 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
2033 goto out; 1469 goto out;
2034 } 1470 }
2035 1471
2036 list_for_each_entry(wk, &ifmgd->work_list, list) {
2037 const u8 *bssid = NULL;
2038
2039 switch (wk->type) {
2040 case IEEE80211_WORK_AUTH_PROBE:
2041 case IEEE80211_WORK_AUTH:
2042 bssid = wk->auth.bssid;
2043 break;
2044 case IEEE80211_WORK_ASSOC:
2045 bssid = wk->assoc.bssid;
2046 break;
2047 default:
2048 continue;
2049 }
2050 if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0)
2051 continue;
2052
2053 switch (fc & IEEE80211_FCTL_STYPE) {
2054 case IEEE80211_STYPE_PROBE_RESP:
2055 ieee80211_rx_mgmt_probe_resp(sdata, wk, mgmt, skb->len,
2056 rx_status);
2057 break;
2058 case IEEE80211_STYPE_AUTH:
2059 rma = ieee80211_rx_mgmt_auth(sdata, wk, mgmt, skb->len);
2060 break;
2061 case IEEE80211_STYPE_ASSOC_RESP:
2062 rma = ieee80211_rx_mgmt_assoc_resp(sdata, wk, mgmt,
2063 skb->len, false);
2064 break;
2065 case IEEE80211_STYPE_REASSOC_RESP:
2066 rma = ieee80211_rx_mgmt_assoc_resp(sdata, wk, mgmt,
2067 skb->len, true);
2068 break;
2069 case IEEE80211_STYPE_DEAUTH:
2070 if (skb->len >= 24 + 2 /* mgmt + deauth reason */) {
2071 /*
2072 * We get here if we get deauth while
2073 * trying to auth/assoc. Telling cfg80211
2074 * is handled below, unconditionally.
2075 */
2076 list_del(&wk->list);
2077 kfree(wk);
2078 }
2079 break;
2080 }
2081 /*
2082 * We've processed this frame for that work, so it can't
2083 * belong to another work struct.
2084 * NB: this is also required for correctness because the
2085 * called functions can free 'wk', and for 'rma'!
2086 */
2087 break;
2088 }
2089
2090 mutex_unlock(&ifmgd->mtx); 1472 mutex_unlock(&ifmgd->mtx);
2091 1473
2092 if (skb->len >= 24 + 2 /* mgmt + deauth reason */ && 1474 if (skb->len >= 24 + 2 /* mgmt + deauth reason */ &&
2093 (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_DEAUTH) { 1475 (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_DEAUTH)
2094 WARN_ON(rma != RX_MGMT_NONE);
2095 rma = RX_MGMT_CFG80211_DEAUTH;
2096 }
2097
2098 switch (rma) {
2099 case RX_MGMT_NONE:
2100 /* no action */
2101 break;
2102 case RX_MGMT_CFG80211_AUTH:
2103 cfg80211_send_rx_auth(sdata->dev, (u8 *) mgmt, skb->len);
2104 break;
2105 case RX_MGMT_CFG80211_ASSOC:
2106 cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, skb->len);
2107 break;
2108 case RX_MGMT_CFG80211_DEAUTH:
2109 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); 1476 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
2110 break;
2111 case RX_MGMT_CFG80211_ASSOC_ERROR:
2112 /* an internal error -- pretend timeout for now */
2113 cfg80211_send_assoc_timeout(sdata->dev, mgmt->bssid);
2114 break;
2115 default:
2116 WARN(1, "unexpected: %d", rma);
2117 }
2118 1477
2119 out: 1478 out:
2120 kfree_skb(skb); 1479 kfree_skb(skb);
@@ -2142,9 +1501,6 @@ static void ieee80211_sta_work(struct work_struct *work)
2142 struct ieee80211_local *local = sdata->local; 1501 struct ieee80211_local *local = sdata->local;
2143 struct ieee80211_if_managed *ifmgd; 1502 struct ieee80211_if_managed *ifmgd;
2144 struct sk_buff *skb; 1503 struct sk_buff *skb;
2145 struct ieee80211_work *wk, *tmp;
2146 LIST_HEAD(free_work);
2147 enum rx_mgmt_action rma;
2148 1504
2149 if (!ieee80211_sdata_running(sdata)) 1505 if (!ieee80211_sdata_running(sdata))
2150 return; 1506 return;
@@ -2214,84 +1570,7 @@ static void ieee80211_sta_work(struct work_struct *work)
2214 } 1570 }
2215 } 1571 }
2216 1572
2217
2218 ieee80211_recalc_idle(local);
2219
2220 list_for_each_entry_safe(wk, tmp, &ifmgd->work_list, list) {
2221 if (time_is_after_jiffies(wk->timeout)) {
2222 /*
2223 * This work item isn't supposed to be worked on
2224 * right now, but take care to adjust the timer
2225 * properly.
2226 */
2227 run_again(ifmgd, wk->timeout);
2228 continue;
2229 }
2230
2231 switch (wk->type) {
2232 default:
2233 WARN_ON(1);
2234 /* nothing */
2235 rma = RX_MGMT_NONE;
2236 break;
2237 case IEEE80211_WORK_AUTH_PROBE:
2238 rma = ieee80211_direct_probe(sdata, wk);
2239 break;
2240 case IEEE80211_WORK_AUTH:
2241 rma = ieee80211_authenticate(sdata, wk);
2242 break;
2243 case IEEE80211_WORK_ASSOC:
2244 rma = ieee80211_associate(sdata, wk);
2245 break;
2246 }
2247
2248 switch (rma) {
2249 case RX_MGMT_NONE:
2250 /* no action required */
2251 break;
2252 case RX_MGMT_CFG80211_AUTH_TO:
2253 case RX_MGMT_CFG80211_ASSOC_TO:
2254 list_del(&wk->list);
2255 list_add(&wk->list, &free_work);
2256 /*
2257 * small abuse but only local -- keep the
2258 * action type in wk->timeout while the item
2259 * is on the cleanup list
2260 */
2261 wk->timeout = rma;
2262 break;
2263 default:
2264 WARN(1, "unexpected: %d", rma);
2265 }
2266 }
2267
2268 if (list_empty(&ifmgd->work_list) &&
2269 test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request))
2270 ieee80211_queue_delayed_work(&local->hw,
2271 &local->scan_work,
2272 round_jiffies_relative(0));
2273
2274 mutex_unlock(&ifmgd->mtx); 1573 mutex_unlock(&ifmgd->mtx);
2275
2276 list_for_each_entry_safe(wk, tmp, &free_work, list) {
2277 /* see above how we're using wk->timeout */
2278 switch (wk->timeout) {
2279 case RX_MGMT_CFG80211_AUTH_TO:
2280 cfg80211_send_auth_timeout(sdata->dev, wk->auth.bssid);
2281 break;
2282 case RX_MGMT_CFG80211_ASSOC_TO:
2283 cfg80211_send_assoc_timeout(sdata->dev,
2284 wk->assoc.bssid);
2285 break;
2286 default:
2287 WARN(1, "unexpected: %lu", wk->timeout);
2288 }
2289
2290 list_del(&wk->list);
2291 kfree(wk);
2292 }
2293
2294 ieee80211_recalc_idle(local);
2295} 1574}
2296 1575
2297static void ieee80211_sta_bcn_mon_timer(unsigned long data) 1576static void ieee80211_sta_bcn_mon_timer(unsigned long data)
@@ -2400,12 +1679,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
2400 (unsigned long) sdata); 1679 (unsigned long) sdata);
2401 skb_queue_head_init(&ifmgd->skb_queue); 1680 skb_queue_head_init(&ifmgd->skb_queue);
2402 1681
2403 INIT_LIST_HEAD(&ifmgd->work_list);
2404
2405 ifmgd->capab = WLAN_CAPABILITY_ESS;
2406 ifmgd->flags = 0; 1682 ifmgd->flags = 0;
2407 if (sdata->local->hw.queues >= 4)
2408 ifmgd->flags |= IEEE80211_STA_WMM_ENABLED;
2409 1683
2410 mutex_init(&ifmgd->mtx); 1684 mutex_init(&ifmgd->mtx);
2411 1685
@@ -2443,10 +1717,32 @@ int ieee80211_max_network_latency(struct notifier_block *nb,
2443} 1717}
2444 1718
2445/* config hooks */ 1719/* config hooks */
1720static enum work_done_result
1721ieee80211_probe_auth_done(struct ieee80211_work *wk,
1722 struct sk_buff *skb)
1723{
1724 if (!skb) {
1725 cfg80211_send_auth_timeout(wk->sdata->dev, wk->filter_ta);
1726 return WORK_DONE_DESTROY;
1727 }
1728
1729 if (wk->type == IEEE80211_WORK_AUTH) {
1730 cfg80211_send_rx_auth(wk->sdata->dev, skb->data, skb->len);
1731 return WORK_DONE_DESTROY;
1732 }
1733
1734 mutex_lock(&wk->sdata->u.mgd.mtx);
1735 ieee80211_rx_mgmt_probe_resp(wk->sdata, skb);
1736 mutex_unlock(&wk->sdata->u.mgd.mtx);
1737
1738 wk->type = IEEE80211_WORK_AUTH;
1739 wk->probe_auth.tries = 0;
1740 return WORK_DONE_REQUEUE;
1741}
1742
2446int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, 1743int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
2447 struct cfg80211_auth_request *req) 1744 struct cfg80211_auth_request *req)
2448{ 1745{
2449 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2450 const u8 *ssid; 1746 const u8 *ssid;
2451 struct ieee80211_work *wk; 1747 struct ieee80211_work *wk;
2452 u16 auth_alg; 1748 u16 auth_alg;
@@ -2472,7 +1768,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
2472 if (!wk) 1768 if (!wk)
2473 return -ENOMEM; 1769 return -ENOMEM;
2474 1770
2475 memcpy(wk->auth.bssid, req->bss->bssid, ETH_ALEN);; 1771 memcpy(wk->filter_ta, req->bss->bssid, ETH_ALEN);;
2476 1772
2477 if (req->ie && req->ie_len) { 1773 if (req->ie && req->ie_len) {
2478 memcpy(wk->ie, req->ie, req->ie_len); 1774 memcpy(wk->ie, req->ie, req->ie_len);
@@ -2480,21 +1776,22 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
2480 } 1776 }
2481 1777
2482 if (req->key && req->key_len) { 1778 if (req->key && req->key_len) {
2483 wk->auth.key_len = req->key_len; 1779 wk->probe_auth.key_len = req->key_len;
2484 wk->auth.key_idx = req->key_idx; 1780 wk->probe_auth.key_idx = req->key_idx;
2485 memcpy(wk->auth.key, req->key, req->key_len); 1781 memcpy(wk->probe_auth.key, req->key, req->key_len);
2486 } 1782 }
2487 1783
2488 ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); 1784 ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
2489 memcpy(wk->auth.ssid, ssid + 2, ssid[1]); 1785 memcpy(wk->probe_auth.ssid, ssid + 2, ssid[1]);
2490 wk->auth.ssid_len = ssid[1]; 1786 wk->probe_auth.ssid_len = ssid[1];
2491 1787
2492 wk->auth.algorithm = auth_alg; 1788 wk->probe_auth.algorithm = auth_alg;
2493 wk->auth.privacy = req->bss->capability & WLAN_CAPABILITY_PRIVACY; 1789 wk->probe_auth.privacy = req->bss->capability & WLAN_CAPABILITY_PRIVACY;
2494 1790
2495 wk->type = IEEE80211_WORK_AUTH_PROBE; 1791 wk->type = IEEE80211_WORK_DIRECT_PROBE;
2496 wk->timeout = jiffies; /* run right away */
2497 wk->chan = req->bss->channel; 1792 wk->chan = req->bss->channel;
1793 wk->sdata = sdata;
1794 wk->done = ieee80211_probe_auth_done;
2498 1795
2499 /* 1796 /*
2500 * XXX: if still associated need to tell AP that we're going 1797 * XXX: if still associated need to tell AP that we're going
@@ -2505,29 +1802,58 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
2505 sdata->local->oper_channel = req->bss->channel; 1802 sdata->local->oper_channel = req->bss->channel;
2506 ieee80211_hw_config(sdata->local, 0); 1803 ieee80211_hw_config(sdata->local, 0);
2507 1804
2508 mutex_lock(&ifmgd->mtx); 1805 ieee80211_add_work(wk);
2509 list_add(&wk->list, &sdata->u.mgd.work_list);
2510 mutex_unlock(&ifmgd->mtx);
2511
2512 ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.work);
2513 return 0; 1806 return 0;
2514} 1807}
2515 1808
1809static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
1810 struct sk_buff *skb)
1811{
1812 struct ieee80211_mgmt *mgmt;
1813 u16 status;
1814
1815 if (!skb) {
1816 cfg80211_send_assoc_timeout(wk->sdata->dev, wk->filter_ta);
1817 return WORK_DONE_DESTROY;
1818 }
1819
1820 mgmt = (void *)skb->data;
1821 status = le16_to_cpu(mgmt->u.assoc_resp.status_code);
1822
1823 if (status == WLAN_STATUS_SUCCESS) {
1824 mutex_lock(&wk->sdata->u.mgd.mtx);
1825 if (!ieee80211_assoc_success(wk, mgmt, skb->len)) {
1826 mutex_unlock(&wk->sdata->u.mgd.mtx);
1827 /* oops -- internal error -- send timeout for now */
1828 cfg80211_send_assoc_timeout(wk->sdata->dev,
1829 wk->filter_ta);
1830 return WORK_DONE_DESTROY;
1831 }
1832 mutex_unlock(&wk->sdata->u.mgd.mtx);
1833 }
1834
1835 cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len);
1836 return WORK_DONE_DESTROY;
1837}
1838
2516int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, 1839int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2517 struct cfg80211_assoc_request *req) 1840 struct cfg80211_assoc_request *req)
2518{ 1841{
2519 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1842 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2520 struct ieee80211_work *wk; 1843 struct ieee80211_work *wk;
2521 const u8 *ssid; 1844 const u8 *ssid;
2522 int i, err; 1845 int i;
2523 1846
2524 mutex_lock(&ifmgd->mtx); 1847 mutex_lock(&ifmgd->mtx);
1848 if (ifmgd->associated) {
1849 mutex_unlock(&ifmgd->mtx);
1850 return -EALREADY;
1851 }
1852 mutex_unlock(&ifmgd->mtx);
2525 1853
2526 wk = kzalloc(sizeof(*wk) + req->ie_len, GFP_KERNEL); 1854 wk = kzalloc(sizeof(*wk) + req->ie_len, GFP_KERNEL);
2527 if (!wk) { 1855 if (!wk)
2528 err = -ENOMEM; 1856 return -ENOMEM;
2529 goto out;
2530 }
2531 1857
2532 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N; 1858 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
2533 1859
@@ -2546,8 +1872,19 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2546 1872
2547 wk->assoc.bss = (void *)req->bss; 1873 wk->assoc.bss = (void *)req->bss;
2548 1874
2549 memcpy(wk->assoc.bssid, req->bss->bssid, ETH_ALEN); 1875 memcpy(wk->filter_ta, req->bss->bssid, ETH_ALEN);
2550 1876
1877 /* new association always uses requested smps mode */
1878 if (ifmgd->req_smps == IEEE80211_SMPS_AUTOMATIC) {
1879 if (ifmgd->powersave)
1880 ifmgd->ap_smps = IEEE80211_SMPS_DYNAMIC;
1881 else
1882 ifmgd->ap_smps = IEEE80211_SMPS_OFF;
1883 } else
1884 ifmgd->ap_smps = ifmgd->req_smps;
1885
1886 wk->assoc.smps = ifmgd->ap_smps;
1887 wk->assoc.use_11n = !(ifmgd->flags & IEEE80211_STA_DISABLE_11N);
2551 wk->assoc.capability = req->bss->capability; 1888 wk->assoc.capability = req->bss->capability;
2552 wk->assoc.wmm_used = wk->assoc.bss->wmm_used; 1889 wk->assoc.wmm_used = wk->assoc.bss->wmm_used;
2553 wk->assoc.supp_rates = wk->assoc.bss->supp_rates; 1890 wk->assoc.supp_rates = wk->assoc.bss->supp_rates;
@@ -2563,8 +1900,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2563 memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN); 1900 memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN);
2564 1901
2565 wk->type = IEEE80211_WORK_ASSOC; 1902 wk->type = IEEE80211_WORK_ASSOC;
2566 wk->timeout = jiffies; /* run right away */
2567 wk->chan = req->bss->channel; 1903 wk->chan = req->bss->channel;
1904 wk->sdata = sdata;
1905 wk->done = ieee80211_assoc_done;
2568 1906
2569 if (req->use_mfp) { 1907 if (req->use_mfp) {
2570 ifmgd->mfp = IEEE80211_MFP_REQUIRED; 1908 ifmgd->mfp = IEEE80211_MFP_REQUIRED;
@@ -2582,56 +1920,56 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2582 sdata->local->oper_channel = req->bss->channel; 1920 sdata->local->oper_channel = req->bss->channel;
2583 ieee80211_hw_config(sdata->local, 0); 1921 ieee80211_hw_config(sdata->local, 0);
2584 1922
2585 list_add(&wk->list, &ifmgd->work_list); 1923 ieee80211_add_work(wk);
2586 ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.work); 1924 return 0;
2587
2588 err = 0;
2589
2590 out:
2591 mutex_unlock(&ifmgd->mtx);
2592 return err;
2593} 1925}
2594 1926
2595int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, 1927int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2596 struct cfg80211_deauth_request *req, 1928 struct cfg80211_deauth_request *req,
2597 void *cookie) 1929 void *cookie)
2598{ 1930{
1931 struct ieee80211_local *local = sdata->local;
2599 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1932 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2600 struct ieee80211_work *wk; 1933 struct ieee80211_work *wk;
2601 const u8 *bssid = req->bss->bssid; 1934 const u8 *bssid = req->bss->bssid;
2602 bool not_auth_yet = false;
2603 1935
2604 mutex_lock(&ifmgd->mtx); 1936 mutex_lock(&ifmgd->mtx);
2605 1937
2606 if (ifmgd->associated && &ifmgd->associated->cbss == req->bss) { 1938 if (ifmgd->associated && &ifmgd->associated->cbss == req->bss) {
2607 bssid = req->bss->bssid; 1939 bssid = req->bss->bssid;
2608 ieee80211_set_disassoc(sdata); 1940 ieee80211_set_disassoc(sdata);
2609 } else list_for_each_entry(wk, &ifmgd->work_list, list) { 1941 mutex_unlock(&ifmgd->mtx);
2610 if (wk->type != IEEE80211_WORK_AUTH_PROBE) 1942 } else {
2611 continue; 1943 bool not_auth_yet = false;
2612 if (memcmp(req->bss->bssid, wk->auth.bssid, ETH_ALEN))
2613 continue;
2614 not_auth_yet = true;
2615 list_del(&wk->list);
2616 kfree(wk);
2617 break;
2618 }
2619 1944
2620 /*
2621 * If somebody requests authentication and we haven't
2622 * sent out an auth frame yet there's no need to send
2623 * out a deauth frame either. If the state was PROBE,
2624 * then this is the case. If it's AUTH we have sent a
2625 * frame, and if it's IDLE we have completed the auth
2626 * process already.
2627 */
2628 if (not_auth_yet) {
2629 mutex_unlock(&ifmgd->mtx); 1945 mutex_unlock(&ifmgd->mtx);
2630 __cfg80211_auth_canceled(sdata->dev, bssid);
2631 return 0;
2632 }
2633 1946
2634 mutex_unlock(&ifmgd->mtx); 1947 mutex_lock(&local->work_mtx);
1948 list_for_each_entry(wk, &local->work_list, list) {
1949 if (wk->type != IEEE80211_WORK_DIRECT_PROBE)
1950 continue;
1951 if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN))
1952 continue;
1953 not_auth_yet = true;
1954 list_del(&wk->list);
1955 free_work(wk);
1956 break;
1957 }
1958 mutex_unlock(&local->work_mtx);
1959
1960 /*
1961 * If somebody requests authentication and we haven't
1962 * sent out an auth frame yet there's no need to send
1963 * out a deauth frame either. If the state was PROBE,
1964 * then this is the case. If it's AUTH we have sent a
1965 * frame, and if it's IDLE we have completed the auth
1966 * process already.
1967 */
1968 if (not_auth_yet) {
1969 __cfg80211_auth_canceled(sdata->dev, bssid);
1970 return 0;
1971 }
1972 }
2635 1973
2636 printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n", 1974 printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n",
2637 sdata->name, bssid, req->reason_code); 1975 sdata->name, bssid, req->reason_code);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index f60dfca52196..bfcf09eb64b4 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1945,6 +1945,7 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
1945{ 1945{
1946 struct ieee80211_sub_if_data *sdata = rx->sdata; 1946 struct ieee80211_sub_if_data *sdata = rx->sdata;
1947 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; 1947 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;
1948 ieee80211_rx_result rxs;
1948 1949
1949 if (!(rx->flags & IEEE80211_RX_RA_MATCH)) 1950 if (!(rx->flags & IEEE80211_RX_RA_MATCH))
1950 return RX_DROP_MONITOR; 1951 return RX_DROP_MONITOR;
@@ -1952,6 +1953,10 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
1952 if (ieee80211_drop_unencrypted(rx, mgmt->frame_control)) 1953 if (ieee80211_drop_unencrypted(rx, mgmt->frame_control))
1953 return RX_DROP_MONITOR; 1954 return RX_DROP_MONITOR;
1954 1955
1956 rxs = ieee80211_work_rx_mgmt(rx->sdata, rx->skb);
1957 if (rxs != RX_CONTINUE)
1958 return rxs;
1959
1955 if (ieee80211_vif_is_mesh(&sdata->vif)) 1960 if (ieee80211_vif_is_mesh(&sdata->vif))
1956 return ieee80211_mesh_rx_mgmt(sdata, rx->skb); 1961 return ieee80211_mesh_rx_mgmt(sdata, rx->skb);
1957 1962
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index d98c45e5528b..fb89e4c0fbfd 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -434,7 +434,6 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
434 struct cfg80211_scan_request *req) 434 struct cfg80211_scan_request *req)
435{ 435{
436 struct ieee80211_local *local = sdata->local; 436 struct ieee80211_local *local = sdata->local;
437 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
438 int rc; 437 int rc;
439 438
440 if (local->scan_req) 439 if (local->scan_req)
@@ -464,11 +463,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
464 local->scan_req = req; 463 local->scan_req = req;
465 local->scan_sdata = sdata; 464 local->scan_sdata = sdata;
466 465
467 if (req != local->int_scan_req && 466 if (!list_empty(&local->work_list)) {
468 sdata->vif.type == NL80211_IFTYPE_STATION && 467 /* wait for the work to finish/time out */
469 !list_empty(&ifmgd->work_list)) {
470 /* actually wait for the work it's doing to finish/time out */
471 set_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request);
472 return 0; 468 return 0;
473 } 469 }
474 470
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
new file mode 100644
index 000000000000..8b8961d806ab
--- /dev/null
+++ b/net/mac80211/work.c
@@ -0,0 +1,902 @@
1/*
2 * mac80211 work implementation
3 *
4 * Copyright 2003-2008, Jouni Malinen <j@w1.fi>
5 * Copyright 2004, Instant802 Networks, Inc.
6 * Copyright 2005, Devicescape Software, Inc.
7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
9 * Copyright 2009, Johannes Berg <johannes@sipsolutions.net>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/delay.h>
17#include <linux/if_ether.h>
18#include <linux/skbuff.h>
19#include <linux/if_arp.h>
20#include <linux/etherdevice.h>
21#include <linux/crc32.h>
22#include <net/mac80211.h>
23#include <asm/unaligned.h>
24
25#include "ieee80211_i.h"
26#include "rate.h"
27
28#define IEEE80211_AUTH_TIMEOUT (HZ / 5)
29#define IEEE80211_AUTH_MAX_TRIES 3
30#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
31#define IEEE80211_ASSOC_MAX_TRIES 3
32#define IEEE80211_MAX_PROBE_TRIES 5
33
34enum work_action {
35 WORK_ACT_NONE,
36 WORK_ACT_TIMEOUT,
37 WORK_ACT_DONE,
38};
39
40
41/* utils */
42static inline void ASSERT_WORK_MTX(struct ieee80211_local *local)
43{
44 WARN_ON(!mutex_is_locked(&local->work_mtx));
45}
46
47/*
48 * We can have multiple work items (and connection probing)
49 * scheduling this timer, but we need to take care to only
50 * reschedule it when it should fire _earlier_ than it was
51 * asked for before, or if it's not pending right now. This
52 * function ensures that. Note that it then is required to
53 * run this function for all timeouts after the first one
54 * has happened -- the work that runs from this timer will
55 * do that.
56 */
57static void run_again(struct ieee80211_local *local,
58 unsigned long timeout)
59{
60 ASSERT_WORK_MTX(local);
61
62 if (!timer_pending(&local->work_timer) ||
63 time_before(timeout, local->work_timer.expires))
64 mod_timer(&local->work_timer, timeout);
65}
66
67static void work_free_rcu(struct rcu_head *head)
68{
69 struct ieee80211_work *wk =
70 container_of(head, struct ieee80211_work, rcu_head);
71
72 kfree(wk);
73}
74
75void free_work(struct ieee80211_work *wk)
76{
77 call_rcu(&wk->rcu_head, work_free_rcu);
78}
79
80static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len,
81 struct ieee80211_supported_band *sband,
82 u32 *rates)
83{
84 int i, j, count;
85 *rates = 0;
86 count = 0;
87 for (i = 0; i < supp_rates_len; i++) {
88 int rate = (supp_rates[i] & 0x7F) * 5;
89
90 for (j = 0; j < sband->n_bitrates; j++)
91 if (sband->bitrates[j].bitrate == rate) {
92 *rates |= BIT(j);
93 count++;
94 break;
95 }
96 }
97
98 return count;
99}
100
101/* frame sending functions */
102
103static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
104 struct ieee80211_work *wk)
105{
106 struct ieee80211_local *local = sdata->local;
107 struct sk_buff *skb;
108 struct ieee80211_mgmt *mgmt;
109 u8 *pos;
110 const u8 *ies, *ht_ie;
111 int i, len, count, rates_len, supp_rates_len;
112 u16 capab;
113 struct ieee80211_supported_band *sband;
114 u32 rates = 0;
115
116 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
117 sizeof(*mgmt) + 200 + wk->ie_len +
118 wk->assoc.ssid_len);
119 if (!skb) {
120 printk(KERN_DEBUG "%s: failed to allocate buffer for assoc "
121 "frame\n", sdata->name);
122 return;
123 }
124 skb_reserve(skb, local->hw.extra_tx_headroom);
125
126 sband = local->hw.wiphy->bands[wk->chan->band];
127
128 capab = WLAN_CAPABILITY_ESS;
129
130 if (sband->band == IEEE80211_BAND_2GHZ) {
131 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
132 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
133 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
134 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
135 }
136
137 if (wk->assoc.capability & WLAN_CAPABILITY_PRIVACY)
138 capab |= WLAN_CAPABILITY_PRIVACY;
139
140 /*
141 * Get all rates supported by the device and the AP as
142 * some APs don't like getting a superset of their rates
143 * in the association request (e.g. D-Link DAP 1353 in
144 * b-only mode)...
145 */
146 rates_len = ieee80211_compatible_rates(wk->assoc.supp_rates,
147 wk->assoc.supp_rates_len,
148 sband, &rates);
149
150 if ((wk->assoc.capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
151 (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
152 capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
153
154 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
155 memset(mgmt, 0, 24);
156 memcpy(mgmt->da, wk->filter_ta, ETH_ALEN);
157 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
158 memcpy(mgmt->bssid, wk->filter_ta, ETH_ALEN);
159
160 if (!is_zero_ether_addr(wk->assoc.prev_bssid)) {
161 skb_put(skb, 10);
162 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
163 IEEE80211_STYPE_REASSOC_REQ);
164 mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
165 mgmt->u.reassoc_req.listen_interval =
166 cpu_to_le16(local->hw.conf.listen_interval);
167 memcpy(mgmt->u.reassoc_req.current_ap, wk->assoc.prev_bssid,
168 ETH_ALEN);
169 } else {
170 skb_put(skb, 4);
171 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
172 IEEE80211_STYPE_ASSOC_REQ);
173 mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
174 mgmt->u.assoc_req.listen_interval =
175 cpu_to_le16(local->hw.conf.listen_interval);
176 }
177
178 /* SSID */
179 ies = pos = skb_put(skb, 2 + wk->assoc.ssid_len);
180 *pos++ = WLAN_EID_SSID;
181 *pos++ = wk->assoc.ssid_len;
182 memcpy(pos, wk->assoc.ssid, wk->assoc.ssid_len);
183
184 /* add all rates which were marked to be used above */
185 supp_rates_len = rates_len;
186 if (supp_rates_len > 8)
187 supp_rates_len = 8;
188
189 len = sband->n_bitrates;
190 pos = skb_put(skb, supp_rates_len + 2);
191 *pos++ = WLAN_EID_SUPP_RATES;
192 *pos++ = supp_rates_len;
193
194 count = 0;
195 for (i = 0; i < sband->n_bitrates; i++) {
196 if (BIT(i) & rates) {
197 int rate = sband->bitrates[i].bitrate;
198 *pos++ = (u8) (rate / 5);
199 if (++count == 8)
200 break;
201 }
202 }
203
204 if (rates_len > count) {
205 pos = skb_put(skb, rates_len - count + 2);
206 *pos++ = WLAN_EID_EXT_SUPP_RATES;
207 *pos++ = rates_len - count;
208
209 for (i++; i < sband->n_bitrates; i++) {
210 if (BIT(i) & rates) {
211 int rate = sband->bitrates[i].bitrate;
212 *pos++ = (u8) (rate / 5);
213 }
214 }
215 }
216
217 if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) {
218 /* 1. power capabilities */
219 pos = skb_put(skb, 4);
220 *pos++ = WLAN_EID_PWR_CAPABILITY;
221 *pos++ = 2;
222 *pos++ = 0; /* min tx power */
223 *pos++ = local->hw.conf.channel->max_power; /* max tx power */
224
225 /* 2. supported channels */
226 /* TODO: get this in reg domain format */
227 pos = skb_put(skb, 2 * sband->n_channels + 2);
228 *pos++ = WLAN_EID_SUPPORTED_CHANNELS;
229 *pos++ = 2 * sband->n_channels;
230 for (i = 0; i < sband->n_channels; i++) {
231 *pos++ = ieee80211_frequency_to_channel(
232 sband->channels[i].center_freq);
233 *pos++ = 1; /* one channel in the subband*/
234 }
235 }
236
237 if (wk->ie_len && wk->ie) {
238 pos = skb_put(skb, wk->ie_len);
239 memcpy(pos, wk->ie, wk->ie_len);
240 }
241
242 if (wk->assoc.wmm_used && local->hw.queues >= 4) {
243 pos = skb_put(skb, 9);
244 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
245 *pos++ = 7; /* len */
246 *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
247 *pos++ = 0x50;
248 *pos++ = 0xf2;
249 *pos++ = 2; /* WME */
250 *pos++ = 0; /* WME info */
251 *pos++ = 1; /* WME ver */
252 *pos++ = 0;
253 }
254
255 /* wmm support is a must to HT */
256 /*
257 * IEEE802.11n does not allow TKIP/WEP as pairwise
258 * ciphers in HT mode. We still associate in non-ht
259 * mode (11a/b/g) if any one of these ciphers is
260 * configured as pairwise.
261 */
262 if (wk->assoc.use_11n && wk->assoc.wmm_used &&
263 (local->hw.queues >= 4) &&
264 sband->ht_cap.ht_supported &&
265 (ht_ie = wk->assoc.ht_information_ie) &&
266 ht_ie[1] >= sizeof(struct ieee80211_ht_info)) {
267 struct ieee80211_ht_info *ht_info =
268 (struct ieee80211_ht_info *)(ht_ie + 2);
269 u16 cap = sband->ht_cap.cap;
270 __le16 tmp;
271 u32 flags = local->hw.conf.channel->flags;
272
273 /* determine capability flags */
274
275 if (ieee80211_disable_40mhz_24ghz &&
276 sband->band == IEEE80211_BAND_2GHZ) {
277 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
278 cap &= ~IEEE80211_HT_CAP_SGI_40;
279 }
280
281 switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
282 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
283 if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
284 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
285 cap &= ~IEEE80211_HT_CAP_SGI_40;
286 }
287 break;
288 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
289 if (flags & IEEE80211_CHAN_NO_HT40MINUS) {
290 cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
291 cap &= ~IEEE80211_HT_CAP_SGI_40;
292 }
293 break;
294 }
295
296 /* set SM PS mode properly */
297 cap &= ~IEEE80211_HT_CAP_SM_PS;
298 switch (wk->assoc.smps) {
299 case IEEE80211_SMPS_AUTOMATIC:
300 case IEEE80211_SMPS_NUM_MODES:
301 WARN_ON(1);
302 case IEEE80211_SMPS_OFF:
303 cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
304 IEEE80211_HT_CAP_SM_PS_SHIFT;
305 break;
306 case IEEE80211_SMPS_STATIC:
307 cap |= WLAN_HT_CAP_SM_PS_STATIC <<
308 IEEE80211_HT_CAP_SM_PS_SHIFT;
309 break;
310 case IEEE80211_SMPS_DYNAMIC:
311 cap |= WLAN_HT_CAP_SM_PS_DYNAMIC <<
312 IEEE80211_HT_CAP_SM_PS_SHIFT;
313 break;
314 }
315
316 /* reserve and fill IE */
317
318 pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
319 *pos++ = WLAN_EID_HT_CAPABILITY;
320 *pos++ = sizeof(struct ieee80211_ht_cap);
321 memset(pos, 0, sizeof(struct ieee80211_ht_cap));
322
323 /* capability flags */
324 tmp = cpu_to_le16(cap);
325 memcpy(pos, &tmp, sizeof(u16));
326 pos += sizeof(u16);
327
328 /* AMPDU parameters */
329 *pos++ = sband->ht_cap.ampdu_factor |
330 (sband->ht_cap.ampdu_density <<
331 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
332
333 /* MCS set */
334 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
335 pos += sizeof(sband->ht_cap.mcs);
336
337 /* extended capabilities */
338 pos += sizeof(__le16);
339
340 /* BF capabilities */
341 pos += sizeof(__le32);
342
343 /* antenna selection */
344 pos += sizeof(u8);
345 }
346
347 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
348 ieee80211_tx_skb(sdata, skb);
349}
350
351static void ieee80211_remove_auth_bss(struct ieee80211_local *local,
352 struct ieee80211_work *wk)
353{
354 struct cfg80211_bss *cbss;
355 u16 capa_val = WLAN_CAPABILITY_ESS;
356
357 if (wk->probe_auth.privacy)
358 capa_val |= WLAN_CAPABILITY_PRIVACY;
359
360 cbss = cfg80211_get_bss(local->hw.wiphy, wk->chan, wk->filter_ta,
361 wk->probe_auth.ssid, wk->probe_auth.ssid_len,
362 WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY,
363 capa_val);
364 if (!cbss)
365 return;
366
367 cfg80211_unlink_bss(local->hw.wiphy, cbss);
368 cfg80211_put_bss(cbss);
369}
370
371static enum work_action __must_check
372ieee80211_direct_probe(struct ieee80211_work *wk)
373{
374 struct ieee80211_sub_if_data *sdata = wk->sdata;
375 struct ieee80211_local *local = sdata->local;
376
377 wk->probe_auth.tries++;
378 if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) {
379 printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n",
380 sdata->name, wk->filter_ta);
381
382 /*
383 * Most likely AP is not in the range so remove the
384 * bss struct for that AP.
385 */
386 ieee80211_remove_auth_bss(local, wk);
387
388 /*
389 * We might have a pending scan which had no chance to run yet
390 * due to work needing to be done. Hence, queue the STAs work
391 * again for that.
392 */
393 ieee80211_queue_work(&local->hw, &local->work_work);
394 return WORK_ACT_TIMEOUT;
395 }
396
397 printk(KERN_DEBUG "%s: direct probe to AP %pM (try %d)\n",
398 sdata->name, wk->filter_ta, wk->probe_auth.tries);
399
400 /*
401 * Direct probe is sent to broadcast address as some APs
402 * will not answer to direct packet in unassociated state.
403 */
404 ieee80211_send_probe_req(sdata, NULL, wk->probe_auth.ssid,
405 wk->probe_auth.ssid_len, NULL, 0);
406
407 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
408 run_again(local, wk->timeout);
409
410 return WORK_ACT_NONE;
411}
412
413
414static enum work_action __must_check
415ieee80211_authenticate(struct ieee80211_work *wk)
416{
417 struct ieee80211_sub_if_data *sdata = wk->sdata;
418 struct ieee80211_local *local = sdata->local;
419
420 wk->probe_auth.tries++;
421 if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) {
422 printk(KERN_DEBUG "%s: authentication with AP %pM"
423 " timed out\n", sdata->name, wk->filter_ta);
424
425 /*
426 * Most likely AP is not in the range so remove the
427 * bss struct for that AP.
428 */
429 ieee80211_remove_auth_bss(local, wk);
430
431 /*
432 * We might have a pending scan which had no chance to run yet
433 * due to work needing to be done. Hence, queue the STAs work
434 * again for that.
435 */
436 ieee80211_queue_work(&local->hw, &local->work_work);
437 return WORK_ACT_TIMEOUT;
438 }
439
440 printk(KERN_DEBUG "%s: authenticate with AP %pM (try %d)\n",
441 sdata->name, wk->filter_ta, wk->probe_auth.tries);
442
443 ieee80211_send_auth(sdata, 1, wk->probe_auth.algorithm, wk->ie,
444 wk->ie_len, wk->filter_ta, NULL, 0, 0);
445 wk->probe_auth.transaction = 2;
446
447 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
448 run_again(local, wk->timeout);
449
450 return WORK_ACT_NONE;
451}
452
453static enum work_action __must_check
454ieee80211_associate(struct ieee80211_work *wk)
455{
456 struct ieee80211_sub_if_data *sdata = wk->sdata;
457 struct ieee80211_local *local = sdata->local;
458
459 wk->assoc.tries++;
460 if (wk->assoc.tries > IEEE80211_ASSOC_MAX_TRIES) {
461 printk(KERN_DEBUG "%s: association with AP %pM"
462 " timed out\n",
463 sdata->name, wk->filter_ta);
464
465 /*
466 * Most likely AP is not in the range so remove the
467 * bss struct for that AP.
468 */
469 if (wk->assoc.bss)
470 cfg80211_unlink_bss(local->hw.wiphy,
471 &wk->assoc.bss->cbss);
472
473 /*
474 * We might have a pending scan which had no chance to run yet
475 * due to work needing to be done. Hence, queue the STAs work
476 * again for that.
477 */
478 ieee80211_queue_work(&local->hw, &local->work_work);
479 return WORK_ACT_TIMEOUT;
480 }
481
482 printk(KERN_DEBUG "%s: associate with AP %pM (try %d)\n",
483 sdata->name, wk->filter_ta, wk->assoc.tries);
484 ieee80211_send_assoc(sdata, wk);
485
486 wk->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
487 run_again(local, wk->timeout);
488
489 return WORK_ACT_NONE;
490}
491
492static void ieee80211_auth_challenge(struct ieee80211_work *wk,
493 struct ieee80211_mgmt *mgmt,
494 size_t len)
495{
496 struct ieee80211_sub_if_data *sdata = wk->sdata;
497 u8 *pos;
498 struct ieee802_11_elems elems;
499
500 pos = mgmt->u.auth.variable;
501 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
502 if (!elems.challenge)
503 return;
504 ieee80211_send_auth(sdata, 3, wk->probe_auth.algorithm,
505 elems.challenge - 2, elems.challenge_len + 2,
506 wk->filter_ta, wk->probe_auth.key,
507 wk->probe_auth.key_len, wk->probe_auth.key_idx);
508 wk->probe_auth.transaction = 4;
509}
510
511static enum work_action __must_check
512ieee80211_rx_mgmt_auth(struct ieee80211_work *wk,
513 struct ieee80211_mgmt *mgmt, size_t len)
514{
515 u16 auth_alg, auth_transaction, status_code;
516
517 if (wk->type != IEEE80211_WORK_AUTH)
518 return WORK_ACT_NONE;
519
520 if (len < 24 + 6)
521 return WORK_ACT_NONE;
522
523 auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
524 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
525 status_code = le16_to_cpu(mgmt->u.auth.status_code);
526
527 if (auth_alg != wk->probe_auth.algorithm ||
528 auth_transaction != wk->probe_auth.transaction)
529 return WORK_ACT_NONE;
530
531 if (status_code != WLAN_STATUS_SUCCESS) {
532 printk(KERN_DEBUG "%s: %pM denied authentication (status %d)\n",
533 wk->sdata->name, mgmt->sa, status_code);
534 return WORK_ACT_DONE;
535 }
536
537 switch (wk->probe_auth.algorithm) {
538 case WLAN_AUTH_OPEN:
539 case WLAN_AUTH_LEAP:
540 case WLAN_AUTH_FT:
541 break;
542 case WLAN_AUTH_SHARED_KEY:
543 if (wk->probe_auth.transaction != 4) {
544 ieee80211_auth_challenge(wk, mgmt, len);
545 /* need another frame */
546 return WORK_ACT_NONE;
547 }
548 break;
549 default:
550 WARN_ON(1);
551 return WORK_ACT_NONE;
552 }
553
554 printk(KERN_DEBUG "%s: authenticated\n", wk->sdata->name);
555 return WORK_ACT_DONE;
556}
557
558static enum work_action __must_check
559ieee80211_rx_mgmt_assoc_resp(struct ieee80211_work *wk,
560 struct ieee80211_mgmt *mgmt, size_t len,
561 bool reassoc)
562{
563 struct ieee80211_sub_if_data *sdata = wk->sdata;
564 struct ieee80211_local *local = sdata->local;
565 u16 capab_info, status_code, aid;
566 struct ieee802_11_elems elems;
567 u8 *pos;
568
569 /*
570 * AssocResp and ReassocResp have identical structure, so process both
571 * of them in this function.
572 */
573
574 if (len < 24 + 6)
575 return WORK_ACT_NONE;
576
577 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
578 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
579 aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
580
581 printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x "
582 "status=%d aid=%d)\n",
583 sdata->name, reassoc ? "Rea" : "A", mgmt->sa,
584 capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
585
586 pos = mgmt->u.assoc_resp.variable;
587 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
588
589 if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
590 elems.timeout_int && elems.timeout_int_len == 5 &&
591 elems.timeout_int[0] == WLAN_TIMEOUT_ASSOC_COMEBACK) {
592 u32 tu, ms;
593 tu = get_unaligned_le32(elems.timeout_int + 1);
594 ms = tu * 1024 / 1000;
595 printk(KERN_DEBUG "%s: AP rejected association temporarily; "
596 "comeback duration %u TU (%u ms)\n",
597 sdata->name, tu, ms);
598 wk->timeout = jiffies + msecs_to_jiffies(ms);
599 if (ms > IEEE80211_ASSOC_TIMEOUT)
600 run_again(local, wk->timeout);
601 return WORK_ACT_NONE;
602 }
603
604 if (status_code != WLAN_STATUS_SUCCESS)
605 printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
606 sdata->name, status_code);
607 else
608 printk(KERN_DEBUG "%s: associated\n", sdata->name);
609
610 return WORK_ACT_DONE;
611}
612
613static enum work_action __must_check
614ieee80211_rx_mgmt_probe_resp(struct ieee80211_work *wk,
615 struct ieee80211_mgmt *mgmt, size_t len,
616 struct ieee80211_rx_status *rx_status)
617{
618 struct ieee80211_sub_if_data *sdata = wk->sdata;
619 struct ieee80211_local *local = sdata->local;
620 size_t baselen;
621
622 ASSERT_WORK_MTX(local);
623
624 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
625 if (baselen > len)
626 return WORK_ACT_NONE;
627
628 printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name);
629 return WORK_ACT_DONE;
630}
631
632static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
633 struct sk_buff *skb)
634{
635 struct ieee80211_rx_status *rx_status;
636 struct ieee80211_mgmt *mgmt;
637 struct ieee80211_work *wk;
638 enum work_action rma = WORK_ACT_NONE;
639 u16 fc;
640
641 rx_status = (struct ieee80211_rx_status *) skb->cb;
642 mgmt = (struct ieee80211_mgmt *) skb->data;
643 fc = le16_to_cpu(mgmt->frame_control);
644
645 mutex_lock(&local->work_mtx);
646
647 list_for_each_entry(wk, &local->work_list, list) {
648 const u8 *bssid = NULL;
649
650 switch (wk->type) {
651 case IEEE80211_WORK_DIRECT_PROBE:
652 case IEEE80211_WORK_AUTH:
653 case IEEE80211_WORK_ASSOC:
654 bssid = wk->filter_ta;
655 break;
656 default:
657 continue;
658 }
659
660 /*
661 * Before queuing, we already verified mgmt->sa,
662 * so this is needed just for matching.
663 */
664 if (compare_ether_addr(bssid, mgmt->bssid))
665 continue;
666
667 switch (fc & IEEE80211_FCTL_STYPE) {
668 case IEEE80211_STYPE_PROBE_RESP:
669 rma = ieee80211_rx_mgmt_probe_resp(wk, mgmt, skb->len,
670 rx_status);
671 break;
672 case IEEE80211_STYPE_AUTH:
673 rma = ieee80211_rx_mgmt_auth(wk, mgmt, skb->len);
674 break;
675 case IEEE80211_STYPE_ASSOC_RESP:
676 rma = ieee80211_rx_mgmt_assoc_resp(wk, mgmt,
677 skb->len, false);
678 break;
679 case IEEE80211_STYPE_REASSOC_RESP:
680 rma = ieee80211_rx_mgmt_assoc_resp(wk, mgmt,
681 skb->len, true);
682 break;
683 default:
684 WARN_ON(1);
685 }
686 /*
687 * We've processed this frame for that work, so it can't
688 * belong to another work struct.
689 * NB: this is also required for correctness for 'rma'!
690 */
691 break;
692 }
693
694 switch (rma) {
695 case WORK_ACT_NONE:
696 break;
697 case WORK_ACT_DONE:
698 list_del_rcu(&wk->list);
699 break;
700 default:
701 WARN(1, "unexpected: %d", rma);
702 }
703
704 mutex_unlock(&local->work_mtx);
705
706 if (rma != WORK_ACT_DONE)
707 goto out;
708
709 switch (wk->done(wk, skb)) {
710 case WORK_DONE_DESTROY:
711 free_work(wk);
712 break;
713 case WORK_DONE_REQUEUE:
714 synchronize_rcu();
715 wk->timeout = jiffies; /* run again directly */
716 mutex_lock(&local->work_mtx);
717 list_add_tail(&wk->list, &local->work_list);
718 mutex_unlock(&local->work_mtx);
719 }
720
721 out:
722 kfree_skb(skb);
723}
724
725static void ieee80211_work_timer(unsigned long data)
726{
727 struct ieee80211_local *local = (void *) data;
728
729 if (local->quiescing)
730 return;
731
732 ieee80211_queue_work(&local->hw, &local->work_work);
733}
734
735static void ieee80211_work_work(struct work_struct *work)
736{
737 struct ieee80211_local *local =
738 container_of(work, struct ieee80211_local, work_work);
739 struct sk_buff *skb;
740 struct ieee80211_work *wk, *tmp;
741 LIST_HEAD(free_work);
742 enum work_action rma;
743
744 if (local->scanning)
745 return;
746
747 /*
748 * ieee80211_queue_work() should have picked up most cases,
749 * here we'll pick the the rest.
750 */
751 if (WARN(local->suspended, "work scheduled while going to suspend\n"))
752 return;
753
754 /* first process frames to avoid timing out while a frame is pending */
755 while ((skb = skb_dequeue(&local->work_skb_queue)))
756 ieee80211_work_rx_queued_mgmt(local, skb);
757
758 ieee80211_recalc_idle(local);
759
760 mutex_lock(&local->work_mtx);
761
762 list_for_each_entry_safe(wk, tmp, &local->work_list, list) {
763 if (time_is_after_jiffies(wk->timeout)) {
764 /*
765 * This work item isn't supposed to be worked on
766 * right now, but take care to adjust the timer
767 * properly.
768 */
769 run_again(local, wk->timeout);
770 continue;
771 }
772
773 switch (wk->type) {
774 default:
775 WARN_ON(1);
776 /* nothing */
777 rma = WORK_ACT_NONE;
778 break;
779 case IEEE80211_WORK_DIRECT_PROBE:
780 rma = ieee80211_direct_probe(wk);
781 break;
782 case IEEE80211_WORK_AUTH:
783 rma = ieee80211_authenticate(wk);
784 break;
785 case IEEE80211_WORK_ASSOC:
786 rma = ieee80211_associate(wk);
787 break;
788 }
789
790 switch (rma) {
791 case WORK_ACT_NONE:
792 /* no action required */
793 break;
794 case WORK_ACT_TIMEOUT:
795 list_del_rcu(&wk->list);
796 synchronize_rcu();
797 list_add(&wk->list, &free_work);
798 break;
799 default:
800 WARN(1, "unexpected: %d", rma);
801 }
802 }
803
804 if (list_empty(&local->work_list) && local->scan_req)
805 ieee80211_queue_delayed_work(&local->hw,
806 &local->scan_work,
807 round_jiffies_relative(0));
808
809 mutex_unlock(&local->work_mtx);
810
811 list_for_each_entry_safe(wk, tmp, &free_work, list) {
812 wk->done(wk, NULL);
813 list_del(&wk->list);
814 kfree(wk);
815 }
816}
817
818void ieee80211_add_work(struct ieee80211_work *wk)
819{
820 struct ieee80211_local *local;
821
822 if (WARN_ON(!wk->chan))
823 return;
824
825 if (WARN_ON(!wk->sdata))
826 return;
827
828 if (WARN_ON(!wk->done))
829 return;
830
831 wk->timeout = jiffies;
832
833 local = wk->sdata->local;
834 mutex_lock(&local->work_mtx);
835 list_add_tail(&wk->list, &local->work_list);
836 mutex_unlock(&local->work_mtx);
837
838 ieee80211_queue_work(&local->hw, &local->work_work);
839}
840
841void ieee80211_work_init(struct ieee80211_local *local)
842{
843 mutex_init(&local->work_mtx);
844 INIT_LIST_HEAD(&local->work_list);
845 setup_timer(&local->work_timer, ieee80211_work_timer,
846 (unsigned long)local);
847 INIT_WORK(&local->work_work, ieee80211_work_work);
848 skb_queue_head_init(&local->work_skb_queue);
849}
850
851void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata)
852{
853 struct ieee80211_local *local = sdata->local;
854 struct ieee80211_work *wk, *tmp;
855
856 mutex_lock(&local->work_mtx);
857 list_for_each_entry_safe(wk, tmp, &local->work_list, list) {
858 if (wk->sdata != sdata)
859 continue;
860 list_del(&wk->list);
861 free_work(wk);
862 }
863 mutex_unlock(&local->work_mtx);
864}
865
866ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata,
867 struct sk_buff *skb)
868{
869 struct ieee80211_local *local = sdata->local;
870 struct ieee80211_mgmt *mgmt;
871 struct ieee80211_work *wk;
872 u16 fc;
873
874 if (skb->len < 24)
875 return RX_DROP_MONITOR;
876
877 mgmt = (struct ieee80211_mgmt *) skb->data;
878 fc = le16_to_cpu(mgmt->frame_control);
879
880 list_for_each_entry_rcu(wk, &local->work_list, list) {
881 if (sdata != wk->sdata)
882 continue;
883 if (compare_ether_addr(wk->filter_ta, mgmt->sa))
884 continue;
885 if (compare_ether_addr(wk->filter_ta, mgmt->bssid))
886 continue;
887
888 switch (fc & IEEE80211_FCTL_STYPE) {
889 case IEEE80211_STYPE_AUTH:
890 case IEEE80211_STYPE_PROBE_RESP:
891 case IEEE80211_STYPE_ASSOC_RESP:
892 case IEEE80211_STYPE_REASSOC_RESP:
893 case IEEE80211_STYPE_DEAUTH:
894 case IEEE80211_STYPE_DISASSOC:
895 skb_queue_tail(&local->work_skb_queue, skb);
896 ieee80211_queue_work(&local->hw, &local->work_work);
897 return RX_QUEUED;
898 }
899 }
900
901 return RX_CONTINUE;
902}