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