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