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