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