Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth
[profile/ivi/kernel-adaptation-intel-automotive.git] / net / mac80211 / work.c
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 <linux/slab.h>
23 #include <net/mac80211.h>
24 #include <asm/unaligned.h>
25
26 #include "ieee80211_i.h"
27 #include "rate.h"
28 #include "driver-ops.h"
29
30 #define IEEE80211_AUTH_TIMEOUT (HZ / 5)
31 #define IEEE80211_AUTH_MAX_TRIES 3
32 #define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
33 #define IEEE80211_ASSOC_MAX_TRIES 3
34
35 enum work_action {
36         WORK_ACT_MISMATCH,
37         WORK_ACT_NONE,
38         WORK_ACT_TIMEOUT,
39         WORK_ACT_DONE,
40 };
41
42
43 /* utils */
44 static inline void ASSERT_WORK_MTX(struct ieee80211_local *local)
45 {
46         lockdep_assert_held(&local->mtx);
47 }
48
49 /*
50  * We can have multiple work items (and connection probing)
51  * scheduling this timer, but we need to take care to only
52  * reschedule it when it should fire _earlier_ than it was
53  * asked for before, or if it's not pending right now. This
54  * function ensures that. Note that it then is required to
55  * run this function for all timeouts after the first one
56  * has happened -- the work that runs from this timer will
57  * do that.
58  */
59 static void run_again(struct ieee80211_local *local,
60                       unsigned long timeout)
61 {
62         ASSERT_WORK_MTX(local);
63
64         if (!timer_pending(&local->work_timer) ||
65             time_before(timeout, local->work_timer.expires))
66                 mod_timer(&local->work_timer, timeout);
67 }
68
69 void free_work(struct ieee80211_work *wk)
70 {
71         kfree_rcu(wk, rcu_head);
72 }
73
74 static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len,
75                                       struct ieee80211_supported_band *sband,
76                                       u32 *rates)
77 {
78         int i, j, count;
79         *rates = 0;
80         count = 0;
81         for (i = 0; i < supp_rates_len; i++) {
82                 int rate = (supp_rates[i] & 0x7F) * 5;
83
84                 for (j = 0; j < sband->n_bitrates; j++)
85                         if (sband->bitrates[j].bitrate == rate) {
86                                 *rates |= BIT(j);
87                                 count++;
88                                 break;
89                         }
90         }
91
92         return count;
93 }
94
95 /* frame sending functions */
96
97 static void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie,
98                                 struct ieee80211_supported_band *sband,
99                                 struct ieee80211_channel *channel,
100                                 enum ieee80211_smps_mode smps)
101 {
102         struct ieee80211_ht_info *ht_info;
103         u8 *pos;
104         u32 flags = channel->flags;
105         u16 cap = sband->ht_cap.cap;
106         __le16 tmp;
107
108         if (!sband->ht_cap.ht_supported)
109                 return;
110
111         if (!ht_info_ie)
112                 return;
113
114         if (ht_info_ie[1] < sizeof(struct ieee80211_ht_info))
115                 return;
116
117         ht_info = (struct ieee80211_ht_info *)(ht_info_ie + 2);
118
119         /* determine capability flags */
120
121         switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
122         case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
123                 if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
124                         cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
125                         cap &= ~IEEE80211_HT_CAP_SGI_40;
126                 }
127                 break;
128         case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
129                 if (flags & IEEE80211_CHAN_NO_HT40MINUS) {
130                         cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
131                         cap &= ~IEEE80211_HT_CAP_SGI_40;
132                 }
133                 break;
134         }
135
136         /* set SM PS mode properly */
137         cap &= ~IEEE80211_HT_CAP_SM_PS;
138         switch (smps) {
139         case IEEE80211_SMPS_AUTOMATIC:
140         case IEEE80211_SMPS_NUM_MODES:
141                 WARN_ON(1);
142         case IEEE80211_SMPS_OFF:
143                 cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
144                         IEEE80211_HT_CAP_SM_PS_SHIFT;
145                 break;
146         case IEEE80211_SMPS_STATIC:
147                 cap |= WLAN_HT_CAP_SM_PS_STATIC <<
148                         IEEE80211_HT_CAP_SM_PS_SHIFT;
149                 break;
150         case IEEE80211_SMPS_DYNAMIC:
151                 cap |= WLAN_HT_CAP_SM_PS_DYNAMIC <<
152                         IEEE80211_HT_CAP_SM_PS_SHIFT;
153                 break;
154         }
155
156         /* reserve and fill IE */
157
158         pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
159         *pos++ = WLAN_EID_HT_CAPABILITY;
160         *pos++ = sizeof(struct ieee80211_ht_cap);
161         memset(pos, 0, sizeof(struct ieee80211_ht_cap));
162
163         /* capability flags */
164         tmp = cpu_to_le16(cap);
165         memcpy(pos, &tmp, sizeof(u16));
166         pos += sizeof(u16);
167
168         /* AMPDU parameters */
169         *pos++ = sband->ht_cap.ampdu_factor |
170                  (sband->ht_cap.ampdu_density <<
171                         IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
172
173         /* MCS set */
174         memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
175         pos += sizeof(sband->ht_cap.mcs);
176
177         /* extended capabilities */
178         pos += sizeof(__le16);
179
180         /* BF capabilities */
181         pos += sizeof(__le32);
182
183         /* antenna selection */
184         pos += sizeof(u8);
185 }
186
187 static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
188                                  struct ieee80211_work *wk)
189 {
190         struct ieee80211_local *local = sdata->local;
191         struct sk_buff *skb;
192         struct ieee80211_mgmt *mgmt;
193         u8 *pos, qos_info;
194         size_t offset = 0, noffset;
195         int i, count, rates_len, supp_rates_len;
196         u16 capab;
197         struct ieee80211_supported_band *sband;
198         u32 rates = 0;
199
200         sband = local->hw.wiphy->bands[wk->chan->band];
201
202         if (wk->assoc.supp_rates_len) {
203                 /*
204                  * Get all rates supported by the device and the AP as
205                  * some APs don't like getting a superset of their rates
206                  * in the association request (e.g. D-Link DAP 1353 in
207                  * b-only mode)...
208                  */
209                 rates_len = ieee80211_compatible_rates(wk->assoc.supp_rates,
210                                                        wk->assoc.supp_rates_len,
211                                                        sband, &rates);
212         } else {
213                 /*
214                  * In case AP not provide any supported rates information
215                  * before association, we send information element(s) with
216                  * all rates that we support.
217                  */
218                 rates = ~0;
219                 rates_len = sband->n_bitrates;
220         }
221
222         skb = alloc_skb(local->hw.extra_tx_headroom +
223                         sizeof(*mgmt) + /* bit too much but doesn't matter */
224                         2 + wk->assoc.ssid_len + /* SSID */
225                         4 + rates_len + /* (extended) rates */
226                         4 + /* power capability */
227                         2 + 2 * sband->n_channels + /* supported channels */
228                         2 + sizeof(struct ieee80211_ht_cap) + /* HT */
229                         wk->ie_len + /* extra IEs */
230                         9, /* WMM */
231                         GFP_KERNEL);
232         if (!skb)
233                 return;
234
235         skb_reserve(skb, local->hw.extra_tx_headroom);
236
237         capab = WLAN_CAPABILITY_ESS;
238
239         if (sband->band == IEEE80211_BAND_2GHZ) {
240                 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
241                         capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
242                 if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
243                         capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
244         }
245
246         if (wk->assoc.capability & WLAN_CAPABILITY_PRIVACY)
247                 capab |= WLAN_CAPABILITY_PRIVACY;
248
249         if ((wk->assoc.capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
250             (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
251                 capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
252
253         mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
254         memset(mgmt, 0, 24);
255         memcpy(mgmt->da, wk->filter_ta, ETH_ALEN);
256         memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
257         memcpy(mgmt->bssid, wk->filter_ta, ETH_ALEN);
258
259         if (!is_zero_ether_addr(wk->assoc.prev_bssid)) {
260                 skb_put(skb, 10);
261                 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
262                                                   IEEE80211_STYPE_REASSOC_REQ);
263                 mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
264                 mgmt->u.reassoc_req.listen_interval =
265                                 cpu_to_le16(local->hw.conf.listen_interval);
266                 memcpy(mgmt->u.reassoc_req.current_ap, wk->assoc.prev_bssid,
267                        ETH_ALEN);
268         } else {
269                 skb_put(skb, 4);
270                 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
271                                                   IEEE80211_STYPE_ASSOC_REQ);
272                 mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
273                 mgmt->u.assoc_req.listen_interval =
274                                 cpu_to_le16(local->hw.conf.listen_interval);
275         }
276
277         /* SSID */
278         pos = skb_put(skb, 2 + wk->assoc.ssid_len);
279         *pos++ = WLAN_EID_SSID;
280         *pos++ = wk->assoc.ssid_len;
281         memcpy(pos, wk->assoc.ssid, wk->assoc.ssid_len);
282
283         /* add all rates which were marked to be used above */
284         supp_rates_len = rates_len;
285         if (supp_rates_len > 8)
286                 supp_rates_len = 8;
287
288         pos = skb_put(skb, supp_rates_len + 2);
289         *pos++ = WLAN_EID_SUPP_RATES;
290         *pos++ = supp_rates_len;
291
292         count = 0;
293         for (i = 0; i < sband->n_bitrates; i++) {
294                 if (BIT(i) & rates) {
295                         int rate = sband->bitrates[i].bitrate;
296                         *pos++ = (u8) (rate / 5);
297                         if (++count == 8)
298                                 break;
299                 }
300         }
301
302         if (rates_len > count) {
303                 pos = skb_put(skb, rates_len - count + 2);
304                 *pos++ = WLAN_EID_EXT_SUPP_RATES;
305                 *pos++ = rates_len - count;
306
307                 for (i++; i < sband->n_bitrates; i++) {
308                         if (BIT(i) & rates) {
309                                 int rate = sband->bitrates[i].bitrate;
310                                 *pos++ = (u8) (rate / 5);
311                         }
312                 }
313         }
314
315         if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) {
316                 /* 1. power capabilities */
317                 pos = skb_put(skb, 4);
318                 *pos++ = WLAN_EID_PWR_CAPABILITY;
319                 *pos++ = 2;
320                 *pos++ = 0; /* min tx power */
321                 *pos++ = wk->chan->max_power; /* max tx power */
322
323                 /* 2. supported channels */
324                 /* TODO: get this in reg domain format */
325                 pos = skb_put(skb, 2 * sband->n_channels + 2);
326                 *pos++ = WLAN_EID_SUPPORTED_CHANNELS;
327                 *pos++ = 2 * sband->n_channels;
328                 for (i = 0; i < sband->n_channels; i++) {
329                         *pos++ = ieee80211_frequency_to_channel(
330                                         sband->channels[i].center_freq);
331                         *pos++ = 1; /* one channel in the subband*/
332                 }
333         }
334
335         /* if present, add any custom IEs that go before HT */
336         if (wk->ie_len && wk->ie) {
337                 static const u8 before_ht[] = {
338                         WLAN_EID_SSID,
339                         WLAN_EID_SUPP_RATES,
340                         WLAN_EID_EXT_SUPP_RATES,
341                         WLAN_EID_PWR_CAPABILITY,
342                         WLAN_EID_SUPPORTED_CHANNELS,
343                         WLAN_EID_RSN,
344                         WLAN_EID_QOS_CAPA,
345                         WLAN_EID_RRM_ENABLED_CAPABILITIES,
346                         WLAN_EID_MOBILITY_DOMAIN,
347                         WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
348                 };
349                 noffset = ieee80211_ie_split(wk->ie, wk->ie_len,
350                                              before_ht, ARRAY_SIZE(before_ht),
351                                              offset);
352                 pos = skb_put(skb, noffset - offset);
353                 memcpy(pos, wk->ie + offset, noffset - offset);
354                 offset = noffset;
355         }
356
357         if (wk->assoc.use_11n && wk->assoc.wmm_used &&
358             local->hw.queues >= 4)
359                 ieee80211_add_ht_ie(skb, wk->assoc.ht_information_ie,
360                                     sband, wk->chan, wk->assoc.smps);
361
362         /* if present, add any custom non-vendor IEs that go after HT */
363         if (wk->ie_len && wk->ie) {
364                 noffset = ieee80211_ie_split_vendor(wk->ie, wk->ie_len,
365                                                     offset);
366                 pos = skb_put(skb, noffset - offset);
367                 memcpy(pos, wk->ie + offset, noffset - offset);
368                 offset = noffset;
369         }
370
371         if (wk->assoc.wmm_used && local->hw.queues >= 4) {
372                 if (wk->assoc.uapsd_used) {
373                         qos_info = local->uapsd_queues;
374                         qos_info |= (local->uapsd_max_sp_len <<
375                                      IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT);
376                 } else {
377                         qos_info = 0;
378                 }
379
380                 pos = skb_put(skb, 9);
381                 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
382                 *pos++ = 7; /* len */
383                 *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
384                 *pos++ = 0x50;
385                 *pos++ = 0xf2;
386                 *pos++ = 2; /* WME */
387                 *pos++ = 0; /* WME info */
388                 *pos++ = 1; /* WME ver */
389                 *pos++ = qos_info;
390         }
391
392         /* add any remaining custom (i.e. vendor specific here) IEs */
393         if (wk->ie_len && wk->ie) {
394                 noffset = wk->ie_len;
395                 pos = skb_put(skb, noffset - offset);
396                 memcpy(pos, wk->ie + offset, noffset - offset);
397         }
398
399         IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
400         ieee80211_tx_skb(sdata, skb);
401 }
402
403 static void ieee80211_remove_auth_bss(struct ieee80211_local *local,
404                                       struct ieee80211_work *wk)
405 {
406         struct cfg80211_bss *cbss;
407         u16 capa_val = WLAN_CAPABILITY_ESS;
408
409         if (wk->probe_auth.privacy)
410                 capa_val |= WLAN_CAPABILITY_PRIVACY;
411
412         cbss = cfg80211_get_bss(local->hw.wiphy, wk->chan, wk->filter_ta,
413                                 wk->probe_auth.ssid, wk->probe_auth.ssid_len,
414                                 WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY,
415                                 capa_val);
416         if (!cbss)
417                 return;
418
419         cfg80211_unlink_bss(local->hw.wiphy, cbss);
420         cfg80211_put_bss(cbss);
421 }
422
423 static enum work_action __must_check
424 ieee80211_direct_probe(struct ieee80211_work *wk)
425 {
426         struct ieee80211_sub_if_data *sdata = wk->sdata;
427         struct ieee80211_local *local = sdata->local;
428
429         if (!wk->probe_auth.synced) {
430                 int ret = drv_tx_sync(local, sdata, wk->filter_ta,
431                                       IEEE80211_TX_SYNC_AUTH);
432                 if (ret)
433                         return WORK_ACT_TIMEOUT;
434         }
435         wk->probe_auth.synced = true;
436
437         wk->probe_auth.tries++;
438         if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) {
439                 printk(KERN_DEBUG "%s: direct probe to %pM timed out\n",
440                        sdata->name, wk->filter_ta);
441
442                 /*
443                  * Most likely AP is not in the range so remove the
444                  * bss struct for that AP.
445                  */
446                 ieee80211_remove_auth_bss(local, wk);
447
448                 return WORK_ACT_TIMEOUT;
449         }
450
451         printk(KERN_DEBUG "%s: direct probe to %pM (try %d/%i)\n",
452                sdata->name, wk->filter_ta, wk->probe_auth.tries,
453                IEEE80211_AUTH_MAX_TRIES);
454
455         /*
456          * Direct probe is sent to broadcast address as some APs
457          * will not answer to direct packet in unassociated state.
458          */
459         ieee80211_send_probe_req(sdata, NULL, wk->probe_auth.ssid,
460                                  wk->probe_auth.ssid_len, NULL, 0,
461                                  (u32) -1, true, false);
462
463         wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
464         run_again(local, wk->timeout);
465
466         return WORK_ACT_NONE;
467 }
468
469
470 static enum work_action __must_check
471 ieee80211_authenticate(struct ieee80211_work *wk)
472 {
473         struct ieee80211_sub_if_data *sdata = wk->sdata;
474         struct ieee80211_local *local = sdata->local;
475
476         if (!wk->probe_auth.synced) {
477                 int ret = drv_tx_sync(local, sdata, wk->filter_ta,
478                                       IEEE80211_TX_SYNC_AUTH);
479                 if (ret)
480                         return WORK_ACT_TIMEOUT;
481         }
482         wk->probe_auth.synced = true;
483
484         wk->probe_auth.tries++;
485         if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) {
486                 printk(KERN_DEBUG "%s: authentication with %pM"
487                        " timed out\n", sdata->name, wk->filter_ta);
488
489                 /*
490                  * Most likely AP is not in the range so remove the
491                  * bss struct for that AP.
492                  */
493                 ieee80211_remove_auth_bss(local, wk);
494
495                 return WORK_ACT_TIMEOUT;
496         }
497
498         printk(KERN_DEBUG "%s: authenticate with %pM (try %d)\n",
499                sdata->name, wk->filter_ta, wk->probe_auth.tries);
500
501         ieee80211_send_auth(sdata, 1, wk->probe_auth.algorithm, wk->ie,
502                             wk->ie_len, wk->filter_ta, NULL, 0, 0);
503         wk->probe_auth.transaction = 2;
504
505         wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
506         run_again(local, wk->timeout);
507
508         return WORK_ACT_NONE;
509 }
510
511 static enum work_action __must_check
512 ieee80211_associate(struct ieee80211_work *wk)
513 {
514         struct ieee80211_sub_if_data *sdata = wk->sdata;
515         struct ieee80211_local *local = sdata->local;
516
517         if (!wk->assoc.synced) {
518                 int ret = drv_tx_sync(local, sdata, wk->filter_ta,
519                                       IEEE80211_TX_SYNC_ASSOC);
520                 if (ret)
521                         return WORK_ACT_TIMEOUT;
522         }
523         wk->assoc.synced = true;
524
525         wk->assoc.tries++;
526         if (wk->assoc.tries > IEEE80211_ASSOC_MAX_TRIES) {
527                 printk(KERN_DEBUG "%s: association with %pM"
528                        " timed out\n",
529                        sdata->name, wk->filter_ta);
530
531                 /*
532                  * Most likely AP is not in the range so remove the
533                  * bss struct for that AP.
534                  */
535                 if (wk->assoc.bss)
536                         cfg80211_unlink_bss(local->hw.wiphy, wk->assoc.bss);
537
538                 return WORK_ACT_TIMEOUT;
539         }
540
541         printk(KERN_DEBUG "%s: associate with %pM (try %d)\n",
542                sdata->name, wk->filter_ta, wk->assoc.tries);
543         ieee80211_send_assoc(sdata, wk);
544
545         wk->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
546         run_again(local, wk->timeout);
547
548         return WORK_ACT_NONE;
549 }
550
551 static enum work_action __must_check
552 ieee80211_remain_on_channel_timeout(struct ieee80211_work *wk)
553 {
554         /*
555          * First time we run, do nothing -- the generic code will
556          * have switched to the right channel etc.
557          */
558         if (!wk->started) {
559                 wk->timeout = jiffies + msecs_to_jiffies(wk->remain.duration);
560
561                 cfg80211_ready_on_channel(wk->sdata->dev, (unsigned long) wk,
562                                           wk->chan, wk->chan_type,
563                                           wk->remain.duration, GFP_KERNEL);
564
565                 return WORK_ACT_NONE;
566         }
567
568         return WORK_ACT_TIMEOUT;
569 }
570
571 static enum work_action __must_check
572 ieee80211_offchannel_tx(struct ieee80211_work *wk)
573 {
574         if (!wk->started) {
575                 wk->timeout = jiffies + msecs_to_jiffies(wk->offchan_tx.wait);
576
577                 /*
578                  * After this, offchan_tx.frame remains but now is no
579                  * longer a valid pointer -- we still need it as the
580                  * cookie for canceling this work/status matching.
581                  */
582                 ieee80211_tx_skb(wk->sdata, wk->offchan_tx.frame);
583
584                 return WORK_ACT_NONE;
585         }
586
587         return WORK_ACT_TIMEOUT;
588 }
589
590 static enum work_action __must_check
591 ieee80211_assoc_beacon_wait(struct ieee80211_work *wk)
592 {
593         if (wk->started)
594                 return WORK_ACT_TIMEOUT;
595
596         /*
597          * Wait up to one beacon interval ...
598          * should this be more if we miss one?
599          */
600         printk(KERN_DEBUG "%s: waiting for beacon from %pM\n",
601                wk->sdata->name, wk->filter_ta);
602         wk->timeout = TU_TO_EXP_TIME(wk->assoc.bss->beacon_interval);
603         return WORK_ACT_NONE;
604 }
605
606 static void ieee80211_auth_challenge(struct ieee80211_work *wk,
607                                      struct ieee80211_mgmt *mgmt,
608                                      size_t len)
609 {
610         struct ieee80211_sub_if_data *sdata = wk->sdata;
611         u8 *pos;
612         struct ieee802_11_elems elems;
613
614         pos = mgmt->u.auth.variable;
615         ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
616         if (!elems.challenge)
617                 return;
618         ieee80211_send_auth(sdata, 3, wk->probe_auth.algorithm,
619                             elems.challenge - 2, elems.challenge_len + 2,
620                             wk->filter_ta, wk->probe_auth.key,
621                             wk->probe_auth.key_len, wk->probe_auth.key_idx);
622         wk->probe_auth.transaction = 4;
623 }
624
625 static enum work_action __must_check
626 ieee80211_rx_mgmt_auth(struct ieee80211_work *wk,
627                        struct ieee80211_mgmt *mgmt, size_t len)
628 {
629         u16 auth_alg, auth_transaction, status_code;
630
631         if (wk->type != IEEE80211_WORK_AUTH)
632                 return WORK_ACT_MISMATCH;
633
634         if (len < 24 + 6)
635                 return WORK_ACT_NONE;
636
637         auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
638         auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
639         status_code = le16_to_cpu(mgmt->u.auth.status_code);
640
641         if (auth_alg != wk->probe_auth.algorithm ||
642             auth_transaction != wk->probe_auth.transaction)
643                 return WORK_ACT_NONE;
644
645         if (status_code != WLAN_STATUS_SUCCESS) {
646                 printk(KERN_DEBUG "%s: %pM denied authentication (status %d)\n",
647                        wk->sdata->name, mgmt->sa, status_code);
648                 return WORK_ACT_DONE;
649         }
650
651         switch (wk->probe_auth.algorithm) {
652         case WLAN_AUTH_OPEN:
653         case WLAN_AUTH_LEAP:
654         case WLAN_AUTH_FT:
655                 break;
656         case WLAN_AUTH_SHARED_KEY:
657                 if (wk->probe_auth.transaction != 4) {
658                         ieee80211_auth_challenge(wk, mgmt, len);
659                         /* need another frame */
660                         return WORK_ACT_NONE;
661                 }
662                 break;
663         default:
664                 WARN_ON(1);
665                 return WORK_ACT_NONE;
666         }
667
668         printk(KERN_DEBUG "%s: authenticated\n", wk->sdata->name);
669         return WORK_ACT_DONE;
670 }
671
672 static enum work_action __must_check
673 ieee80211_rx_mgmt_assoc_resp(struct ieee80211_work *wk,
674                              struct ieee80211_mgmt *mgmt, size_t len,
675                              bool reassoc)
676 {
677         struct ieee80211_sub_if_data *sdata = wk->sdata;
678         struct ieee80211_local *local = sdata->local;
679         u16 capab_info, status_code, aid;
680         struct ieee802_11_elems elems;
681         u8 *pos;
682
683         if (wk->type != IEEE80211_WORK_ASSOC)
684                 return WORK_ACT_MISMATCH;
685
686         /*
687          * AssocResp and ReassocResp have identical structure, so process both
688          * of them in this function.
689          */
690
691         if (len < 24 + 6)
692                 return WORK_ACT_NONE;
693
694         capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
695         status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
696         aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
697
698         printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x "
699                "status=%d aid=%d)\n",
700                sdata->name, reassoc ? "Rea" : "A", mgmt->sa,
701                capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
702
703         pos = mgmt->u.assoc_resp.variable;
704         ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
705
706         if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
707             elems.timeout_int && elems.timeout_int_len == 5 &&
708             elems.timeout_int[0] == WLAN_TIMEOUT_ASSOC_COMEBACK) {
709                 u32 tu, ms;
710                 tu = get_unaligned_le32(elems.timeout_int + 1);
711                 ms = tu * 1024 / 1000;
712                 printk(KERN_DEBUG "%s: %pM rejected association temporarily; "
713                        "comeback duration %u TU (%u ms)\n",
714                        sdata->name, mgmt->sa, tu, ms);
715                 wk->timeout = jiffies + msecs_to_jiffies(ms);
716                 if (ms > IEEE80211_ASSOC_TIMEOUT)
717                         run_again(local, wk->timeout);
718                 return WORK_ACT_NONE;
719         }
720
721         if (status_code != WLAN_STATUS_SUCCESS)
722                 printk(KERN_DEBUG "%s: %pM denied association (code=%d)\n",
723                        sdata->name, mgmt->sa, status_code);
724         else
725                 printk(KERN_DEBUG "%s: associated\n", sdata->name);
726
727         return WORK_ACT_DONE;
728 }
729
730 static enum work_action __must_check
731 ieee80211_rx_mgmt_probe_resp(struct ieee80211_work *wk,
732                              struct ieee80211_mgmt *mgmt, size_t len,
733                              struct ieee80211_rx_status *rx_status)
734 {
735         struct ieee80211_sub_if_data *sdata = wk->sdata;
736         struct ieee80211_local *local = sdata->local;
737         size_t baselen;
738
739         ASSERT_WORK_MTX(local);
740
741         if (wk->type != IEEE80211_WORK_DIRECT_PROBE)
742                 return WORK_ACT_MISMATCH;
743
744         if (len < 24 + 12)
745                 return WORK_ACT_NONE;
746
747         baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
748         if (baselen > len)
749                 return WORK_ACT_NONE;
750
751         printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name);
752         return WORK_ACT_DONE;
753 }
754
755 static enum work_action __must_check
756 ieee80211_rx_mgmt_beacon(struct ieee80211_work *wk,
757                          struct ieee80211_mgmt *mgmt, size_t len)
758 {
759         struct ieee80211_sub_if_data *sdata = wk->sdata;
760         struct ieee80211_local *local = sdata->local;
761
762         ASSERT_WORK_MTX(local);
763
764         if (wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
765                 return WORK_ACT_MISMATCH;
766
767         if (len < 24 + 12)
768                 return WORK_ACT_NONE;
769
770         printk(KERN_DEBUG "%s: beacon received\n", sdata->name);
771         return WORK_ACT_DONE;
772 }
773
774 static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local,
775                                           struct sk_buff *skb)
776 {
777         struct ieee80211_rx_status *rx_status;
778         struct ieee80211_mgmt *mgmt;
779         struct ieee80211_work *wk;
780         enum work_action rma = WORK_ACT_NONE;
781         u16 fc;
782
783         rx_status = (struct ieee80211_rx_status *) skb->cb;
784         mgmt = (struct ieee80211_mgmt *) skb->data;
785         fc = le16_to_cpu(mgmt->frame_control);
786
787         mutex_lock(&local->mtx);
788
789         list_for_each_entry(wk, &local->work_list, list) {
790                 const u8 *bssid = NULL;
791
792                 switch (wk->type) {
793                 case IEEE80211_WORK_DIRECT_PROBE:
794                 case IEEE80211_WORK_AUTH:
795                 case IEEE80211_WORK_ASSOC:
796                 case IEEE80211_WORK_ASSOC_BEACON_WAIT:
797                         bssid = wk->filter_ta;
798                         break;
799                 default:
800                         continue;
801                 }
802
803                 /*
804                  * Before queuing, we already verified mgmt->sa,
805                  * so this is needed just for matching.
806                  */
807                 if (compare_ether_addr(bssid, mgmt->bssid))
808                         continue;
809
810                 switch (fc & IEEE80211_FCTL_STYPE) {
811                 case IEEE80211_STYPE_BEACON:
812                         rma = ieee80211_rx_mgmt_beacon(wk, mgmt, skb->len);
813                         break;
814                 case IEEE80211_STYPE_PROBE_RESP:
815                         rma = ieee80211_rx_mgmt_probe_resp(wk, mgmt, skb->len,
816                                                            rx_status);
817                         break;
818                 case IEEE80211_STYPE_AUTH:
819                         rma = ieee80211_rx_mgmt_auth(wk, mgmt, skb->len);
820                         break;
821                 case IEEE80211_STYPE_ASSOC_RESP:
822                         rma = ieee80211_rx_mgmt_assoc_resp(wk, mgmt,
823                                                            skb->len, false);
824                         break;
825                 case IEEE80211_STYPE_REASSOC_RESP:
826                         rma = ieee80211_rx_mgmt_assoc_resp(wk, mgmt,
827                                                            skb->len, true);
828                         break;
829                 default:
830                         WARN_ON(1);
831                         rma = WORK_ACT_NONE;
832                 }
833
834                 /*
835                  * We've either received an unexpected frame, or we have
836                  * multiple work items and need to match the frame to the
837                  * right one.
838                  */
839                 if (rma == WORK_ACT_MISMATCH)
840                         continue;
841
842                 /*
843                  * We've processed this frame for that work, so it can't
844                  * belong to another work struct.
845                  * NB: this is also required for correctness for 'rma'!
846                  */
847                 break;
848         }
849
850         switch (rma) {
851         case WORK_ACT_MISMATCH:
852                 /* ignore this unmatched frame */
853                 break;
854         case WORK_ACT_NONE:
855                 break;
856         case WORK_ACT_DONE:
857                 list_del_rcu(&wk->list);
858                 break;
859         default:
860                 WARN(1, "unexpected: %d", rma);
861         }
862
863         mutex_unlock(&local->mtx);
864
865         if (rma != WORK_ACT_DONE)
866                 goto out;
867
868         switch (wk->done(wk, skb)) {
869         case WORK_DONE_DESTROY:
870                 free_work(wk);
871                 break;
872         case WORK_DONE_REQUEUE:
873                 synchronize_rcu();
874                 wk->started = false; /* restart */
875                 mutex_lock(&local->mtx);
876                 list_add_tail(&wk->list, &local->work_list);
877                 mutex_unlock(&local->mtx);
878         }
879
880  out:
881         kfree_skb(skb);
882 }
883
884 static bool ieee80211_work_ct_coexists(enum nl80211_channel_type wk_ct,
885                                        enum nl80211_channel_type oper_ct)
886 {
887         switch (wk_ct) {
888         case NL80211_CHAN_NO_HT:
889                 return true;
890         case NL80211_CHAN_HT20:
891                 if (oper_ct != NL80211_CHAN_NO_HT)
892                         return true;
893                 return false;
894         case NL80211_CHAN_HT40MINUS:
895         case NL80211_CHAN_HT40PLUS:
896                 return (wk_ct == oper_ct);
897         }
898         WARN_ON(1); /* shouldn't get here */
899         return false;
900 }
901
902 static enum nl80211_channel_type
903 ieee80211_calc_ct(enum nl80211_channel_type wk_ct,
904                   enum nl80211_channel_type oper_ct)
905 {
906         switch (wk_ct) {
907         case NL80211_CHAN_NO_HT:
908                 return oper_ct;
909         case NL80211_CHAN_HT20:
910                 if (oper_ct != NL80211_CHAN_NO_HT)
911                         return oper_ct;
912                 return wk_ct;
913         case NL80211_CHAN_HT40MINUS:
914         case NL80211_CHAN_HT40PLUS:
915                 return wk_ct;
916         }
917         WARN_ON(1); /* shouldn't get here */
918         return wk_ct;
919 }
920
921
922 static void ieee80211_work_timer(unsigned long data)
923 {
924         struct ieee80211_local *local = (void *) data;
925
926         if (local->quiescing)
927                 return;
928
929         ieee80211_queue_work(&local->hw, &local->work_work);
930 }
931
932 static void ieee80211_work_work(struct work_struct *work)
933 {
934         struct ieee80211_local *local =
935                 container_of(work, struct ieee80211_local, work_work);
936         struct sk_buff *skb;
937         struct ieee80211_work *wk, *tmp;
938         LIST_HEAD(free_work);
939         enum work_action rma;
940         bool remain_off_channel = false;
941
942         if (local->scanning)
943                 return;
944
945         /*
946          * ieee80211_queue_work() should have picked up most cases,
947          * here we'll pick the rest.
948          */
949         if (WARN(local->suspended, "work scheduled while going to suspend\n"))
950                 return;
951
952         /* first process frames to avoid timing out while a frame is pending */
953         while ((skb = skb_dequeue(&local->work_skb_queue)))
954                 ieee80211_work_rx_queued_mgmt(local, skb);
955
956         mutex_lock(&local->mtx);
957
958         ieee80211_recalc_idle(local);
959
960         list_for_each_entry_safe(wk, tmp, &local->work_list, list) {
961                 bool started = wk->started;
962
963                 /* mark work as started if it's on the current off-channel */
964                 if (!started && local->tmp_channel &&
965                     wk->chan == local->tmp_channel &&
966                     wk->chan_type == local->tmp_channel_type) {
967                         started = true;
968                         wk->timeout = jiffies;
969                 }
970
971                 if (!started && !local->tmp_channel) {
972                         bool on_oper_chan;
973                         bool tmp_chan_changed = false;
974                         bool on_oper_chan2;
975                         enum nl80211_channel_type wk_ct;
976                         on_oper_chan = ieee80211_cfg_on_oper_channel(local);
977
978                         /* Work with existing channel type if possible. */
979                         wk_ct = wk->chan_type;
980                         if (wk->chan == local->hw.conf.channel)
981                                 wk_ct = ieee80211_calc_ct(wk->chan_type,
982                                                 local->hw.conf.channel_type);
983
984                         if (local->tmp_channel)
985                                 if ((local->tmp_channel != wk->chan) ||
986                                     (local->tmp_channel_type != wk_ct))
987                                         tmp_chan_changed = true;
988
989                         local->tmp_channel = wk->chan;
990                         local->tmp_channel_type = wk_ct;
991                         /*
992                          * Leave the station vifs in awake mode if they
993                          * happen to be on the same channel as
994                          * the requested channel.
995                          */
996                         on_oper_chan2 = ieee80211_cfg_on_oper_channel(local);
997                         if (on_oper_chan != on_oper_chan2) {
998                                 if (on_oper_chan2) {
999                                         /* going off oper channel, PS too */
1000                                         ieee80211_offchannel_stop_vifs(local,
1001                                                                        true);
1002                                         ieee80211_hw_config(local, 0);
1003                                 } else {
1004                                         /* going on channel, but leave PS
1005                                          * off-channel. */
1006                                         ieee80211_hw_config(local, 0);
1007                                         ieee80211_offchannel_return(local,
1008                                                                     true,
1009                                                                     false);
1010                                 }
1011                         } else if (tmp_chan_changed)
1012                                 /* Still off-channel, but on some other
1013                                  * channel, so update hardware.
1014                                  * PS should already be off-channel.
1015                                  */
1016                                 ieee80211_hw_config(local, 0);
1017
1018                         started = true;
1019                         wk->timeout = jiffies;
1020                 }
1021
1022                 /* don't try to work with items that aren't started */
1023                 if (!started)
1024                         continue;
1025
1026                 if (time_is_after_jiffies(wk->timeout)) {
1027                         /*
1028                          * This work item isn't supposed to be worked on
1029                          * right now, but take care to adjust the timer
1030                          * properly.
1031                          */
1032                         run_again(local, wk->timeout);
1033                         continue;
1034                 }
1035
1036                 switch (wk->type) {
1037                 default:
1038                         WARN_ON(1);
1039                         /* nothing */
1040                         rma = WORK_ACT_NONE;
1041                         break;
1042                 case IEEE80211_WORK_ABORT:
1043                         rma = WORK_ACT_TIMEOUT;
1044                         break;
1045                 case IEEE80211_WORK_DIRECT_PROBE:
1046                         rma = ieee80211_direct_probe(wk);
1047                         break;
1048                 case IEEE80211_WORK_AUTH:
1049                         rma = ieee80211_authenticate(wk);
1050                         break;
1051                 case IEEE80211_WORK_ASSOC:
1052                         rma = ieee80211_associate(wk);
1053                         break;
1054                 case IEEE80211_WORK_REMAIN_ON_CHANNEL:
1055                         rma = ieee80211_remain_on_channel_timeout(wk);
1056                         break;
1057                 case IEEE80211_WORK_OFFCHANNEL_TX:
1058                         rma = ieee80211_offchannel_tx(wk);
1059                         break;
1060                 case IEEE80211_WORK_ASSOC_BEACON_WAIT:
1061                         rma = ieee80211_assoc_beacon_wait(wk);
1062                         break;
1063                 }
1064
1065                 wk->started = started;
1066
1067                 switch (rma) {
1068                 case WORK_ACT_NONE:
1069                         /* might have changed the timeout */
1070                         run_again(local, wk->timeout);
1071                         break;
1072                 case WORK_ACT_TIMEOUT:
1073                         list_del_rcu(&wk->list);
1074                         synchronize_rcu();
1075                         list_add(&wk->list, &free_work);
1076                         break;
1077                 default:
1078                         WARN(1, "unexpected: %d", rma);
1079                 }
1080         }
1081
1082         list_for_each_entry(wk, &local->work_list, list) {
1083                 if (!wk->started)
1084                         continue;
1085                 if (wk->chan != local->tmp_channel)
1086                         continue;
1087                 if (ieee80211_work_ct_coexists(wk->chan_type,
1088                                                local->tmp_channel_type))
1089                         continue;
1090                 remain_off_channel = true;
1091         }
1092
1093         if (!remain_off_channel && local->tmp_channel) {
1094                 bool on_oper_chan = ieee80211_cfg_on_oper_channel(local);
1095                 local->tmp_channel = NULL;
1096                 /* If tmp_channel wasn't operating channel, then
1097                  * we need to go back on-channel.
1098                  * NOTE:  If we can ever be here while scannning,
1099                  * or if the hw_config() channel config logic changes,
1100                  * then we may need to do a more thorough check to see if
1101                  * we still need to do a hardware config.  Currently,
1102                  * we cannot be here while scanning, however.
1103                  */
1104                 if (ieee80211_cfg_on_oper_channel(local) && !on_oper_chan)
1105                         ieee80211_hw_config(local, 0);
1106
1107                 /* At the least, we need to disable offchannel_ps,
1108                  * so just go ahead and run the entire offchannel
1109                  * return logic here.  We *could* skip enabling
1110                  * beaconing if we were already on-oper-channel
1111                  * as a future optimization.
1112                  */
1113                 ieee80211_offchannel_return(local, true, true);
1114
1115                 /* give connection some time to breathe */
1116                 run_again(local, jiffies + HZ/2);
1117         }
1118
1119         if (list_empty(&local->work_list) && local->scan_req &&
1120             !local->scanning)
1121                 ieee80211_queue_delayed_work(&local->hw,
1122                                              &local->scan_work,
1123                                              round_jiffies_relative(0));
1124
1125         ieee80211_recalc_idle(local);
1126
1127         mutex_unlock(&local->mtx);
1128
1129         list_for_each_entry_safe(wk, tmp, &free_work, list) {
1130                 wk->done(wk, NULL);
1131                 list_del(&wk->list);
1132                 kfree(wk);
1133         }
1134 }
1135
1136 void ieee80211_add_work(struct ieee80211_work *wk)
1137 {
1138         struct ieee80211_local *local;
1139
1140         if (WARN_ON(!wk->chan))
1141                 return;
1142
1143         if (WARN_ON(!wk->sdata))
1144                 return;
1145
1146         if (WARN_ON(!wk->done))
1147                 return;
1148
1149         if (WARN_ON(!ieee80211_sdata_running(wk->sdata)))
1150                 return;
1151
1152         wk->started = false;
1153
1154         local = wk->sdata->local;
1155         mutex_lock(&local->mtx);
1156         list_add_tail(&wk->list, &local->work_list);
1157         mutex_unlock(&local->mtx);
1158
1159         ieee80211_queue_work(&local->hw, &local->work_work);
1160 }
1161
1162 void ieee80211_work_init(struct ieee80211_local *local)
1163 {
1164         INIT_LIST_HEAD(&local->work_list);
1165         setup_timer(&local->work_timer, ieee80211_work_timer,
1166                     (unsigned long)local);
1167         INIT_WORK(&local->work_work, ieee80211_work_work);
1168         skb_queue_head_init(&local->work_skb_queue);
1169 }
1170
1171 void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata)
1172 {
1173         struct ieee80211_local *local = sdata->local;
1174         struct ieee80211_work *wk;
1175         bool cleanup = false;
1176
1177         mutex_lock(&local->mtx);
1178         list_for_each_entry(wk, &local->work_list, list) {
1179                 if (wk->sdata != sdata)
1180                         continue;
1181                 cleanup = true;
1182                 wk->type = IEEE80211_WORK_ABORT;
1183                 wk->started = true;
1184                 wk->timeout = jiffies;
1185         }
1186         mutex_unlock(&local->mtx);
1187
1188         /* run cleanups etc. */
1189         if (cleanup)
1190                 ieee80211_work_work(&local->work_work);
1191
1192         mutex_lock(&local->mtx);
1193         list_for_each_entry(wk, &local->work_list, list) {
1194                 if (wk->sdata != sdata)
1195                         continue;
1196                 WARN_ON(1);
1197                 break;
1198         }
1199         mutex_unlock(&local->mtx);
1200 }
1201
1202 ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata,
1203                                            struct sk_buff *skb)
1204 {
1205         struct ieee80211_local *local = sdata->local;
1206         struct ieee80211_mgmt *mgmt;
1207         struct ieee80211_work *wk;
1208         u16 fc;
1209
1210         if (skb->len < 24)
1211                 return RX_DROP_MONITOR;
1212
1213         mgmt = (struct ieee80211_mgmt *) skb->data;
1214         fc = le16_to_cpu(mgmt->frame_control);
1215
1216         list_for_each_entry_rcu(wk, &local->work_list, list) {
1217                 if (sdata != wk->sdata)
1218                         continue;
1219                 if (compare_ether_addr(wk->filter_ta, mgmt->sa))
1220                         continue;
1221                 if (compare_ether_addr(wk->filter_ta, mgmt->bssid))
1222                         continue;
1223
1224                 switch (fc & IEEE80211_FCTL_STYPE) {
1225                 case IEEE80211_STYPE_AUTH:
1226                 case IEEE80211_STYPE_PROBE_RESP:
1227                 case IEEE80211_STYPE_ASSOC_RESP:
1228                 case IEEE80211_STYPE_REASSOC_RESP:
1229                 case IEEE80211_STYPE_BEACON:
1230                         skb_queue_tail(&local->work_skb_queue, skb);
1231                         ieee80211_queue_work(&local->hw, &local->work_work);
1232                         return RX_QUEUED;
1233                 }
1234         }
1235
1236         return RX_CONTINUE;
1237 }
1238
1239 static enum work_done_result ieee80211_remain_done(struct ieee80211_work *wk,
1240                                                    struct sk_buff *skb)
1241 {
1242         /*
1243          * We are done serving the remain-on-channel command.
1244          */
1245         cfg80211_remain_on_channel_expired(wk->sdata->dev, (unsigned long) wk,
1246                                            wk->chan, wk->chan_type,
1247                                            GFP_KERNEL);
1248
1249         return WORK_DONE_DESTROY;
1250 }
1251
1252 int ieee80211_wk_remain_on_channel(struct ieee80211_sub_if_data *sdata,
1253                                    struct ieee80211_channel *chan,
1254                                    enum nl80211_channel_type channel_type,
1255                                    unsigned int duration, u64 *cookie)
1256 {
1257         struct ieee80211_work *wk;
1258
1259         wk = kzalloc(sizeof(*wk), GFP_KERNEL);
1260         if (!wk)
1261                 return -ENOMEM;
1262
1263         wk->type = IEEE80211_WORK_REMAIN_ON_CHANNEL;
1264         wk->chan = chan;
1265         wk->chan_type = channel_type;
1266         wk->sdata = sdata;
1267         wk->done = ieee80211_remain_done;
1268
1269         wk->remain.duration = duration;
1270
1271         *cookie = (unsigned long) wk;
1272
1273         ieee80211_add_work(wk);
1274
1275         return 0;
1276 }
1277
1278 int ieee80211_wk_cancel_remain_on_channel(struct ieee80211_sub_if_data *sdata,
1279                                           u64 cookie)
1280 {
1281         struct ieee80211_local *local = sdata->local;
1282         struct ieee80211_work *wk, *tmp;
1283         bool found = false;
1284
1285         mutex_lock(&local->mtx);
1286         list_for_each_entry_safe(wk, tmp, &local->work_list, list) {
1287                 if ((unsigned long) wk == cookie) {
1288                         wk->timeout = jiffies;
1289                         found = true;
1290                         break;
1291                 }
1292         }
1293         mutex_unlock(&local->mtx);
1294
1295         if (!found)
1296                 return -ENOENT;
1297
1298         ieee80211_queue_work(&local->hw, &local->work_work);
1299
1300         return 0;
1301 }