1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include "ieee80211.h"
18
19#include <linux/random.h>
20#include <linux/delay.h>
21#include <linux/slab.h>
22#include <asm/uaccess.h>
23#include <linux/etherdevice.h>
24
25#include "dot11d.h"
26
27u8 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
36short ieee80211_is_54g(const struct ieee80211_network *net)
37{
38 return (net->rates_ex_len > 0) || (net->rates_len > 4);
39}
40
41short ieee80211_is_shortslot(const struct ieee80211_network *net)
42{
43 return net->capability & WLAN_CAPABILITY_SHORT_SLOT;
44}
45
46
47
48
49
50unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
51{
52 unsigned int rate_len = 0;
53
54 if (ieee->modulation & IEEE80211_CCK_MODULATION)
55 rate_len = IEEE80211_CCK_RATE_LEN + 2;
56
57 if (ieee->modulation & IEEE80211_OFDM_MODULATION)
58
59 rate_len += IEEE80211_OFDM_RATE_LEN + 2;
60
61 return rate_len;
62}
63
64
65
66
67
68void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
69{
70 u8 *tag = *tag_p;
71
72 if (ieee->modulation & IEEE80211_CCK_MODULATION){
73 *tag++ = MFIE_TYPE_RATES;
74 *tag++ = 4;
75 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
76 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
77 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
78 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
79 }
80
81
82 *tag_p = tag;
83}
84
85void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
86{
87 u8 *tag = *tag_p;
88
89 if (ieee->modulation & IEEE80211_OFDM_MODULATION){
90
91 *tag++ = MFIE_TYPE_RATES_EX;
92 *tag++ = 8;
93 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
94 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
95 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
96 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
97 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
98 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
99 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
100 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
101
102 }
103
104
105 *tag_p = tag;
106}
107
108
109void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) {
110 u8 *tag = *tag_p;
111
112 *tag++ = MFIE_TYPE_GENERIC;
113 *tag++ = 7;
114 *tag++ = 0x00;
115 *tag++ = 0x50;
116 *tag++ = 0xf2;
117 *tag++ = 0x02;
118 *tag++ = 0x00;
119 *tag++ = 0x01;
120#ifdef SUPPORT_USPD
121 if(ieee->current_network.wmm_info & 0x80) {
122 *tag++ = 0x0f|MAX_SP_Len;
123 } else {
124 *tag++ = MAX_SP_Len;
125 }
126#else
127 *tag++ = MAX_SP_Len;
128#endif
129 *tag_p = tag;
130}
131
132#ifdef THOMAS_TURBO
133void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
134 u8 *tag = *tag_p;
135
136 *tag++ = MFIE_TYPE_GENERIC;
137 *tag++ = 7;
138 *tag++ = 0x00;
139 *tag++ = 0xe0;
140 *tag++ = 0x4c;
141 *tag++ = 0x01;
142 *tag++ = 0x02;
143 *tag++ = 0x11;
144 *tag++ = 0x00;
145
146 *tag_p = tag;
147 printk(KERN_ALERT "This is enable turbo mode IE process\n");
148}
149#endif
150
151void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
152{
153 int nh;
154 nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
155
156
157
158
159
160
161
162
163 ieee->mgmt_queue_head = nh;
164 ieee->mgmt_queue_ring[nh] = skb;
165
166
167}
168
169struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
170{
171 struct sk_buff *ret;
172
173 if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
174 return NULL;
175
176 ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
177
178 ieee->mgmt_queue_tail =
179 (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
180
181 return ret;
182}
183
184void init_mgmt_queue(struct ieee80211_device *ieee)
185{
186 ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
187}
188
189u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee)
190{
191 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
192 u8 rate;
193
194
195 if(pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M)
196 rate = 0x0c;
197 else
198 rate = ieee->basic_rate & 0x7f;
199
200 if(rate == 0){
201
202 if(ieee->mode == IEEE_A||
203 ieee->mode== IEEE_N_5G||
204 (ieee->mode== IEEE_N_24G&&!pHTInfo->bCurSuppCCK))
205 rate = 0x0c;
206 else
207 rate = 0x02;
208 }
209
210
211
212
213
214
215
216
217
218
219
220 return rate;
221}
222
223
224void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
225
226inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
227{
228 unsigned long flags;
229 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
230 struct ieee80211_hdr_3addr *header=
231 (struct ieee80211_hdr_3addr *) skb->data;
232
233 cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8);
234 spin_lock_irqsave(&ieee->lock, flags);
235
236
237 ieee80211_sta_wakeup(ieee,0);
238
239 tcb_desc->queue_index = MGNT_QUEUE;
240 tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
241 tcb_desc->RATRIndex = 7;
242 tcb_desc->bTxDisableRateFallBack = 1;
243 tcb_desc->bTxUseDriverAssingedRate = 1;
244
245 if(single){
246 if(ieee->queue_stop){
247 enqueue_mgmt(ieee,skb);
248 }else{
249 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
250
251 if (ieee->seq_ctrl[0] == 0xFFF)
252 ieee->seq_ctrl[0] = 0;
253 else
254 ieee->seq_ctrl[0]++;
255
256
257 ieee->dev->trans_start = jiffies;
258 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
259
260 }
261
262 spin_unlock_irqrestore(&ieee->lock, flags);
263 }else{
264 spin_unlock_irqrestore(&ieee->lock, flags);
265 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
266
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
275 if(!ieee->check_nic_enough_desc(ieee->dev,tcb_desc->queue_index)||\
276 (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)||\
277 (ieee->queue_stop) ) {
278
279
280
281
282 printk("%s():insert to waitqueue!\n",__FUNCTION__);
283 skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb);
284 } else {
285
286 ieee->softmac_hard_start_xmit(skb,ieee->dev);
287
288 }
289 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
290 }
291}
292
293inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
294{
295
296 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
297 struct ieee80211_hdr_3addr *header =
298 (struct ieee80211_hdr_3addr *) skb->data;
299
300
301 if(single){
302
303 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
304
305 if (ieee->seq_ctrl[0] == 0xFFF)
306 ieee->seq_ctrl[0] = 0;
307 else
308 ieee->seq_ctrl[0]++;
309
310
311 ieee->dev->trans_start = jiffies;
312 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
313
314 }else{
315
316 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
317
318 if (ieee->seq_ctrl[0] == 0xFFF)
319 ieee->seq_ctrl[0] = 0;
320 else
321 ieee->seq_ctrl[0]++;
322
323 ieee->softmac_hard_start_xmit(skb,ieee->dev);
324
325 }
326
327}
328
329inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
330{
331 unsigned int len,rate_len;
332 u8 *tag;
333 struct sk_buff *skb;
334 struct ieee80211_probe_request *req;
335
336 len = ieee->current_network.ssid_len;
337
338 rate_len = ieee80211_MFIE_rate_len(ieee);
339
340 skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
341 2 + len + rate_len + ieee->tx_headroom);
342 if (!skb)
343 return NULL;
344
345 skb_reserve(skb, ieee->tx_headroom);
346
347 req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
348 req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
349 req->header.duration_id = 0;
350
351 memset(req->header.addr1, 0xff, ETH_ALEN);
352 memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
353 memset(req->header.addr3, 0xff, ETH_ALEN);
354
355 tag = (u8 *) skb_put(skb,len+2+rate_len);
356
357 *tag++ = MFIE_TYPE_SSID;
358 *tag++ = len;
359 memcpy(tag, ieee->current_network.ssid, len);
360 tag += len;
361
362 ieee80211_MFIE_Brate(ieee,&tag);
363 ieee80211_MFIE_Grate(ieee,&tag);
364 return skb;
365}
366
367struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
368void ieee80211_send_beacon(struct ieee80211_device *ieee)
369{
370 struct sk_buff *skb;
371 if(!ieee->ieee_up)
372 return;
373
374 skb = ieee80211_get_beacon_(ieee);
375
376 if (skb){
377 softmac_mgmt_xmit(skb, ieee);
378 ieee->softmac_stats.tx_beacons++;
379
380 }
381
382
383
384
385 if(ieee->beacon_txing && ieee->ieee_up){
386
387
388 mod_timer(&ieee->beacon_timer,jiffies+(MSECS(ieee->current_network.beacon_interval-5)));
389 }
390
391}
392
393
394void ieee80211_send_beacon_cb(unsigned long _ieee)
395{
396 struct ieee80211_device *ieee =
397 (struct ieee80211_device *) _ieee;
398 unsigned long flags;
399
400 spin_lock_irqsave(&ieee->beacon_lock, flags);
401 ieee80211_send_beacon(ieee);
402 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
403}
404
405
406void ieee80211_send_probe(struct ieee80211_device *ieee)
407{
408 struct sk_buff *skb;
409
410 skb = ieee80211_probe_req(ieee);
411 if (skb){
412 softmac_mgmt_xmit(skb, ieee);
413 ieee->softmac_stats.tx_probe_rq++;
414
415 }
416}
417
418void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
419{
420 if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){
421 ieee80211_send_probe(ieee);
422 ieee80211_send_probe(ieee);
423 }
424}
425
426
427
428
429void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
430{
431 short ch = 0;
432 u8 channel_map[MAX_CHANNEL_NUMBER+1];
433 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
434 down(&ieee->scan_sem);
435
436 while(1)
437 {
438
439 do{
440 ch++;
441 if (ch > MAX_CHANNEL_NUMBER)
442 goto out;
443 }while(!channel_map[ch]);
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464 if (ieee->state == IEEE80211_LINKED)
465 goto out;
466 ieee->set_chan(ieee->dev, ch);
467 if(channel_map[ch] == 1)
468 ieee80211_send_probe_requests(ieee);
469
470
471
472
473 if(ieee->state < IEEE80211_LINKED)
474 ;
475 else
476 if (ieee->sync_scan_hurryup)
477 goto out;
478
479
480 msleep_interruptible_rsl(IEEE80211_SOFTMAC_SCAN_TIME);
481
482 }
483out:
484 if(ieee->state < IEEE80211_LINKED){
485 ieee->actscanning = false;
486 up(&ieee->scan_sem);
487 }
488 else{
489 ieee->sync_scan_hurryup = 0;
490 if(IS_DOT11D_ENABLE(ieee))
491 DOT11D_ScanComplete(ieee);
492 up(&ieee->scan_sem);
493}
494}
495
496
497void ieee80211_softmac_scan_wq(struct work_struct *work)
498{
499 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
500 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
501 static short watchdog;
502 u8 channel_map[MAX_CHANNEL_NUMBER+1];
503 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
504 if(!ieee->ieee_up)
505 return;
506 down(&ieee->scan_sem);
507 do{
508 ieee->current_network.channel =
509 (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
510 if (watchdog++ > MAX_CHANNEL_NUMBER)
511 {
512
513 if (!channel_map[ieee->current_network.channel]) {
514 ieee->current_network.channel = 6;
515 goto out;
516 }
517 }
518 }while(!channel_map[ieee->current_network.channel]);
519 if (ieee->scanning == 0 )
520 goto out;
521 ieee->set_chan(ieee->dev, ieee->current_network.channel);
522 if(channel_map[ieee->current_network.channel] == 1)
523 ieee80211_send_probe_requests(ieee);
524
525
526 queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
527
528 up(&ieee->scan_sem);
529 return;
530out:
531 if(IS_DOT11D_ENABLE(ieee))
532 DOT11D_ScanComplete(ieee);
533 ieee->actscanning = false;
534 watchdog = 0;
535 ieee->scanning = 0;
536 up(&ieee->scan_sem);
537}
538
539
540
541void ieee80211_beacons_start(struct ieee80211_device *ieee)
542{
543 unsigned long flags;
544 spin_lock_irqsave(&ieee->beacon_lock,flags);
545
546 ieee->beacon_txing = 1;
547 ieee80211_send_beacon(ieee);
548
549 spin_unlock_irqrestore(&ieee->beacon_lock,flags);
550}
551
552void ieee80211_beacons_stop(struct ieee80211_device *ieee)
553{
554 unsigned long flags;
555
556 spin_lock_irqsave(&ieee->beacon_lock,flags);
557
558 ieee->beacon_txing = 0;
559 del_timer_sync(&ieee->beacon_timer);
560
561 spin_unlock_irqrestore(&ieee->beacon_lock,flags);
562
563}
564
565
566void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
567{
568 if(ieee->stop_send_beacons)
569 ieee->stop_send_beacons(ieee->dev);
570 if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
571 ieee80211_beacons_stop(ieee);
572}
573
574
575void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
576{
577 if(ieee->start_send_beacons)
578 ieee->start_send_beacons(ieee->dev,ieee->basic_rate);
579 if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
580 ieee80211_beacons_start(ieee);
581}
582
583
584void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
585{
586
587
588
589
590 down(&ieee->scan_sem);
591
592
593 if (ieee->scanning == 1){
594 ieee->scanning = 0;
595
596 cancel_delayed_work(&ieee->softmac_scan_wq);
597 }
598
599
600 up(&ieee->scan_sem);
601}
602
603void ieee80211_stop_scan(struct ieee80211_device *ieee)
604{
605 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
606 ieee80211_softmac_stop_scan(ieee);
607 else
608 ieee->stop_scan(ieee->dev);
609}
610
611
612void ieee80211_start_scan(struct ieee80211_device *ieee)
613{
614 if(IS_DOT11D_ENABLE(ieee) )
615 {
616 if(IS_COUNTRY_IE_VALID(ieee))
617 {
618 RESET_CIE_WATCHDOG(ieee);
619 }
620 }
621 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
622 if (ieee->scanning == 0){
623 ieee->scanning = 1;
624 queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0);
625 }
626 }else
627 ieee->start_scan(ieee->dev);
628
629}
630
631
632void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
633{
634 if(IS_DOT11D_ENABLE(ieee) )
635 {
636 if(IS_COUNTRY_IE_VALID(ieee))
637 {
638 RESET_CIE_WATCHDOG(ieee);
639 }
640 }
641 ieee->sync_scan_hurryup = 0;
642 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
643 ieee80211_softmac_scan_syncro(ieee);
644 else
645 ieee->scan_syncro(ieee->dev);
646
647}
648
649inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
650 struct ieee80211_device *ieee, int challengelen)
651{
652 struct sk_buff *skb;
653 struct ieee80211_authentication *auth;
654 int len = sizeof(struct ieee80211_authentication) + challengelen + ieee->tx_headroom;
655
656
657 skb = dev_alloc_skb(len);
658 if (!skb) return NULL;
659
660 skb_reserve(skb, ieee->tx_headroom);
661 auth = (struct ieee80211_authentication *)
662 skb_put(skb, sizeof(struct ieee80211_authentication));
663
664 auth->header.frame_ctl = IEEE80211_STYPE_AUTH;
665 if (challengelen) auth->header.frame_ctl |= IEEE80211_FCTL_WEP;
666
667 auth->header.duration_id = 0x013a;
668
669 memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
670 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
671 memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
672
673
674 if(ieee->auth_mode == 0)
675 auth->algorithm = WLAN_AUTH_OPEN;
676 else if(ieee->auth_mode == 1)
677 auth->algorithm = WLAN_AUTH_SHARED_KEY;
678 else if(ieee->auth_mode == 2)
679 auth->algorithm = WLAN_AUTH_OPEN;
680 printk("=================>%s():auth->algorithm is %d\n",__FUNCTION__,auth->algorithm);
681 auth->transaction = cpu_to_le16(ieee->associate_seq);
682 ieee->associate_seq++;
683
684 auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
685
686 return skb;
687
688}
689
690
691static struct sk_buff *ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
692{
693 u8 *tag;
694 int beacon_size;
695 struct ieee80211_probe_response *beacon_buf;
696 struct sk_buff *skb = NULL;
697 int encrypt;
698 int atim_len,erp_len;
699 struct ieee80211_crypt_data *crypt;
700
701 char *ssid = ieee->current_network.ssid;
702 int ssid_len = ieee->current_network.ssid_len;
703 int rate_len = ieee->current_network.rates_len+2;
704 int rate_ex_len = ieee->current_network.rates_ex_len;
705 int wpa_ie_len = ieee->wpa_ie_len;
706 u8 erpinfo_content = 0;
707
708 u8 *tmp_ht_cap_buf;
709 u8 tmp_ht_cap_len=0;
710 u8 *tmp_ht_info_buf;
711 u8 tmp_ht_info_len=0;
712 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
713 u8 *tmp_generic_ie_buf=NULL;
714 u8 tmp_generic_ie_len=0;
715
716 if(rate_ex_len > 0) rate_ex_len+=2;
717
718 if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
719 atim_len = 4;
720 else
721 atim_len = 0;
722
723 if(ieee80211_is_54g(&ieee->current_network))
724 erp_len = 3;
725 else
726 erp_len = 0;
727
728
729 crypt = ieee->crypt[ieee->tx_keyidx];
730
731
732 encrypt = ieee->host_encrypt && crypt && crypt->ops &&
733 ((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len));
734
735 tmp_ht_cap_buf =(u8 *) &(ieee->pHTInfo->SelfHTCap);
736 tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
737 tmp_ht_info_buf =(u8 *) &(ieee->pHTInfo->SelfHTInfo);
738 tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo);
739 HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len,encrypt);
740 HTConstructInfoElement(ieee,tmp_ht_info_buf,&tmp_ht_info_len, encrypt);
741
742
743 if(pHTInfo->bRegRT2RTAggregation)
744 {
745 tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
746 tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer);
747 HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len);
748 }
749
750 beacon_size = sizeof(struct ieee80211_probe_response)+2+
751 ssid_len
752 +3
753 +rate_len
754 +rate_ex_len
755 +atim_len
756 +erp_len
757 +wpa_ie_len
758
759
760
761
762 +ieee->tx_headroom;
763 skb = dev_alloc_skb(beacon_size);
764 if (!skb)
765 return NULL;
766 skb_reserve(skb, ieee->tx_headroom);
767 beacon_buf = (struct ieee80211_probe_response *) skb_put(skb, (beacon_size - ieee->tx_headroom));
768 memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
769 memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
770 memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
771
772 beacon_buf->header.duration_id = 0;
773 beacon_buf->beacon_interval =
774 cpu_to_le16(ieee->current_network.beacon_interval);
775 beacon_buf->capability =
776 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
777 beacon_buf->capability |=
778 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE);
779
780 if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
781 beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
782
783 crypt = ieee->crypt[ieee->tx_keyidx];
784 if (encrypt)
785 beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
786
787
788 beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
789 beacon_buf->info_element[0].id = MFIE_TYPE_SSID;
790 beacon_buf->info_element[0].len = ssid_len;
791
792 tag = (u8 *) beacon_buf->info_element[0].data;
793
794 memcpy(tag, ssid, ssid_len);
795
796 tag += ssid_len;
797
798 *(tag++) = MFIE_TYPE_RATES;
799 *(tag++) = rate_len-2;
800 memcpy(tag,ieee->current_network.rates,rate_len-2);
801 tag+=rate_len-2;
802
803 *(tag++) = MFIE_TYPE_DS_SET;
804 *(tag++) = 1;
805 *(tag++) = ieee->current_network.channel;
806
807 if(atim_len){
808 u16 val16;
809 *(tag++) = MFIE_TYPE_IBSS_SET;
810 *(tag++) = 2;
811
812 val16 = cpu_to_le16(ieee->current_network.atim_window);
813 memcpy((u8 *)tag, (u8 *)&val16, 2);
814 tag+=2;
815 }
816
817 if(erp_len){
818 *(tag++) = MFIE_TYPE_ERP;
819 *(tag++) = 1;
820 *(tag++) = erpinfo_content;
821 }
822 if(rate_ex_len){
823 *(tag++) = MFIE_TYPE_RATES_EX;
824 *(tag++) = rate_ex_len-2;
825 memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
826 tag+=rate_ex_len-2;
827 }
828
829 if (wpa_ie_len)
830 {
831 if (ieee->iw_mode == IW_MODE_ADHOC)
832 {
833 memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
834 }
835 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
836 tag += wpa_ie_len;
837 }
838
839
840 return skb;
841}
842
843
844struct sk_buff *ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
845{
846 struct sk_buff *skb;
847 u8 *tag;
848
849 struct ieee80211_crypt_data *crypt;
850 struct ieee80211_assoc_response_frame *assoc;
851 short encrypt;
852
853 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
854 int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len + ieee->tx_headroom;
855
856 skb = dev_alloc_skb(len);
857
858 if (!skb)
859 return NULL;
860
861 skb_reserve(skb, ieee->tx_headroom);
862
863 assoc = (struct ieee80211_assoc_response_frame *)
864 skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
865
866 assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
867 memcpy(assoc->header.addr1, dest,ETH_ALEN);
868 memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
869 memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
870 assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
871 WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
872
873
874 if(ieee->short_slot)
875 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
876
877 if (ieee->host_encrypt)
878 crypt = ieee->crypt[ieee->tx_keyidx];
879 else crypt = NULL;
880
881 encrypt = ( crypt && crypt->ops);
882
883 if (encrypt)
884 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
885
886 assoc->status = 0;
887 assoc->aid = cpu_to_le16(ieee->assoc_id);
888 if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
889 else ieee->assoc_id++;
890
891 tag = (u8 *) skb_put(skb, rate_len);
892
893 ieee80211_MFIE_Brate(ieee, &tag);
894 ieee80211_MFIE_Grate(ieee, &tag);
895
896 return skb;
897}
898
899struct sk_buff *ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest)
900{
901 struct sk_buff *skb;
902 struct ieee80211_authentication *auth;
903 int len = ieee->tx_headroom + sizeof(struct ieee80211_authentication)+1;
904
905 skb = dev_alloc_skb(len);
906
907 if (!skb)
908 return NULL;
909
910 skb->len = sizeof(struct ieee80211_authentication);
911
912 auth = (struct ieee80211_authentication *)skb->data;
913
914 auth->status = cpu_to_le16(status);
915 auth->transaction = cpu_to_le16(2);
916 auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
917
918 memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
919 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
920 memcpy(auth->header.addr1, dest, ETH_ALEN);
921 auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
922 return skb;
923
924
925}
926
927struct sk_buff *ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
928{
929 struct sk_buff *skb;
930 struct ieee80211_hdr_3addr *hdr;
931
932 skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
933
934 if (!skb)
935 return NULL;
936
937 hdr = (struct ieee80211_hdr_3addr *)skb_put(skb,sizeof(struct ieee80211_hdr_3addr));
938
939 memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
940 memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
941 memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
942
943 hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
944 IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
945 (pwr ? IEEE80211_FCTL_PM:0));
946
947 return skb;
948
949
950}
951
952
953void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8 *dest)
954{
955 struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
956
957 if (buf)
958 softmac_mgmt_xmit(buf, ieee);
959}
960
961
962void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8 *dest)
963{
964 struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
965
966 if (buf)
967 softmac_mgmt_xmit(buf, ieee);
968}
969
970
971void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
972{
973
974
975 struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
976 if (buf)
977 softmac_mgmt_xmit(buf, ieee);
978}
979
980
981inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
982{
983 struct sk_buff *skb;
984
985
986 struct ieee80211_assoc_request_frame *hdr;
987 u8 *tag;
988
989
990
991
992
993
994 u8 *ht_cap_buf = NULL;
995 u8 ht_cap_len=0;
996 u8 *realtek_ie_buf=NULL;
997 u8 realtek_ie_len=0;
998 int wpa_ie_len= ieee->wpa_ie_len;
999 unsigned int ckip_ie_len=0;
1000 unsigned int ccxrm_ie_len=0;
1001 unsigned int cxvernum_ie_len=0;
1002 struct ieee80211_crypt_data *crypt;
1003 int encrypt;
1004
1005 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
1006 unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
1007#ifdef THOMAS_TURBO
1008 unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
1009#endif
1010
1011 int len = 0;
1012
1013 crypt = ieee->crypt[ieee->tx_keyidx];
1014 encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len));
1015
1016
1017 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1018 {
1019 ht_cap_buf = (u8 *)&(ieee->pHTInfo->SelfHTCap);
1020 ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
1021 HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt);
1022 if(ieee->pHTInfo->bCurrentRT2RTAggregation)
1023 {
1024 realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
1025 realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer);
1026 HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len);
1027
1028 }
1029 }
1030 if(ieee->qos_support){
1031 wmm_info_len = beacon->qos_data.supported?9:0;
1032 }
1033
1034
1035 if(beacon->bCkipSupported)
1036 {
1037 ckip_ie_len = 30+2;
1038 }
1039 if(beacon->bCcxRmEnable)
1040 {
1041 ccxrm_ie_len = 6+2;
1042 }
1043 if( beacon->BssCcxVerNumber >= 2 )
1044 {
1045 cxvernum_ie_len = 5+2;
1046 }
1047#ifdef THOMAS_TURBO
1048 len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1049 + beacon->ssid_len
1050 + rate_len
1051 + wpa_ie_len
1052 + wmm_info_len
1053 + turbo_info_len
1054 + ht_cap_len
1055 + realtek_ie_len
1056 + ckip_ie_len
1057 + ccxrm_ie_len
1058 + cxvernum_ie_len
1059 + ieee->tx_headroom;
1060#else
1061 len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1062 + beacon->ssid_len
1063 + rate_len
1064 + wpa_ie_len
1065 + wmm_info_len
1066 + ht_cap_len
1067 + realtek_ie_len
1068 + ckip_ie_len
1069 + ccxrm_ie_len
1070 + cxvernum_ie_len
1071 + ieee->tx_headroom;
1072#endif
1073
1074 skb = dev_alloc_skb(len);
1075
1076 if (!skb)
1077 return NULL;
1078
1079 skb_reserve(skb, ieee->tx_headroom);
1080
1081 hdr = (struct ieee80211_assoc_request_frame *)
1082 skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)+2);
1083
1084
1085 hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
1086 hdr->header.duration_id= 37;
1087 memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
1088 memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1089 memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
1090
1091 memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);
1092
1093 hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
1094 if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
1095 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1096
1097 if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1098 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
1099
1100 if(ieee->short_slot)
1101 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
1102 if (wmm_info_len)
1103 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS);
1104
1105 hdr->listen_interval = 0xa;
1106
1107 hdr->info_element[0].id = MFIE_TYPE_SSID;
1108
1109 hdr->info_element[0].len = beacon->ssid_len;
1110 tag = skb_put(skb, beacon->ssid_len);
1111 memcpy(tag, beacon->ssid, beacon->ssid_len);
1112
1113 tag = skb_put(skb, rate_len);
1114
1115 ieee80211_MFIE_Brate(ieee, &tag);
1116 ieee80211_MFIE_Grate(ieee, &tag);
1117
1118 if( beacon->bCkipSupported )
1119 {
1120 static u8 AironetIeOui[] = {0x00, 0x01, 0x66};
1121 u8 CcxAironetBuf[30];
1122 OCTET_STRING osCcxAironetIE;
1123
1124 memset(CcxAironetBuf, 0,30);
1125 osCcxAironetIE.Octet = CcxAironetBuf;
1126 osCcxAironetIE.Length = sizeof(CcxAironetBuf);
1127
1128
1129
1130
1131 memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui));
1132
1133
1134
1135
1136 osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |= (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ;
1137 tag = skb_put(skb, ckip_ie_len);
1138 *tag++ = MFIE_TYPE_AIRONET;
1139 *tag++ = osCcxAironetIE.Length;
1140 memcpy(tag,osCcxAironetIE.Octet,osCcxAironetIE.Length);
1141 tag += osCcxAironetIE.Length;
1142 }
1143
1144 if(beacon->bCcxRmEnable)
1145 {
1146 static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
1147 OCTET_STRING osCcxRmCap;
1148
1149 osCcxRmCap.Octet = CcxRmCapBuf;
1150 osCcxRmCap.Length = sizeof(CcxRmCapBuf);
1151 tag = skb_put(skb,ccxrm_ie_len);
1152 *tag++ = MFIE_TYPE_GENERIC;
1153 *tag++ = osCcxRmCap.Length;
1154 memcpy(tag,osCcxRmCap.Octet,osCcxRmCap.Length);
1155 tag += osCcxRmCap.Length;
1156 }
1157
1158 if( beacon->BssCcxVerNumber >= 2 )
1159 {
1160 u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
1161 OCTET_STRING osCcxVerNum;
1162 CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
1163 osCcxVerNum.Octet = CcxVerNumBuf;
1164 osCcxVerNum.Length = sizeof(CcxVerNumBuf);
1165 tag = skb_put(skb,cxvernum_ie_len);
1166 *tag++ = MFIE_TYPE_GENERIC;
1167 *tag++ = osCcxVerNum.Length;
1168 memcpy(tag,osCcxVerNum.Octet,osCcxVerNum.Length);
1169 tag += osCcxVerNum.Length;
1170 }
1171
1172 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
1173 if(ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC)
1174 {
1175 tag = skb_put(skb, ht_cap_len);
1176 *tag++ = MFIE_TYPE_HT_CAP;
1177 *tag++ = ht_cap_len - 2;
1178 memcpy(tag, ht_cap_buf,ht_cap_len -2);
1179 tag += ht_cap_len -2;
1180 }
1181 }
1182
1183
1184
1185 tag = skb_put(skb, wpa_ie_len);
1186 if (wpa_ie_len){
1187 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
1188 }
1189
1190 tag = skb_put(skb,wmm_info_len);
1191 if(wmm_info_len) {
1192 ieee80211_WMM_Info(ieee, &tag);
1193 }
1194#ifdef THOMAS_TURBO
1195 tag = skb_put(skb,turbo_info_len);
1196 if(turbo_info_len) {
1197 ieee80211_TURBO_Info(ieee, &tag);
1198 }
1199#endif
1200
1201 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
1202 if(ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC)
1203 {
1204 tag = skb_put(skb, ht_cap_len);
1205 *tag++ = MFIE_TYPE_GENERIC;
1206 *tag++ = ht_cap_len - 2;
1207 memcpy(tag, ht_cap_buf,ht_cap_len - 2);
1208 tag += ht_cap_len -2;
1209 }
1210
1211 if(ieee->pHTInfo->bCurrentRT2RTAggregation){
1212 tag = skb_put(skb, realtek_ie_len);
1213 *tag++ = MFIE_TYPE_GENERIC;
1214 *tag++ = realtek_ie_len - 2;
1215 memcpy(tag, realtek_ie_buf,realtek_ie_len -2 );
1216 }
1217 }
1218
1219
1220 return skb;
1221}
1222
1223void ieee80211_associate_abort(struct ieee80211_device *ieee)
1224{
1225
1226 unsigned long flags;
1227 spin_lock_irqsave(&ieee->lock, flags);
1228
1229 ieee->associate_seq++;
1230
1231
1232
1233
1234
1235
1236
1237 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
1238 IEEE80211_DEBUG_MGMT("Authentication failed\n");
1239 ieee->softmac_stats.no_auth_rs++;
1240 }else{
1241 IEEE80211_DEBUG_MGMT("Association failed\n");
1242 ieee->softmac_stats.no_ass_rs++;
1243 }
1244
1245 ieee->state = IEEE80211_ASSOCIATING_RETRY;
1246
1247 queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \
1248 IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
1249
1250 spin_unlock_irqrestore(&ieee->lock, flags);
1251}
1252
1253void ieee80211_associate_abort_cb(unsigned long dev)
1254{
1255 ieee80211_associate_abort((struct ieee80211_device *) dev);
1256}
1257
1258
1259void ieee80211_associate_step1(struct ieee80211_device *ieee)
1260{
1261 struct ieee80211_network *beacon = &ieee->current_network;
1262 struct sk_buff *skb;
1263
1264 IEEE80211_DEBUG_MGMT("Stopping scan\n");
1265
1266 ieee->softmac_stats.tx_auth_rq++;
1267 skb=ieee80211_authentication_req(beacon, ieee, 0);
1268
1269 if (!skb)
1270 ieee80211_associate_abort(ieee);
1271 else{
1272 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
1273 IEEE80211_DEBUG_MGMT("Sending authentication request\n");
1274
1275 softmac_mgmt_xmit(skb, ieee);
1276
1277 if(!timer_pending(&ieee->associate_timer)){
1278 ieee->associate_timer.expires = jiffies + (HZ / 2);
1279 add_timer(&ieee->associate_timer);
1280 }
1281
1282 }
1283}
1284
1285void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
1286{
1287 u8 *c;
1288 struct sk_buff *skb;
1289 struct ieee80211_network *beacon = &ieee->current_network;
1290
1291
1292 ieee->associate_seq++;
1293 ieee->softmac_stats.tx_auth_rq++;
1294
1295 skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
1296 if (!skb)
1297 ieee80211_associate_abort(ieee);
1298 else{
1299 c = skb_put(skb, chlen+2);
1300 *(c++) = MFIE_TYPE_CHALLENGE;
1301 *(c++) = chlen;
1302 memcpy(c, challenge, chlen);
1303
1304 IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
1305
1306 ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr ));
1307
1308 softmac_mgmt_xmit(skb, ieee);
1309 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1310
1311 }
1312 kfree(challenge);
1313}
1314
1315void ieee80211_associate_step2(struct ieee80211_device *ieee)
1316{
1317 struct sk_buff *skb;
1318 struct ieee80211_network *beacon = &ieee->current_network;
1319
1320 del_timer_sync(&ieee->associate_timer);
1321
1322 IEEE80211_DEBUG_MGMT("Sending association request\n");
1323
1324 ieee->softmac_stats.tx_ass_rq++;
1325 skb=ieee80211_association_req(beacon, ieee);
1326 if (!skb)
1327 ieee80211_associate_abort(ieee);
1328 else{
1329 softmac_mgmt_xmit(skb, ieee);
1330 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1331
1332 }
1333}
1334void ieee80211_associate_complete_wq(struct work_struct *work)
1335{
1336 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
1337 printk(KERN_INFO "Associated successfully\n");
1338 if(ieee80211_is_54g(&ieee->current_network) &&
1339 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1340
1341 ieee->rate = 108;
1342 printk(KERN_INFO"Using G rates:%d\n", ieee->rate);
1343 }else{
1344 ieee->rate = 22;
1345 printk(KERN_INFO"Using B rates:%d\n", ieee->rate);
1346 }
1347 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1348 {
1349 printk("Successfully associated, ht enabled\n");
1350 HTOnAssocRsp(ieee);
1351 }
1352 else
1353 {
1354 printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
1355 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1356
1357 }
1358 ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500);
1359
1360 if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
1361 {
1362 ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
1363 ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
1364 }
1365 ieee->link_change(ieee->dev);
1366 if(ieee->is_silent_reset == 0){
1367 printk("============>normal associate\n");
1368 notify_wx_assoc_event(ieee);
1369 }
1370 else if(ieee->is_silent_reset == 1)
1371 {
1372 printk("==================>silent reset associate\n");
1373 ieee->is_silent_reset = 0;
1374 }
1375
1376 if (ieee->data_hard_resume)
1377 ieee->data_hard_resume(ieee->dev);
1378 netif_carrier_on(ieee->dev);
1379}
1380
1381void ieee80211_associate_complete(struct ieee80211_device *ieee)
1382{
1383
1384
1385 del_timer_sync(&ieee->associate_timer);
1386
1387 ieee->state = IEEE80211_LINKED;
1388
1389 queue_work(ieee->wq, &ieee->associate_complete_wq);
1390}
1391
1392void ieee80211_associate_procedure_wq(struct work_struct *work)
1393{
1394 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
1395 ieee->sync_scan_hurryup = 1;
1396 down(&ieee->wx_sem);
1397
1398 if (ieee->data_hard_stop)
1399 ieee->data_hard_stop(ieee->dev);
1400
1401 ieee80211_stop_scan(ieee);
1402 printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);
1403
1404 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1405
1406 ieee->associate_seq = 1;
1407 ieee80211_associate_step1(ieee);
1408
1409 up(&ieee->wx_sem);
1410}
1411
1412inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
1413{
1414 u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
1415 int tmp_ssid_len = 0;
1416
1417 short apset,ssidset,ssidbroad,apmatch,ssidmatch;
1418
1419
1420
1421
1422 if (ieee->state != IEEE80211_NOLINK)
1423 return;
1424
1425 if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
1426 return;
1427
1428 if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
1429 return;
1430
1431
1432 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){
1433
1434
1435
1436
1437 apset = ieee->wap_set;
1438 ssidset = ieee->ssid_set;
1439 ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0');
1440 apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
1441 ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\
1442 (!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
1443
1444
1445 if (
1446
1447
1448
1449
1450 ( apset && apmatch &&
1451 ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
1452
1453
1454
1455 (!apset && ssidset && ssidbroad && ssidmatch)
1456 ){
1457
1458
1459
1460 if (!ssidbroad){
1461 strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
1462 tmp_ssid_len = ieee->current_network.ssid_len;
1463 }
1464 memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
1465
1466 if (!ssidbroad){
1467 strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
1468 ieee->current_network.ssid_len = tmp_ssid_len;
1469 }
1470 printk(KERN_INFO"Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d\n",ieee->current_network.ssid,ieee->current_network.channel, ieee->current_network.qos_data.supported, ieee->pHTInfo->bEnableHT, ieee->current_network.bssht.bdSupportHT);
1471
1472
1473 HTResetIOTSetting(ieee->pHTInfo);
1474 if (ieee->iw_mode == IW_MODE_INFRA){
1475
1476 ieee->AsocRetryCount = 0;
1477
1478 if((ieee->current_network.qos_data.supported == 1) &&
1479
1480 ieee->current_network.bssht.bdSupportHT)
1481
1482 {
1483
1484 HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network));
1485 }
1486 else
1487 {
1488 ieee->pHTInfo->bCurrentHTSupport = false;
1489 }
1490
1491 ieee->state = IEEE80211_ASSOCIATING;
1492 queue_work(ieee->wq, &ieee->associate_procedure_wq);
1493 }else{
1494 if(ieee80211_is_54g(&ieee->current_network) &&
1495 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1496 ieee->rate = 108;
1497 ieee->SetWirelessMode(ieee->dev, IEEE_G);
1498 printk(KERN_INFO"Using G rates\n");
1499 }else{
1500 ieee->rate = 22;
1501 ieee->SetWirelessMode(ieee->dev, IEEE_B);
1502 printk(KERN_INFO"Using B rates\n");
1503 }
1504 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1505
1506 ieee->state = IEEE80211_LINKED;
1507 }
1508
1509 }
1510 }
1511
1512}
1513
1514void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
1515{
1516 unsigned long flags;
1517 struct ieee80211_network *target;
1518
1519 spin_lock_irqsave(&ieee->lock, flags);
1520
1521 list_for_each_entry(target, &ieee->network_list, list) {
1522
1523
1524
1525
1526
1527 if (ieee->state != IEEE80211_NOLINK)
1528 break;
1529
1530 if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
1531 ieee80211_softmac_new_net(ieee, target);
1532 }
1533
1534 spin_unlock_irqrestore(&ieee->lock, flags);
1535
1536}
1537
1538
1539static inline u16 auth_parse(struct sk_buff *skb, u8 **challenge, int *chlen)
1540{
1541 struct ieee80211_authentication *a;
1542 u8 *t;
1543 if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
1544 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
1545 return 0xcafe;
1546 }
1547 *challenge = NULL;
1548 a = (struct ieee80211_authentication *) skb->data;
1549 if(skb->len > (sizeof(struct ieee80211_authentication) +3)){
1550 t = skb->data + sizeof(struct ieee80211_authentication);
1551
1552 if(*(t++) == MFIE_TYPE_CHALLENGE){
1553 *chlen = *(t++);
1554 *challenge = kmemdup(t, *chlen, GFP_ATOMIC);
1555 if (!*challenge)
1556 return -ENOMEM;
1557 }
1558 }
1559
1560 return cpu_to_le16(a->status);
1561
1562}
1563
1564
1565int auth_rq_parse(struct sk_buff *skb,u8 *dest)
1566{
1567 struct ieee80211_authentication *a;
1568
1569 if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
1570 IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
1571 return -1;
1572 }
1573 a = (struct ieee80211_authentication *) skb->data;
1574
1575 memcpy(dest,a->header.addr2, ETH_ALEN);
1576
1577 if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
1578 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1579
1580 return WLAN_STATUS_SUCCESS;
1581}
1582
1583static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
1584{
1585 u8 *tag;
1586 u8 *skbend;
1587 u8 *ssid=NULL;
1588 u8 ssidlen = 0;
1589
1590 struct ieee80211_hdr_3addr *header =
1591 (struct ieee80211_hdr_3addr *) skb->data;
1592
1593 if (skb->len < sizeof (struct ieee80211_hdr_3addr ))
1594 return -1;
1595
1596 memcpy(src,header->addr2, ETH_ALEN);
1597
1598 skbend = (u8 *)skb->data + skb->len;
1599
1600 tag = skb->data + sizeof (struct ieee80211_hdr_3addr );
1601
1602 while (tag+1 < skbend){
1603 if (*tag == 0){
1604 ssid = tag+2;
1605 ssidlen = *(tag+1);
1606 break;
1607 }
1608 tag++;
1609 tag = tag + *(tag);
1610 tag++;
1611 }
1612
1613
1614 if (ssidlen == 0) return 1;
1615
1616 if (!ssid) return 1;
1617 return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
1618
1619}
1620
1621int assoc_rq_parse(struct sk_buff *skb,u8 *dest)
1622{
1623 struct ieee80211_assoc_request_frame *a;
1624
1625 if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
1626 sizeof(struct ieee80211_info_element))) {
1627
1628 IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
1629 return -1;
1630 }
1631
1632 a = (struct ieee80211_assoc_request_frame *) skb->data;
1633
1634 memcpy(dest,a->header.addr2,ETH_ALEN);
1635
1636 return 0;
1637}
1638
1639static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid)
1640{
1641 struct ieee80211_assoc_response_frame *response_head;
1642 u16 status_code;
1643
1644 if (skb->len < sizeof(struct ieee80211_assoc_response_frame)){
1645 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
1646 return 0xcafe;
1647 }
1648
1649 response_head = (struct ieee80211_assoc_response_frame *) skb->data;
1650 *aid = le16_to_cpu(response_head->aid) & 0x3fff;
1651
1652 status_code = le16_to_cpu(response_head->status);
1653 if((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \
1654 status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&&
1655 ((ieee->mode == IEEE_G) &&
1656 (ieee->current_network.mode == IEEE_N_24G) &&
1657 (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) {
1658 ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
1659 }else {
1660 ieee->AsocRetryCount = 0;
1661 }
1662
1663 return le16_to_cpu(response_head->status);
1664}
1665
1666static inline void
1667ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1668{
1669 u8 dest[ETH_ALEN];
1670
1671
1672 ieee->softmac_stats.rx_probe_rq++;
1673
1674 if (probe_rq_parse(ieee, skb, dest)){
1675
1676 ieee->softmac_stats.tx_probe_rs++;
1677 ieee80211_resp_to_probe(ieee, dest);
1678 }
1679}
1680
1681static inline void
1682ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1683{
1684 u8 dest[ETH_ALEN];
1685 int status;
1686
1687 ieee->softmac_stats.rx_auth_rq++;
1688
1689 status = auth_rq_parse(skb, dest);
1690 if (status != -1) {
1691 ieee80211_resp_to_auth(ieee, status, dest);
1692 }
1693
1694
1695}
1696
1697static inline void
1698ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1699{
1700
1701 u8 dest[ETH_ALEN];
1702
1703
1704 ieee->softmac_stats.rx_ass_rq++;
1705 if (assoc_rq_parse(skb,dest) != -1){
1706 ieee80211_resp_to_assoc_rq(ieee, dest);
1707 }
1708
1709 printk(KERN_INFO"New client associated: %pM\n", dest);
1710
1711}
1712
1713
1714
1715void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
1716{
1717
1718 struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
1719
1720 if (buf)
1721 softmac_ps_mgmt_xmit(buf, ieee);
1722
1723}
1724
1725
1726short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
1727{
1728 int timeout = ieee->ps_timeout;
1729 u8 dtim;
1730
1731
1732
1733
1734
1735
1736 dtim = ieee->current_network.dtim_data;
1737
1738 if(!(dtim & IEEE80211_DTIM_VALID))
1739 return 0;
1740 timeout = ieee->current_network.beacon_interval;
1741
1742 ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
1743
1744 if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
1745 return 2;
1746
1747 if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
1748 return 0;
1749
1750 if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
1751 return 0;
1752
1753 if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
1754 (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
1755 return 0;
1756
1757 if(time_l){
1758 *time_l = ieee->current_network.last_dtim_sta_time[0]
1759 + (ieee->current_network.beacon_interval
1760 * ieee->current_network.dtim_period) * 1000;
1761 }
1762
1763 if(time_h){
1764 *time_h = ieee->current_network.last_dtim_sta_time[1];
1765 if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
1766 *time_h += 1;
1767 }
1768
1769 return 1;
1770
1771
1772}
1773
1774inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
1775{
1776
1777 u32 th,tl;
1778 short sleep;
1779
1780 unsigned long flags,flags2;
1781
1782 spin_lock_irqsave(&ieee->lock, flags);
1783
1784 if((ieee->ps == IEEE80211_PS_DISABLED ||
1785 ieee->iw_mode != IW_MODE_INFRA ||
1786 ieee->state != IEEE80211_LINKED)){
1787
1788
1789 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1790
1791 ieee80211_sta_wakeup(ieee, 1);
1792
1793 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1794 }
1795
1796 sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
1797
1798 if(sleep == 0)
1799 goto out;
1800
1801 if(sleep == 1){
1802
1803 if(ieee->sta_sleep == 1)
1804 ieee->enter_sleep_state(ieee->dev,th,tl);
1805
1806 else if(ieee->sta_sleep == 0){
1807
1808 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1809
1810 if(ieee->ps_is_queue_empty(ieee->dev)){
1811
1812
1813 ieee->sta_sleep = 2;
1814
1815 ieee->ps_request_tx_ack(ieee->dev);
1816
1817 ieee80211_sta_ps_send_null_frame(ieee,1);
1818
1819 ieee->ps_th = th;
1820 ieee->ps_tl = tl;
1821 }
1822 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1823
1824 }
1825
1826
1827 }else if(sleep == 2){
1828
1829 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1830
1831 ieee80211_sta_wakeup(ieee,1);
1832
1833 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1834 }
1835
1836out:
1837 spin_unlock_irqrestore(&ieee->lock, flags);
1838
1839}
1840
1841void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
1842{
1843 if(ieee->sta_sleep == 0){
1844 if(nl){
1845 printk("Warning: driver is probably failing to report TX ps error\n");
1846 ieee->ps_request_tx_ack(ieee->dev);
1847 ieee80211_sta_ps_send_null_frame(ieee, 0);
1848 }
1849 return;
1850
1851 }
1852
1853 if(ieee->sta_sleep == 1)
1854 ieee->sta_wake_up(ieee->dev);
1855
1856 ieee->sta_sleep = 0;
1857
1858 if(nl){
1859 ieee->ps_request_tx_ack(ieee->dev);
1860 ieee80211_sta_ps_send_null_frame(ieee, 0);
1861 }
1862}
1863
1864void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
1865{
1866 unsigned long flags,flags2;
1867
1868 spin_lock_irqsave(&ieee->lock, flags);
1869
1870 if(ieee->sta_sleep == 2){
1871
1872 if(success){
1873 ieee->sta_sleep = 1;
1874 ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
1875 }
1876
1877
1878
1879 }
1880
1881 else {
1882
1883 if((ieee->sta_sleep == 0) && !success){
1884 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1885 ieee80211_sta_ps_send_null_frame(ieee, 0);
1886 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1887 }
1888 }
1889 spin_unlock_irqrestore(&ieee->lock, flags);
1890}
1891void ieee80211_process_action(struct ieee80211_device *ieee, struct sk_buff *skb)
1892{
1893 struct ieee80211_hdr *header = (struct ieee80211_hdr *)skb->data;
1894 u8 *act = ieee80211_get_payload(header);
1895 u8 tmp = 0;
1896
1897 if (act == NULL)
1898 {
1899 IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
1900 return;
1901 }
1902 tmp = *act;
1903 act ++;
1904 switch (tmp)
1905 {
1906 case ACT_CAT_BA:
1907 if (*act == ACT_ADDBAREQ)
1908 ieee80211_rx_ADDBAReq(ieee, skb);
1909 else if (*act == ACT_ADDBARSP)
1910 ieee80211_rx_ADDBARsp(ieee, skb);
1911 else if (*act == ACT_DELBA)
1912 ieee80211_rx_DELBA(ieee, skb);
1913 break;
1914 default:
1915
1916
1917 break;
1918 }
1919 return;
1920
1921}
1922inline int
1923ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
1924 struct ieee80211_rx_stats *rx_stats, u16 type,
1925 u16 stype)
1926{
1927 struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
1928 u16 errcode;
1929 u8 *challenge;
1930 int chlen=0;
1931 int aid;
1932 struct ieee80211_assoc_response_frame *assoc_resp;
1933
1934 bool bSupportNmode = true, bHalfSupportNmode = false;
1935
1936 if(!ieee->proto_started)
1937 return 0;
1938
1939 if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
1940 ieee->iw_mode == IW_MODE_INFRA &&
1941 ieee->state == IEEE80211_LINKED))
1942
1943 tasklet_schedule(&ieee->ps_task);
1944
1945 if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
1946 WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
1947 ieee->last_rx_ps_time = jiffies;
1948
1949 switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
1950
1951 case IEEE80211_STYPE_ASSOC_RESP:
1952 case IEEE80211_STYPE_REASSOC_RESP:
1953
1954 IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
1955 WLAN_FC_GET_STYPE(header->frame_ctl));
1956 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
1957 ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
1958 ieee->iw_mode == IW_MODE_INFRA){
1959 struct ieee80211_network network_resp;
1960 struct ieee80211_network *network = &network_resp;
1961
1962 if (0 == (errcode=assoc_parse(ieee,skb, &aid))){
1963 ieee->state=IEEE80211_LINKED;
1964 ieee->assoc_id = aid;
1965 ieee->softmac_stats.rx_ass_ok++;
1966
1967
1968 if(ieee->qos_support) {
1969 assoc_resp = (struct ieee80211_assoc_response_frame *)skb->data;
1970 memset(network, 0, sizeof(*network));
1971 if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\
1972 rx_stats->len - sizeof(*assoc_resp),\
1973 network,rx_stats)){
1974 return 1;
1975 }
1976 else
1977 {
1978 memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
1979 memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
1980 }
1981 if (ieee->handle_assoc_response != NULL)
1982 ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame *)header, network);
1983 }
1984 ieee80211_associate_complete(ieee);
1985 } else {
1986
1987 ieee->softmac_stats.rx_ass_err++;
1988 printk(
1989 "Association response status code 0x%x\n",
1990 errcode);
1991 IEEE80211_DEBUG_MGMT(
1992 "Association response status code 0x%x\n",
1993 errcode);
1994 if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
1995 queue_work(ieee->wq, &ieee->associate_procedure_wq);
1996 } else {
1997 ieee80211_associate_abort(ieee);
1998 }
1999 }
2000 }
2001 break;
2002
2003 case IEEE80211_STYPE_ASSOC_REQ:
2004 case IEEE80211_STYPE_REASSOC_REQ:
2005
2006 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2007 ieee->iw_mode == IW_MODE_MASTER)
2008
2009 ieee80211_rx_assoc_rq(ieee, skb);
2010 break;
2011
2012 case IEEE80211_STYPE_AUTH:
2013
2014 if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){
2015 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
2016 ieee->iw_mode == IW_MODE_INFRA){
2017
2018 IEEE80211_DEBUG_MGMT("Received authentication response");
2019
2020 if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){
2021 if(ieee->open_wep || !challenge){
2022 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
2023 ieee->softmac_stats.rx_auth_rs_ok++;
2024 if(!(ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE))
2025 {
2026 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
2027 {
2028
2029 if(IsHTHalfNmodeAPs(ieee))
2030 {
2031 bSupportNmode = true;
2032 bHalfSupportNmode = true;
2033 }
2034 else
2035 {
2036 bSupportNmode = false;
2037 bHalfSupportNmode = false;
2038 }
2039 printk("==========>to link with AP using SEC(%d, %d)", bSupportNmode, bHalfSupportNmode);
2040 }
2041 }
2042
2043 if(bSupportNmode) {
2044
2045 ieee->SetWirelessMode(ieee->dev, \
2046 ieee->current_network.mode);
2047 }else{
2048
2049
2050 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2051 }
2052
2053 if (ieee->current_network.mode == IEEE_N_24G && bHalfSupportNmode == true)
2054 {
2055 printk("===============>entern half N mode\n");
2056 ieee->bHalfWirelessN24GMode = true;
2057 }
2058 else
2059 ieee->bHalfWirelessN24GMode = false;
2060
2061 ieee80211_associate_step2(ieee);
2062 }else{
2063 ieee80211_auth_challenge(ieee, challenge, chlen);
2064 }
2065 }else{
2066 ieee->softmac_stats.rx_auth_rs_err++;
2067 IEEE80211_DEBUG_MGMT("Authentication response status code 0x%x",errcode);
2068 ieee80211_associate_abort(ieee);
2069 }
2070
2071 }else if (ieee->iw_mode == IW_MODE_MASTER){
2072 ieee80211_rx_auth_rq(ieee, skb);
2073 }
2074 }
2075 break;
2076
2077 case IEEE80211_STYPE_PROBE_REQ:
2078
2079 if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
2080 ((ieee->iw_mode == IW_MODE_ADHOC ||
2081 ieee->iw_mode == IW_MODE_MASTER) &&
2082 ieee->state == IEEE80211_LINKED)){
2083 ieee80211_rx_probe_rq(ieee, skb);
2084 }
2085 break;
2086
2087 case IEEE80211_STYPE_DISASSOC:
2088 case IEEE80211_STYPE_DEAUTH:
2089
2090
2091
2092 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2093 ieee->state == IEEE80211_LINKED &&
2094 ieee->iw_mode == IW_MODE_INFRA){
2095
2096 ieee->state = IEEE80211_ASSOCIATING;
2097 ieee->softmac_stats.reassoc++;
2098
2099 notify_wx_assoc_event(ieee);
2100
2101 RemovePeerTS(ieee, header->addr2);
2102 queue_work(ieee->wq, &ieee->associate_procedure_wq);
2103 }
2104 break;
2105 case IEEE80211_STYPE_MANAGE_ACT:
2106 ieee80211_process_action(ieee,skb);
2107 break;
2108 default:
2109 return -1;
2110 break;
2111 }
2112
2113
2114 return 0;
2115}
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
2136{
2137
2138 unsigned int queue_index = txb->queue_index;
2139 unsigned long flags;
2140 int i;
2141 cb_desc *tcb_desc = NULL;
2142
2143 spin_lock_irqsave(&ieee->lock,flags);
2144
2145
2146 ieee80211_sta_wakeup(ieee,0);
2147
2148
2149 ieee->stats.tx_bytes += txb->payload_size;
2150 ieee->stats.tx_packets++;
2151 tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
2152 if(tcb_desc->bMulticast) {
2153 ieee->stats.multicast++;
2154 }
2155
2156 for(i = 0; i < txb->nr_frags; i++) {
2157#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2158 if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) ||
2159#else
2160 if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
2161#endif
2162 (!ieee->check_nic_enough_desc(ieee->dev,queue_index))||\
2163 (ieee->queue_stop)) {
2164
2165
2166
2167
2168
2169
2170#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2171 skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]);
2172#else
2173 skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
2174#endif
2175 }else{
2176 ieee->softmac_data_hard_start_xmit(
2177 txb->fragments[i],
2178 ieee->dev,ieee->rate);
2179
2180
2181
2182 }
2183 }
2184 ieee80211_txb_free(txb);
2185
2186
2187 spin_unlock_irqrestore(&ieee->lock,flags);
2188
2189}
2190
2191
2192void ieee80211_resume_tx(struct ieee80211_device *ieee)
2193{
2194 int i;
2195 for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
2196
2197 if (ieee->queue_stop){
2198 ieee->tx_pending.frag = i;
2199 return;
2200 }else{
2201
2202 ieee->softmac_data_hard_start_xmit(
2203 ieee->tx_pending.txb->fragments[i],
2204 ieee->dev,ieee->rate);
2205
2206 ieee->stats.tx_packets++;
2207 ieee->dev->trans_start = jiffies;
2208 }
2209 }
2210
2211
2212 ieee80211_txb_free(ieee->tx_pending.txb);
2213 ieee->tx_pending.txb = NULL;
2214}
2215
2216
2217void ieee80211_reset_queue(struct ieee80211_device *ieee)
2218{
2219 unsigned long flags;
2220
2221 spin_lock_irqsave(&ieee->lock,flags);
2222 init_mgmt_queue(ieee);
2223 if (ieee->tx_pending.txb){
2224 ieee80211_txb_free(ieee->tx_pending.txb);
2225 ieee->tx_pending.txb = NULL;
2226 }
2227 ieee->queue_stop = 0;
2228 spin_unlock_irqrestore(&ieee->lock,flags);
2229
2230}
2231
2232void ieee80211_wake_queue(struct ieee80211_device *ieee)
2233{
2234
2235 unsigned long flags;
2236 struct sk_buff *skb;
2237 struct ieee80211_hdr_3addr *header;
2238
2239 spin_lock_irqsave(&ieee->lock,flags);
2240 if (! ieee->queue_stop) goto exit;
2241
2242 ieee->queue_stop = 0;
2243
2244 if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){
2245 while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
2246
2247 header = (struct ieee80211_hdr_3addr *) skb->data;
2248
2249 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2250
2251 if (ieee->seq_ctrl[0] == 0xFFF)
2252 ieee->seq_ctrl[0] = 0;
2253 else
2254 ieee->seq_ctrl[0]++;
2255
2256 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
2257
2258 }
2259 }
2260 if (!ieee->queue_stop && ieee->tx_pending.txb)
2261 ieee80211_resume_tx(ieee);
2262
2263 if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){
2264 ieee->softmac_stats.swtxawake++;
2265 netif_wake_queue(ieee->dev);
2266 }
2267
2268exit :
2269 spin_unlock_irqrestore(&ieee->lock,flags);
2270}
2271
2272
2273void ieee80211_stop_queue(struct ieee80211_device *ieee)
2274{
2275
2276
2277
2278 if (! netif_queue_stopped(ieee->dev)){
2279 netif_stop_queue(ieee->dev);
2280 ieee->softmac_stats.swtxstop++;
2281 }
2282 ieee->queue_stop = 1;
2283
2284
2285}
2286
2287
2288inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
2289{
2290
2291 random_ether_addr(ieee->current_network.bssid);
2292}
2293
2294
2295void ieee80211_start_master_bss(struct ieee80211_device *ieee)
2296{
2297 ieee->assoc_id = 1;
2298
2299 if (ieee->current_network.ssid_len == 0){
2300 strncpy(ieee->current_network.ssid,
2301 IEEE80211_DEFAULT_TX_ESSID,
2302 IW_ESSID_MAX_SIZE);
2303
2304 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2305 ieee->ssid_set = 1;
2306 }
2307
2308 memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
2309
2310 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2311 ieee->state = IEEE80211_LINKED;
2312 ieee->link_change(ieee->dev);
2313 notify_wx_assoc_event(ieee);
2314
2315 if (ieee->data_hard_resume)
2316 ieee->data_hard_resume(ieee->dev);
2317
2318 netif_carrier_on(ieee->dev);
2319}
2320
2321void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
2322{
2323 if(ieee->raw_tx){
2324
2325 if (ieee->data_hard_resume)
2326 ieee->data_hard_resume(ieee->dev);
2327
2328 netif_carrier_on(ieee->dev);
2329 }
2330}
2331void ieee80211_start_ibss_wq(struct work_struct *work)
2332{
2333
2334 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2335 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
2336
2337
2338
2339
2340
2341
2342
2343 if(!ieee->proto_started){
2344 printk("==========oh driver down return\n");
2345 return;
2346 }
2347 down(&ieee->wx_sem);
2348
2349 if (ieee->current_network.ssid_len == 0){
2350 strcpy(ieee->current_network.ssid,IEEE80211_DEFAULT_TX_ESSID);
2351 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2352 ieee->ssid_set = 1;
2353 }
2354
2355
2356 ieee80211_softmac_check_all_nets(ieee);
2357
2358
2359
2360 if (ieee->state == IEEE80211_NOLINK)
2361 ieee->current_network.channel = 6;
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376 if (ieee->state == IEEE80211_NOLINK)
2377 ieee80211_start_scan_syncro(ieee);
2378
2379
2380 if (ieee->state == IEEE80211_NOLINK){
2381 printk("creating new IBSS cell\n");
2382 if(!ieee->wap_set)
2383 ieee80211_randomize_cell(ieee);
2384
2385 if(ieee->modulation & IEEE80211_CCK_MODULATION){
2386
2387 ieee->current_network.rates_len = 4;
2388
2389 ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
2390 ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
2391 ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
2392 ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
2393
2394 }else
2395 ieee->current_network.rates_len = 0;
2396
2397 if(ieee->modulation & IEEE80211_OFDM_MODULATION){
2398 ieee->current_network.rates_ex_len = 8;
2399
2400 ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
2401 ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
2402 ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
2403 ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
2404 ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
2405 ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
2406 ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
2407 ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
2408
2409 ieee->rate = 108;
2410 }else{
2411 ieee->current_network.rates_ex_len = 0;
2412 ieee->rate = 22;
2413 }
2414
2415
2416 ieee->current_network.QoS_Enable = 0;
2417 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2418 ieee->current_network.atim_window = 0;
2419 ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
2420 if(ieee->short_slot)
2421 ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
2422
2423 }
2424
2425 ieee->state = IEEE80211_LINKED;
2426
2427 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2428 ieee->link_change(ieee->dev);
2429
2430 notify_wx_assoc_event(ieee);
2431
2432 ieee80211_start_send_beacons(ieee);
2433
2434 if (ieee->data_hard_resume)
2435 ieee->data_hard_resume(ieee->dev);
2436 netif_carrier_on(ieee->dev);
2437
2438 up(&ieee->wx_sem);
2439}
2440
2441inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
2442{
2443 queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150);
2444}
2445
2446
2447void ieee80211_start_bss(struct ieee80211_device *ieee)
2448{
2449 unsigned long flags;
2450
2451
2452
2453
2454 if(IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
2455 {
2456 if(! ieee->bGlobalDomain)
2457 {
2458 return;
2459 }
2460 }
2461
2462
2463
2464
2465
2466 ieee80211_softmac_check_all_nets(ieee);
2467
2468
2469
2470
2471
2472
2473
2474
2475 spin_lock_irqsave(&ieee->lock, flags);
2476
2477 if (ieee->state == IEEE80211_NOLINK){
2478 ieee->actscanning = true;
2479 ieee80211_start_scan(ieee);
2480 }
2481 spin_unlock_irqrestore(&ieee->lock, flags);
2482}
2483
2484
2485void ieee80211_disassociate(struct ieee80211_device *ieee)
2486{
2487
2488
2489 netif_carrier_off(ieee->dev);
2490 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
2491 ieee80211_reset_queue(ieee);
2492
2493 if (ieee->data_hard_stop)
2494 ieee->data_hard_stop(ieee->dev);
2495 if(IS_DOT11D_ENABLE(ieee))
2496 Dot11d_Reset(ieee);
2497 ieee->state = IEEE80211_NOLINK;
2498 ieee->is_set_key = false;
2499 ieee->link_change(ieee->dev);
2500
2501 notify_wx_assoc_event(ieee);
2502
2503}
2504void ieee80211_associate_retry_wq(struct work_struct *work)
2505{
2506 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2507 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
2508 unsigned long flags;
2509
2510 down(&ieee->wx_sem);
2511 if(!ieee->proto_started)
2512 goto exit;
2513
2514 if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
2515 goto exit;
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530 ieee->state = IEEE80211_NOLINK;
2531
2532 ieee80211_softmac_check_all_nets(ieee);
2533
2534 spin_lock_irqsave(&ieee->lock, flags);
2535
2536 if(ieee->state == IEEE80211_NOLINK)
2537 ieee80211_start_scan(ieee);
2538
2539 spin_unlock_irqrestore(&ieee->lock, flags);
2540
2541exit:
2542 up(&ieee->wx_sem);
2543}
2544
2545struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
2546{
2547 u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
2548
2549 struct sk_buff *skb;
2550 struct ieee80211_probe_response *b;
2551
2552 skb = ieee80211_probe_resp(ieee, broadcast_addr);
2553
2554 if (!skb)
2555 return NULL;
2556
2557 b = (struct ieee80211_probe_response *) skb->data;
2558 b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
2559
2560 return skb;
2561
2562}
2563
2564struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
2565{
2566 struct sk_buff *skb;
2567 struct ieee80211_probe_response *b;
2568
2569 skb = ieee80211_get_beacon_(ieee);
2570 if(!skb)
2571 return NULL;
2572
2573 b = (struct ieee80211_probe_response *) skb->data;
2574 b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2575
2576 if (ieee->seq_ctrl[0] == 0xFFF)
2577 ieee->seq_ctrl[0] = 0;
2578 else
2579 ieee->seq_ctrl[0]++;
2580
2581 return skb;
2582}
2583
2584void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
2585{
2586 ieee->sync_scan_hurryup = 1;
2587 down(&ieee->wx_sem);
2588 ieee80211_stop_protocol(ieee);
2589 up(&ieee->wx_sem);
2590}
2591
2592
2593void ieee80211_stop_protocol(struct ieee80211_device *ieee)
2594{
2595 if (!ieee->proto_started)
2596 return;
2597
2598 ieee->proto_started = 0;
2599
2600 ieee80211_stop_send_beacons(ieee);
2601 del_timer_sync(&ieee->associate_timer);
2602 cancel_delayed_work(&ieee->associate_retry_wq);
2603 cancel_delayed_work(&ieee->start_ibss_wq);
2604 ieee80211_stop_scan(ieee);
2605
2606 ieee80211_disassociate(ieee);
2607 RemoveAllTS(ieee);
2608}
2609
2610void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
2611{
2612 ieee->sync_scan_hurryup = 0;
2613 down(&ieee->wx_sem);
2614 ieee80211_start_protocol(ieee);
2615 up(&ieee->wx_sem);
2616}
2617
2618void ieee80211_start_protocol(struct ieee80211_device *ieee)
2619{
2620 short ch = 0;
2621 int i = 0;
2622 if (ieee->proto_started)
2623 return;
2624
2625 ieee->proto_started = 1;
2626
2627 if (ieee->current_network.channel == 0){
2628 do{
2629 ch++;
2630 if (ch > MAX_CHANNEL_NUMBER)
2631 return;
2632 }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
2633 ieee->current_network.channel = ch;
2634 }
2635
2636 if (ieee->current_network.beacon_interval == 0)
2637 ieee->current_network.beacon_interval = 100;
2638
2639
2640
2641 for(i = 0; i < 17; i++) {
2642 ieee->last_rxseq_num[i] = -1;
2643 ieee->last_rxfrag_num[i] = -1;
2644 ieee->last_packet_time[i] = 0;
2645 }
2646
2647 ieee->init_wmmparam_flag = 0;
2648
2649
2650
2651
2652
2653
2654
2655 if (ieee->iw_mode == IW_MODE_INFRA)
2656 ieee80211_start_bss(ieee);
2657
2658 else if (ieee->iw_mode == IW_MODE_ADHOC)
2659 ieee80211_start_ibss(ieee);
2660
2661 else if (ieee->iw_mode == IW_MODE_MASTER)
2662 ieee80211_start_master_bss(ieee);
2663
2664 else if(ieee->iw_mode == IW_MODE_MONITOR)
2665 ieee80211_start_monitor_mode(ieee);
2666}
2667
2668
2669#define DRV_NAME "Ieee80211"
2670void ieee80211_softmac_init(struct ieee80211_device *ieee)
2671{
2672 int i;
2673 memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
2674
2675 ieee->state = IEEE80211_NOLINK;
2676 ieee->sync_scan_hurryup = 0;
2677 for(i = 0; i < 5; i++) {
2678 ieee->seq_ctrl[i] = 0;
2679 }
2680 ieee->pDot11dInfo = kzalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
2681 if (!ieee->pDot11dInfo)
2682 IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
2683
2684 ieee->LinkDetectInfo.SlotNum = 2;
2685 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
2686 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
2687
2688 ieee->assoc_id = 0;
2689 ieee->queue_stop = 0;
2690 ieee->scanning = 0;
2691 ieee->softmac_features = 0;
2692 ieee->wap_set = 0;
2693 ieee->ssid_set = 0;
2694 ieee->proto_started = 0;
2695 ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
2696 ieee->rate = 22;
2697 ieee->ps = IEEE80211_PS_DISABLED;
2698 ieee->sta_sleep = 0;
2699 ieee->Regdot11HTOperationalRateSet[0]= 0xff;
2700 ieee->Regdot11HTOperationalRateSet[1]= 0xff;
2701 ieee->Regdot11HTOperationalRateSet[4]= 0x01;
2702
2703 ieee->actscanning = false;
2704 ieee->beinretry = false;
2705 ieee->is_set_key = false;
2706 init_mgmt_queue(ieee);
2707
2708 ieee->sta_edca_param[0] = 0x0000A403;
2709 ieee->sta_edca_param[1] = 0x0000A427;
2710 ieee->sta_edca_param[2] = 0x005E4342;
2711 ieee->sta_edca_param[3] = 0x002F3262;
2712 ieee->aggregation = true;
2713 ieee->enable_rx_imm_BA = 1;
2714 ieee->tx_pending.txb = NULL;
2715
2716 init_timer(&ieee->associate_timer);
2717 ieee->associate_timer.data = (unsigned long)ieee;
2718 ieee->associate_timer.function = ieee80211_associate_abort_cb;
2719
2720 init_timer(&ieee->beacon_timer);
2721 ieee->beacon_timer.data = (unsigned long) ieee;
2722 ieee->beacon_timer.function = ieee80211_send_beacon_cb;
2723
2724 ieee->wq = create_workqueue(DRV_NAME);
2725
2726 INIT_DELAYED_WORK(&ieee->start_ibss_wq,ieee80211_start_ibss_wq);
2727 INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
2728 INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
2729 INIT_DELAYED_WORK(&ieee->softmac_scan_wq,ieee80211_softmac_scan_wq);
2730 INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
2731 INIT_WORK(&ieee->wx_sync_scan_wq,ieee80211_wx_sync_scan_wq);
2732
2733
2734 sema_init(&ieee->wx_sem, 1);
2735 sema_init(&ieee->scan_sem, 1);
2736
2737 spin_lock_init(&ieee->mgmt_tx_lock);
2738 spin_lock_init(&ieee->beacon_lock);
2739
2740 tasklet_init(&ieee->ps_task,
2741 (void(*)(unsigned long)) ieee80211_sta_ps,
2742 (unsigned long)ieee);
2743
2744}
2745
2746void ieee80211_softmac_free(struct ieee80211_device *ieee)
2747{
2748 down(&ieee->wx_sem);
2749 kfree(ieee->pDot11dInfo);
2750 ieee->pDot11dInfo = NULL;
2751 del_timer_sync(&ieee->associate_timer);
2752
2753 cancel_delayed_work(&ieee->associate_retry_wq);
2754 destroy_workqueue(ieee->wq);
2755
2756 up(&ieee->wx_sem);
2757}
2758
2759
2760
2761
2762
2763
2764
2765static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
2766{
2767
2768
2769 printk("%s WPA\n",value ? "enabling" : "disabling");
2770 ieee->wpa_enabled = value;
2771 return 0;
2772}
2773
2774
2775void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len)
2776{
2777
2778 ieee80211_wpa_enable(ieee, 1);
2779
2780 ieee80211_disassociate(ieee);
2781}
2782
2783
2784static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
2785{
2786
2787 int ret = 0;
2788
2789 switch (command) {
2790 case IEEE_MLME_STA_DEAUTH:
2791
2792 break;
2793
2794 case IEEE_MLME_STA_DISASSOC:
2795 ieee80211_disassociate(ieee);
2796 break;
2797
2798 default:
2799 printk("Unknown MLME request: %d\n", command);
2800 ret = -EOPNOTSUPP;
2801 }
2802
2803 return ret;
2804}
2805
2806
2807static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
2808 struct ieee_param *param, int plen)
2809{
2810 u8 *buf;
2811
2812 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
2813 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
2814 return -EINVAL;
2815
2816 if (param->u.wpa_ie.len) {
2817 buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len,
2818 GFP_KERNEL);
2819 if (buf == NULL)
2820 return -ENOMEM;
2821
2822 kfree(ieee->wpa_ie);
2823 ieee->wpa_ie = buf;
2824 ieee->wpa_ie_len = param->u.wpa_ie.len;
2825 } else {
2826 kfree(ieee->wpa_ie);
2827 ieee->wpa_ie = NULL;
2828 ieee->wpa_ie_len = 0;
2829 }
2830
2831 ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
2832 return 0;
2833}
2834
2835#define AUTH_ALG_OPEN_SYSTEM 0x1
2836#define AUTH_ALG_SHARED_KEY 0x2
2837
2838static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
2839{
2840
2841 struct ieee80211_security sec = {
2842 .flags = SEC_AUTH_MODE,
2843 };
2844 int ret = 0;
2845
2846 if (value & AUTH_ALG_SHARED_KEY) {
2847 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
2848 ieee->open_wep = 0;
2849 ieee->auth_mode = 1;
2850 } else if (value & AUTH_ALG_OPEN_SYSTEM){
2851 sec.auth_mode = WLAN_AUTH_OPEN;
2852 ieee->open_wep = 1;
2853 ieee->auth_mode = 0;
2854 }
2855 else if (value & IW_AUTH_ALG_LEAP){
2856 sec.auth_mode = WLAN_AUTH_LEAP;
2857 ieee->open_wep = 1;
2858 ieee->auth_mode = 2;
2859 }
2860
2861
2862 if (ieee->set_security)
2863 ieee->set_security(ieee->dev, &sec);
2864
2865
2866
2867 return ret;
2868}
2869
2870static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
2871{
2872 int ret=0;
2873 unsigned long flags;
2874
2875 switch (name) {
2876 case IEEE_PARAM_WPA_ENABLED:
2877 ret = ieee80211_wpa_enable(ieee, value);
2878 break;
2879
2880 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2881 ieee->tkip_countermeasures=value;
2882 break;
2883
2884 case IEEE_PARAM_DROP_UNENCRYPTED: {
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896 struct ieee80211_security sec = {
2897 .flags = SEC_ENABLED,
2898 .enabled = value,
2899 };
2900 ieee->drop_unencrypted = value;
2901
2902
2903
2904 if (!value) {
2905 sec.flags |= SEC_LEVEL;
2906 sec.level = SEC_LEVEL_0;
2907 }
2908 else {
2909 sec.flags |= SEC_LEVEL;
2910 sec.level = SEC_LEVEL_1;
2911 }
2912 if (ieee->set_security)
2913 ieee->set_security(ieee->dev, &sec);
2914 break;
2915 }
2916
2917 case IEEE_PARAM_PRIVACY_INVOKED:
2918 ieee->privacy_invoked=value;
2919 break;
2920
2921 case IEEE_PARAM_AUTH_ALGS:
2922 ret = ieee80211_wpa_set_auth_algs(ieee, value);
2923 break;
2924
2925 case IEEE_PARAM_IEEE_802_1X:
2926 ieee->ieee802_1x=value;
2927 break;
2928 case IEEE_PARAM_WPAX_SELECT:
2929
2930 spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
2931 ieee->wpax_type_set = 1;
2932 ieee->wpax_type_notify = value;
2933 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
2934 break;
2935
2936 default:
2937 printk("Unknown WPA param: %d\n",name);
2938 ret = -EOPNOTSUPP;
2939 }
2940
2941 return ret;
2942}
2943
2944
2945
2946static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
2947 struct ieee_param *param, int param_len)
2948{
2949 int ret = 0;
2950
2951 struct ieee80211_crypto_ops *ops;
2952 struct ieee80211_crypt_data **crypt;
2953
2954 struct ieee80211_security sec = {
2955 .flags = 0,
2956 };
2957
2958 param->u.crypt.err = 0;
2959 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
2960
2961 if (param_len !=
2962 (int) ((char *) param->u.crypt.key - (char *) param) +
2963 param->u.crypt.key_len) {
2964 printk("Len mismatch %d, %d\n", param_len,
2965 param->u.crypt.key_len);
2966 return -EINVAL;
2967 }
2968 if (is_broadcast_ether_addr(param->sta_addr)) {
2969 if (param->u.crypt.idx >= WEP_KEYS)
2970 return -EINVAL;
2971 crypt = &ieee->crypt[param->u.crypt.idx];
2972 } else {
2973 return -EINVAL;
2974 }
2975
2976 if (strcmp(param->u.crypt.alg, "none") == 0) {
2977 if (crypt) {
2978 sec.enabled = 0;
2979
2980
2981 sec.level = SEC_LEVEL_0;
2982 sec.flags |= SEC_ENABLED | SEC_LEVEL;
2983 ieee80211_crypt_delayed_deinit(ieee, crypt);
2984 }
2985 goto done;
2986 }
2987 sec.enabled = 1;
2988
2989
2990 sec.flags |= SEC_ENABLED;
2991
2992
2993 if (!(ieee->host_encrypt || ieee->host_decrypt) &&
2994 strcmp(param->u.crypt.alg, "TKIP"))
2995 goto skip_host_crypt;
2996
2997 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
2998 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
2999 request_module("ieee80211_crypt_wep");
3000 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3001
3002 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
3003 request_module("ieee80211_crypt_tkip");
3004 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3005 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
3006 request_module("ieee80211_crypt_ccmp");
3007 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3008 }
3009 if (ops == NULL) {
3010 printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
3011 param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
3012 ret = -EINVAL;
3013 goto done;
3014 }
3015
3016 if (*crypt == NULL || (*crypt)->ops != ops) {
3017 struct ieee80211_crypt_data *new_crypt;
3018
3019 ieee80211_crypt_delayed_deinit(ieee, crypt);
3020
3021 new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL);
3022 if (new_crypt == NULL) {
3023 ret = -ENOMEM;
3024 goto done;
3025 }
3026 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
3027 new_crypt->ops = ops;
3028 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
3029 new_crypt->priv =
3030 new_crypt->ops->init(param->u.crypt.idx);
3031
3032 if (new_crypt->priv == NULL) {
3033 kfree(new_crypt);
3034 param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
3035 ret = -EINVAL;
3036 goto done;
3037 }
3038
3039 *crypt = new_crypt;
3040 }
3041
3042 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
3043 (*crypt)->ops->set_key(param->u.crypt.key,
3044 param->u.crypt.key_len, param->u.crypt.seq,
3045 (*crypt)->priv) < 0) {
3046 printk("key setting failed\n");
3047 param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
3048 ret = -EINVAL;
3049 goto done;
3050 }
3051
3052 skip_host_crypt:
3053 if (param->u.crypt.set_tx) {
3054 ieee->tx_keyidx = param->u.crypt.idx;
3055 sec.active_key = param->u.crypt.idx;
3056 sec.flags |= SEC_ACTIVE_KEY;
3057 } else
3058 sec.flags &= ~SEC_ACTIVE_KEY;
3059
3060 if (param->u.crypt.alg != NULL) {
3061 memcpy(sec.keys[param->u.crypt.idx],
3062 param->u.crypt.key,
3063 param->u.crypt.key_len);
3064 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
3065 sec.flags |= (1 << param->u.crypt.idx);
3066
3067 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3068 sec.flags |= SEC_LEVEL;
3069 sec.level = SEC_LEVEL_1;
3070 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3071 sec.flags |= SEC_LEVEL;
3072 sec.level = SEC_LEVEL_2;
3073 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3074 sec.flags |= SEC_LEVEL;
3075 sec.level = SEC_LEVEL_3;
3076 }
3077 }
3078 done:
3079 if (ieee->set_security)
3080 ieee->set_security(ieee->dev, &sec);
3081
3082
3083
3084
3085
3086
3087 if (ieee->reset_on_keychange &&
3088 ieee->iw_mode != IW_MODE_INFRA &&
3089 ieee->reset_port &&
3090 ieee->reset_port(ieee->dev)) {
3091 printk("reset_port failed\n");
3092 param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
3093 return -EINVAL;
3094 }
3095
3096 return ret;
3097}
3098
3099inline struct sk_buff *ieee80211_disassociate_skb(
3100 struct ieee80211_network *beacon,
3101 struct ieee80211_device *ieee,
3102 u8 asRsn)
3103{
3104 struct sk_buff *skb;
3105 struct ieee80211_disassoc *disass;
3106
3107 skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc));
3108 if (!skb)
3109 return NULL;
3110
3111 disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc));
3112 disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
3113 disass->header.duration_id = 0;
3114
3115 memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
3116 memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
3117 memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
3118
3119 disass->reason = asRsn;
3120 return skb;
3121}
3122
3123
3124void
3125SendDisassociation(
3126 struct ieee80211_device *ieee,
3127 u8 *asSta,
3128 u8 asRsn
3129)
3130{
3131 struct ieee80211_network *beacon = &ieee->current_network;
3132 struct sk_buff *skb;
3133 skb = ieee80211_disassociate_skb(beacon,ieee,asRsn);
3134 if (skb){
3135 softmac_mgmt_xmit(skb, ieee);
3136
3137 }
3138}
3139
3140int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
3141{
3142 struct ieee_param *param;
3143 int ret=0;
3144
3145 down(&ieee->wx_sem);
3146
3147
3148 if (p->length < sizeof(struct ieee_param) || !p->pointer){
3149 ret = -EINVAL;
3150 goto out;
3151 }
3152
3153 param = memdup_user(p->pointer, p->length);
3154 if (IS_ERR(param)) {
3155 ret = PTR_ERR(param);
3156 goto out;
3157 }
3158
3159 switch (param->cmd) {
3160
3161 case IEEE_CMD_SET_WPA_PARAM:
3162 ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
3163 param->u.wpa_param.value);
3164 break;
3165
3166 case IEEE_CMD_SET_WPA_IE:
3167 ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
3168 break;
3169
3170 case IEEE_CMD_SET_ENCRYPTION:
3171 ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
3172 break;
3173
3174 case IEEE_CMD_MLME:
3175 ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
3176 param->u.mlme.reason_code);
3177 break;
3178
3179 default:
3180 printk("Unknown WPA supplicant request: %d\n",param->cmd);
3181 ret = -EOPNOTSUPP;
3182 break;
3183 }
3184
3185 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
3186 ret = -EFAULT;
3187
3188 kfree(param);
3189out:
3190 up(&ieee->wx_sem);
3191
3192 return ret;
3193}
3194
3195void notify_wx_assoc_event(struct ieee80211_device *ieee)
3196{
3197 union iwreq_data wrqu;
3198 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3199 if (ieee->state == IEEE80211_LINKED)
3200 memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
3201 else
3202 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
3203 wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
3204}
3205
3206EXPORT_SYMBOL(ieee80211_get_beacon);
3207EXPORT_SYMBOL(ieee80211_wake_queue);
3208EXPORT_SYMBOL(ieee80211_stop_queue);
3209EXPORT_SYMBOL(ieee80211_reset_queue);
3210EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
3211EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
3212EXPORT_SYMBOL(ieee80211_is_shortslot);
3213EXPORT_SYMBOL(ieee80211_is_54g);
3214EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
3215EXPORT_SYMBOL(ieee80211_ps_tx_ack);
3216EXPORT_SYMBOL(ieee80211_softmac_xmit);
3217EXPORT_SYMBOL(ieee80211_stop_send_beacons);
3218EXPORT_SYMBOL(notify_wx_assoc_event);
3219EXPORT_SYMBOL(SendDisassociation);
3220EXPORT_SYMBOL(ieee80211_disassociate);
3221EXPORT_SYMBOL(ieee80211_start_send_beacons);
3222EXPORT_SYMBOL(ieee80211_stop_scan);
3223EXPORT_SYMBOL(ieee80211_send_probe_requests);
3224EXPORT_SYMBOL(ieee80211_softmac_scan_syncro);
3225EXPORT_SYMBOL(ieee80211_start_scan_syncro);
3226
3227