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