]> Git Repo - J-linux.git/blob - drivers/staging/rtl8192e/rtllib_softmac.c
Merge tag 'amd-drm-next-6.5-2023-06-09' of https://gitlab.freedesktop.org/agd5f/linux...
[J-linux.git] / drivers / staging / rtl8192e / rtllib_softmac.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* IEEE 802.11 SoftMAC layer
3  * Copyright (c) 2005 Andrea Merello <[email protected]>
4  *
5  * Mostly extracted from the rtl8180-sa2400 driver for the
6  * in-kernel generic ieee802.11 stack.
7  *
8  * Few lines might be stolen from other part of the rtllib
9  * stack. Copyright who own it's copyright
10  *
11  * WPA code stolen from the ipw2200 driver.
12  * Copyright who own it's copyright.
13  */
14 #include "rtllib.h"
15
16 #include <linux/random.h>
17 #include <linux/delay.h>
18 #include <linux/uaccess.h>
19 #include <linux/etherdevice.h>
20 #include <linux/ieee80211.h>
21 #include "dot11d.h"
22
23 static void rtllib_sta_wakeup(struct rtllib_device *ieee, short nl);
24
25
26 static short rtllib_is_54g(struct rtllib_network *net)
27 {
28         return (net->rates_ex_len > 0) || (net->rates_len > 4);
29 }
30
31 /* returns the total length needed for placing the RATE MFIE
32  * tag and the EXTENDED RATE MFIE tag if needed.
33  * It encludes two bytes per tag for the tag itself and its len
34  */
35 static unsigned int rtllib_MFIE_rate_len(struct rtllib_device *ieee)
36 {
37         unsigned int rate_len = 0;
38
39         if (ieee->modulation & RTLLIB_CCK_MODULATION)
40                 rate_len = RTLLIB_CCK_RATE_LEN + 2;
41
42         if (ieee->modulation & RTLLIB_OFDM_MODULATION)
43
44                 rate_len += RTLLIB_OFDM_RATE_LEN + 2;
45
46         return rate_len;
47 }
48
49 /* place the MFIE rate, tag to the memory (double) pointed.
50  * Then it updates the pointer so that
51  * it points after the new MFIE tag added.
52  */
53 static void rtllib_MFIE_Brate(struct rtllib_device *ieee, u8 **tag_p)
54 {
55         u8 *tag = *tag_p;
56
57         if (ieee->modulation & RTLLIB_CCK_MODULATION) {
58                 *tag++ = MFIE_TYPE_RATES;
59                 *tag++ = 4;
60                 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_1MB;
61                 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_2MB;
62                 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_5MB;
63                 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_11MB;
64         }
65
66         /* We may add an option for custom rates that specific HW
67          * might support
68          */
69         *tag_p = tag;
70 }
71
72 static void rtllib_MFIE_Grate(struct rtllib_device *ieee, u8 **tag_p)
73 {
74         u8 *tag = *tag_p;
75
76         if (ieee->modulation & RTLLIB_OFDM_MODULATION) {
77                 *tag++ = MFIE_TYPE_RATES_EX;
78                 *tag++ = 8;
79                 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_6MB;
80                 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_9MB;
81                 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_12MB;
82                 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_18MB;
83                 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_24MB;
84                 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_36MB;
85                 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_48MB;
86                 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_54MB;
87         }
88         /* We may add an option for custom rates that specific HW might
89          * support
90          */
91         *tag_p = tag;
92 }
93
94 static void rtllib_WMM_Info(struct rtllib_device *ieee, u8 **tag_p)
95 {
96         u8 *tag = *tag_p;
97
98         *tag++ = MFIE_TYPE_GENERIC;
99         *tag++ = 7;
100         *tag++ = 0x00;
101         *tag++ = 0x50;
102         *tag++ = 0xf2;
103         *tag++ = 0x02;
104         *tag++ = 0x00;
105         *tag++ = 0x01;
106         *tag++ = MAX_SP_Len;
107         *tag_p = tag;
108 }
109
110 static void rtllib_TURBO_Info(struct rtllib_device *ieee, u8 **tag_p)
111 {
112         u8 *tag = *tag_p;
113
114         *tag++ = MFIE_TYPE_GENERIC;
115         *tag++ = 7;
116         *tag++ = 0x00;
117         *tag++ = 0xe0;
118         *tag++ = 0x4c;
119         *tag++ = 0x01;
120         *tag++ = 0x02;
121         *tag++ = 0x11;
122         *tag++ = 0x00;
123
124         *tag_p = tag;
125         netdev_alert(ieee->dev, "This is enable turbo mode IE process\n");
126 }
127
128 static void enqueue_mgmt(struct rtllib_device *ieee, struct sk_buff *skb)
129 {
130         int nh;
131
132         nh = (ieee->mgmt_queue_head + 1) % MGMT_QUEUE_NUM;
133
134 /* if the queue is full but we have newer frames then
135  * just overwrites the oldest.
136  *
137  * if (nh == ieee->mgmt_queue_tail)
138  *              return -1;
139  */
140         ieee->mgmt_queue_head = nh;
141         ieee->mgmt_queue_ring[nh] = skb;
142
143 }
144
145 static void init_mgmt_queue(struct rtllib_device *ieee)
146 {
147         ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
148 }
149
150
151 u8 MgntQuery_TxRateExcludeCCKRates(struct rtllib_device *ieee)
152 {
153         u16     i;
154         u8      QueryRate = 0;
155         u8      BasicRate;
156
157
158         for (i = 0; i < ieee->current_network.rates_len; i++) {
159                 BasicRate = ieee->current_network.rates[i]&0x7F;
160                 if (!rtllib_is_cck_rate(BasicRate)) {
161                         if (QueryRate == 0) {
162                                 QueryRate = BasicRate;
163                         } else {
164                                 if (BasicRate < QueryRate)
165                                         QueryRate = BasicRate;
166                         }
167                 }
168         }
169
170         if (QueryRate == 0) {
171                 QueryRate = 12;
172                 netdev_info(ieee->dev, "No BasicRate found!!\n");
173         }
174         return QueryRate;
175 }
176
177 static u8 MgntQuery_MgntFrameTxRate(struct rtllib_device *ieee)
178 {
179         struct rt_hi_throughput *ht_info = ieee->ht_info;
180         u8 rate;
181
182         if (ht_info->iot_action & HT_IOT_ACT_MGNT_USE_CCK_6M)
183                 rate = 0x0c;
184         else
185                 rate = ieee->basic_rate & 0x7f;
186
187         if (rate == 0) {
188                 if (ieee->mode == IEEE_A ||
189                    ieee->mode == IEEE_N_5G ||
190                    (ieee->mode == IEEE_N_24G && !ht_info->bCurSuppCCK))
191                         rate = 0x0c;
192                 else
193                         rate = 0x02;
194         }
195
196         return rate;
197 }
198
199 inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee)
200 {
201         unsigned long flags;
202         short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
203         struct rtllib_hdr_3addr  *header =
204                 (struct rtllib_hdr_3addr  *)skb->data;
205
206         struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8);
207
208         spin_lock_irqsave(&ieee->lock, flags);
209
210         /* called with 2nd param 0, no mgmt lock required */
211         rtllib_sta_wakeup(ieee, 0);
212
213         if (le16_to_cpu(header->frame_ctl) == RTLLIB_STYPE_BEACON)
214                 tcb_desc->queue_index = BEACON_QUEUE;
215         else
216                 tcb_desc->queue_index = MGNT_QUEUE;
217
218         if (ieee->disable_mgnt_queue)
219                 tcb_desc->queue_index = HIGH_QUEUE;
220
221         tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
222         tcb_desc->RATRIndex = 7;
223         tcb_desc->tx_dis_rate_fallback = 1;
224         tcb_desc->tx_use_drv_assinged_rate = 1;
225         if (single) {
226                 if (ieee->queue_stop) {
227                         enqueue_mgmt(ieee, skb);
228                 } else {
229                         header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
230
231                         if (ieee->seq_ctrl[0] == 0xFFF)
232                                 ieee->seq_ctrl[0] = 0;
233                         else
234                                 ieee->seq_ctrl[0]++;
235
236                         /* avoid watchdog triggers */
237                         ieee->softmac_data_hard_start_xmit(skb, ieee->dev,
238                                                            ieee->basic_rate);
239                 }
240
241                 spin_unlock_irqrestore(&ieee->lock, flags);
242         } else {
243                 spin_unlock_irqrestore(&ieee->lock, flags);
244                 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
245
246                 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
247
248                 if (ieee->seq_ctrl[0] == 0xFFF)
249                         ieee->seq_ctrl[0] = 0;
250                 else
251                         ieee->seq_ctrl[0]++;
252
253                 /* check whether the managed packet queued greater than 5 */
254                 if (!ieee->check_nic_enough_desc(ieee->dev,
255                                                  tcb_desc->queue_index) ||
256                     skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) ||
257                     ieee->queue_stop) {
258                         /* insert the skb packet to the management queue
259                          *
260                          * as for the completion function, it does not need
261                          * to check it any more.
262                          */
263                         netdev_info(ieee->dev,
264                                "%s():insert to waitqueue, queue_index:%d!\n",
265                                __func__, tcb_desc->queue_index);
266                         skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index],
267                                        skb);
268                 } else {
269                         ieee->softmac_hard_start_xmit(skb, ieee->dev);
270                 }
271                 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
272         }
273 }
274
275 static inline void
276 softmac_ps_mgmt_xmit(struct sk_buff *skb,
277                      struct rtllib_device *ieee)
278 {
279         short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
280         struct rtllib_hdr_3addr  *header =
281                 (struct rtllib_hdr_3addr  *)skb->data;
282         u16 fc, type, stype;
283         struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8);
284
285         fc = le16_to_cpu(header->frame_ctl);
286         type = WLAN_FC_GET_TYPE(fc);
287         stype = WLAN_FC_GET_STYPE(fc);
288
289
290         if (stype != RTLLIB_STYPE_PSPOLL)
291                 tcb_desc->queue_index = MGNT_QUEUE;
292         else
293                 tcb_desc->queue_index = HIGH_QUEUE;
294
295         if (ieee->disable_mgnt_queue)
296                 tcb_desc->queue_index = HIGH_QUEUE;
297
298
299         tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
300         tcb_desc->RATRIndex = 7;
301         tcb_desc->tx_dis_rate_fallback = 1;
302         tcb_desc->tx_use_drv_assinged_rate = 1;
303         if (single) {
304                 if (type != RTLLIB_FTYPE_CTL) {
305                         header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
306
307                         if (ieee->seq_ctrl[0] == 0xFFF)
308                                 ieee->seq_ctrl[0] = 0;
309                         else
310                                 ieee->seq_ctrl[0]++;
311
312                 }
313                 /* avoid watchdog triggers */
314                 ieee->softmac_data_hard_start_xmit(skb, ieee->dev,
315                                                    ieee->basic_rate);
316
317         } else {
318                 if (type != RTLLIB_FTYPE_CTL) {
319                         header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
320
321                         if (ieee->seq_ctrl[0] == 0xFFF)
322                                 ieee->seq_ctrl[0] = 0;
323                         else
324                                 ieee->seq_ctrl[0]++;
325                 }
326                 ieee->softmac_hard_start_xmit(skb, ieee->dev);
327
328         }
329 }
330
331 static inline struct sk_buff *rtllib_probe_req(struct rtllib_device *ieee)
332 {
333         unsigned int len, rate_len;
334         u8 *tag;
335         struct sk_buff *skb;
336         struct rtllib_probe_request *req;
337
338         len = ieee->current_network.ssid_len;
339
340         rate_len = rtllib_MFIE_rate_len(ieee);
341
342         skb = dev_alloc_skb(sizeof(struct rtllib_probe_request) +
343                             2 + len + rate_len + ieee->tx_headroom);
344
345         if (!skb)
346                 return NULL;
347
348         skb_reserve(skb, ieee->tx_headroom);
349
350         req = skb_put(skb, sizeof(struct rtllib_probe_request));
351         req->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_PROBE_REQ);
352         req->header.duration_id = 0;
353
354         eth_broadcast_addr(req->header.addr1);
355         ether_addr_copy(req->header.addr2, ieee->dev->dev_addr);
356         eth_broadcast_addr(req->header.addr3);
357
358         tag = skb_put(skb, len + 2 + rate_len);
359
360         *tag++ = MFIE_TYPE_SSID;
361         *tag++ = len;
362         memcpy(tag, ieee->current_network.ssid, len);
363         tag += len;
364
365         rtllib_MFIE_Brate(ieee, &tag);
366         rtllib_MFIE_Grate(ieee, &tag);
367
368         return skb;
369 }
370
371 static struct sk_buff *rtllib_get_beacon_(struct rtllib_device *ieee);
372
373 static void rtllib_send_beacon(struct rtllib_device *ieee)
374 {
375         struct sk_buff *skb;
376
377         if (!ieee->ieee_up)
378                 return;
379         skb = rtllib_get_beacon_(ieee);
380
381         if (skb) {
382                 softmac_mgmt_xmit(skb, ieee);
383                 ieee->softmac_stats.tx_beacons++;
384         }
385
386         if (ieee->beacon_txing && ieee->ieee_up)
387                 mod_timer(&ieee->beacon_timer, jiffies +
388                           (msecs_to_jiffies(ieee->current_network.beacon_interval - 5)));
389 }
390
391
392 static void rtllib_send_beacon_cb(struct timer_list *t)
393 {
394         struct rtllib_device *ieee =
395                 from_timer(ieee, t, beacon_timer);
396         unsigned long flags;
397
398         spin_lock_irqsave(&ieee->beacon_lock, flags);
399         rtllib_send_beacon(ieee);
400         spin_unlock_irqrestore(&ieee->beacon_lock, flags);
401 }
402
403 /* Enables network monitor mode, all rx packets will be received. */
404 void rtllib_EnableNetMonitorMode(struct net_device *dev,
405                 bool bInitState)
406 {
407         struct rtllib_device *ieee = netdev_priv_rsl(dev);
408
409         netdev_info(dev, "========>Enter Monitor Mode\n");
410
411         ieee->AllowAllDestAddrHandler(dev, true, !bInitState);
412 }
413
414
415 /* Disables network monitor mode. Only packets destinated to
416  * us will be received.
417  */
418 void rtllib_DisableNetMonitorMode(struct net_device *dev,
419                 bool bInitState)
420 {
421         struct rtllib_device *ieee = netdev_priv_rsl(dev);
422
423         netdev_info(dev, "========>Exit Monitor Mode\n");
424
425         ieee->AllowAllDestAddrHandler(dev, false, !bInitState);
426 }
427
428
429 /* Enables the specialized promiscuous mode required by Intel.
430  * In this mode, Intel intends to hear traffics from/to other STAs in the
431  * same BSS. Therefore we don't have to disable checking BSSID and we only need
432  * to allow all dest. BUT: if we enable checking BSSID then we can't recv
433  * packets from other STA.
434  */
435 void rtllib_EnableIntelPromiscuousMode(struct net_device *dev,
436                 bool bInitState)
437 {
438         bool bFilterOutNonAssociatedBSSID = false;
439
440         struct rtllib_device *ieee = netdev_priv_rsl(dev);
441
442         netdev_info(dev, "========>Enter Intel Promiscuous Mode\n");
443
444         ieee->AllowAllDestAddrHandler(dev, true, !bInitState);
445         ieee->SetHwRegHandler(dev, HW_VAR_CECHK_BSSID,
446                              (u8 *)&bFilterOutNonAssociatedBSSID);
447
448         ieee->net_promiscuous_md = true;
449 }
450 EXPORT_SYMBOL(rtllib_EnableIntelPromiscuousMode);
451
452
453 /* Disables the specialized promiscuous mode required by Intel.
454  * See MgntEnableIntelPromiscuousMode for detail.
455  */
456 void rtllib_DisableIntelPromiscuousMode(struct net_device *dev,
457                 bool bInitState)
458 {
459         bool bFilterOutNonAssociatedBSSID = true;
460
461         struct rtllib_device *ieee = netdev_priv_rsl(dev);
462
463         netdev_info(dev, "========>Exit Intel Promiscuous Mode\n");
464
465         ieee->AllowAllDestAddrHandler(dev, false, !bInitState);
466         ieee->SetHwRegHandler(dev, HW_VAR_CECHK_BSSID,
467                              (u8 *)&bFilterOutNonAssociatedBSSID);
468
469         ieee->net_promiscuous_md = false;
470 }
471 EXPORT_SYMBOL(rtllib_DisableIntelPromiscuousMode);
472
473 static void rtllib_send_probe(struct rtllib_device *ieee, u8 is_mesh)
474 {
475         struct sk_buff *skb;
476
477         skb = rtllib_probe_req(ieee);
478         if (skb) {
479                 softmac_mgmt_xmit(skb, ieee);
480                 ieee->softmac_stats.tx_probe_rq++;
481         }
482 }
483
484
485 static void rtllib_send_probe_requests(struct rtllib_device *ieee, u8 is_mesh)
486 {
487         if (ieee->active_scan && (ieee->softmac_features &
488             IEEE_SOFTMAC_PROBERQ)) {
489                 rtllib_send_probe(ieee, 0);
490                 rtllib_send_probe(ieee, 0);
491         }
492 }
493
494 static void rtllib_update_active_chan_map(struct rtllib_device *ieee)
495 {
496         memcpy(ieee->active_channel_map, GET_DOT11D_INFO(ieee)->channel_map,
497                MAX_CHANNEL_NUMBER+1);
498 }
499
500 /* this performs syncro scan blocking the caller until all channels
501  * in the allowed channel map has been checked.
502  */
503 static void rtllib_softmac_scan_syncro(struct rtllib_device *ieee, u8 is_mesh)
504 {
505         union iwreq_data wrqu;
506         short ch = 0;
507
508         rtllib_update_active_chan_map(ieee);
509
510         ieee->be_scan_inprogress = true;
511
512         mutex_lock(&ieee->scan_mutex);
513
514         while (1) {
515                 do {
516                         ch++;
517                         if (ch > MAX_CHANNEL_NUMBER)
518                                 goto out; /* scan completed */
519                 } while (!ieee->active_channel_map[ch]);
520
521                 /* this function can be called in two situations
522                  * 1- We have switched to ad-hoc mode and we are
523                  *    performing a complete syncro scan before conclude
524                  *    there are no interesting cell and to create a
525                  *    new one. In this case the link state is
526                  *    RTLLIB_NOLINK until we found an interesting cell.
527                  *    If so the ieee8021_new_net, called by the RX path
528                  *    will set the state to RTLLIB_LINKED, so we stop
529                  *    scanning
530                  * 2- We are linked and the root uses run iwlist scan.
531                  *    So we switch to RTLLIB_LINKED_SCANNING to remember
532                  *    that we are still logically linked (not interested in
533                  *    new network events, despite for updating the net list,
534                  *    but we are temporarly 'unlinked' as the driver shall
535                  *    not filter RX frames and the channel is changing.
536                  * So the only situation in which are interested is to check
537                  * if the state become LINKED because of the #1 situation
538                  */
539
540                 if (ieee->state == RTLLIB_LINKED)
541                         goto out;
542                 if (ieee->sync_scan_hurryup) {
543                         netdev_info(ieee->dev,
544                                     "============>sync_scan_hurryup out\n");
545                         goto out;
546                 }
547
548                 ieee->set_chan(ieee->dev, ch);
549                 if (ieee->active_channel_map[ch] == 1)
550                         rtllib_send_probe_requests(ieee, 0);
551
552                 /* this prevent excessive time wait when we
553                  * need to wait for a syncro scan to end..
554                  */
555                 msleep_interruptible_rsl(RTLLIB_SOFTMAC_SCAN_TIME);
556         }
557 out:
558         ieee->actscanning = false;
559         ieee->sync_scan_hurryup = 0;
560
561         if (ieee->state >= RTLLIB_LINKED) {
562                 if (IS_DOT11D_ENABLE(ieee))
563                         dot11d_scan_complete(ieee);
564         }
565         mutex_unlock(&ieee->scan_mutex);
566
567         ieee->be_scan_inprogress = false;
568
569         memset(&wrqu, 0, sizeof(wrqu));
570         wireless_send_event(ieee->dev, SIOCGIWSCAN, &wrqu, NULL);
571 }
572
573 static void rtllib_softmac_scan_wq(void *data)
574 {
575         struct rtllib_device *ieee = container_of_dwork_rsl(data,
576                                      struct rtllib_device, softmac_scan_wq);
577         u8 last_channel = ieee->current_network.channel;
578
579         rtllib_update_active_chan_map(ieee);
580
581         if (!ieee->ieee_up)
582                 return;
583         if (rtllib_act_scanning(ieee, true))
584                 return;
585
586         mutex_lock(&ieee->scan_mutex);
587
588         if (ieee->rf_power_state == rf_off) {
589                 netdev_info(ieee->dev,
590                             "======>%s():rf state is rf_off, return\n",
591                             __func__);
592                 goto out1;
593         }
594
595         do {
596                 ieee->current_network.channel =
597                         (ieee->current_network.channel + 1) %
598                         MAX_CHANNEL_NUMBER;
599                 if (ieee->scan_watch_dog++ > MAX_CHANNEL_NUMBER) {
600                         if (!ieee->active_channel_map[ieee->current_network.channel])
601                                 ieee->current_network.channel = 6;
602                         goto out; /* no good chans */
603                 }
604         } while (!ieee->active_channel_map[ieee->current_network.channel]);
605
606         if (ieee->scanning_continue == 0)
607                 goto out;
608
609         ieee->set_chan(ieee->dev, ieee->current_network.channel);
610
611         if (ieee->active_channel_map[ieee->current_network.channel] == 1)
612                 rtllib_send_probe_requests(ieee, 0);
613
614         schedule_delayed_work(&ieee->softmac_scan_wq,
615                               msecs_to_jiffies(RTLLIB_SOFTMAC_SCAN_TIME));
616
617         mutex_unlock(&ieee->scan_mutex);
618         return;
619
620 out:
621         if (IS_DOT11D_ENABLE(ieee))
622                 dot11d_scan_complete(ieee);
623         ieee->current_network.channel = last_channel;
624
625 out1:
626         ieee->actscanning = false;
627         ieee->scan_watch_dog = 0;
628         ieee->scanning_continue = 0;
629         mutex_unlock(&ieee->scan_mutex);
630 }
631
632
633
634 static void rtllib_beacons_start(struct rtllib_device *ieee)
635 {
636         unsigned long flags;
637
638         spin_lock_irqsave(&ieee->beacon_lock, flags);
639
640         ieee->beacon_txing = 1;
641         rtllib_send_beacon(ieee);
642
643         spin_unlock_irqrestore(&ieee->beacon_lock, flags);
644 }
645
646 static void rtllib_beacons_stop(struct rtllib_device *ieee)
647 {
648         unsigned long flags;
649
650         spin_lock_irqsave(&ieee->beacon_lock, flags);
651
652         ieee->beacon_txing = 0;
653
654         spin_unlock_irqrestore(&ieee->beacon_lock, flags);
655         del_timer_sync(&ieee->beacon_timer);
656
657 }
658
659
660 void rtllib_stop_send_beacons(struct rtllib_device *ieee)
661 {
662         ieee->stop_send_beacons(ieee->dev);
663         if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
664                 rtllib_beacons_stop(ieee);
665 }
666 EXPORT_SYMBOL(rtllib_stop_send_beacons);
667
668
669 void rtllib_start_send_beacons(struct rtllib_device *ieee)
670 {
671         ieee->start_send_beacons(ieee->dev);
672         if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
673                 rtllib_beacons_start(ieee);
674 }
675 EXPORT_SYMBOL(rtllib_start_send_beacons);
676
677
678 static void rtllib_softmac_stop_scan(struct rtllib_device *ieee)
679 {
680         mutex_lock(&ieee->scan_mutex);
681         ieee->scan_watch_dog = 0;
682         if (ieee->scanning_continue == 1) {
683                 ieee->scanning_continue = 0;
684                 ieee->actscanning = false;
685
686                 cancel_delayed_work_sync(&ieee->softmac_scan_wq);
687         }
688
689         mutex_unlock(&ieee->scan_mutex);
690 }
691
692 void rtllib_stop_scan(struct rtllib_device *ieee)
693 {
694         if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) {
695                 rtllib_softmac_stop_scan(ieee);
696         } else {
697                 if (ieee->rtllib_stop_hw_scan)
698                         ieee->rtllib_stop_hw_scan(ieee->dev);
699         }
700 }
701 EXPORT_SYMBOL(rtllib_stop_scan);
702
703 void rtllib_stop_scan_syncro(struct rtllib_device *ieee)
704 {
705         if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) {
706                 ieee->sync_scan_hurryup = 1;
707         } else {
708                 if (ieee->rtllib_stop_hw_scan)
709                         ieee->rtllib_stop_hw_scan(ieee->dev);
710         }
711 }
712 EXPORT_SYMBOL(rtllib_stop_scan_syncro);
713
714 bool rtllib_act_scanning(struct rtllib_device *ieee, bool sync_scan)
715 {
716         if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) {
717                 if (sync_scan)
718                         return ieee->be_scan_inprogress;
719                 else
720                         return ieee->actscanning || ieee->be_scan_inprogress;
721         } else {
722                 return test_bit(STATUS_SCANNING, &ieee->status);
723         }
724 }
725 EXPORT_SYMBOL(rtllib_act_scanning);
726
727 /* called with ieee->lock held */
728 static void rtllib_start_scan(struct rtllib_device *ieee)
729 {
730         ieee->rtllib_ips_leave_wq(ieee->dev);
731
732         if (IS_DOT11D_ENABLE(ieee)) {
733                 if (IS_COUNTRY_IE_VALID(ieee))
734                         RESET_CIE_WATCHDOG(ieee);
735         }
736         if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) {
737                 if (ieee->scanning_continue == 0) {
738                         ieee->actscanning = true;
739                         ieee->scanning_continue = 1;
740                         schedule_delayed_work(&ieee->softmac_scan_wq, 0);
741                 }
742         } else {
743                 if (ieee->rtllib_start_hw_scan)
744                         ieee->rtllib_start_hw_scan(ieee->dev);
745         }
746 }
747
748 /* called with wx_mutex held */
749 void rtllib_start_scan_syncro(struct rtllib_device *ieee, u8 is_mesh)
750 {
751         if (IS_DOT11D_ENABLE(ieee)) {
752                 if (IS_COUNTRY_IE_VALID(ieee))
753                         RESET_CIE_WATCHDOG(ieee);
754         }
755         ieee->sync_scan_hurryup = 0;
756         if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) {
757                 rtllib_softmac_scan_syncro(ieee, is_mesh);
758         } else {
759                 if (ieee->rtllib_start_hw_scan)
760                         ieee->rtllib_start_hw_scan(ieee->dev);
761         }
762 }
763 EXPORT_SYMBOL(rtllib_start_scan_syncro);
764
765 static inline struct sk_buff *
766 rtllib_authentication_req(struct rtllib_network *beacon,
767                           struct rtllib_device *ieee,
768                           int challengelen, u8 *daddr)
769 {
770         struct sk_buff *skb;
771         struct rtllib_authentication *auth;
772         int  len;
773
774         len = sizeof(struct rtllib_authentication) + challengelen +
775                      ieee->tx_headroom + 4;
776         skb = dev_alloc_skb(len);
777
778         if (!skb)
779                 return NULL;
780
781         skb_reserve(skb, ieee->tx_headroom);
782
783         auth = skb_put(skb, sizeof(struct rtllib_authentication));
784
785         auth->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_AUTH);
786         if (challengelen)
787                 auth->header.frame_ctl |= cpu_to_le16(RTLLIB_FCTL_WEP);
788
789         auth->header.duration_id = cpu_to_le16(0x013a);
790         ether_addr_copy(auth->header.addr1, beacon->bssid);
791         ether_addr_copy(auth->header.addr2, ieee->dev->dev_addr);
792         ether_addr_copy(auth->header.addr3, beacon->bssid);
793         if (ieee->auth_mode == 0)
794                 auth->algorithm = WLAN_AUTH_OPEN;
795         else if (ieee->auth_mode == 1)
796                 auth->algorithm = cpu_to_le16(WLAN_AUTH_SHARED_KEY);
797         else if (ieee->auth_mode == 2)
798                 auth->algorithm = WLAN_AUTH_OPEN;
799         auth->transaction = cpu_to_le16(ieee->associate_seq);
800         ieee->associate_seq++;
801
802         auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
803
804         return skb;
805 }
806
807 static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee,
808                                          const u8 *dest)
809 {
810         u8 *tag;
811         int beacon_size;
812         struct rtllib_probe_response *beacon_buf;
813         struct sk_buff *skb = NULL;
814         int encrypt;
815         int atim_len, erp_len;
816         struct lib80211_crypt_data *crypt;
817
818         char *ssid = ieee->current_network.ssid;
819         int ssid_len = ieee->current_network.ssid_len;
820         int rate_len = ieee->current_network.rates_len+2;
821         int rate_ex_len = ieee->current_network.rates_ex_len;
822         int wpa_ie_len = ieee->wpa_ie_len;
823         u8 erpinfo_content = 0;
824
825         u8 *tmp_ht_cap_buf = NULL;
826         u8 tmp_ht_cap_len = 0;
827         u8 *tmp_ht_info_buf = NULL;
828         u8 tmp_ht_info_len = 0;
829         struct rt_hi_throughput *ht_info = ieee->ht_info;
830         u8 *tmp_generic_ie_buf = NULL;
831         u8 tmp_generic_ie_len = 0;
832
833         if (rate_ex_len > 0)
834                 rate_ex_len += 2;
835
836         if (ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
837                 atim_len = 4;
838         else
839                 atim_len = 0;
840
841         if ((ieee->current_network.mode == IEEE_G) ||
842            (ieee->current_network.mode == IEEE_N_24G &&
843            ieee->ht_info->bCurSuppCCK)) {
844                 erp_len = 3;
845                 erpinfo_content = 0;
846                 if (ieee->current_network.buseprotection)
847                         erpinfo_content |= ERP_UseProtection;
848         } else
849                 erp_len = 0;
850
851         crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
852         encrypt = ieee->host_encrypt && crypt && crypt->ops &&
853                 ((strcmp(crypt->ops->name, "R-WEP") == 0 || wpa_ie_len));
854         if (ieee->ht_info->bCurrentHTSupport) {
855                 tmp_ht_cap_buf = (u8 *)&(ieee->ht_info->SelfHTCap);
856                 tmp_ht_cap_len = sizeof(ieee->ht_info->SelfHTCap);
857                 tmp_ht_info_buf = (u8 *)&(ieee->ht_info->SelfHTInfo);
858                 tmp_ht_info_len = sizeof(ieee->ht_info->SelfHTInfo);
859                 HTConstructCapabilityElement(ieee, tmp_ht_cap_buf,
860                                              &tmp_ht_cap_len, encrypt, false);
861                 HTConstructInfoElement(ieee, tmp_ht_info_buf, &tmp_ht_info_len,
862                                        encrypt);
863
864                 if (ht_info->reg_rt2rt_aggregation) {
865                         tmp_generic_ie_buf = ieee->ht_info->sz_rt2rt_agg_buf;
866                         tmp_generic_ie_len =
867                                  sizeof(ieee->ht_info->sz_rt2rt_agg_buf);
868                         HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf,
869                                                    &tmp_generic_ie_len);
870                 }
871         }
872
873         beacon_size = sizeof(struct rtllib_probe_response)+2+
874                 ssid_len + 3 + rate_len + rate_ex_len + atim_len + erp_len
875                 + wpa_ie_len + ieee->tx_headroom;
876         skb = dev_alloc_skb(beacon_size);
877         if (!skb)
878                 return NULL;
879
880         skb_reserve(skb, ieee->tx_headroom);
881
882         beacon_buf = skb_put(skb, (beacon_size - ieee->tx_headroom));
883         ether_addr_copy(beacon_buf->header.addr1, dest);
884         ether_addr_copy(beacon_buf->header.addr2, ieee->dev->dev_addr);
885         ether_addr_copy(beacon_buf->header.addr3, ieee->current_network.bssid);
886
887         beacon_buf->header.duration_id = 0;
888         beacon_buf->beacon_interval =
889                 cpu_to_le16(ieee->current_network.beacon_interval);
890         beacon_buf->capability =
891                 cpu_to_le16(ieee->current_network.capability &
892                 WLAN_CAPABILITY_IBSS);
893         beacon_buf->capability |=
894                 cpu_to_le16(ieee->current_network.capability &
895                 WLAN_CAPABILITY_SHORT_PREAMBLE);
896
897         if (ieee->short_slot && (ieee->current_network.capability &
898             WLAN_CAPABILITY_SHORT_SLOT_TIME))
899                 beacon_buf->capability |=
900                         cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);
901
902         crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
903         if (encrypt)
904                 beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
905
906
907         beacon_buf->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_PROBE_RESP);
908         beacon_buf->info_element[0].id = MFIE_TYPE_SSID;
909         beacon_buf->info_element[0].len = ssid_len;
910
911         tag = (u8 *)beacon_buf->info_element[0].data;
912
913         memcpy(tag, ssid, ssid_len);
914
915         tag += ssid_len;
916
917         *(tag++) = MFIE_TYPE_RATES;
918         *(tag++) = rate_len-2;
919         memcpy(tag, ieee->current_network.rates, rate_len-2);
920         tag += rate_len-2;
921
922         *(tag++) = MFIE_TYPE_DS_SET;
923         *(tag++) = 1;
924         *(tag++) = ieee->current_network.channel;
925
926         if (atim_len) {
927                 u16 val16;
928                 *(tag++) = MFIE_TYPE_IBSS_SET;
929                 *(tag++) = 2;
930                 val16 = ieee->current_network.atim_window;
931                 memcpy((u8 *)tag, (u8 *)&val16, 2);
932                 tag += 2;
933         }
934
935         if (erp_len) {
936                 *(tag++) = MFIE_TYPE_ERP;
937                 *(tag++) = 1;
938                 *(tag++) = erpinfo_content;
939         }
940         if (rate_ex_len) {
941                 *(tag++) = MFIE_TYPE_RATES_EX;
942                 *(tag++) = rate_ex_len-2;
943                 memcpy(tag, ieee->current_network.rates_ex, rate_ex_len-2);
944                 tag += rate_ex_len-2;
945         }
946
947         if (wpa_ie_len) {
948                 if (ieee->iw_mode == IW_MODE_ADHOC)
949                         memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
950                 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
951                 tag += ieee->wpa_ie_len;
952         }
953         return skb;
954 }
955
956 static struct sk_buff *rtllib_assoc_resp(struct rtllib_device *ieee, u8 *dest)
957 {
958         struct sk_buff *skb;
959         u8 *tag;
960
961         struct lib80211_crypt_data *crypt;
962         struct rtllib_assoc_response_frame *assoc;
963         short encrypt;
964
965         unsigned int rate_len = rtllib_MFIE_rate_len(ieee);
966         int len = sizeof(struct rtllib_assoc_response_frame) + rate_len +
967                   ieee->tx_headroom;
968
969         skb = dev_alloc_skb(len);
970
971         if (!skb)
972                 return NULL;
973
974         skb_reserve(skb, ieee->tx_headroom);
975
976         assoc = skb_put(skb, sizeof(struct rtllib_assoc_response_frame));
977
978         assoc->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_ASSOC_RESP);
979         ether_addr_copy(assoc->header.addr1, dest);
980         ether_addr_copy(assoc->header.addr3, ieee->dev->dev_addr);
981         ether_addr_copy(assoc->header.addr2, ieee->dev->dev_addr);
982         assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
983                 WLAN_CAPABILITY_ESS : WLAN_CAPABILITY_IBSS);
984
985
986         if (ieee->short_slot)
987                 assoc->capability |=
988                                  cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);
989
990         if (ieee->host_encrypt)
991                 crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
992         else
993                 crypt = NULL;
994
995         encrypt = (crypt && crypt->ops);
996
997         if (encrypt)
998                 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
999
1000         assoc->status = 0;
1001         assoc->aid = cpu_to_le16(ieee->assoc_id);
1002         if (ieee->assoc_id == 0x2007)
1003                 ieee->assoc_id = 0;
1004         else
1005                 ieee->assoc_id++;
1006
1007         tag = skb_put(skb, rate_len);
1008         rtllib_MFIE_Brate(ieee, &tag);
1009         rtllib_MFIE_Grate(ieee, &tag);
1010
1011         return skb;
1012 }
1013
1014 static struct sk_buff *rtllib_auth_resp(struct rtllib_device *ieee, int status,
1015                                  u8 *dest)
1016 {
1017         struct sk_buff *skb = NULL;
1018         struct rtllib_authentication *auth;
1019         int len = ieee->tx_headroom + sizeof(struct rtllib_authentication) + 1;
1020
1021         skb = dev_alloc_skb(len);
1022         if (!skb)
1023                 return NULL;
1024
1025         skb->len = sizeof(struct rtllib_authentication);
1026
1027         skb_reserve(skb, ieee->tx_headroom);
1028
1029         auth = skb_put(skb, sizeof(struct rtllib_authentication));
1030
1031         auth->status = cpu_to_le16(status);
1032         auth->transaction = cpu_to_le16(2);
1033         auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
1034
1035         ether_addr_copy(auth->header.addr3, ieee->dev->dev_addr);
1036         ether_addr_copy(auth->header.addr2, ieee->dev->dev_addr);
1037         ether_addr_copy(auth->header.addr1, dest);
1038         auth->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_AUTH);
1039         return skb;
1040
1041
1042 }
1043
1044 static struct sk_buff *rtllib_null_func(struct rtllib_device *ieee, short pwr)
1045 {
1046         struct sk_buff *skb;
1047         struct rtllib_hdr_3addr *hdr;
1048
1049         skb = dev_alloc_skb(sizeof(struct rtllib_hdr_3addr)+ieee->tx_headroom);
1050         if (!skb)
1051                 return NULL;
1052
1053         skb_reserve(skb, ieee->tx_headroom);
1054
1055         hdr = skb_put(skb, sizeof(struct rtllib_hdr_3addr));
1056
1057         ether_addr_copy(hdr->addr1, ieee->current_network.bssid);
1058         ether_addr_copy(hdr->addr2, ieee->dev->dev_addr);
1059         ether_addr_copy(hdr->addr3, ieee->current_network.bssid);
1060
1061         hdr->frame_ctl = cpu_to_le16(RTLLIB_FTYPE_DATA |
1062                 RTLLIB_STYPE_NULLFUNC | RTLLIB_FCTL_TODS |
1063                 (pwr ? RTLLIB_FCTL_PM : 0));
1064
1065         return skb;
1066
1067
1068 }
1069
1070 static struct sk_buff *rtllib_pspoll_func(struct rtllib_device *ieee)
1071 {
1072         struct sk_buff *skb;
1073         struct rtllib_pspoll_hdr *hdr;
1074
1075         skb = dev_alloc_skb(sizeof(struct rtllib_pspoll_hdr)+ieee->tx_headroom);
1076         if (!skb)
1077                 return NULL;
1078
1079         skb_reserve(skb, ieee->tx_headroom);
1080
1081         hdr = skb_put(skb, sizeof(struct rtllib_pspoll_hdr));
1082
1083         ether_addr_copy(hdr->bssid, ieee->current_network.bssid);
1084         ether_addr_copy(hdr->ta, ieee->dev->dev_addr);
1085
1086         hdr->aid = cpu_to_le16(ieee->assoc_id | 0xc000);
1087         hdr->frame_ctl = cpu_to_le16(RTLLIB_FTYPE_CTL | RTLLIB_STYPE_PSPOLL |
1088                          RTLLIB_FCTL_PM);
1089
1090         return skb;
1091
1092 }
1093
1094 static void rtllib_resp_to_assoc_rq(struct rtllib_device *ieee, u8 *dest)
1095 {
1096         struct sk_buff *buf = rtllib_assoc_resp(ieee, dest);
1097
1098         if (buf)
1099                 softmac_mgmt_xmit(buf, ieee);
1100 }
1101
1102
1103 static void rtllib_resp_to_auth(struct rtllib_device *ieee, int s, u8 *dest)
1104 {
1105         struct sk_buff *buf = rtllib_auth_resp(ieee, s, dest);
1106
1107         if (buf)
1108                 softmac_mgmt_xmit(buf, ieee);
1109 }
1110
1111
1112 static void rtllib_resp_to_probe(struct rtllib_device *ieee, u8 *dest)
1113 {
1114         struct sk_buff *buf = rtllib_probe_resp(ieee, dest);
1115
1116         if (buf)
1117                 softmac_mgmt_xmit(buf, ieee);
1118 }
1119
1120
1121 static inline int SecIsInPMKIDList(struct rtllib_device *ieee, u8 *bssid)
1122 {
1123         int i = 0;
1124
1125         do {
1126                 if ((ieee->PMKIDList[i].bUsed) &&
1127                    (memcmp(ieee->PMKIDList[i].Bssid, bssid, ETH_ALEN) == 0))
1128                         break;
1129                 i++;
1130         } while (i < NUM_PMKID_CACHE);
1131
1132         if (i == NUM_PMKID_CACHE)
1133                 i = -1;
1134         return i;
1135 }
1136
1137 static inline struct sk_buff *
1138 rtllib_association_req(struct rtllib_network *beacon,
1139                        struct rtllib_device *ieee)
1140 {
1141         struct sk_buff *skb;
1142         struct rtllib_assoc_request_frame *hdr;
1143         u8 *tag, *ies;
1144         int i;
1145         u8 *ht_cap_buf = NULL;
1146         u8 ht_cap_len = 0;
1147         u8 *realtek_ie_buf = NULL;
1148         u8 realtek_ie_len = 0;
1149         int wpa_ie_len = ieee->wpa_ie_len;
1150         int wps_ie_len = ieee->wps_ie_len;
1151         unsigned int ckip_ie_len = 0;
1152         unsigned int ccxrm_ie_len = 0;
1153         unsigned int cxvernum_ie_len = 0;
1154         struct lib80211_crypt_data *crypt;
1155         int encrypt;
1156         int     PMKCacheIdx;
1157
1158         unsigned int rate_len = (beacon->rates_len ?
1159                                 (beacon->rates_len + 2) : 0) +
1160                                 (beacon->rates_ex_len ? (beacon->rates_ex_len) +
1161                                 2 : 0);
1162
1163         unsigned int wmm_info_len = beacon->qos_data.supported ? 9 : 0;
1164         unsigned int turbo_info_len = beacon->Turbo_Enable ? 9 : 0;
1165
1166         int len = 0;
1167
1168         crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
1169         if (crypt != NULL)
1170                 encrypt = ieee->host_encrypt && crypt && crypt->ops &&
1171                           ((strcmp(crypt->ops->name, "R-WEP") == 0 ||
1172                           wpa_ie_len));
1173         else
1174                 encrypt = 0;
1175
1176         if ((ieee->rtllib_ap_sec_type &&
1177             (ieee->rtllib_ap_sec_type(ieee) & SEC_ALG_TKIP)) ||
1178             ieee->bForcedBgMode) {
1179                 ieee->ht_info->enable_ht = 0;
1180                 ieee->mode = WIRELESS_MODE_G;
1181         }
1182
1183         if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht) {
1184                 ht_cap_buf = (u8 *)&(ieee->ht_info->SelfHTCap);
1185                 ht_cap_len = sizeof(ieee->ht_info->SelfHTCap);
1186                 HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len,
1187                                              encrypt, true);
1188                 if (ieee->ht_info->current_rt2rt_aggregation) {
1189                         realtek_ie_buf = ieee->ht_info->sz_rt2rt_agg_buf;
1190                         realtek_ie_len =
1191                                  sizeof(ieee->ht_info->sz_rt2rt_agg_buf);
1192                         HTConstructRT2RTAggElement(ieee, realtek_ie_buf,
1193                                                    &realtek_ie_len);
1194                 }
1195         }
1196
1197         if (beacon->bCkipSupported)
1198                 ckip_ie_len = 30+2;
1199         if (beacon->bCcxRmEnable)
1200                 ccxrm_ie_len = 6+2;
1201         if (beacon->BssCcxVerNumber >= 2)
1202                 cxvernum_ie_len = 5+2;
1203
1204         PMKCacheIdx = SecIsInPMKIDList(ieee, ieee->current_network.bssid);
1205         if (PMKCacheIdx >= 0) {
1206                 wpa_ie_len += 18;
1207                 netdev_info(ieee->dev, "[PMK cache]: WPA2 IE length: %x\n",
1208                             wpa_ie_len);
1209         }
1210         len = sizeof(struct rtllib_assoc_request_frame) + 2
1211                 + beacon->ssid_len
1212                 + rate_len
1213                 + wpa_ie_len
1214                 + wps_ie_len
1215                 + wmm_info_len
1216                 + turbo_info_len
1217                 + ht_cap_len
1218                 + realtek_ie_len
1219                 + ckip_ie_len
1220                 + ccxrm_ie_len
1221                 + cxvernum_ie_len
1222                 + ieee->tx_headroom;
1223
1224         skb = dev_alloc_skb(len);
1225
1226         if (!skb)
1227                 return NULL;
1228
1229         skb_reserve(skb, ieee->tx_headroom);
1230
1231         hdr = skb_put(skb, sizeof(struct rtllib_assoc_request_frame) + 2);
1232
1233
1234         hdr->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_ASSOC_REQ);
1235         hdr->header.duration_id = cpu_to_le16(37);
1236         ether_addr_copy(hdr->header.addr1, beacon->bssid);
1237         ether_addr_copy(hdr->header.addr2, ieee->dev->dev_addr);
1238         ether_addr_copy(hdr->header.addr3, beacon->bssid);
1239
1240         ether_addr_copy(ieee->ap_mac_addr, beacon->bssid);
1241
1242         hdr->capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
1243         if (beacon->capability & WLAN_CAPABILITY_PRIVACY)
1244                 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1245
1246         if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1247                 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
1248
1249         if (ieee->short_slot &&
1250            (beacon->capability&WLAN_CAPABILITY_SHORT_SLOT_TIME))
1251                 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);
1252
1253
1254         hdr->listen_interval = cpu_to_le16(beacon->listen_interval);
1255
1256         hdr->info_element[0].id = MFIE_TYPE_SSID;
1257
1258         hdr->info_element[0].len = beacon->ssid_len;
1259         skb_put_data(skb, beacon->ssid, beacon->ssid_len);
1260
1261         tag = skb_put(skb, rate_len);
1262
1263         if (beacon->rates_len) {
1264                 *tag++ = MFIE_TYPE_RATES;
1265                 *tag++ = beacon->rates_len;
1266                 for (i = 0; i < beacon->rates_len; i++)
1267                         *tag++ = beacon->rates[i];
1268         }
1269
1270         if (beacon->rates_ex_len) {
1271                 *tag++ = MFIE_TYPE_RATES_EX;
1272                 *tag++ = beacon->rates_ex_len;
1273                 for (i = 0; i < beacon->rates_ex_len; i++)
1274                         *tag++ = beacon->rates_ex[i];
1275         }
1276
1277         if (beacon->bCkipSupported) {
1278                 static const u8 AironetIeOui[] = {0x00, 0x01, 0x66};
1279                 u8      CcxAironetBuf[30];
1280                 struct octet_string osCcxAironetIE;
1281
1282                 memset(CcxAironetBuf, 0, 30);
1283                 osCcxAironetIE.Octet = CcxAironetBuf;
1284                 osCcxAironetIE.Length = sizeof(CcxAironetBuf);
1285                 memcpy(osCcxAironetIE.Octet, AironetIeOui,
1286                        sizeof(AironetIeOui));
1287
1288                 osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |=
1289                                          (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC);
1290                 tag = skb_put(skb, ckip_ie_len);
1291                 *tag++ = MFIE_TYPE_AIRONET;
1292                 *tag++ = osCcxAironetIE.Length;
1293                 memcpy(tag, osCcxAironetIE.Octet, osCcxAironetIE.Length);
1294                 tag += osCcxAironetIE.Length;
1295         }
1296
1297         if (beacon->bCcxRmEnable) {
1298                 static const u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01,
1299                         0x00};
1300                 struct octet_string osCcxRmCap;
1301
1302                 osCcxRmCap.Octet = (u8 *)CcxRmCapBuf;
1303                 osCcxRmCap.Length = sizeof(CcxRmCapBuf);
1304                 tag = skb_put(skb, ccxrm_ie_len);
1305                 *tag++ = MFIE_TYPE_GENERIC;
1306                 *tag++ = osCcxRmCap.Length;
1307                 memcpy(tag, osCcxRmCap.Octet, osCcxRmCap.Length);
1308                 tag += osCcxRmCap.Length;
1309         }
1310
1311         if (beacon->BssCcxVerNumber >= 2) {
1312                 u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
1313                 struct octet_string osCcxVerNum;
1314
1315                 CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
1316                 osCcxVerNum.Octet = CcxVerNumBuf;
1317                 osCcxVerNum.Length = sizeof(CcxVerNumBuf);
1318                 tag = skb_put(skb, cxvernum_ie_len);
1319                 *tag++ = MFIE_TYPE_GENERIC;
1320                 *tag++ = osCcxVerNum.Length;
1321                 memcpy(tag, osCcxVerNum.Octet, osCcxVerNum.Length);
1322                 tag += osCcxVerNum.Length;
1323         }
1324         if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht) {
1325                 if (ieee->ht_info->ePeerHTSpecVer != HT_SPEC_VER_EWC) {
1326                         tag = skb_put(skb, ht_cap_len);
1327                         *tag++ = MFIE_TYPE_HT_CAP;
1328                         *tag++ = ht_cap_len - 2;
1329                         memcpy(tag, ht_cap_buf, ht_cap_len - 2);
1330                         tag += ht_cap_len - 2;
1331                 }
1332         }
1333
1334         if (wpa_ie_len) {
1335                 skb_put_data(skb, ieee->wpa_ie, ieee->wpa_ie_len);
1336
1337                 if (PMKCacheIdx >= 0) {
1338                         tag = skb_put(skb, 18);
1339                         *tag = 1;
1340                         *(tag + 1) = 0;
1341                         memcpy((tag + 2), &ieee->PMKIDList[PMKCacheIdx].PMKID,
1342                                16);
1343                 }
1344         }
1345         if (wmm_info_len) {
1346                 tag = skb_put(skb, wmm_info_len);
1347                 rtllib_WMM_Info(ieee, &tag);
1348         }
1349
1350         if (wps_ie_len && ieee->wps_ie)
1351                 skb_put_data(skb, ieee->wps_ie, wps_ie_len);
1352
1353         if (turbo_info_len) {
1354                 tag = skb_put(skb, turbo_info_len);
1355                 rtllib_TURBO_Info(ieee, &tag);
1356         }
1357
1358         if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht) {
1359                 if (ieee->ht_info->ePeerHTSpecVer == HT_SPEC_VER_EWC) {
1360                         tag = skb_put(skb, ht_cap_len);
1361                         *tag++ = MFIE_TYPE_GENERIC;
1362                         *tag++ = ht_cap_len - 2;
1363                         memcpy(tag, ht_cap_buf, ht_cap_len - 2);
1364                         tag += ht_cap_len - 2;
1365                 }
1366
1367                 if (ieee->ht_info->current_rt2rt_aggregation) {
1368                         tag = skb_put(skb, realtek_ie_len);
1369                         *tag++ = MFIE_TYPE_GENERIC;
1370                         *tag++ = realtek_ie_len - 2;
1371                         memcpy(tag, realtek_ie_buf, realtek_ie_len - 2);
1372                 }
1373         }
1374
1375         kfree(ieee->assocreq_ies);
1376         ieee->assocreq_ies = NULL;
1377         ies = &(hdr->info_element[0].id);
1378         ieee->assocreq_ies_len = (skb->data + skb->len) - ies;
1379         ieee->assocreq_ies = kmemdup(ies, ieee->assocreq_ies_len, GFP_ATOMIC);
1380         if (!ieee->assocreq_ies)
1381                 ieee->assocreq_ies_len = 0;
1382
1383         return skb;
1384 }
1385
1386 static void rtllib_associate_abort(struct rtllib_device *ieee)
1387 {
1388         unsigned long flags;
1389
1390         spin_lock_irqsave(&ieee->lock, flags);
1391
1392         ieee->associate_seq++;
1393
1394         /* don't scan, and avoid to have the RX path possibily
1395          * try again to associate. Even do not react to AUTH or
1396          * ASSOC response. Just wait for the retry wq to be scheduled.
1397          * Here we will check if there are good nets to associate
1398          * with, so we retry or just get back to NO_LINK and scanning
1399          */
1400         if (ieee->state == RTLLIB_ASSOCIATING_AUTHENTICATING) {
1401                 netdev_dbg(ieee->dev, "Authentication failed\n");
1402                 ieee->softmac_stats.no_auth_rs++;
1403         } else {
1404                 netdev_dbg(ieee->dev, "Association failed\n");
1405                 ieee->softmac_stats.no_ass_rs++;
1406         }
1407
1408         ieee->state = RTLLIB_ASSOCIATING_RETRY;
1409
1410         schedule_delayed_work(&ieee->associate_retry_wq,
1411                               RTLLIB_SOFTMAC_ASSOC_RETRY_TIME);
1412
1413         spin_unlock_irqrestore(&ieee->lock, flags);
1414 }
1415
1416 static void rtllib_associate_abort_cb(struct timer_list *t)
1417 {
1418         struct rtllib_device *dev = from_timer(dev, t, associate_timer);
1419
1420         rtllib_associate_abort(dev);
1421 }
1422
1423 static void rtllib_associate_step1(struct rtllib_device *ieee, u8 *daddr)
1424 {
1425         struct rtllib_network *beacon = &ieee->current_network;
1426         struct sk_buff *skb;
1427
1428         netdev_dbg(ieee->dev, "Stopping scan\n");
1429
1430         ieee->softmac_stats.tx_auth_rq++;
1431
1432         skb = rtllib_authentication_req(beacon, ieee, 0, daddr);
1433
1434         if (!skb)
1435                 rtllib_associate_abort(ieee);
1436         else {
1437                 ieee->state = RTLLIB_ASSOCIATING_AUTHENTICATING;
1438                 netdev_dbg(ieee->dev, "Sending authentication request\n");
1439                 softmac_mgmt_xmit(skb, ieee);
1440                 if (!timer_pending(&ieee->associate_timer)) {
1441                         ieee->associate_timer.expires = jiffies + (HZ / 2);
1442                         add_timer(&ieee->associate_timer);
1443                 }
1444         }
1445 }
1446
1447 static void rtllib_auth_challenge(struct rtllib_device *ieee, u8 *challenge,
1448                                   int chlen)
1449 {
1450         u8 *c;
1451         struct sk_buff *skb;
1452         struct rtllib_network *beacon = &ieee->current_network;
1453
1454         ieee->associate_seq++;
1455         ieee->softmac_stats.tx_auth_rq++;
1456
1457         skb = rtllib_authentication_req(beacon, ieee, chlen + 2, beacon->bssid);
1458
1459         if (!skb)
1460                 rtllib_associate_abort(ieee);
1461         else {
1462                 c = skb_put(skb, chlen+2);
1463                 *(c++) = MFIE_TYPE_CHALLENGE;
1464                 *(c++) = chlen;
1465                 memcpy(c, challenge, chlen);
1466
1467                 netdev_dbg(ieee->dev,
1468                            "Sending authentication challenge response\n");
1469
1470                 rtllib_encrypt_fragment(ieee, skb,
1471                                         sizeof(struct rtllib_hdr_3addr));
1472
1473                 softmac_mgmt_xmit(skb, ieee);
1474                 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1475         }
1476         kfree(challenge);
1477 }
1478
1479 static void rtllib_associate_step2(struct rtllib_device *ieee)
1480 {
1481         struct sk_buff *skb;
1482         struct rtllib_network *beacon = &ieee->current_network;
1483
1484         del_timer_sync(&ieee->associate_timer);
1485
1486         netdev_dbg(ieee->dev, "Sending association request\n");
1487
1488         ieee->softmac_stats.tx_ass_rq++;
1489         skb = rtllib_association_req(beacon, ieee);
1490         if (!skb)
1491                 rtllib_associate_abort(ieee);
1492         else {
1493                 softmac_mgmt_xmit(skb, ieee);
1494                 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1495         }
1496 }
1497
1498 static void rtllib_associate_complete_wq(void *data)
1499 {
1500         struct rtllib_device *ieee = (struct rtllib_device *)
1501                                      container_of(data,
1502                                      struct rtllib_device,
1503                                      associate_complete_wq);
1504         struct rt_pwr_save_ctrl *psc = &ieee->pwr_save_ctrl;
1505
1506         netdev_info(ieee->dev, "Associated successfully with %pM\n",
1507                     ieee->current_network.bssid);
1508         if (!ieee->is_silent_reset) {
1509                 netdev_info(ieee->dev, "normal associate\n");
1510                 notify_wx_assoc_event(ieee);
1511         }
1512
1513         netif_carrier_on(ieee->dev);
1514         ieee->is_roaming = false;
1515         if (rtllib_is_54g(&ieee->current_network) &&
1516            (ieee->modulation & RTLLIB_OFDM_MODULATION)) {
1517                 ieee->rate = 108;
1518                 netdev_info(ieee->dev, "Using G rates:%d\n", ieee->rate);
1519         } else {
1520                 ieee->rate = 22;
1521                 ieee->SetWirelessMode(ieee->dev, IEEE_B);
1522                 netdev_info(ieee->dev, "Using B rates:%d\n", ieee->rate);
1523         }
1524         if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht) {
1525                 netdev_info(ieee->dev, "Successfully associated, ht enabled\n");
1526                 HTOnAssocRsp(ieee);
1527         } else {
1528                 netdev_info(ieee->dev,
1529                             "Successfully associated, ht not enabled(%d, %d)\n",
1530                             ieee->ht_info->bCurrentHTSupport,
1531                             ieee->ht_info->enable_ht);
1532                 memset(ieee->dot11ht_oper_rate_set, 0, 16);
1533         }
1534         ieee->link_detect_info.SlotNum = 2 * (1 +
1535                                        ieee->current_network.beacon_interval /
1536                                        500);
1537         if (ieee->link_detect_info.NumRecvBcnInPeriod == 0 ||
1538             ieee->link_detect_info.NumRecvDataInPeriod == 0) {
1539                 ieee->link_detect_info.NumRecvBcnInPeriod = 1;
1540                 ieee->link_detect_info.NumRecvDataInPeriod = 1;
1541         }
1542         psc->LpsIdleCount = 0;
1543         ieee->link_change(ieee->dev);
1544
1545         if (ieee->is_silent_reset) {
1546                 netdev_info(ieee->dev, "silent reset associate\n");
1547                 ieee->is_silent_reset = false;
1548         }
1549
1550         if (ieee->data_hard_resume)
1551                 ieee->data_hard_resume(ieee->dev);
1552
1553 }
1554
1555 static void rtllib_sta_send_associnfo(struct rtllib_device *ieee)
1556 {
1557 }
1558
1559 static void rtllib_associate_complete(struct rtllib_device *ieee)
1560 {
1561         del_timer_sync(&ieee->associate_timer);
1562
1563         ieee->state = RTLLIB_LINKED;
1564         rtllib_sta_send_associnfo(ieee);
1565
1566         schedule_work(&ieee->associate_complete_wq);
1567 }
1568
1569 static void rtllib_associate_procedure_wq(void *data)
1570 {
1571         struct rtllib_device *ieee = container_of_dwork_rsl(data,
1572                                      struct rtllib_device,
1573                                      associate_procedure_wq);
1574         rtllib_stop_scan_syncro(ieee);
1575         ieee->rtllib_ips_leave(ieee->dev);
1576         mutex_lock(&ieee->wx_mutex);
1577
1578         if (ieee->data_hard_stop)
1579                 ieee->data_hard_stop(ieee->dev);
1580
1581         rtllib_stop_scan(ieee);
1582         HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1583         if (ieee->rf_power_state == rf_off) {
1584                 ieee->rtllib_ips_leave_wq(ieee->dev);
1585                 mutex_unlock(&ieee->wx_mutex);
1586                 return;
1587         }
1588         ieee->associate_seq = 1;
1589
1590         rtllib_associate_step1(ieee, ieee->current_network.bssid);
1591
1592         mutex_unlock(&ieee->wx_mutex);
1593 }
1594
1595 inline void rtllib_softmac_new_net(struct rtllib_device *ieee,
1596                                    struct rtllib_network *net)
1597 {
1598         u8 tmp_ssid[IW_ESSID_MAX_SIZE + 1];
1599         int tmp_ssid_len = 0;
1600
1601         short apset, ssidset, ssidbroad, apmatch, ssidmatch;
1602
1603         /* we are interested in new only if we are not associated
1604          * and we are not associating / authenticating
1605          */
1606         if (ieee->state != RTLLIB_NOLINK)
1607                 return;
1608
1609         if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability &
1610             WLAN_CAPABILITY_ESS))
1611                 return;
1612
1613         if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability &
1614              WLAN_CAPABILITY_IBSS))
1615                 return;
1616
1617         if ((ieee->iw_mode == IW_MODE_ADHOC) &&
1618             (net->channel > ieee->ibss_maxjoin_chal))
1619                 return;
1620         if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) {
1621                 /* if the user specified the AP MAC, we need also the essid
1622                  * This could be obtained by beacons or, if the network does not
1623                  * broadcast it, it can be put manually.
1624                  */
1625                 apset = ieee->wap_set;
1626                 ssidset = ieee->ssid_set;
1627                 ssidbroad =  !(net->ssid_len == 0 || net->ssid[0] == '\0');
1628                 apmatch = (memcmp(ieee->current_network.bssid, net->bssid,
1629                                   ETH_ALEN) == 0);
1630                 if (!ssidbroad) {
1631                         ssidmatch = (ieee->current_network.ssid_len ==
1632                                     net->hidden_ssid_len) &&
1633                                     (!strncmp(ieee->current_network.ssid,
1634                                     net->hidden_ssid, net->hidden_ssid_len));
1635                         if (net->hidden_ssid_len > 0) {
1636                                 strncpy(net->ssid, net->hidden_ssid,
1637                                         net->hidden_ssid_len);
1638                                 net->ssid_len = net->hidden_ssid_len;
1639                                 ssidbroad = 1;
1640                         }
1641                 } else
1642                         ssidmatch =
1643                            (ieee->current_network.ssid_len == net->ssid_len) &&
1644                            (!strncmp(ieee->current_network.ssid, net->ssid,
1645                            net->ssid_len));
1646
1647                 /* if the user set the AP check if match.
1648                  * if the network does not broadcast essid we check the
1649                  *       user supplied ANY essid
1650                  * if the network does broadcast and the user does not set
1651                  *       essid it is OK
1652                  * if the network does broadcast and the user did set essid
1653                  * check if essid match
1654                  * if the ap is not set, check that the user set the bssid
1655                  * and the network does broadcast and that those two bssid match
1656                  */
1657                 if ((apset && apmatch &&
1658                    ((ssidset && ssidbroad && ssidmatch) ||
1659                    (ssidbroad && !ssidset) || (!ssidbroad && ssidset))) ||
1660                    (!apset && ssidset && ssidbroad && ssidmatch) ||
1661                    (ieee->is_roaming && ssidset && ssidbroad && ssidmatch)) {
1662                         /* Save the essid so that if it is hidden, it is
1663                          * replaced with the essid provided by the user.
1664                          */
1665                         if (!ssidbroad) {
1666                                 memcpy(tmp_ssid, ieee->current_network.ssid,
1667                                        ieee->current_network.ssid_len);
1668                                 tmp_ssid_len = ieee->current_network.ssid_len;
1669                         }
1670                         memcpy(&ieee->current_network, net,
1671                                 sizeof(ieee->current_network));
1672                         if (!ssidbroad) {
1673                                 memcpy(ieee->current_network.ssid, tmp_ssid,
1674                                        tmp_ssid_len);
1675                                 ieee->current_network.ssid_len = tmp_ssid_len;
1676                         }
1677                         netdev_info(ieee->dev,
1678                                     "Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d, mode:%x cur_net.flags:0x%x\n",
1679                                     ieee->current_network.ssid,
1680                                     ieee->current_network.channel,
1681                                     ieee->current_network.qos_data.supported,
1682                                     ieee->ht_info->enable_ht,
1683                                     ieee->current_network.bssht.bd_support_ht,
1684                                     ieee->current_network.mode,
1685                                     ieee->current_network.flags);
1686
1687                         if ((rtllib_act_scanning(ieee, false)) &&
1688                            !(ieee->softmac_features & IEEE_SOFTMAC_SCAN))
1689                                 rtllib_stop_scan_syncro(ieee);
1690
1691                         HTResetIOTSetting(ieee->ht_info);
1692                         ieee->wmm_acm = 0;
1693                         if (ieee->iw_mode == IW_MODE_INFRA) {
1694                                 /* Join the network for the first time */
1695                                 ieee->AsocRetryCount = 0;
1696                                 if ((ieee->current_network.qos_data.supported == 1) &&
1697                                     ieee->current_network.bssht.bd_support_ht)
1698                                         HTResetSelfAndSavePeerSetting(ieee,
1699                                                  &(ieee->current_network));
1700                                 else
1701                                         ieee->ht_info->bCurrentHTSupport =
1702                                                                  false;
1703
1704                                 ieee->state = RTLLIB_ASSOCIATING;
1705                                 if (ieee->LedControlHandler != NULL)
1706                                         ieee->LedControlHandler(ieee->dev,
1707                                                          LED_CTL_START_TO_LINK);
1708                                 schedule_delayed_work(
1709                                            &ieee->associate_procedure_wq, 0);
1710                         } else {
1711                                 if (rtllib_is_54g(&ieee->current_network) &&
1712                                     (ieee->modulation &
1713                                      RTLLIB_OFDM_MODULATION)) {
1714                                         ieee->rate = 108;
1715                                         ieee->SetWirelessMode(ieee->dev,
1716                                                               IEEE_G);
1717                                         netdev_info(ieee->dev,
1718                                                     "Using G rates\n");
1719                                 } else {
1720                                         ieee->rate = 22;
1721                                         ieee->SetWirelessMode(ieee->dev,
1722                                                               IEEE_B);
1723                                         netdev_info(ieee->dev,
1724                                                     "Using B rates\n");
1725                                 }
1726                                 memset(ieee->dot11ht_oper_rate_set, 0, 16);
1727                                 ieee->state = RTLLIB_LINKED;
1728                         }
1729                 }
1730         }
1731 }
1732
1733 static void rtllib_softmac_check_all_nets(struct rtllib_device *ieee)
1734 {
1735         unsigned long flags;
1736         struct rtllib_network *target;
1737
1738         spin_lock_irqsave(&ieee->lock, flags);
1739
1740         list_for_each_entry(target, &ieee->network_list, list) {
1741
1742                 /* if the state become different that NOLINK means
1743                  * we had found what we are searching for
1744                  */
1745
1746                 if (ieee->state != RTLLIB_NOLINK)
1747                         break;
1748
1749                 if (ieee->scan_age == 0 || time_after(target->last_scanned +
1750                     ieee->scan_age, jiffies))
1751                         rtllib_softmac_new_net(ieee, target);
1752         }
1753         spin_unlock_irqrestore(&ieee->lock, flags);
1754 }
1755
1756 static inline int auth_parse(struct net_device *dev, struct sk_buff *skb,
1757                              u8 **challenge, int *chlen)
1758 {
1759         struct rtllib_authentication *a;
1760         u8 *t;
1761
1762         if (skb->len <  (sizeof(struct rtllib_authentication) -
1763             sizeof(struct rtllib_info_element))) {
1764                 netdev_dbg(dev, "invalid len in auth resp: %d\n", skb->len);
1765                 return -EINVAL;
1766         }
1767         *challenge = NULL;
1768         a = (struct rtllib_authentication *)skb->data;
1769         if (skb->len > (sizeof(struct rtllib_authentication) + 3)) {
1770                 t = skb->data + sizeof(struct rtllib_authentication);
1771
1772                 if (*(t++) == MFIE_TYPE_CHALLENGE) {
1773                         *chlen = *(t++);
1774                         *challenge = kmemdup(t, *chlen, GFP_ATOMIC);
1775                         if (!*challenge)
1776                                 return -ENOMEM;
1777                 }
1778         }
1779
1780         if (a->status) {
1781                 netdev_dbg(dev, "auth_parse() failed\n");
1782                 return -EINVAL;
1783         }
1784
1785         return 0;
1786 }
1787
1788 static int auth_rq_parse(struct net_device *dev, struct sk_buff *skb, u8 *dest)
1789 {
1790         struct rtllib_authentication *a;
1791
1792         if (skb->len <  (sizeof(struct rtllib_authentication) -
1793             sizeof(struct rtllib_info_element))) {
1794                 netdev_dbg(dev, "invalid len in auth request: %d\n", skb->len);
1795                 return -1;
1796         }
1797         a = (struct rtllib_authentication *)skb->data;
1798
1799         ether_addr_copy(dest, a->header.addr2);
1800
1801         if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
1802                 return  WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1803
1804         return WLAN_STATUS_SUCCESS;
1805 }
1806
1807 static short probe_rq_parse(struct rtllib_device *ieee, struct sk_buff *skb,
1808                             u8 *src)
1809 {
1810         u8 *tag;
1811         u8 *skbend;
1812         u8 *ssid = NULL;
1813         u8 ssidlen = 0;
1814         struct rtllib_hdr_3addr   *header =
1815                 (struct rtllib_hdr_3addr   *)skb->data;
1816         bool bssid_match;
1817
1818         if (skb->len < sizeof(struct rtllib_hdr_3addr))
1819                 return -1; /* corrupted */
1820
1821         bssid_match =
1822           (!ether_addr_equal(header->addr3, ieee->current_network.bssid)) &&
1823           (!is_broadcast_ether_addr(header->addr3));
1824         if (bssid_match)
1825                 return -1;
1826
1827         ether_addr_copy(src, header->addr2);
1828
1829         skbend = (u8 *)skb->data + skb->len;
1830
1831         tag = skb->data + sizeof(struct rtllib_hdr_3addr);
1832
1833         while (tag + 1 < skbend) {
1834                 if (*tag == 0) {
1835                         ssid = tag + 2;
1836                         ssidlen = *(tag + 1);
1837                         break;
1838                 }
1839                 tag++; /* point to the len field */
1840                 tag = tag + *(tag); /* point to the last data byte of the tag */
1841                 tag++; /* point to the next tag */
1842         }
1843
1844         if (ssidlen == 0)
1845                 return 1;
1846
1847         if (!ssid)
1848                 return 1; /* ssid not found in tagged param */
1849
1850         return !strncmp(ssid, ieee->current_network.ssid, ssidlen);
1851 }
1852
1853 static int assoc_rq_parse(struct net_device *dev, struct sk_buff *skb, u8 *dest)
1854 {
1855         struct rtllib_assoc_request_frame *a;
1856
1857         if (skb->len < (sizeof(struct rtllib_assoc_request_frame) -
1858                 sizeof(struct rtllib_info_element))) {
1859                 netdev_dbg(dev, "invalid len in auth request:%d\n", skb->len);
1860                 return -1;
1861         }
1862
1863         a = (struct rtllib_assoc_request_frame *)skb->data;
1864
1865         ether_addr_copy(dest, a->header.addr2);
1866
1867         return 0;
1868 }
1869
1870 static inline u16 assoc_parse(struct rtllib_device *ieee, struct sk_buff *skb,
1871                               int *aid)
1872 {
1873         struct rtllib_assoc_response_frame *response_head;
1874         u16 status_code;
1875
1876         if (skb->len <  sizeof(struct rtllib_assoc_response_frame)) {
1877                 netdev_dbg(ieee->dev, "Invalid len in auth resp: %d\n",
1878                            skb->len);
1879                 return 0xcafe;
1880         }
1881
1882         response_head = (struct rtllib_assoc_response_frame *)skb->data;
1883         *aid = le16_to_cpu(response_head->aid) & 0x3fff;
1884
1885         status_code = le16_to_cpu(response_head->status);
1886         if ((status_code == WLAN_STATUS_ASSOC_DENIED_RATES ||
1887            status_code == WLAN_STATUS_CAPS_UNSUPPORTED) &&
1888            ((ieee->mode == IEEE_G) &&
1889            (ieee->current_network.mode == IEEE_N_24G) &&
1890            (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) {
1891                 ieee->ht_info->iot_action |= HT_IOT_ACT_PURE_N_MODE;
1892         } else {
1893                 ieee->AsocRetryCount = 0;
1894         }
1895
1896         return le16_to_cpu(response_head->status);
1897 }
1898
1899 void rtllib_rx_probe_rq(struct rtllib_device *ieee, struct sk_buff *skb)
1900 {
1901         u8 dest[ETH_ALEN];
1902
1903         ieee->softmac_stats.rx_probe_rq++;
1904         if (probe_rq_parse(ieee, skb, dest) > 0) {
1905                 ieee->softmac_stats.tx_probe_rs++;
1906                 rtllib_resp_to_probe(ieee, dest);
1907         }
1908 }
1909
1910 static inline void rtllib_rx_auth_rq(struct rtllib_device *ieee,
1911                                      struct sk_buff *skb)
1912 {
1913         u8 dest[ETH_ALEN];
1914         int status;
1915
1916         ieee->softmac_stats.rx_auth_rq++;
1917
1918         status = auth_rq_parse(ieee->dev, skb, dest);
1919         if (status != -1)
1920                 rtllib_resp_to_auth(ieee, status, dest);
1921 }
1922
1923 static inline void rtllib_rx_assoc_rq(struct rtllib_device *ieee,
1924                                       struct sk_buff *skb)
1925 {
1926         u8 dest[ETH_ALEN];
1927
1928
1929         ieee->softmac_stats.rx_ass_rq++;
1930         if (assoc_rq_parse(ieee->dev, skb, dest) != -1)
1931                 rtllib_resp_to_assoc_rq(ieee, dest);
1932
1933         netdev_info(ieee->dev, "New client associated: %pM\n", dest);
1934 }
1935
1936 void rtllib_sta_ps_send_null_frame(struct rtllib_device *ieee, short pwr)
1937 {
1938
1939         struct sk_buff *buf = rtllib_null_func(ieee, pwr);
1940
1941         if (buf)
1942                 softmac_ps_mgmt_xmit(buf, ieee);
1943 }
1944 EXPORT_SYMBOL(rtllib_sta_ps_send_null_frame);
1945
1946 void rtllib_sta_ps_send_pspoll_frame(struct rtllib_device *ieee)
1947 {
1948         struct sk_buff *buf = rtllib_pspoll_func(ieee);
1949
1950         if (buf)
1951                 softmac_ps_mgmt_xmit(buf, ieee);
1952 }
1953
1954 static short rtllib_sta_ps_sleep(struct rtllib_device *ieee, u64 *time)
1955 {
1956         int timeout;
1957         u8 dtim;
1958         struct rt_pwr_save_ctrl *psc = &ieee->pwr_save_ctrl;
1959
1960         if (ieee->LPSDelayCnt) {
1961                 ieee->LPSDelayCnt--;
1962                 return 0;
1963         }
1964
1965         dtim = ieee->current_network.dtim_data;
1966         if (!(dtim & RTLLIB_DTIM_VALID))
1967                 return 0;
1968         timeout = ieee->current_network.beacon_interval;
1969         ieee->current_network.dtim_data = RTLLIB_DTIM_INVALID;
1970         /* there's no need to nofity AP that I find you buffered
1971          * with broadcast packet
1972          */
1973         if (dtim & (RTLLIB_DTIM_UCAST & ieee->ps))
1974                 return 2;
1975
1976         if (!time_after(jiffies,
1977                         dev_trans_start(ieee->dev) + msecs_to_jiffies(timeout)))
1978                 return 0;
1979         if (!time_after(jiffies,
1980                         ieee->last_rx_ps_time + msecs_to_jiffies(timeout)))
1981                 return 0;
1982         if ((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) &&
1983             (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
1984                 return 0;
1985
1986         if (time) {
1987                 if (ieee->bAwakePktSent) {
1988                         psc->LPSAwakeIntvl = 1;
1989                 } else {
1990                         u8 MaxPeriod = 1;
1991
1992                         if (psc->LPSAwakeIntvl == 0)
1993                                 psc->LPSAwakeIntvl = 1;
1994                         if (psc->reg_max_lps_awake_intvl == 0)
1995                                 MaxPeriod = 1;
1996                         else if (psc->reg_max_lps_awake_intvl == 0xFF)
1997                                 MaxPeriod = ieee->current_network.dtim_period;
1998                         else
1999                                 MaxPeriod = psc->reg_max_lps_awake_intvl;
2000                         psc->LPSAwakeIntvl = (psc->LPSAwakeIntvl >=
2001                                                MaxPeriod) ? MaxPeriod :
2002                                                (psc->LPSAwakeIntvl + 1);
2003                 }
2004                 {
2005                         u8 LPSAwakeIntvl_tmp = 0;
2006                         u8 period = ieee->current_network.dtim_period;
2007                         u8 count = ieee->current_network.tim.tim_count;
2008
2009                         if (count == 0) {
2010                                 if (psc->LPSAwakeIntvl > period)
2011                                         LPSAwakeIntvl_tmp = period +
2012                                                  (psc->LPSAwakeIntvl -
2013                                                  period) -
2014                                                  ((psc->LPSAwakeIntvl-period) %
2015                                                  period);
2016                                 else
2017                                         LPSAwakeIntvl_tmp = psc->LPSAwakeIntvl;
2018
2019                         } else {
2020                                 if (psc->LPSAwakeIntvl >
2021                                     ieee->current_network.tim.tim_count)
2022                                         LPSAwakeIntvl_tmp = count +
2023                                         (psc->LPSAwakeIntvl - count) -
2024                                         ((psc->LPSAwakeIntvl-count)%period);
2025                                 else
2026                                         LPSAwakeIntvl_tmp = psc->LPSAwakeIntvl;
2027                         }
2028
2029                 *time = ieee->current_network.last_dtim_sta_time
2030                         + msecs_to_jiffies(ieee->current_network.beacon_interval *
2031                         LPSAwakeIntvl_tmp);
2032         }
2033         }
2034
2035         return 1;
2036
2037
2038 }
2039
2040 static inline void rtllib_sta_ps(struct work_struct *work)
2041 {
2042         struct rtllib_device *ieee;
2043         u64 time;
2044         short sleep;
2045         unsigned long flags, flags2;
2046
2047         ieee = container_of(work, struct rtllib_device, ps_task);
2048
2049         spin_lock_irqsave(&ieee->lock, flags);
2050
2051         if ((ieee->ps == RTLLIB_PS_DISABLED ||
2052              ieee->iw_mode != IW_MODE_INFRA ||
2053              ieee->state != RTLLIB_LINKED)) {
2054                 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
2055                 rtllib_sta_wakeup(ieee, 1);
2056
2057                 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
2058         }
2059         sleep = rtllib_sta_ps_sleep(ieee, &time);
2060         /* 2 wake, 1 sleep, 0 do nothing */
2061         if (sleep == 0)
2062                 goto out;
2063         if (sleep == 1) {
2064                 if (ieee->sta_sleep == LPS_IS_SLEEP) {
2065                         ieee->enter_sleep_state(ieee->dev, time);
2066                 } else if (ieee->sta_sleep == LPS_IS_WAKE) {
2067                         spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
2068
2069                         if (ieee->ps_is_queue_empty(ieee->dev)) {
2070                                 ieee->sta_sleep = LPS_WAIT_NULL_DATA_SEND;
2071                                 ieee->ack_tx_to_ieee = 1;
2072                                 rtllib_sta_ps_send_null_frame(ieee, 1);
2073                                 ieee->ps_time = time;
2074                         }
2075                         spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
2076
2077                 }
2078
2079                 ieee->bAwakePktSent = false;
2080
2081         } else if (sleep == 2) {
2082                 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
2083
2084                 rtllib_sta_wakeup(ieee, 1);
2085
2086                 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
2087         }
2088
2089 out:
2090         spin_unlock_irqrestore(&ieee->lock, flags);
2091
2092 }
2093
2094 static void rtllib_sta_wakeup(struct rtllib_device *ieee, short nl)
2095 {
2096         if (ieee->sta_sleep == LPS_IS_WAKE) {
2097                 if (nl) {
2098                         if (ieee->ht_info->iot_action &
2099                             HT_IOT_ACT_NULL_DATA_POWER_SAVING) {
2100                                 ieee->ack_tx_to_ieee = 1;
2101                                 rtllib_sta_ps_send_null_frame(ieee, 0);
2102                         } else {
2103                                 ieee->ack_tx_to_ieee = 1;
2104                                 rtllib_sta_ps_send_pspoll_frame(ieee);
2105                         }
2106                 }
2107                 return;
2108
2109         }
2110
2111         if (ieee->sta_sleep == LPS_IS_SLEEP)
2112                 ieee->sta_wake_up(ieee->dev);
2113         if (nl) {
2114                 if (ieee->ht_info->iot_action &
2115                     HT_IOT_ACT_NULL_DATA_POWER_SAVING) {
2116                         ieee->ack_tx_to_ieee = 1;
2117                         rtllib_sta_ps_send_null_frame(ieee, 0);
2118                 } else {
2119                         ieee->ack_tx_to_ieee = 1;
2120                         ieee->polling = true;
2121                         rtllib_sta_ps_send_pspoll_frame(ieee);
2122                 }
2123
2124         } else {
2125                 ieee->sta_sleep = LPS_IS_WAKE;
2126                 ieee->polling = false;
2127         }
2128 }
2129
2130 void rtllib_ps_tx_ack(struct rtllib_device *ieee, short success)
2131 {
2132         unsigned long flags, flags2;
2133
2134         spin_lock_irqsave(&ieee->lock, flags);
2135
2136         if (ieee->sta_sleep == LPS_WAIT_NULL_DATA_SEND) {
2137                 /* Null frame with PS bit set */
2138                 if (success) {
2139                         ieee->sta_sleep = LPS_IS_SLEEP;
2140                         ieee->enter_sleep_state(ieee->dev, ieee->ps_time);
2141                 }
2142                 /* if the card report not success we can't be sure the AP
2143                  * has not RXed so we can't assume the AP believe us awake
2144                  */
2145         } else {/* 21112005 - tx again null without PS bit if lost */
2146
2147                 if ((ieee->sta_sleep == LPS_IS_WAKE) && !success) {
2148                         spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
2149                         if (ieee->ht_info->iot_action &
2150                             HT_IOT_ACT_NULL_DATA_POWER_SAVING)
2151                                 rtllib_sta_ps_send_null_frame(ieee, 0);
2152                         else
2153                                 rtllib_sta_ps_send_pspoll_frame(ieee);
2154                         spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
2155                 }
2156         }
2157         spin_unlock_irqrestore(&ieee->lock, flags);
2158 }
2159 EXPORT_SYMBOL(rtllib_ps_tx_ack);
2160
2161 static void rtllib_process_action(struct rtllib_device *ieee,
2162                                   struct sk_buff *skb)
2163 {
2164         struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *)skb->data;
2165         u8 *act = rtllib_get_payload((struct rtllib_hdr *)header);
2166         u8 category = 0;
2167
2168         if (act == NULL) {
2169                 netdev_warn(ieee->dev,
2170                             "Error getting payload of action frame\n");
2171                 return;
2172         }
2173
2174         category = *act;
2175         act++;
2176         switch (category) {
2177         case ACT_CAT_BA:
2178                 switch (*act) {
2179                 case ACT_ADDBAREQ:
2180                         rtllib_rx_ADDBAReq(ieee, skb);
2181                         break;
2182                 case ACT_ADDBARSP:
2183                         rtllib_rx_ADDBARsp(ieee, skb);
2184                         break;
2185                 case ACT_DELBA:
2186                         rtllib_rx_DELBA(ieee, skb);
2187                         break;
2188                 }
2189                 break;
2190         default:
2191                 break;
2192         }
2193 }
2194
2195 static inline int
2196 rtllib_rx_assoc_resp(struct rtllib_device *ieee, struct sk_buff *skb,
2197                      struct rtllib_rx_stats *rx_stats)
2198 {
2199         u16 errcode;
2200         int aid;
2201         u8 *ies;
2202         struct rtllib_assoc_response_frame *assoc_resp;
2203         struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *)skb->data;
2204         u16 frame_ctl = le16_to_cpu(header->frame_ctl);
2205
2206         netdev_dbg(ieee->dev, "received [RE]ASSOCIATION RESPONSE (%d)\n",
2207                    WLAN_FC_GET_STYPE(frame_ctl));
2208
2209         if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2210              ieee->state == RTLLIB_ASSOCIATING_AUTHENTICATED &&
2211              (ieee->iw_mode == IW_MODE_INFRA)) {
2212                 errcode = assoc_parse(ieee, skb, &aid);
2213                 if (!errcode) {
2214                         struct rtllib_network *network =
2215                                  kzalloc(sizeof(struct rtllib_network),
2216                                  GFP_ATOMIC);
2217
2218                         if (!network)
2219                                 return 1;
2220                         ieee->state = RTLLIB_LINKED;
2221                         ieee->assoc_id = aid;
2222                         ieee->softmac_stats.rx_ass_ok++;
2223                         /* station support qos */
2224                         /* Let the register setting default with Legacy station */
2225                         assoc_resp = (struct rtllib_assoc_response_frame *)skb->data;
2226                         if (ieee->current_network.qos_data.supported == 1) {
2227                                 if (rtllib_parse_info_param(ieee, assoc_resp->info_element,
2228                                                         rx_stats->len - sizeof(*assoc_resp),
2229                                                         network, rx_stats)) {
2230                                         kfree(network);
2231                                         return 1;
2232                                 }
2233                                 memcpy(ieee->ht_info->PeerHTCapBuf,
2234                                        network->bssht.bd_ht_cap_buf,
2235                                        network->bssht.bd_ht_cap_len);
2236                                 memcpy(ieee->ht_info->PeerHTInfoBuf,
2237                                        network->bssht.bd_ht_info_buf,
2238                                        network->bssht.bd_ht_info_len);
2239                                 ieee->handle_assoc_response(ieee->dev,
2240                                         (struct rtllib_assoc_response_frame *)header, network);
2241                         }
2242                         kfree(network);
2243
2244                         kfree(ieee->assocresp_ies);
2245                         ieee->assocresp_ies = NULL;
2246                         ies = &(assoc_resp->info_element[0].id);
2247                         ieee->assocresp_ies_len = (skb->data + skb->len) - ies;
2248                         ieee->assocresp_ies = kmemdup(ies,
2249                                                       ieee->assocresp_ies_len,
2250                                                       GFP_ATOMIC);
2251                         if (!ieee->assocresp_ies)
2252                                 ieee->assocresp_ies_len = 0;
2253
2254                         rtllib_associate_complete(ieee);
2255                 } else {
2256                         /* aid could not been allocated */
2257                         ieee->softmac_stats.rx_ass_err++;
2258                         netdev_info(ieee->dev,
2259                                     "Association response status code 0x%x\n",
2260                                     errcode);
2261                         if (ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT)
2262                                 schedule_delayed_work(
2263                                          &ieee->associate_procedure_wq, 0);
2264                         else
2265                                 rtllib_associate_abort(ieee);
2266                 }
2267         }
2268         return 0;
2269 }
2270
2271 static void rtllib_rx_auth_resp(struct rtllib_device *ieee, struct sk_buff *skb)
2272 {
2273         int errcode;
2274         u8 *challenge;
2275         int chlen = 0;
2276         bool bSupportNmode = true, bHalfSupportNmode = false;
2277
2278         errcode = auth_parse(ieee->dev, skb, &challenge, &chlen);
2279
2280         if (errcode) {
2281                 ieee->softmac_stats.rx_auth_rs_err++;
2282                 netdev_info(ieee->dev,
2283                             "Authentication response status code %d", errcode);
2284                 rtllib_associate_abort(ieee);
2285                 return;
2286         }
2287
2288         if (ieee->open_wep || !challenge) {
2289                 ieee->state = RTLLIB_ASSOCIATING_AUTHENTICATED;
2290                 ieee->softmac_stats.rx_auth_rs_ok++;
2291                 if (!(ieee->ht_info->iot_action & HT_IOT_ACT_PURE_N_MODE)) {
2292                         if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) {
2293                                 if (IsHTHalfNmodeAPs(ieee)) {
2294                                         bSupportNmode = true;
2295                                         bHalfSupportNmode = true;
2296                                 } else {
2297                                         bSupportNmode = false;
2298                                         bHalfSupportNmode = false;
2299                                 }
2300                         }
2301                 }
2302                 /* Dummy wirless mode setting to avoid encryption issue */
2303                 if (bSupportNmode) {
2304                         ieee->SetWirelessMode(ieee->dev,
2305                                               ieee->current_network.mode);
2306                 } else {
2307                         /*TODO*/
2308                         ieee->SetWirelessMode(ieee->dev, IEEE_G);
2309                 }
2310
2311                 if ((ieee->current_network.mode == IEEE_N_24G) &&
2312                     bHalfSupportNmode) {
2313                         netdev_info(ieee->dev, "======>enter half N mode\n");
2314                         ieee->bHalfWirelessN24GMode = true;
2315                 } else {
2316                         ieee->bHalfWirelessN24GMode = false;
2317                 }
2318                 rtllib_associate_step2(ieee);
2319         } else {
2320                 rtllib_auth_challenge(ieee, challenge,  chlen);
2321         }
2322 }
2323
2324 static inline int
2325 rtllib_rx_auth(struct rtllib_device *ieee, struct sk_buff *skb,
2326                struct rtllib_rx_stats *rx_stats)
2327 {
2328
2329         if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) {
2330                 if (ieee->state == RTLLIB_ASSOCIATING_AUTHENTICATING &&
2331                     (ieee->iw_mode == IW_MODE_INFRA)) {
2332                         netdev_dbg(ieee->dev,
2333                                    "Received authentication response");
2334                         rtllib_rx_auth_resp(ieee, skb);
2335                 } else if (ieee->iw_mode == IW_MODE_MASTER) {
2336                         rtllib_rx_auth_rq(ieee, skb);
2337                 }
2338         }
2339         return 0;
2340 }
2341
2342 static inline int
2343 rtllib_rx_deauth(struct rtllib_device *ieee, struct sk_buff *skb)
2344 {
2345         struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *)skb->data;
2346         u16 frame_ctl;
2347
2348         if (memcmp(header->addr3, ieee->current_network.bssid, ETH_ALEN) != 0)
2349                 return 0;
2350
2351         /* FIXME for now repeat all the association procedure
2352          * both for disassociation and deauthentication
2353          */
2354         if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2355             ieee->state == RTLLIB_LINKED &&
2356             (ieee->iw_mode == IW_MODE_INFRA)) {
2357                 frame_ctl = le16_to_cpu(header->frame_ctl);
2358                 netdev_info(ieee->dev,
2359                             "==========>received disassoc/deauth(%x) frame, reason code:%x\n",
2360                             WLAN_FC_GET_STYPE(frame_ctl),
2361                             ((struct rtllib_disassoc *)skb->data)->reason);
2362                 ieee->state = RTLLIB_ASSOCIATING;
2363                 ieee->softmac_stats.reassoc++;
2364                 ieee->is_roaming = true;
2365                 ieee->link_detect_info.bBusyTraffic = false;
2366                 rtllib_disassociate(ieee);
2367                 RemovePeerTS(ieee, header->addr2);
2368                 if (ieee->LedControlHandler != NULL)
2369                         ieee->LedControlHandler(ieee->dev,
2370                                                 LED_CTL_START_TO_LINK);
2371
2372                 if (!(ieee->rtllib_ap_sec_type(ieee) &
2373                     (SEC_ALG_CCMP|SEC_ALG_TKIP)))
2374                         schedule_delayed_work(
2375                                        &ieee->associate_procedure_wq, 5);
2376         }
2377         return 0;
2378 }
2379
2380 inline int rtllib_rx_frame_softmac(struct rtllib_device *ieee,
2381                                    struct sk_buff *skb,
2382                                    struct rtllib_rx_stats *rx_stats, u16 type,
2383                                    u16 stype)
2384 {
2385         struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *)skb->data;
2386         u16 frame_ctl;
2387
2388         if (!ieee->proto_started)
2389                 return 0;
2390
2391         frame_ctl = le16_to_cpu(header->frame_ctl);
2392         switch (WLAN_FC_GET_STYPE(frame_ctl)) {
2393         case RTLLIB_STYPE_ASSOC_RESP:
2394         case RTLLIB_STYPE_REASSOC_RESP:
2395                 if (rtllib_rx_assoc_resp(ieee, skb, rx_stats) == 1)
2396                         return 1;
2397                 break;
2398         case RTLLIB_STYPE_ASSOC_REQ:
2399         case RTLLIB_STYPE_REASSOC_REQ:
2400                 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2401                      ieee->iw_mode == IW_MODE_MASTER)
2402                         rtllib_rx_assoc_rq(ieee, skb);
2403                 break;
2404         case RTLLIB_STYPE_AUTH:
2405                 rtllib_rx_auth(ieee, skb, rx_stats);
2406                 break;
2407         case RTLLIB_STYPE_DISASSOC:
2408         case RTLLIB_STYPE_DEAUTH:
2409                 rtllib_rx_deauth(ieee, skb);
2410                 break;
2411         case RTLLIB_STYPE_MANAGE_ACT:
2412                 rtllib_process_action(ieee, skb);
2413                 break;
2414         default:
2415                 return -1;
2416         }
2417         return 0;
2418 }
2419
2420 /* following are for a simpler TX queue management.
2421  * Instead of using netif_[stop/wake]_queue the driver
2422  * will use these two functions (plus a reset one), that
2423  * will internally use the kernel netif_* and takes
2424  * care of the ieee802.11 fragmentation.
2425  * So the driver receives a fragment per time and might
2426  * call the stop function when it wants to not
2427  * have enough room to TX an entire packet.
2428  * This might be useful if each fragment needs it's own
2429  * descriptor, thus just keep a total free memory > than
2430  * the max fragmentation threshold is not enough.. If the
2431  * ieee802.11 stack passed a TXB struct then you need
2432  * to keep N free descriptors where
2433  * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
2434  * In this way you need just one and the 802.11 stack
2435  * will take care of buffering fragments and pass them to
2436  * the driver later, when it wakes the queue.
2437  */
2438 void rtllib_softmac_xmit(struct rtllib_txb *txb, struct rtllib_device *ieee)
2439 {
2440
2441         unsigned int queue_index = txb->queue_index;
2442         unsigned long flags;
2443         int  i;
2444         struct cb_desc *tcb_desc = NULL;
2445         unsigned long queue_len = 0;
2446
2447         spin_lock_irqsave(&ieee->lock, flags);
2448
2449         /* called with 2nd parm 0, no tx mgmt lock required */
2450         rtllib_sta_wakeup(ieee, 0);
2451
2452         /* update the tx status */
2453         tcb_desc = (struct cb_desc *)(txb->fragments[0]->cb +
2454                    MAX_DEV_ADDR_SIZE);
2455         if (tcb_desc->bMulticast)
2456                 ieee->stats.multicast++;
2457
2458         /* if xmit available, just xmit it immediately, else just insert it to
2459          * the wait queue
2460          */
2461         for (i = 0; i < txb->nr_frags; i++) {
2462                 queue_len = skb_queue_len(&ieee->skb_waitQ[queue_index]);
2463                 if ((queue_len  != 0) ||
2464                     (!ieee->check_nic_enough_desc(ieee->dev, queue_index)) ||
2465                     (ieee->queue_stop)) {
2466                         /* insert the skb packet to the wait queue
2467                          * as for the completion function, it does not need
2468                          * to check it any more.
2469                          */
2470                         if (queue_len < 200)
2471                                 skb_queue_tail(&ieee->skb_waitQ[queue_index],
2472                                                txb->fragments[i]);
2473                         else
2474                                 kfree_skb(txb->fragments[i]);
2475                 } else {
2476                         ieee->softmac_data_hard_start_xmit(
2477                                         txb->fragments[i],
2478                                         ieee->dev, ieee->rate);
2479                 }
2480         }
2481
2482         rtllib_txb_free(txb);
2483
2484         spin_unlock_irqrestore(&ieee->lock, flags);
2485
2486 }
2487
2488 void rtllib_reset_queue(struct rtllib_device *ieee)
2489 {
2490         unsigned long flags;
2491
2492         spin_lock_irqsave(&ieee->lock, flags);
2493         init_mgmt_queue(ieee);
2494         if (ieee->tx_pending.txb) {
2495                 rtllib_txb_free(ieee->tx_pending.txb);
2496                 ieee->tx_pending.txb = NULL;
2497         }
2498         ieee->queue_stop = 0;
2499         spin_unlock_irqrestore(&ieee->lock, flags);
2500
2501 }
2502 EXPORT_SYMBOL(rtllib_reset_queue);
2503
2504 void rtllib_stop_all_queues(struct rtllib_device *ieee)
2505 {
2506         unsigned int i;
2507
2508         for (i = 0; i < ieee->dev->num_tx_queues; i++)
2509                 txq_trans_cond_update(netdev_get_tx_queue(ieee->dev, i));
2510
2511         netif_tx_stop_all_queues(ieee->dev);
2512 }
2513
2514 void rtllib_wake_all_queues(struct rtllib_device *ieee)
2515 {
2516         netif_tx_wake_all_queues(ieee->dev);
2517 }
2518
2519 /* called in user context only */
2520 static void rtllib_start_master_bss(struct rtllib_device *ieee)
2521 {
2522         ieee->assoc_id = 1;
2523
2524         if (ieee->current_network.ssid_len == 0) {
2525                 strncpy(ieee->current_network.ssid,
2526                         RTLLIB_DEFAULT_TX_ESSID,
2527                         IW_ESSID_MAX_SIZE);
2528
2529                 ieee->current_network.ssid_len =
2530                                  strlen(RTLLIB_DEFAULT_TX_ESSID);
2531                 ieee->ssid_set = 1;
2532         }
2533
2534         ether_addr_copy(ieee->current_network.bssid, ieee->dev->dev_addr);
2535
2536         ieee->set_chan(ieee->dev, ieee->current_network.channel);
2537         ieee->state = RTLLIB_LINKED;
2538         ieee->link_change(ieee->dev);
2539         notify_wx_assoc_event(ieee);
2540
2541         if (ieee->data_hard_resume)
2542                 ieee->data_hard_resume(ieee->dev);
2543
2544         netif_carrier_on(ieee->dev);
2545 }
2546
2547 static void rtllib_start_monitor_mode(struct rtllib_device *ieee)
2548 {
2549         /* reset hardware status */
2550         if (ieee->raw_tx) {
2551                 if (ieee->data_hard_resume)
2552                         ieee->data_hard_resume(ieee->dev);
2553
2554                 netif_carrier_on(ieee->dev);
2555         }
2556 }
2557
2558 static void rtllib_start_ibss_wq(void *data)
2559 {
2560         struct rtllib_device *ieee = container_of_dwork_rsl(data,
2561                                      struct rtllib_device, start_ibss_wq);
2562         /* iwconfig mode ad-hoc will schedule this and return
2563          * on the other hand this will block further iwconfig SET
2564          * operations because of the wx_mutex hold.
2565          * Anyway some most set operations set a flag to speed-up
2566          * (abort) this wq (when syncro scanning) before sleeping
2567          * on the mutex
2568          */
2569         if (!ieee->proto_started) {
2570                 netdev_info(ieee->dev, "==========oh driver down return\n");
2571                 return;
2572         }
2573         mutex_lock(&ieee->wx_mutex);
2574
2575         if (ieee->current_network.ssid_len == 0) {
2576                 strscpy(ieee->current_network.ssid, RTLLIB_DEFAULT_TX_ESSID,
2577                         sizeof(ieee->current_network.ssid));
2578                 ieee->current_network.ssid_len = strlen(RTLLIB_DEFAULT_TX_ESSID);
2579                 ieee->ssid_set = 1;
2580         }
2581
2582         ieee->state = RTLLIB_NOLINK;
2583         ieee->mode = IEEE_G;
2584         /* check if we have this cell in our network list */
2585         rtllib_softmac_check_all_nets(ieee);
2586
2587
2588         /* if not then the state is not linked. Maybe the user switched to
2589          * ad-hoc mode just after being in monitor mode, or just after
2590          * being very few time in managed mode (so the card have had no
2591          * time to scan all the chans..) or we have just run up the iface
2592          * after setting ad-hoc mode. So we have to give another try..
2593          * Here, in ibss mode, should be safe to do this without extra care
2594          * (in bss mode we had to make sure no-one tried to associate when
2595          * we had just checked the ieee->state and we was going to start the
2596          * scan) because in ibss mode the rtllib_new_net function, when
2597          * finds a good net, just set the ieee->state to RTLLIB_LINKED,
2598          * so, at worst, we waste a bit of time to initiate an unneeded syncro
2599          * scan, that will stop at the first round because it sees the state
2600          * associated.
2601          */
2602         if (ieee->state == RTLLIB_NOLINK)
2603                 rtllib_start_scan_syncro(ieee, 0);
2604
2605         /* the network definitively is not here.. create a new cell */
2606         if (ieee->state == RTLLIB_NOLINK) {
2607                 netdev_info(ieee->dev, "creating new IBSS cell\n");
2608                 ieee->current_network.channel = ieee->bss_start_channel;
2609                 if (!ieee->wap_set)
2610                         eth_random_addr(ieee->current_network.bssid);
2611
2612                 if (ieee->modulation & RTLLIB_CCK_MODULATION) {
2613
2614                         ieee->current_network.rates_len = 4;
2615
2616                         ieee->current_network.rates[0] =
2617                                  RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_1MB;
2618                         ieee->current_network.rates[1] =
2619                                  RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_2MB;
2620                         ieee->current_network.rates[2] =
2621                                  RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_5MB;
2622                         ieee->current_network.rates[3] =
2623                                  RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_11MB;
2624
2625                 } else
2626                         ieee->current_network.rates_len = 0;
2627
2628                 if (ieee->modulation & RTLLIB_OFDM_MODULATION) {
2629                         ieee->current_network.rates_ex_len = 8;
2630
2631                         ieee->current_network.rates_ex[0] =
2632                                                  RTLLIB_OFDM_RATE_6MB;
2633                         ieee->current_network.rates_ex[1] =
2634                                                  RTLLIB_OFDM_RATE_9MB;
2635                         ieee->current_network.rates_ex[2] =
2636                                                  RTLLIB_OFDM_RATE_12MB;
2637                         ieee->current_network.rates_ex[3] =
2638                                                  RTLLIB_OFDM_RATE_18MB;
2639                         ieee->current_network.rates_ex[4] =
2640                                                  RTLLIB_OFDM_RATE_24MB;
2641                         ieee->current_network.rates_ex[5] =
2642                                                  RTLLIB_OFDM_RATE_36MB;
2643                         ieee->current_network.rates_ex[6] =
2644                                                  RTLLIB_OFDM_RATE_48MB;
2645                         ieee->current_network.rates_ex[7] =
2646                                                  RTLLIB_OFDM_RATE_54MB;
2647
2648                         ieee->rate = 108;
2649                 } else {
2650                         ieee->current_network.rates_ex_len = 0;
2651                         ieee->rate = 22;
2652                 }
2653
2654                 ieee->current_network.qos_data.supported = 0;
2655                 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2656                 ieee->current_network.mode = ieee->mode;
2657                 ieee->current_network.atim_window = 0;
2658                 ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
2659         }
2660
2661         netdev_info(ieee->dev, "%s(): ieee->mode = %d\n", __func__, ieee->mode);
2662         if ((ieee->mode == IEEE_N_24G) || (ieee->mode == IEEE_N_5G))
2663                 HTUseDefaultSetting(ieee);
2664         else
2665                 ieee->ht_info->bCurrentHTSupport = false;
2666
2667         ieee->SetHwRegHandler(ieee->dev, HW_VAR_MEDIA_STATUS,
2668                               (u8 *)(&ieee->state));
2669
2670         ieee->state = RTLLIB_LINKED;
2671         ieee->link_change(ieee->dev);
2672
2673         HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2674         if (ieee->LedControlHandler != NULL)
2675                 ieee->LedControlHandler(ieee->dev, LED_CTL_LINK);
2676
2677         rtllib_start_send_beacons(ieee);
2678
2679         notify_wx_assoc_event(ieee);
2680
2681         if (ieee->data_hard_resume)
2682                 ieee->data_hard_resume(ieee->dev);
2683
2684         netif_carrier_on(ieee->dev);
2685
2686         mutex_unlock(&ieee->wx_mutex);
2687 }
2688
2689 inline void rtllib_start_ibss(struct rtllib_device *ieee)
2690 {
2691         schedule_delayed_work(&ieee->start_ibss_wq, msecs_to_jiffies(150));
2692 }
2693
2694 /* this is called only in user context, with wx_mutex held */
2695 static void rtllib_start_bss(struct rtllib_device *ieee)
2696 {
2697         unsigned long flags;
2698
2699         if (IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee)) {
2700                 if (!ieee->global_domain)
2701                         return;
2702         }
2703         /* check if we have already found the net we
2704          * are interested in (if any).
2705          * if not (we are disassociated and we are not
2706          * in associating / authenticating phase) start the background scanning.
2707          */
2708         rtllib_softmac_check_all_nets(ieee);
2709
2710         /* ensure no-one start an associating process (thus setting
2711          * the ieee->state to rtllib_ASSOCIATING) while we
2712          * have just checked it and we are going to enable scan.
2713          * The rtllib_new_net function is always called with
2714          * lock held (from both rtllib_softmac_check_all_nets and
2715          * the rx path), so we cannot be in the middle of such function
2716          */
2717         spin_lock_irqsave(&ieee->lock, flags);
2718
2719         if (ieee->state == RTLLIB_NOLINK)
2720                 rtllib_start_scan(ieee);
2721         spin_unlock_irqrestore(&ieee->lock, flags);
2722 }
2723
2724 static void rtllib_link_change_wq(void *data)
2725 {
2726         struct rtllib_device *ieee = container_of_dwork_rsl(data,
2727                                      struct rtllib_device, link_change_wq);
2728         ieee->link_change(ieee->dev);
2729 }
2730 /* called only in userspace context */
2731 void rtllib_disassociate(struct rtllib_device *ieee)
2732 {
2733         netif_carrier_off(ieee->dev);
2734         if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
2735                 rtllib_reset_queue(ieee);
2736
2737         if (ieee->data_hard_stop)
2738                 ieee->data_hard_stop(ieee->dev);
2739         if (IS_DOT11D_ENABLE(ieee))
2740                 dot11d_reset(ieee);
2741         ieee->state = RTLLIB_NOLINK;
2742         ieee->is_set_key = false;
2743         ieee->wap_set = 0;
2744
2745         schedule_delayed_work(&ieee->link_change_wq, 0);
2746
2747         notify_wx_assoc_event(ieee);
2748 }
2749
2750 static void rtllib_associate_retry_wq(void *data)
2751 {
2752         struct rtllib_device *ieee = container_of_dwork_rsl(data,
2753                                      struct rtllib_device, associate_retry_wq);
2754         unsigned long flags;
2755
2756         mutex_lock(&ieee->wx_mutex);
2757         if (!ieee->proto_started)
2758                 goto exit;
2759
2760         if (ieee->state != RTLLIB_ASSOCIATING_RETRY)
2761                 goto exit;
2762
2763         /* until we do not set the state to RTLLIB_NOLINK
2764          * there are no possibility to have someone else trying
2765          * to start an association procedure (we get here with
2766          * ieee->state = RTLLIB_ASSOCIATING).
2767          * When we set the state to RTLLIB_NOLINK it is possible
2768          * that the RX path run an attempt to associate, but
2769          * both rtllib_softmac_check_all_nets and the
2770          * RX path works with ieee->lock held so there are no
2771          * problems. If we are still disassociated then start a scan.
2772          * the lock here is necessary to ensure no one try to start
2773          * an association procedure when we have just checked the
2774          * state and we are going to start the scan.
2775          */
2776         ieee->beinretry = true;
2777         ieee->state = RTLLIB_NOLINK;
2778
2779         rtllib_softmac_check_all_nets(ieee);
2780
2781         spin_lock_irqsave(&ieee->lock, flags);
2782
2783         if (ieee->state == RTLLIB_NOLINK)
2784                 rtllib_start_scan(ieee);
2785         spin_unlock_irqrestore(&ieee->lock, flags);
2786
2787         ieee->beinretry = false;
2788 exit:
2789         mutex_unlock(&ieee->wx_mutex);
2790 }
2791
2792 static struct sk_buff *rtllib_get_beacon_(struct rtllib_device *ieee)
2793 {
2794         static const u8 broadcast_addr[] = {
2795                 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2796         };
2797         struct sk_buff *skb;
2798         struct rtllib_probe_response *b;
2799
2800         skb = rtllib_probe_resp(ieee, broadcast_addr);
2801
2802         if (!skb)
2803                 return NULL;
2804
2805         b = (struct rtllib_probe_response *)skb->data;
2806         b->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_BEACON);
2807
2808         return skb;
2809
2810 }
2811
2812 struct sk_buff *rtllib_get_beacon(struct rtllib_device *ieee)
2813 {
2814         struct sk_buff *skb;
2815         struct rtllib_probe_response *b;
2816
2817         skb = rtllib_get_beacon_(ieee);
2818         if (!skb)
2819                 return NULL;
2820
2821         b = (struct rtllib_probe_response *)skb->data;
2822         b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2823
2824         if (ieee->seq_ctrl[0] == 0xFFF)
2825                 ieee->seq_ctrl[0] = 0;
2826         else
2827                 ieee->seq_ctrl[0]++;
2828
2829         return skb;
2830 }
2831 EXPORT_SYMBOL(rtllib_get_beacon);
2832
2833 void rtllib_softmac_stop_protocol(struct rtllib_device *ieee, u8 mesh_flag,
2834                                   u8 shutdown)
2835 {
2836         rtllib_stop_scan_syncro(ieee);
2837         mutex_lock(&ieee->wx_mutex);
2838         rtllib_stop_protocol(ieee, shutdown);
2839         mutex_unlock(&ieee->wx_mutex);
2840 }
2841 EXPORT_SYMBOL(rtllib_softmac_stop_protocol);
2842
2843
2844 void rtllib_stop_protocol(struct rtllib_device *ieee, u8 shutdown)
2845 {
2846         if (!ieee->proto_started)
2847                 return;
2848
2849         if (shutdown) {
2850                 ieee->proto_started = 0;
2851                 ieee->proto_stoppping = 1;
2852                 ieee->rtllib_ips_leave(ieee->dev);
2853         }
2854
2855         rtllib_stop_send_beacons(ieee);
2856         del_timer_sync(&ieee->associate_timer);
2857         cancel_delayed_work_sync(&ieee->associate_retry_wq);
2858         cancel_delayed_work_sync(&ieee->start_ibss_wq);
2859         cancel_delayed_work_sync(&ieee->link_change_wq);
2860         rtllib_stop_scan(ieee);
2861
2862         if (ieee->state <= RTLLIB_ASSOCIATING_AUTHENTICATED)
2863                 ieee->state = RTLLIB_NOLINK;
2864
2865         if (ieee->state == RTLLIB_LINKED) {
2866                 if (ieee->iw_mode == IW_MODE_INFRA)
2867                         SendDisassociation(ieee, 1, WLAN_REASON_DEAUTH_LEAVING);
2868                 rtllib_disassociate(ieee);
2869         }
2870
2871         if (shutdown) {
2872                 RemoveAllTS(ieee);
2873                 ieee->proto_stoppping = 0;
2874         }
2875         kfree(ieee->assocreq_ies);
2876         ieee->assocreq_ies = NULL;
2877         ieee->assocreq_ies_len = 0;
2878         kfree(ieee->assocresp_ies);
2879         ieee->assocresp_ies = NULL;
2880         ieee->assocresp_ies_len = 0;
2881 }
2882
2883 void rtllib_softmac_start_protocol(struct rtllib_device *ieee, u8 mesh_flag)
2884 {
2885         mutex_lock(&ieee->wx_mutex);
2886         rtllib_start_protocol(ieee);
2887         mutex_unlock(&ieee->wx_mutex);
2888 }
2889 EXPORT_SYMBOL(rtllib_softmac_start_protocol);
2890
2891 void rtllib_start_protocol(struct rtllib_device *ieee)
2892 {
2893         short ch = 0;
2894         int i = 0;
2895
2896         rtllib_update_active_chan_map(ieee);
2897
2898         if (ieee->proto_started)
2899                 return;
2900
2901         ieee->proto_started = 1;
2902
2903         if (ieee->current_network.channel == 0) {
2904                 do {
2905                         ch++;
2906                         if (ch > MAX_CHANNEL_NUMBER)
2907                                 return; /* no channel found */
2908                 } while (!ieee->active_channel_map[ch]);
2909                 ieee->current_network.channel = ch;
2910         }
2911
2912         if (ieee->current_network.beacon_interval == 0)
2913                 ieee->current_network.beacon_interval = 100;
2914
2915         for (i = 0; i < 17; i++) {
2916                 ieee->last_rxseq_num[i] = -1;
2917                 ieee->last_rxfrag_num[i] = -1;
2918                 ieee->last_packet_time[i] = 0;
2919         }
2920
2921         if (ieee->UpdateBeaconInterruptHandler)
2922                 ieee->UpdateBeaconInterruptHandler(ieee->dev, false);
2923
2924         ieee->wmm_acm = 0;
2925         /* if the user set the MAC of the ad-hoc cell and then
2926          * switch to managed mode, shall we  make sure that association
2927          * attempts does not fail just because the user provide the essid
2928          * and the nic is still checking for the AP MAC ??
2929          */
2930         if (ieee->iw_mode == IW_MODE_INFRA) {
2931                 rtllib_start_bss(ieee);
2932         } else if (ieee->iw_mode == IW_MODE_ADHOC) {
2933                 if (ieee->UpdateBeaconInterruptHandler)
2934                         ieee->UpdateBeaconInterruptHandler(ieee->dev, true);
2935
2936                 rtllib_start_ibss(ieee);
2937
2938         } else if (ieee->iw_mode == IW_MODE_MASTER) {
2939                 rtllib_start_master_bss(ieee);
2940         } else if (ieee->iw_mode == IW_MODE_MONITOR) {
2941                 rtllib_start_monitor_mode(ieee);
2942         }
2943 }
2944
2945 int rtllib_softmac_init(struct rtllib_device *ieee)
2946 {
2947         int i;
2948
2949         memset(&ieee->current_network, 0, sizeof(struct rtllib_network));
2950
2951         ieee->state = RTLLIB_NOLINK;
2952         for (i = 0; i < 5; i++)
2953                 ieee->seq_ctrl[i] = 0;
2954         ieee->dot11d_info = kzalloc(sizeof(struct rt_dot11d_info), GFP_ATOMIC);
2955         if (!ieee->dot11d_info)
2956                 return -ENOMEM;
2957
2958         ieee->link_detect_info.SlotIndex = 0;
2959         ieee->link_detect_info.SlotNum = 2;
2960         ieee->link_detect_info.NumRecvBcnInPeriod = 0;
2961         ieee->link_detect_info.NumRecvDataInPeriod = 0;
2962         ieee->link_detect_info.NumTxOkInPeriod = 0;
2963         ieee->link_detect_info.NumRxOkInPeriod = 0;
2964         ieee->link_detect_info.NumRxUnicastOkInPeriod = 0;
2965         ieee->bIsAggregateFrame = false;
2966         ieee->assoc_id = 0;
2967         ieee->queue_stop = 0;
2968         ieee->scanning_continue = 0;
2969         ieee->softmac_features = 0;
2970         ieee->wap_set = 0;
2971         ieee->ssid_set = 0;
2972         ieee->proto_started = 0;
2973         ieee->proto_stoppping = 0;
2974         ieee->basic_rate = RTLLIB_DEFAULT_BASIC_RATE;
2975         ieee->rate = 22;
2976         ieee->ps = RTLLIB_PS_DISABLED;
2977         ieee->sta_sleep = LPS_IS_WAKE;
2978
2979         ieee->reg_dot11ht_oper_rate_set[0] = 0xff;
2980         ieee->reg_dot11ht_oper_rate_set[1] = 0xff;
2981         ieee->reg_dot11ht_oper_rate_set[4] = 0x01;
2982
2983         ieee->reg_dot11tx_ht_oper_rate_set[0] = 0xff;
2984         ieee->reg_dot11tx_ht_oper_rate_set[1] = 0xff;
2985         ieee->reg_dot11tx_ht_oper_rate_set[4] = 0x01;
2986
2987         ieee->FirstIe_InScan = false;
2988         ieee->actscanning = false;
2989         ieee->beinretry = false;
2990         ieee->is_set_key = false;
2991         init_mgmt_queue(ieee);
2992
2993         ieee->tx_pending.txb = NULL;
2994
2995         timer_setup(&ieee->associate_timer, rtllib_associate_abort_cb, 0);
2996
2997         timer_setup(&ieee->beacon_timer, rtllib_send_beacon_cb, 0);
2998
2999         INIT_DELAYED_WORK(&ieee->link_change_wq, (void *)rtllib_link_change_wq);
3000         INIT_DELAYED_WORK(&ieee->start_ibss_wq, (void *)rtllib_start_ibss_wq);
3001         INIT_WORK(&ieee->associate_complete_wq, (void *)rtllib_associate_complete_wq);
3002         INIT_DELAYED_WORK(&ieee->associate_procedure_wq, (void *)rtllib_associate_procedure_wq);
3003         INIT_DELAYED_WORK(&ieee->softmac_scan_wq, (void *)rtllib_softmac_scan_wq);
3004         INIT_DELAYED_WORK(&ieee->associate_retry_wq, (void *)rtllib_associate_retry_wq);
3005         INIT_WORK(&ieee->wx_sync_scan_wq, (void *)rtllib_wx_sync_scan_wq);
3006
3007         mutex_init(&ieee->wx_mutex);
3008         mutex_init(&ieee->scan_mutex);
3009         mutex_init(&ieee->ips_mutex);
3010
3011         spin_lock_init(&ieee->mgmt_tx_lock);
3012         spin_lock_init(&ieee->beacon_lock);
3013
3014         INIT_WORK(&ieee->ps_task, rtllib_sta_ps);
3015
3016         return 0;
3017 }
3018
3019 void rtllib_softmac_free(struct rtllib_device *ieee)
3020 {
3021         mutex_lock(&ieee->wx_mutex);
3022         kfree(ieee->dot11d_info);
3023         ieee->dot11d_info = NULL;
3024         del_timer_sync(&ieee->associate_timer);
3025
3026         cancel_delayed_work_sync(&ieee->associate_retry_wq);
3027         cancel_delayed_work_sync(&ieee->associate_procedure_wq);
3028         cancel_delayed_work_sync(&ieee->softmac_scan_wq);
3029         cancel_delayed_work_sync(&ieee->start_ibss_wq);
3030         cancel_delayed_work_sync(&ieee->hw_wakeup_wq);
3031         cancel_delayed_work_sync(&ieee->hw_sleep_wq);
3032         cancel_delayed_work_sync(&ieee->link_change_wq);
3033         cancel_work_sync(&ieee->associate_complete_wq);
3034         cancel_work_sync(&ieee->ips_leave_wq);
3035         cancel_work_sync(&ieee->wx_sync_scan_wq);
3036         cancel_work_sync(&ieee->ps_task);
3037         mutex_unlock(&ieee->wx_mutex);
3038 }
3039
3040 static inline struct sk_buff *
3041 rtllib_disauth_skb(struct rtllib_network *beacon,
3042                    struct rtllib_device *ieee, u16 asRsn)
3043 {
3044         struct sk_buff *skb;
3045         struct rtllib_disauth *disauth;
3046         int len = sizeof(struct rtllib_disauth) + ieee->tx_headroom;
3047
3048         skb = dev_alloc_skb(len);
3049         if (!skb)
3050                 return NULL;
3051
3052         skb_reserve(skb, ieee->tx_headroom);
3053
3054         disauth = skb_put(skb, sizeof(struct rtllib_disauth));
3055         disauth->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_DEAUTH);
3056         disauth->header.duration_id = 0;
3057
3058         ether_addr_copy(disauth->header.addr1, beacon->bssid);
3059         ether_addr_copy(disauth->header.addr2, ieee->dev->dev_addr);
3060         ether_addr_copy(disauth->header.addr3, beacon->bssid);
3061
3062         disauth->reason = cpu_to_le16(asRsn);
3063         return skb;
3064 }
3065
3066 static inline struct sk_buff *
3067 rtllib_disassociate_skb(struct rtllib_network *beacon,
3068                         struct rtllib_device *ieee, u16 asRsn)
3069 {
3070         struct sk_buff *skb;
3071         struct rtllib_disassoc *disass;
3072         int len = sizeof(struct rtllib_disassoc) + ieee->tx_headroom;
3073
3074         skb = dev_alloc_skb(len);
3075
3076         if (!skb)
3077                 return NULL;
3078
3079         skb_reserve(skb, ieee->tx_headroom);
3080
3081         disass = skb_put(skb, sizeof(struct rtllib_disassoc));
3082         disass->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_DISASSOC);
3083         disass->header.duration_id = 0;
3084
3085         ether_addr_copy(disass->header.addr1, beacon->bssid);
3086         ether_addr_copy(disass->header.addr2, ieee->dev->dev_addr);
3087         ether_addr_copy(disass->header.addr3, beacon->bssid);
3088
3089         disass->reason = cpu_to_le16(asRsn);
3090         return skb;
3091 }
3092
3093 void SendDisassociation(struct rtllib_device *ieee, bool deauth, u16 asRsn)
3094 {
3095         struct rtllib_network *beacon = &ieee->current_network;
3096         struct sk_buff *skb;
3097
3098         if (deauth)
3099                 skb = rtllib_disauth_skb(beacon, ieee, asRsn);
3100         else
3101                 skb = rtllib_disassociate_skb(beacon, ieee, asRsn);
3102
3103         if (skb)
3104                 softmac_mgmt_xmit(skb, ieee);
3105 }
3106
3107 u8 rtllib_ap_sec_type(struct rtllib_device *ieee)
3108 {
3109         static u8 ccmp_ie[4] = {0x00, 0x50, 0xf2, 0x04};
3110         static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
3111         int wpa_ie_len = ieee->wpa_ie_len;
3112         struct lib80211_crypt_data *crypt;
3113         int encrypt;
3114
3115         crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
3116         encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY)
3117                   || (ieee->host_encrypt && crypt && crypt->ops &&
3118                   (strcmp(crypt->ops->name, "R-WEP") == 0));
3119
3120         /* simply judge  */
3121         if (encrypt && (wpa_ie_len == 0)) {
3122                 return SEC_ALG_WEP;
3123         } else if ((wpa_ie_len != 0)) {
3124                 if (((ieee->wpa_ie[0] == 0xdd) &&
3125                     (!memcmp(&(ieee->wpa_ie[14]), ccmp_ie, 4))) ||
3126                     ((ieee->wpa_ie[0] == 0x30) &&
3127                     (!memcmp(&ieee->wpa_ie[10], ccmp_rsn_ie, 4))))
3128                         return SEC_ALG_CCMP;
3129                 else
3130                         return SEC_ALG_TKIP;
3131         } else {
3132                 return SEC_ALG_NONE;
3133         }
3134 }
3135
3136 static void rtllib_MgntDisconnectIBSS(struct rtllib_device *rtllib)
3137 {
3138         u8      OpMode;
3139         u8      i;
3140         bool    bFilterOutNonAssociatedBSSID = false;
3141
3142         rtllib->state = RTLLIB_NOLINK;
3143
3144         for (i = 0; i < 6; i++)
3145                 rtllib->current_network.bssid[i] = 0x55;
3146
3147         rtllib->OpMode = RT_OP_MODE_NO_LINK;
3148         rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_BSSID,
3149                                 rtllib->current_network.bssid);
3150         OpMode = RT_OP_MODE_NO_LINK;
3151         rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_MEDIA_STATUS, &OpMode);
3152         rtllib_stop_send_beacons(rtllib);
3153
3154         bFilterOutNonAssociatedBSSID = false;
3155         rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_CECHK_BSSID,
3156                                 (u8 *)(&bFilterOutNonAssociatedBSSID));
3157         notify_wx_assoc_event(rtllib);
3158
3159 }
3160
3161 static void rtllib_MlmeDisassociateRequest(struct rtllib_device *rtllib,
3162                                            u8 *asSta, u8 asRsn)
3163 {
3164         u8 i;
3165         u8      OpMode;
3166
3167         RemovePeerTS(rtllib, asSta);
3168
3169         if (memcmp(rtllib->current_network.bssid, asSta, 6) == 0) {
3170                 rtllib->state = RTLLIB_NOLINK;
3171
3172                 for (i = 0; i < 6; i++)
3173                         rtllib->current_network.bssid[i] = 0x22;
3174                 OpMode = RT_OP_MODE_NO_LINK;
3175                 rtllib->OpMode = RT_OP_MODE_NO_LINK;
3176                 rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_MEDIA_STATUS,
3177                                         (u8 *)(&OpMode));
3178                 rtllib_disassociate(rtllib);
3179
3180                 rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_BSSID,
3181                                         rtllib->current_network.bssid);
3182
3183         }
3184
3185 }
3186
3187 static void
3188 rtllib_MgntDisconnectAP(
3189         struct rtllib_device *rtllib,
3190         u8 asRsn
3191 )
3192 {
3193         bool bFilterOutNonAssociatedBSSID = false;
3194
3195         bFilterOutNonAssociatedBSSID = false;
3196         rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_CECHK_BSSID,
3197                                 (u8 *)(&bFilterOutNonAssociatedBSSID));
3198         rtllib_MlmeDisassociateRequest(rtllib, rtllib->current_network.bssid,
3199                                        asRsn);
3200
3201         rtllib->state = RTLLIB_NOLINK;
3202 }
3203
3204 bool rtllib_MgntDisconnect(struct rtllib_device *rtllib, u8 asRsn)
3205 {
3206         if (rtllib->ps != RTLLIB_PS_DISABLED)
3207                 rtllib->sta_wake_up(rtllib->dev);
3208
3209         if (rtllib->state == RTLLIB_LINKED) {
3210                 if (rtllib->iw_mode == IW_MODE_ADHOC)
3211                         rtllib_MgntDisconnectIBSS(rtllib);
3212                 if (rtllib->iw_mode == IW_MODE_INFRA)
3213                         rtllib_MgntDisconnectAP(rtllib, asRsn);
3214
3215         }
3216
3217         return true;
3218 }
3219 EXPORT_SYMBOL(rtllib_MgntDisconnect);
3220
3221 void notify_wx_assoc_event(struct rtllib_device *ieee)
3222 {
3223         union iwreq_data wrqu;
3224
3225         if (ieee->cannot_notify)
3226                 return;
3227
3228         wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3229         if (ieee->state == RTLLIB_LINKED)
3230                 memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid,
3231                        ETH_ALEN);
3232         else {
3233
3234                 netdev_info(ieee->dev, "%s(): Tell user space disconnected\n",
3235                             __func__);
3236                 eth_zero_addr(wrqu.ap_addr.sa_data);
3237         }
3238         wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
3239 }
3240 EXPORT_SYMBOL(notify_wx_assoc_event);
This page took 0.229696 seconds and 4 git commands to generate.