1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include "ieee80211.h"
18
19#include <linux/random.h>
20#include <linux/delay.h>
21#include <linux/slab.h>
22#include <linux/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 rtl_80211_hdr_3addr *header=
226 (struct rtl_80211_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 netif_trans_update(ieee->dev);
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 ieee->softmac_hard_start_xmit(skb, ieee->dev);
281
282 }
283 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
284 }
285}
286
287static inline void
288softmac_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 rtl_80211_hdr_3addr *header =
293 (struct rtl_80211_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 netif_trans_update(ieee->dev);
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
324static inline 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 eth_broadcast_addr(req->header.addr1);
347 memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
348 eth_broadcast_addr(req->header.addr3);
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,
385 jiffies + msecs_to_jiffies(ieee->current_network.beacon_interval-5));
386 }
387
388}
389
390
391static void ieee80211_send_beacon_cb(unsigned long _ieee)
392{
393 struct ieee80211_device *ieee =
394 (struct ieee80211_device *) _ieee;
395 unsigned long flags;
396
397 spin_lock_irqsave(&ieee->beacon_lock, flags);
398 ieee80211_send_beacon(ieee);
399 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
400}
401
402
403static void ieee80211_send_probe(struct ieee80211_device *ieee)
404{
405 struct sk_buff *skb;
406
407 skb = ieee80211_probe_req(ieee);
408 if (skb) {
409 softmac_mgmt_xmit(skb, ieee);
410 ieee->softmac_stats.tx_probe_rq++;
411
412 }
413}
414
415static void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
416{
417 if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)) {
418 ieee80211_send_probe(ieee);
419 ieee80211_send_probe(ieee);
420 }
421}
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 mutex_lock(&ieee->scan_mutex);
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 && ieee->sync_scan_hurryup)
471 goto out;
472
473 msleep_interruptible(IEEE80211_SOFTMAC_SCAN_TIME);
474
475 }
476out:
477 if(ieee->state < IEEE80211_LINKED){
478 ieee->actscanning = false;
479 mutex_unlock(&ieee->scan_mutex);
480 }
481 else{
482 ieee->sync_scan_hurryup = 0;
483 if(IS_DOT11D_ENABLE(ieee))
484 DOT11D_ScanComplete(ieee);
485 mutex_unlock(&ieee->scan_mutex);
486}
487}
488EXPORT_SYMBOL(ieee80211_softmac_scan_syncro);
489
490static void ieee80211_softmac_scan_wq(struct work_struct *work)
491{
492 struct delayed_work *dwork = to_delayed_work(work);
493 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
494 static short watchdog;
495 u8 channel_map[MAX_CHANNEL_NUMBER+1];
496 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
497 if(!ieee->ieee_up)
498 return;
499 mutex_lock(&ieee->scan_mutex);
500 do{
501 ieee->current_network.channel =
502 (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
503 if (watchdog++ > MAX_CHANNEL_NUMBER)
504 {
505
506 if (!channel_map[ieee->current_network.channel]) {
507 ieee->current_network.channel = 6;
508 goto out;
509 }
510 }
511 }while(!channel_map[ieee->current_network.channel]);
512 if (ieee->scanning == 0 )
513 goto out;
514 ieee->set_chan(ieee->dev, ieee->current_network.channel);
515 if(channel_map[ieee->current_network.channel] == 1)
516 ieee80211_send_probe_requests(ieee);
517
518
519 schedule_delayed_work(&ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
520
521 mutex_unlock(&ieee->scan_mutex);
522 return;
523out:
524 if(IS_DOT11D_ENABLE(ieee))
525 DOT11D_ScanComplete(ieee);
526 ieee->actscanning = false;
527 watchdog = 0;
528 ieee->scanning = 0;
529 mutex_unlock(&ieee->scan_mutex);
530}
531
532
533
534static void ieee80211_beacons_start(struct ieee80211_device *ieee)
535{
536 unsigned long flags;
537 spin_lock_irqsave(&ieee->beacon_lock,flags);
538
539 ieee->beacon_txing = 1;
540 ieee80211_send_beacon(ieee);
541
542 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
543}
544
545static void ieee80211_beacons_stop(struct ieee80211_device *ieee)
546{
547 unsigned long flags;
548
549 spin_lock_irqsave(&ieee->beacon_lock, flags);
550
551 ieee->beacon_txing = 0;
552 del_timer_sync(&ieee->beacon_timer);
553
554 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
555
556}
557
558
559void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
560{
561 if(ieee->stop_send_beacons)
562 ieee->stop_send_beacons(ieee->dev);
563 if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
564 ieee80211_beacons_stop(ieee);
565}
566EXPORT_SYMBOL(ieee80211_stop_send_beacons);
567
568void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
569{
570 if(ieee->start_send_beacons)
571 ieee->start_send_beacons(ieee->dev, ieee->basic_rate);
572 if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
573 ieee80211_beacons_start(ieee);
574}
575EXPORT_SYMBOL(ieee80211_start_send_beacons);
576
577static void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
578{
579
580
581
582
583 mutex_lock(&ieee->scan_mutex);
584
585
586 if (ieee->scanning == 1) {
587 ieee->scanning = 0;
588
589 cancel_delayed_work(&ieee->softmac_scan_wq);
590 }
591
592
593 mutex_unlock(&ieee->scan_mutex);
594}
595
596void ieee80211_stop_scan(struct ieee80211_device *ieee)
597{
598 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
599 ieee80211_softmac_stop_scan(ieee);
600 else
601 ieee->stop_scan(ieee->dev);
602}
603EXPORT_SYMBOL(ieee80211_stop_scan);
604
605
606static void ieee80211_start_scan(struct ieee80211_device *ieee)
607{
608 if (IS_DOT11D_ENABLE(ieee) )
609 {
610 if (IS_COUNTRY_IE_VALID(ieee))
611 {
612 RESET_CIE_WATCHDOG(ieee);
613 }
614 }
615 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
616 if (ieee->scanning == 0) {
617 ieee->scanning = 1;
618 schedule_delayed_work(&ieee->softmac_scan_wq, 0);
619 }
620 }else
621 ieee->start_scan(ieee->dev);
622
623}
624
625
626void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
627{
628 if (IS_DOT11D_ENABLE(ieee) )
629 {
630 if (IS_COUNTRY_IE_VALID(ieee))
631 {
632 RESET_CIE_WATCHDOG(ieee);
633 }
634 }
635 ieee->sync_scan_hurryup = 0;
636 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
637 ieee80211_softmac_scan_syncro(ieee);
638 else
639 ieee->scan_syncro(ieee->dev);
640
641}
642EXPORT_SYMBOL(ieee80211_start_scan_syncro);
643
644static inline struct sk_buff *
645ieee80211_authentication_req(struct ieee80211_network *beacon,
646 struct ieee80211_device *ieee, int challengelen)
647{
648 struct sk_buff *skb;
649 struct ieee80211_authentication *auth;
650 int len = sizeof(struct ieee80211_authentication) + challengelen + ieee->tx_headroom;
651
652
653 skb = dev_alloc_skb(len);
654 if (!skb) return NULL;
655
656 skb_reserve(skb, ieee->tx_headroom);
657 auth = (struct ieee80211_authentication *)
658 skb_put(skb, sizeof(struct ieee80211_authentication));
659
660 if (challengelen)
661 auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH
662 | IEEE80211_FCTL_WEP);
663 else
664 auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
665
666 auth->header.duration_id = cpu_to_le16(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 = cpu_to_le16(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 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 rtl_80211_hdr_3addr *hdr;
932
933 skb = dev_alloc_skb(sizeof(struct rtl_80211_hdr_3addr));
934
935 if (!skb)
936 return NULL;
937
938 hdr = (struct rtl_80211_hdr_3addr *)skb_put(skb,sizeof(struct rtl_80211_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
983static inline struct sk_buff *
984ieee80211_association_req(struct ieee80211_network *beacon,
985 struct ieee80211_device *ieee)
986{
987 struct sk_buff *skb;
988
989
990 struct ieee80211_assoc_request_frame *hdr;
991 u8 *tag;
992
993
994
995
996
997
998 u8 *ht_cap_buf = NULL;
999 u8 ht_cap_len=0;
1000 u8 *realtek_ie_buf=NULL;
1001 u8 realtek_ie_len=0;
1002 int wpa_ie_len= ieee->wpa_ie_len;
1003 unsigned int ckip_ie_len=0;
1004 unsigned int ccxrm_ie_len=0;
1005 unsigned int cxvernum_ie_len=0;
1006 struct ieee80211_crypt_data *crypt;
1007 int encrypt;
1008
1009 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
1010 unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
1011#ifdef THOMAS_TURBO
1012 unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
1013#endif
1014
1015 int len = 0;
1016
1017 crypt = ieee->crypt[ieee->tx_keyidx];
1018 encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len));
1019
1020
1021 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1022 {
1023 ht_cap_buf = (u8 *)&(ieee->pHTInfo->SelfHTCap);
1024 ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
1025 HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt);
1026 if (ieee->pHTInfo->bCurrentRT2RTAggregation)
1027 {
1028 realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
1029 realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer);
1030 HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len);
1031
1032 }
1033 }
1034 if (ieee->qos_support) {
1035 wmm_info_len = beacon->qos_data.supported?9:0;
1036 }
1037
1038
1039 if (beacon->bCkipSupported)
1040 {
1041 ckip_ie_len = 30+2;
1042 }
1043 if (beacon->bCcxRmEnable)
1044 {
1045 ccxrm_ie_len = 6+2;
1046 }
1047 if (beacon->BssCcxVerNumber >= 2)
1048 cxvernum_ie_len = 5+2;
1049
1050#ifdef THOMAS_TURBO
1051 len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1052 + beacon->ssid_len
1053 + rate_len
1054 + wpa_ie_len
1055 + wmm_info_len
1056 + turbo_info_len
1057 + ht_cap_len
1058 + realtek_ie_len
1059 + ckip_ie_len
1060 + ccxrm_ie_len
1061 + cxvernum_ie_len
1062 + ieee->tx_headroom;
1063#else
1064 len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1065 + beacon->ssid_len
1066 + rate_len
1067 + wpa_ie_len
1068 + wmm_info_len
1069 + ht_cap_len
1070 + realtek_ie_len
1071 + ckip_ie_len
1072 + ccxrm_ie_len
1073 + cxvernum_ie_len
1074 + ieee->tx_headroom;
1075#endif
1076
1077 skb = dev_alloc_skb(len);
1078
1079 if (!skb)
1080 return NULL;
1081
1082 skb_reserve(skb, ieee->tx_headroom);
1083
1084 hdr = (struct ieee80211_assoc_request_frame *)
1085 skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)+2);
1086
1087
1088 hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
1089 hdr->header.duration_id = cpu_to_le16(37);
1090 memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
1091 memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1092 memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
1093
1094 memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);
1095
1096 hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
1097 if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
1098 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1099
1100 if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1101 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
1102
1103 if(ieee->short_slot)
1104 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
1105 if (wmm_info_len)
1106 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS);
1107
1108 hdr->listen_interval = cpu_to_le16(0xa);
1109
1110 hdr->info_element[0].id = MFIE_TYPE_SSID;
1111
1112 hdr->info_element[0].len = beacon->ssid_len;
1113 tag = skb_put(skb, beacon->ssid_len);
1114 memcpy(tag, beacon->ssid, beacon->ssid_len);
1115
1116 tag = skb_put(skb, rate_len);
1117
1118 ieee80211_MFIE_Brate(ieee, &tag);
1119 ieee80211_MFIE_Grate(ieee, &tag);
1120
1121 if (beacon->bCkipSupported) {
1122 static u8 AironetIeOui[] = {0x00, 0x01, 0x66};
1123 u8 CcxAironetBuf[30];
1124 OCTET_STRING osCcxAironetIE;
1125
1126 memset(CcxAironetBuf, 0, 30);
1127 osCcxAironetIE.Octet = CcxAironetBuf;
1128 osCcxAironetIE.Length = sizeof(CcxAironetBuf);
1129
1130
1131
1132
1133 memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui));
1134
1135
1136
1137
1138 osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |= (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ;
1139 tag = skb_put(skb, ckip_ie_len);
1140 *tag++ = MFIE_TYPE_AIRONET;
1141 *tag++ = osCcxAironetIE.Length;
1142 memcpy(tag, osCcxAironetIE.Octet, osCcxAironetIE.Length);
1143 tag += osCcxAironetIE.Length;
1144 }
1145
1146 if (beacon->bCcxRmEnable)
1147 {
1148 static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
1149 OCTET_STRING osCcxRmCap;
1150
1151 osCcxRmCap.Octet = CcxRmCapBuf;
1152 osCcxRmCap.Length = sizeof(CcxRmCapBuf);
1153 tag = skb_put(skb, ccxrm_ie_len);
1154 *tag++ = MFIE_TYPE_GENERIC;
1155 *tag++ = osCcxRmCap.Length;
1156 memcpy(tag, osCcxRmCap.Octet, osCcxRmCap.Length);
1157 tag += osCcxRmCap.Length;
1158 }
1159
1160 if (beacon->BssCcxVerNumber >= 2) {
1161 u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
1162 OCTET_STRING osCcxVerNum;
1163 CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
1164 osCcxVerNum.Octet = CcxVerNumBuf;
1165 osCcxVerNum.Length = sizeof(CcxVerNumBuf);
1166 tag = skb_put(skb, cxvernum_ie_len);
1167 *tag++ = MFIE_TYPE_GENERIC;
1168 *tag++ = osCcxVerNum.Length;
1169 memcpy(tag, osCcxVerNum.Octet, osCcxVerNum.Length);
1170 tag += osCcxVerNum.Length;
1171 }
1172
1173 if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
1174 if (ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC)
1175 {
1176 tag = skb_put(skb, ht_cap_len);
1177 *tag++ = MFIE_TYPE_HT_CAP;
1178 *tag++ = ht_cap_len - 2;
1179 memcpy(tag, ht_cap_buf, ht_cap_len - 2);
1180 tag += ht_cap_len -2;
1181 }
1182 }
1183
1184
1185
1186 tag = skb_put(skb, wpa_ie_len);
1187 if (wpa_ie_len) {
1188 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
1189 }
1190
1191 tag = skb_put(skb, wmm_info_len);
1192 if (wmm_info_len) {
1193 ieee80211_WMM_Info(ieee, &tag);
1194 }
1195#ifdef THOMAS_TURBO
1196 tag = skb_put(skb, turbo_info_len);
1197 if (turbo_info_len) {
1198 ieee80211_TURBO_Info(ieee, &tag);
1199 }
1200#endif
1201
1202 if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
1203 if(ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC)
1204 {
1205 tag = skb_put(skb, ht_cap_len);
1206 *tag++ = MFIE_TYPE_GENERIC;
1207 *tag++ = ht_cap_len - 2;
1208 memcpy(tag, ht_cap_buf, ht_cap_len - 2);
1209 tag += ht_cap_len -2;
1210 }
1211
1212 if (ieee->pHTInfo->bCurrentRT2RTAggregation) {
1213 tag = skb_put(skb, realtek_ie_len);
1214 *tag++ = MFIE_TYPE_GENERIC;
1215 *tag++ = realtek_ie_len - 2;
1216 memcpy(tag, realtek_ie_buf, realtek_ie_len - 2);
1217 }
1218 }
1219
1220
1221 return skb;
1222}
1223
1224void ieee80211_associate_abort(struct ieee80211_device *ieee)
1225{
1226
1227 unsigned long flags;
1228 spin_lock_irqsave(&ieee->lock, flags);
1229
1230 ieee->associate_seq++;
1231
1232
1233
1234
1235
1236
1237
1238 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
1239 IEEE80211_DEBUG_MGMT("Authentication failed\n");
1240 ieee->softmac_stats.no_auth_rs++;
1241 }else{
1242 IEEE80211_DEBUG_MGMT("Association failed\n");
1243 ieee->softmac_stats.no_ass_rs++;
1244 }
1245
1246 ieee->state = IEEE80211_ASSOCIATING_RETRY;
1247
1248 schedule_delayed_work(&ieee->associate_retry_wq, \
1249 IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
1250
1251 spin_unlock_irqrestore(&ieee->lock, flags);
1252}
1253
1254static void ieee80211_associate_abort_cb(unsigned long dev)
1255{
1256 ieee80211_associate_abort((struct ieee80211_device *) dev);
1257}
1258
1259
1260static void ieee80211_associate_step1(struct ieee80211_device *ieee)
1261{
1262 struct ieee80211_network *beacon = &ieee->current_network;
1263 struct sk_buff *skb;
1264
1265 IEEE80211_DEBUG_MGMT("Stopping scan\n");
1266
1267 ieee->softmac_stats.tx_auth_rq++;
1268 skb=ieee80211_authentication_req(beacon, ieee, 0);
1269
1270 if (!skb)
1271 ieee80211_associate_abort(ieee);
1272 else{
1273 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
1274 IEEE80211_DEBUG_MGMT("Sending authentication request\n");
1275 softmac_mgmt_xmit(skb, ieee);
1276
1277 if (!timer_pending(&ieee->associate_timer)) {
1278 ieee->associate_timer.expires = jiffies + (HZ / 2);
1279 add_timer(&ieee->associate_timer);
1280 }
1281
1282 }
1283}
1284
1285static void ieee80211_auth_challenge(struct ieee80211_device *ieee,
1286 u8 *challenge,
1287 int chlen)
1288{
1289 u8 *c;
1290 struct sk_buff *skb;
1291 struct ieee80211_network *beacon = &ieee->current_network;
1292
1293
1294 ieee->associate_seq++;
1295 ieee->softmac_stats.tx_auth_rq++;
1296
1297 skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
1298 if (!skb)
1299 ieee80211_associate_abort(ieee);
1300 else{
1301 c = skb_put(skb, chlen+2);
1302 *(c++) = MFIE_TYPE_CHALLENGE;
1303 *(c++) = chlen;
1304 memcpy(c, challenge, chlen);
1305
1306 IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
1307
1308 ieee80211_encrypt_fragment(ieee, skb, sizeof(struct rtl_80211_hdr_3addr ));
1309
1310 softmac_mgmt_xmit(skb, ieee);
1311 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1312
1313 }
1314 kfree(challenge);
1315}
1316
1317static void ieee80211_associate_step2(struct ieee80211_device *ieee)
1318{
1319 struct sk_buff *skb;
1320 struct ieee80211_network *beacon = &ieee->current_network;
1321
1322 del_timer_sync(&ieee->associate_timer);
1323
1324 IEEE80211_DEBUG_MGMT("Sending association request\n");
1325
1326 ieee->softmac_stats.tx_ass_rq++;
1327 skb=ieee80211_association_req(beacon, ieee);
1328 if (!skb)
1329 ieee80211_associate_abort(ieee);
1330 else{
1331 softmac_mgmt_xmit(skb, ieee);
1332 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1333
1334 }
1335}
1336static void ieee80211_associate_complete_wq(struct work_struct *work)
1337{
1338 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
1339 printk(KERN_INFO "Associated successfully\n");
1340 if(ieee80211_is_54g(&ieee->current_network) &&
1341 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1342
1343 ieee->rate = 108;
1344 printk(KERN_INFO"Using G rates:%d\n", ieee->rate);
1345 }else{
1346 ieee->rate = 22;
1347 printk(KERN_INFO"Using B rates:%d\n", ieee->rate);
1348 }
1349 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1350 {
1351 printk("Successfully associated, ht enabled\n");
1352 HTOnAssocRsp(ieee);
1353 }
1354 else
1355 {
1356 printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
1357 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1358
1359 }
1360 ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500);
1361
1362 if (ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
1363 {
1364 ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
1365 ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
1366 }
1367 ieee->link_change(ieee->dev);
1368 if (!ieee->is_silent_reset) {
1369 printk("============>normal associate\n");
1370 notify_wx_assoc_event(ieee);
1371 } else {
1372 printk("==================>silent reset associate\n");
1373 ieee->is_silent_reset = false;
1374 }
1375
1376 if (ieee->data_hard_resume)
1377 ieee->data_hard_resume(ieee->dev);
1378 netif_carrier_on(ieee->dev);
1379}
1380
1381static void ieee80211_associate_complete(struct ieee80211_device *ieee)
1382{
1383
1384
1385 del_timer_sync(&ieee->associate_timer);
1386
1387 ieee->state = IEEE80211_LINKED;
1388
1389 schedule_work(&ieee->associate_complete_wq);
1390}
1391
1392static void ieee80211_associate_procedure_wq(struct work_struct *work)
1393{
1394 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
1395 ieee->sync_scan_hurryup = 1;
1396 mutex_lock(&ieee->wx_mutex);
1397
1398 if (ieee->data_hard_stop)
1399 ieee->data_hard_stop(ieee->dev);
1400
1401 ieee80211_stop_scan(ieee);
1402 printk("===>%s(), chan:%d\n", __func__, ieee->current_network.channel);
1403
1404 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1405
1406 ieee->associate_seq = 1;
1407 ieee80211_associate_step1(ieee);
1408
1409 mutex_unlock(&ieee->wx_mutex);
1410}
1411
1412inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
1413{
1414 u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
1415 int tmp_ssid_len = 0;
1416
1417 short apset, ssidset, ssidbroad, apmatch, ssidmatch;
1418
1419
1420
1421
1422 if (ieee->state != IEEE80211_NOLINK)
1423 return;
1424
1425 if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
1426 return;
1427
1428 if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
1429 return;
1430
1431
1432 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) {
1433
1434
1435
1436
1437 apset = ieee->wap_set;
1438 ssidset = ieee->ssid_set;
1439 ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0');
1440 apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
1441 ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\
1442 (!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
1443
1444
1445 if (
1446
1447
1448
1449
1450 (apset && apmatch &&
1451 ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
1452
1453
1454
1455 (!apset && ssidset && ssidbroad && ssidmatch)
1456 ){
1457
1458
1459
1460 if (!ssidbroad) {
1461 strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
1462 tmp_ssid_len = ieee->current_network.ssid_len;
1463 }
1464 memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
1465
1466 strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
1467 ieee->current_network.ssid_len = tmp_ssid_len;
1468 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);
1469
1470
1471 HTResetIOTSetting(ieee->pHTInfo);
1472 if (ieee->iw_mode == IW_MODE_INFRA){
1473
1474 ieee->AsocRetryCount = 0;
1475
1476 if((ieee->current_network.qos_data.supported == 1) &&
1477
1478 ieee->current_network.bssht.bdSupportHT)
1479
1480 {
1481
1482 HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network));
1483 }
1484 else
1485 {
1486 ieee->pHTInfo->bCurrentHTSupport = false;
1487 }
1488
1489 ieee->state = IEEE80211_ASSOCIATING;
1490 schedule_work(&ieee->associate_procedure_wq);
1491 }else{
1492 if(ieee80211_is_54g(&ieee->current_network) &&
1493 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1494 ieee->rate = 108;
1495 ieee->SetWirelessMode(ieee->dev, IEEE_G);
1496 printk(KERN_INFO"Using G rates\n");
1497 }else{
1498 ieee->rate = 22;
1499 ieee->SetWirelessMode(ieee->dev, IEEE_B);
1500 printk(KERN_INFO"Using B rates\n");
1501 }
1502 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1503
1504 ieee->state = IEEE80211_LINKED;
1505 }
1506
1507 }
1508 }
1509
1510}
1511
1512void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
1513{
1514 unsigned long flags;
1515 struct ieee80211_network *target;
1516
1517 spin_lock_irqsave(&ieee->lock, flags);
1518
1519 list_for_each_entry(target, &ieee->network_list, list) {
1520
1521
1522
1523
1524
1525 if (ieee->state != IEEE80211_NOLINK)
1526 break;
1527
1528 if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
1529 ieee80211_softmac_new_net(ieee, target);
1530 }
1531
1532 spin_unlock_irqrestore(&ieee->lock, flags);
1533
1534}
1535
1536
1537static inline u16 auth_parse(struct sk_buff *skb, u8 **challenge, int *chlen)
1538{
1539 struct ieee80211_authentication *a;
1540 u8 *t;
1541 if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
1542 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
1543 return 0xcafe;
1544 }
1545 *challenge = NULL;
1546 a = (struct ieee80211_authentication *) skb->data;
1547 if (skb->len > (sizeof(struct ieee80211_authentication) + 3)) {
1548 t = skb->data + sizeof(struct ieee80211_authentication);
1549
1550 if (*(t++) == MFIE_TYPE_CHALLENGE) {
1551 *chlen = *(t++);
1552 *challenge = kmemdup(t, *chlen, GFP_ATOMIC);
1553 if (!*challenge)
1554 return -ENOMEM;
1555 }
1556 }
1557
1558 return le16_to_cpu(a->status);
1559
1560}
1561
1562
1563static int auth_rq_parse(struct sk_buff *skb, u8 *dest)
1564{
1565 struct ieee80211_authentication *a;
1566
1567 if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
1568 IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
1569 return -1;
1570 }
1571 a = (struct ieee80211_authentication *) skb->data;
1572
1573 memcpy(dest,a->header.addr2, ETH_ALEN);
1574
1575 if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
1576 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1577
1578 return WLAN_STATUS_SUCCESS;
1579}
1580
1581static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
1582{
1583 u8 *tag;
1584 u8 *skbend;
1585 u8 *ssid=NULL;
1586 u8 ssidlen = 0;
1587
1588 struct rtl_80211_hdr_3addr *header =
1589 (struct rtl_80211_hdr_3addr *) skb->data;
1590
1591 if (skb->len < sizeof (struct rtl_80211_hdr_3addr ))
1592 return -1;
1593
1594 memcpy(src,header->addr2, ETH_ALEN);
1595
1596 skbend = (u8 *)skb->data + skb->len;
1597
1598 tag = skb->data + sizeof (struct rtl_80211_hdr_3addr );
1599
1600 while (tag+1 < skbend){
1601 if (*tag == 0) {
1602 ssid = tag+2;
1603 ssidlen = *(tag+1);
1604 break;
1605 }
1606 tag++;
1607 tag = tag + *(tag);
1608 tag++;
1609 }
1610
1611
1612 if (ssidlen == 0) return 1;
1613
1614 if (!ssid) return 1;
1615 return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
1616
1617}
1618
1619static int assoc_rq_parse(struct sk_buff *skb, u8 *dest)
1620{
1621 struct ieee80211_assoc_request_frame *a;
1622
1623 if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
1624 sizeof(struct ieee80211_info_element))) {
1625
1626 IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
1627 return -1;
1628 }
1629
1630 a = (struct ieee80211_assoc_request_frame *) skb->data;
1631
1632 memcpy(dest,a->header.addr2,ETH_ALEN);
1633
1634 return 0;
1635}
1636
1637static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid)
1638{
1639 struct ieee80211_assoc_response_frame *response_head;
1640 u16 status_code;
1641
1642 if (skb->len < sizeof(struct ieee80211_assoc_response_frame)) {
1643 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
1644 return 0xcafe;
1645 }
1646
1647 response_head = (struct ieee80211_assoc_response_frame *) skb->data;
1648 *aid = le16_to_cpu(response_head->aid) & 0x3fff;
1649
1650 status_code = le16_to_cpu(response_head->status);
1651 if((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \
1652 status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&&
1653 ((ieee->mode == IEEE_G) &&
1654 (ieee->current_network.mode == IEEE_N_24G) &&
1655 (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) {
1656 ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
1657 }else {
1658 ieee->AsocRetryCount = 0;
1659 }
1660
1661 return le16_to_cpu(response_head->status);
1662}
1663
1664static inline void
1665ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1666{
1667 u8 dest[ETH_ALEN];
1668
1669
1670 ieee->softmac_stats.rx_probe_rq++;
1671
1672 if (probe_rq_parse(ieee, skb, dest)) {
1673
1674 ieee->softmac_stats.tx_probe_rs++;
1675 ieee80211_resp_to_probe(ieee, dest);
1676 }
1677}
1678
1679static inline void
1680ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1681{
1682 u8 dest[ETH_ALEN];
1683 int status;
1684
1685 ieee->softmac_stats.rx_auth_rq++;
1686
1687 status = auth_rq_parse(skb, dest);
1688 if (status != -1) {
1689 ieee80211_resp_to_auth(ieee, status, dest);
1690 }
1691
1692
1693}
1694
1695static inline void
1696ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1697{
1698
1699 u8 dest[ETH_ALEN];
1700
1701
1702 ieee->softmac_stats.rx_ass_rq++;
1703 if (assoc_rq_parse(skb, dest) != -1) {
1704 ieee80211_resp_to_assoc_rq(ieee, dest);
1705 }
1706
1707 printk(KERN_INFO"New client associated: %pM\n", dest);
1708
1709}
1710
1711static void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee,
1712 short pwr)
1713{
1714
1715 struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
1716
1717 if (buf)
1718 softmac_ps_mgmt_xmit(buf, ieee);
1719
1720}
1721
1722
1723static short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h,
1724 u32 *time_l)
1725{
1726 int timeout = ieee->ps_timeout;
1727 u8 dtim;
1728
1729
1730
1731
1732
1733
1734 dtim = ieee->current_network.dtim_data;
1735 if(!(dtim & IEEE80211_DTIM_VALID))
1736 return 0;
1737 timeout = ieee->current_network.beacon_interval;
1738 ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
1739
1740 if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
1741 return 2;
1742
1743 if(!time_after(jiffies,
1744 dev_trans_start(ieee->dev) + msecs_to_jiffies(timeout)))
1745 return 0;
1746
1747 if(!time_after(jiffies,
1748 ieee->last_rx_ps_time + msecs_to_jiffies(timeout)))
1749 return 0;
1750
1751 if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
1752 (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
1753 return 0;
1754
1755 if (time_l) {
1756 *time_l = ieee->current_network.last_dtim_sta_time[0]
1757 + (ieee->current_network.beacon_interval
1758 * ieee->current_network.dtim_period) * 1000;
1759 }
1760
1761 if (time_h) {
1762 *time_h = ieee->current_network.last_dtim_sta_time[1];
1763 if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
1764 *time_h += 1;
1765 }
1766
1767 return 1;
1768
1769
1770}
1771
1772static inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
1773{
1774
1775 u32 th, tl;
1776 short sleep;
1777
1778 unsigned long flags, flags2;
1779
1780 spin_lock_irqsave(&ieee->lock, flags);
1781
1782 if ((ieee->ps == IEEE80211_PS_DISABLED ||
1783 ieee->iw_mode != IW_MODE_INFRA ||
1784 ieee->state != IEEE80211_LINKED)){
1785
1786
1787 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1788
1789 ieee80211_sta_wakeup(ieee, 1);
1790
1791 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1792 }
1793
1794 sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
1795
1796 if(sleep == 0)
1797 goto out;
1798
1799 if(sleep == 1){
1800
1801 if(ieee->sta_sleep == 1)
1802 ieee->enter_sleep_state(ieee->dev, th, tl);
1803
1804 else if(ieee->sta_sleep == 0){
1805
1806 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1807
1808 if(ieee->ps_is_queue_empty(ieee->dev)){
1809
1810
1811 ieee->sta_sleep = 2;
1812
1813 ieee->ps_request_tx_ack(ieee->dev);
1814
1815 ieee80211_sta_ps_send_null_frame(ieee, 1);
1816
1817 ieee->ps_th = th;
1818 ieee->ps_tl = tl;
1819 }
1820 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1821
1822 }
1823
1824
1825 }else if(sleep == 2){
1826
1827 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1828
1829 ieee80211_sta_wakeup(ieee, 1);
1830
1831 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1832 }
1833
1834out:
1835 spin_unlock_irqrestore(&ieee->lock, flags);
1836
1837}
1838
1839void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
1840{
1841 if (ieee->sta_sleep == 0) {
1842 if (nl) {
1843 printk("Warning: driver is probably failing to report TX ps error\n");
1844 ieee->ps_request_tx_ack(ieee->dev);
1845 ieee80211_sta_ps_send_null_frame(ieee, 0);
1846 }
1847 return;
1848
1849 }
1850
1851 if(ieee->sta_sleep == 1)
1852 ieee->sta_wake_up(ieee->dev);
1853
1854 ieee->sta_sleep = 0;
1855
1856 if (nl) {
1857 ieee->ps_request_tx_ack(ieee->dev);
1858 ieee80211_sta_ps_send_null_frame(ieee, 0);
1859 }
1860}
1861
1862void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
1863{
1864 unsigned long flags, flags2;
1865
1866 spin_lock_irqsave(&ieee->lock, flags);
1867
1868 if(ieee->sta_sleep == 2){
1869
1870 if (success) {
1871 ieee->sta_sleep = 1;
1872 ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
1873 }
1874
1875
1876
1877 }
1878
1879 else {
1880
1881 if ((ieee->sta_sleep == 0) && !success) {
1882 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1883 ieee80211_sta_ps_send_null_frame(ieee, 0);
1884 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1885 }
1886 }
1887 spin_unlock_irqrestore(&ieee->lock, flags);
1888}
1889EXPORT_SYMBOL(ieee80211_ps_tx_ack);
1890
1891static void ieee80211_process_action(struct ieee80211_device *ieee,
1892 struct sk_buff *skb)
1893{
1894 struct rtl_80211_hdr *header = (struct rtl_80211_hdr *)skb->data;
1895 u8 *act = ieee80211_get_payload(header);
1896 u8 tmp = 0;
1897
1898 if (act == NULL)
1899 {
1900 IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
1901 return;
1902 }
1903 tmp = *act;
1904 act ++;
1905 switch (tmp) {
1906 case ACT_CAT_BA:
1907 if (*act == ACT_ADDBAREQ)
1908 ieee80211_rx_ADDBAReq(ieee, skb);
1909 else if (*act == ACT_ADDBARSP)
1910 ieee80211_rx_ADDBARsp(ieee, skb);
1911 else if (*act == ACT_DELBA)
1912 ieee80211_rx_DELBA(ieee, skb);
1913 break;
1914 default:
1915 break;
1916 }
1917 return;
1918
1919}
1920
1921static void ieee80211_check_auth_response(struct ieee80211_device *ieee,
1922 struct sk_buff *skb)
1923{
1924
1925 bool bSupportNmode = true, bHalfSupportNmode = false;
1926 u16 errcode;
1927 u8 *challenge;
1928 int chlen = 0;
1929 u32 iotAction;
1930
1931 errcode = auth_parse(skb, &challenge, &chlen);
1932 if (!errcode) {
1933 if (ieee->open_wep || !challenge) {
1934 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
1935 ieee->softmac_stats.rx_auth_rs_ok++;
1936 iotAction = ieee->pHTInfo->IOTAction;
1937 if (!(iotAction & HT_IOT_ACT_PURE_N_MODE)) {
1938 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) {
1939
1940 if (IsHTHalfNmodeAPs(ieee)) {
1941 bSupportNmode = true;
1942 bHalfSupportNmode = true;
1943 } else {
1944 bSupportNmode = false;
1945 bHalfSupportNmode = false;
1946 }
1947 netdev_dbg(ieee->dev, "SEC(%d, %d)\n",
1948 bSupportNmode,
1949 bHalfSupportNmode);
1950 }
1951 }
1952
1953 if (bSupportNmode) {
1954
1955 ieee->SetWirelessMode(ieee->dev,
1956 ieee->current_network.mode);
1957 } else {
1958
1959 ieee->SetWirelessMode(ieee->dev, IEEE_G);
1960 }
1961
1962 if (ieee->current_network.mode == IEEE_N_24G &&
1963 bHalfSupportNmode) {
1964 netdev_dbg(ieee->dev, "enter half N mode\n");
1965 ieee->bHalfWirelessN24GMode = true;
1966 } else
1967 ieee->bHalfWirelessN24GMode = false;
1968
1969 ieee80211_associate_step2(ieee);
1970 } else {
1971 ieee80211_auth_challenge(ieee, challenge, chlen);
1972 }
1973 } else {
1974 ieee->softmac_stats.rx_auth_rs_err++;
1975 IEEE80211_DEBUG_MGMT("Auth response status code 0x%x", errcode);
1976 ieee80211_associate_abort(ieee);
1977 }
1978}
1979
1980inline int
1981ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
1982 struct ieee80211_rx_stats *rx_stats, u16 type,
1983 u16 stype)
1984{
1985 struct rtl_80211_hdr_3addr *header = (struct rtl_80211_hdr_3addr *) skb->data;
1986 u16 errcode;
1987 int aid;
1988 struct ieee80211_assoc_response_frame *assoc_resp;
1989
1990
1991 if(!ieee->proto_started)
1992 return 0;
1993
1994 if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
1995 ieee->iw_mode == IW_MODE_INFRA &&
1996 ieee->state == IEEE80211_LINKED))
1997
1998 tasklet_schedule(&ieee->ps_task);
1999
2000 if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
2001 WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
2002 ieee->last_rx_ps_time = jiffies;
2003
2004 switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
2005
2006 case IEEE80211_STYPE_ASSOC_RESP:
2007 case IEEE80211_STYPE_REASSOC_RESP:
2008
2009 IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
2010 WLAN_FC_GET_STYPE(header->frame_ctl));
2011 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2012 ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
2013 ieee->iw_mode == IW_MODE_INFRA){
2014 struct ieee80211_network network_resp;
2015 struct ieee80211_network *network = &network_resp;
2016
2017 errcode = assoc_parse(ieee, skb, &aid);
2018 if (!errcode) {
2019 ieee->state=IEEE80211_LINKED;
2020 ieee->assoc_id = aid;
2021 ieee->softmac_stats.rx_ass_ok++;
2022
2023
2024 if (ieee->qos_support) {
2025 assoc_resp = (struct ieee80211_assoc_response_frame *)skb->data;
2026 memset(network, 0, sizeof(*network));
2027 if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\
2028 rx_stats->len - sizeof(*assoc_resp),\
2029 network,rx_stats)){
2030 return 1;
2031 }
2032 else
2033 {
2034 memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
2035 memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
2036 }
2037 if (ieee->handle_assoc_response != NULL)
2038 ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame *)header, network);
2039 }
2040 ieee80211_associate_complete(ieee);
2041 } else {
2042
2043 ieee->softmac_stats.rx_ass_err++;
2044 printk(
2045 "Association response status code 0x%x\n",
2046 errcode);
2047 IEEE80211_DEBUG_MGMT(
2048 "Association response status code 0x%x\n",
2049 errcode);
2050 if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
2051 schedule_work(&ieee->associate_procedure_wq);
2052 } else {
2053 ieee80211_associate_abort(ieee);
2054 }
2055 }
2056 }
2057 break;
2058
2059 case IEEE80211_STYPE_ASSOC_REQ:
2060 case IEEE80211_STYPE_REASSOC_REQ:
2061
2062 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2063 ieee->iw_mode == IW_MODE_MASTER)
2064
2065 ieee80211_rx_assoc_rq(ieee, skb);
2066 break;
2067
2068 case IEEE80211_STYPE_AUTH:
2069
2070 if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) {
2071 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING
2072 && ieee->iw_mode == IW_MODE_INFRA) {
2073
2074 IEEE80211_DEBUG_MGMT("Received auth response");
2075 ieee80211_check_auth_response(ieee, skb);
2076 } else if (ieee->iw_mode == IW_MODE_MASTER) {
2077 ieee80211_rx_auth_rq(ieee, skb);
2078 }
2079 }
2080 break;
2081
2082 case IEEE80211_STYPE_PROBE_REQ:
2083
2084 if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
2085 ((ieee->iw_mode == IW_MODE_ADHOC ||
2086 ieee->iw_mode == IW_MODE_MASTER) &&
2087 ieee->state == IEEE80211_LINKED)){
2088 ieee80211_rx_probe_rq(ieee, skb);
2089 }
2090 break;
2091
2092 case IEEE80211_STYPE_DISASSOC:
2093 case IEEE80211_STYPE_DEAUTH:
2094
2095
2096
2097 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2098 ieee->state == IEEE80211_LINKED &&
2099 ieee->iw_mode == IW_MODE_INFRA){
2100
2101 ieee->state = IEEE80211_ASSOCIATING;
2102 ieee->softmac_stats.reassoc++;
2103
2104 notify_wx_assoc_event(ieee);
2105
2106 RemovePeerTS(ieee, header->addr2);
2107 schedule_work(&ieee->associate_procedure_wq);
2108 }
2109 break;
2110 case IEEE80211_STYPE_MANAGE_ACT:
2111 ieee80211_process_action(ieee, skb);
2112 break;
2113 default:
2114 return -1;
2115 }
2116
2117
2118 return 0;
2119}
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
2140{
2141
2142 unsigned int queue_index = txb->queue_index;
2143 unsigned long flags;
2144 int i;
2145 cb_desc *tcb_desc = NULL;
2146
2147 spin_lock_irqsave(&ieee->lock, flags);
2148
2149
2150 ieee80211_sta_wakeup(ieee, 0);
2151
2152
2153 ieee->stats.tx_bytes += le16_to_cpu(txb->payload_size);
2154 ieee->stats.tx_packets++;
2155 tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
2156 if (tcb_desc->bMulticast) {
2157 ieee->stats.multicast++;
2158 }
2159
2160 for(i = 0; i < txb->nr_frags; i++) {
2161#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2162 if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) ||
2163#else
2164 if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
2165#endif
2166 (!ieee->check_nic_enough_desc(ieee->dev,queue_index))||\
2167 (ieee->queue_stop)) {
2168
2169
2170
2171
2172
2173
2174#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2175 skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]);
2176#else
2177 skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
2178#endif
2179 }else{
2180 ieee->softmac_data_hard_start_xmit(
2181 txb->fragments[i],
2182 ieee->dev, ieee->rate);
2183
2184
2185
2186 }
2187 }
2188 ieee80211_txb_free(txb);
2189
2190
2191 spin_unlock_irqrestore(&ieee->lock, flags);
2192
2193}
2194EXPORT_SYMBOL(ieee80211_softmac_xmit);
2195
2196
2197static void ieee80211_resume_tx(struct ieee80211_device *ieee)
2198{
2199 int i;
2200 for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
2201
2202 if (ieee->queue_stop){
2203 ieee->tx_pending.frag = i;
2204 return;
2205 }else{
2206
2207 ieee->softmac_data_hard_start_xmit(
2208 ieee->tx_pending.txb->fragments[i],
2209 ieee->dev, ieee->rate);
2210
2211 ieee->stats.tx_packets++;
2212 netif_trans_update(ieee->dev);
2213 }
2214 }
2215
2216
2217 ieee80211_txb_free(ieee->tx_pending.txb);
2218 ieee->tx_pending.txb = NULL;
2219}
2220
2221
2222void ieee80211_reset_queue(struct ieee80211_device *ieee)
2223{
2224 unsigned long flags;
2225
2226 spin_lock_irqsave(&ieee->lock, flags);
2227 init_mgmt_queue(ieee);
2228 if (ieee->tx_pending.txb) {
2229 ieee80211_txb_free(ieee->tx_pending.txb);
2230 ieee->tx_pending.txb = NULL;
2231 }
2232 ieee->queue_stop = 0;
2233 spin_unlock_irqrestore(&ieee->lock, flags);
2234
2235}
2236EXPORT_SYMBOL(ieee80211_reset_queue);
2237
2238void ieee80211_wake_queue(struct ieee80211_device *ieee)
2239{
2240
2241 unsigned long flags;
2242 struct sk_buff *skb;
2243 struct rtl_80211_hdr_3addr *header;
2244
2245 spin_lock_irqsave(&ieee->lock, flags);
2246 if (! ieee->queue_stop) goto exit;
2247
2248 ieee->queue_stop = 0;
2249
2250 if (ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) {
2251 while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
2252
2253 header = (struct rtl_80211_hdr_3addr *) skb->data;
2254
2255 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2256
2257 if (ieee->seq_ctrl[0] == 0xFFF)
2258 ieee->seq_ctrl[0] = 0;
2259 else
2260 ieee->seq_ctrl[0]++;
2261
2262 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
2263
2264 }
2265 }
2266 if (!ieee->queue_stop && ieee->tx_pending.txb)
2267 ieee80211_resume_tx(ieee);
2268
2269 if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)) {
2270 ieee->softmac_stats.swtxawake++;
2271 netif_wake_queue(ieee->dev);
2272 }
2273
2274exit :
2275 spin_unlock_irqrestore(&ieee->lock, flags);
2276}
2277EXPORT_SYMBOL(ieee80211_wake_queue);
2278
2279void ieee80211_stop_queue(struct ieee80211_device *ieee)
2280{
2281
2282
2283
2284 if (!netif_queue_stopped(ieee->dev)) {
2285 netif_stop_queue(ieee->dev);
2286 ieee->softmac_stats.swtxstop++;
2287 }
2288 ieee->queue_stop = 1;
2289
2290
2291}
2292EXPORT_SYMBOL(ieee80211_stop_queue);
2293
2294
2295void ieee80211_start_master_bss(struct ieee80211_device *ieee)
2296{
2297 ieee->assoc_id = 1;
2298
2299 if (ieee->current_network.ssid_len == 0) {
2300 strncpy(ieee->current_network.ssid,
2301 IEEE80211_DEFAULT_TX_ESSID,
2302 IW_ESSID_MAX_SIZE);
2303
2304 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2305 ieee->ssid_set = 1;
2306 }
2307
2308 memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
2309
2310 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2311 ieee->state = IEEE80211_LINKED;
2312 ieee->link_change(ieee->dev);
2313 notify_wx_assoc_event(ieee);
2314
2315 if (ieee->data_hard_resume)
2316 ieee->data_hard_resume(ieee->dev);
2317
2318 netif_carrier_on(ieee->dev);
2319}
2320
2321static void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
2322{
2323 if (ieee->raw_tx) {
2324
2325 if (ieee->data_hard_resume)
2326 ieee->data_hard_resume(ieee->dev);
2327
2328 netif_carrier_on(ieee->dev);
2329 }
2330}
2331static void ieee80211_start_ibss_wq(struct work_struct *work)
2332{
2333
2334 struct delayed_work *dwork = to_delayed_work(work);
2335 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
2336
2337
2338
2339
2340
2341
2342
2343 if (!ieee->proto_started) {
2344 printk("==========oh driver down return\n");
2345 return;
2346 }
2347 mutex_lock(&ieee->wx_mutex);
2348
2349 if (ieee->current_network.ssid_len == 0) {
2350 strcpy(ieee->current_network.ssid, IEEE80211_DEFAULT_TX_ESSID);
2351 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2352 ieee->ssid_set = 1;
2353 }
2354
2355
2356 ieee80211_softmac_check_all_nets(ieee);
2357
2358
2359
2360 if (ieee->state == IEEE80211_NOLINK)
2361 ieee->current_network.channel = 6;
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376 if (ieee->state == IEEE80211_NOLINK)
2377 ieee80211_start_scan_syncro(ieee);
2378
2379
2380 if (ieee->state == IEEE80211_NOLINK) {
2381 printk("creating new IBSS cell\n");
2382 if(!ieee->wap_set)
2383 random_ether_addr(ieee->current_network.bssid);
2384
2385 if(ieee->modulation & IEEE80211_CCK_MODULATION){
2386
2387 ieee->current_network.rates_len = 4;
2388
2389 ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
2390 ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
2391 ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
2392 ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
2393
2394 }else
2395 ieee->current_network.rates_len = 0;
2396
2397 if(ieee->modulation & IEEE80211_OFDM_MODULATION){
2398 ieee->current_network.rates_ex_len = 8;
2399
2400 ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
2401 ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
2402 ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
2403 ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
2404 ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
2405 ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
2406 ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
2407 ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
2408
2409 ieee->rate = 108;
2410 }else{
2411 ieee->current_network.rates_ex_len = 0;
2412 ieee->rate = 22;
2413 }
2414
2415
2416 ieee->current_network.QoS_Enable = 0;
2417 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2418 ieee->current_network.atim_window = 0;
2419 ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
2420 if(ieee->short_slot)
2421 ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
2422
2423 }
2424
2425 ieee->state = IEEE80211_LINKED;
2426
2427 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2428 ieee->link_change(ieee->dev);
2429
2430 notify_wx_assoc_event(ieee);
2431
2432 ieee80211_start_send_beacons(ieee);
2433
2434 if (ieee->data_hard_resume)
2435 ieee->data_hard_resume(ieee->dev);
2436 netif_carrier_on(ieee->dev);
2437
2438 mutex_unlock(&ieee->wx_mutex);
2439}
2440
2441inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
2442{
2443 schedule_delayed_work(&ieee->start_ibss_wq, 150);
2444}
2445
2446
2447void ieee80211_start_bss(struct ieee80211_device *ieee)
2448{
2449 unsigned long flags;
2450
2451
2452
2453
2454 if (IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
2455 {
2456 if (! ieee->bGlobalDomain)
2457 {
2458 return;
2459 }
2460 }
2461
2462
2463
2464
2465
2466 ieee80211_softmac_check_all_nets(ieee);
2467
2468
2469
2470
2471
2472
2473
2474
2475 spin_lock_irqsave(&ieee->lock, flags);
2476
2477 if (ieee->state == IEEE80211_NOLINK) {
2478 ieee->actscanning = true;
2479 ieee80211_start_scan(ieee);
2480 }
2481 spin_unlock_irqrestore(&ieee->lock, flags);
2482}
2483
2484
2485void ieee80211_disassociate(struct ieee80211_device *ieee)
2486{
2487
2488
2489 netif_carrier_off(ieee->dev);
2490 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
2491 ieee80211_reset_queue(ieee);
2492
2493 if (ieee->data_hard_stop)
2494 ieee->data_hard_stop(ieee->dev);
2495 if(IS_DOT11D_ENABLE(ieee))
2496 Dot11d_Reset(ieee);
2497 ieee->state = IEEE80211_NOLINK;
2498 ieee->is_set_key = false;
2499 ieee->link_change(ieee->dev);
2500
2501 notify_wx_assoc_event(ieee);
2502
2503}
2504EXPORT_SYMBOL(ieee80211_disassociate);
2505
2506static void ieee80211_associate_retry_wq(struct work_struct *work)
2507{
2508 struct delayed_work *dwork = to_delayed_work(work);
2509 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
2510 unsigned long flags;
2511
2512 mutex_lock(&ieee->wx_mutex);
2513 if(!ieee->proto_started)
2514 goto exit;
2515
2516 if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
2517 goto exit;
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532 ieee->state = IEEE80211_NOLINK;
2533
2534 ieee80211_softmac_check_all_nets(ieee);
2535
2536 spin_lock_irqsave(&ieee->lock, flags);
2537
2538 if(ieee->state == IEEE80211_NOLINK)
2539 ieee80211_start_scan(ieee);
2540
2541 spin_unlock_irqrestore(&ieee->lock, flags);
2542
2543exit:
2544 mutex_unlock(&ieee->wx_mutex);
2545}
2546
2547struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
2548{
2549 u8 broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2550
2551 struct sk_buff *skb;
2552 struct ieee80211_probe_response *b;
2553
2554 skb = ieee80211_probe_resp(ieee, broadcast_addr);
2555
2556 if (!skb)
2557 return NULL;
2558
2559 b = (struct ieee80211_probe_response *) skb->data;
2560 b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
2561
2562 return skb;
2563
2564}
2565
2566struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
2567{
2568 struct sk_buff *skb;
2569 struct ieee80211_probe_response *b;
2570
2571 skb = ieee80211_get_beacon_(ieee);
2572 if(!skb)
2573 return NULL;
2574
2575 b = (struct ieee80211_probe_response *) skb->data;
2576 b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2577
2578 if (ieee->seq_ctrl[0] == 0xFFF)
2579 ieee->seq_ctrl[0] = 0;
2580 else
2581 ieee->seq_ctrl[0]++;
2582
2583 return skb;
2584}
2585EXPORT_SYMBOL(ieee80211_get_beacon);
2586
2587void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
2588{
2589 ieee->sync_scan_hurryup = 1;
2590 mutex_lock(&ieee->wx_mutex);
2591 ieee80211_stop_protocol(ieee);
2592 mutex_unlock(&ieee->wx_mutex);
2593}
2594EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
2595
2596void ieee80211_stop_protocol(struct ieee80211_device *ieee)
2597{
2598 if (!ieee->proto_started)
2599 return;
2600
2601 ieee->proto_started = 0;
2602
2603 ieee80211_stop_send_beacons(ieee);
2604 del_timer_sync(&ieee->associate_timer);
2605 cancel_delayed_work(&ieee->associate_retry_wq);
2606 cancel_delayed_work(&ieee->start_ibss_wq);
2607 ieee80211_stop_scan(ieee);
2608
2609 ieee80211_disassociate(ieee);
2610 RemoveAllTS(ieee);
2611}
2612
2613void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
2614{
2615 ieee->sync_scan_hurryup = 0;
2616 mutex_lock(&ieee->wx_mutex);
2617 ieee80211_start_protocol(ieee);
2618 mutex_unlock(&ieee->wx_mutex);
2619}
2620EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
2621
2622void ieee80211_start_protocol(struct ieee80211_device *ieee)
2623{
2624 short ch = 0;
2625 int i = 0;
2626 if (ieee->proto_started)
2627 return;
2628
2629 ieee->proto_started = 1;
2630
2631 if (ieee->current_network.channel == 0) {
2632 do{
2633 ch++;
2634 if (ch > MAX_CHANNEL_NUMBER)
2635 return;
2636 }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
2637 ieee->current_network.channel = ch;
2638 }
2639
2640 if (ieee->current_network.beacon_interval == 0)
2641 ieee->current_network.beacon_interval = 100;
2642
2643
2644
2645 for(i = 0; i < 17; i++) {
2646 ieee->last_rxseq_num[i] = -1;
2647 ieee->last_rxfrag_num[i] = -1;
2648 ieee->last_packet_time[i] = 0;
2649 }
2650
2651 ieee->init_wmmparam_flag = 0;
2652
2653
2654
2655
2656
2657
2658
2659 if (ieee->iw_mode == IW_MODE_INFRA)
2660 ieee80211_start_bss(ieee);
2661
2662 else if (ieee->iw_mode == IW_MODE_ADHOC)
2663 ieee80211_start_ibss(ieee);
2664
2665 else if (ieee->iw_mode == IW_MODE_MASTER)
2666 ieee80211_start_master_bss(ieee);
2667
2668 else if(ieee->iw_mode == IW_MODE_MONITOR)
2669 ieee80211_start_monitor_mode(ieee);
2670}
2671
2672
2673#define DRV_NAME "Ieee80211"
2674void ieee80211_softmac_init(struct ieee80211_device *ieee)
2675{
2676 int i;
2677 memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
2678
2679 ieee->state = IEEE80211_NOLINK;
2680 ieee->sync_scan_hurryup = 0;
2681 for(i = 0; i < 5; i++) {
2682 ieee->seq_ctrl[i] = 0;
2683 }
2684 ieee->pDot11dInfo = kzalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
2685 if (!ieee->pDot11dInfo)
2686 IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
2687
2688 ieee->LinkDetectInfo.SlotNum = 2;
2689 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
2690 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
2691
2692 ieee->assoc_id = 0;
2693 ieee->queue_stop = 0;
2694 ieee->scanning = 0;
2695 ieee->softmac_features = 0;
2696 ieee->wap_set = 0;
2697 ieee->ssid_set = 0;
2698 ieee->proto_started = 0;
2699 ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
2700 ieee->rate = 22;
2701 ieee->ps = IEEE80211_PS_DISABLED;
2702 ieee->sta_sleep = 0;
2703 ieee->Regdot11HTOperationalRateSet[0]= 0xff;
2704 ieee->Regdot11HTOperationalRateSet[1]= 0xff;
2705 ieee->Regdot11HTOperationalRateSet[4]= 0x01;
2706
2707 ieee->actscanning = false;
2708 ieee->beinretry = false;
2709 ieee->is_set_key = false;
2710 init_mgmt_queue(ieee);
2711
2712 ieee->sta_edca_param[0] = 0x0000A403;
2713 ieee->sta_edca_param[1] = 0x0000A427;
2714 ieee->sta_edca_param[2] = 0x005E4342;
2715 ieee->sta_edca_param[3] = 0x002F3262;
2716 ieee->aggregation = true;
2717 ieee->enable_rx_imm_BA = true;
2718 ieee->tx_pending.txb = NULL;
2719
2720 setup_timer(&ieee->associate_timer, ieee80211_associate_abort_cb,
2721 (unsigned long)ieee);
2722
2723 setup_timer(&ieee->beacon_timer, ieee80211_send_beacon_cb,
2724 (unsigned long)ieee);
2725
2726
2727 INIT_DELAYED_WORK(&ieee->start_ibss_wq, ieee80211_start_ibss_wq);
2728 INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
2729 INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
2730 INIT_DELAYED_WORK(&ieee->softmac_scan_wq, ieee80211_softmac_scan_wq);
2731 INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
2732 INIT_WORK(&ieee->wx_sync_scan_wq, ieee80211_wx_sync_scan_wq);
2733
2734
2735 mutex_init(&ieee->wx_mutex);
2736 mutex_init(&ieee->scan_mutex);
2737
2738 spin_lock_init(&ieee->mgmt_tx_lock);
2739 spin_lock_init(&ieee->beacon_lock);
2740
2741 tasklet_init(&ieee->ps_task,
2742 (void(*)(unsigned long)) ieee80211_sta_ps,
2743 (unsigned long)ieee);
2744
2745}
2746
2747void ieee80211_softmac_free(struct ieee80211_device *ieee)
2748{
2749 mutex_lock(&ieee->wx_mutex);
2750 kfree(ieee->pDot11dInfo);
2751 ieee->pDot11dInfo = NULL;
2752 del_timer_sync(&ieee->associate_timer);
2753
2754 cancel_delayed_work(&ieee->associate_retry_wq);
2755
2756 mutex_unlock(&ieee->wx_mutex);
2757}
2758
2759
2760
2761
2762
2763
2764
2765static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
2766{
2767
2768
2769 printk("%s WPA\n",value ? "enabling" : "disabling");
2770 ieee->wpa_enabled = value;
2771 return 0;
2772}
2773
2774
2775static void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee,
2776 char *wpa_ie, int wpa_ie_len)
2777{
2778
2779 ieee80211_wpa_enable(ieee, 1);
2780
2781 ieee80211_disassociate(ieee);
2782}
2783
2784
2785static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
2786{
2787
2788 int ret = 0;
2789
2790 switch (command) {
2791 case IEEE_MLME_STA_DEAUTH:
2792
2793 break;
2794
2795 case IEEE_MLME_STA_DISASSOC:
2796 ieee80211_disassociate(ieee);
2797 break;
2798
2799 default:
2800 printk("Unknown MLME request: %d\n", command);
2801 ret = -EOPNOTSUPP;
2802 }
2803
2804 return ret;
2805}
2806
2807
2808static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
2809 struct ieee_param *param, int plen)
2810{
2811 u8 *buf;
2812
2813 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
2814 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
2815 return -EINVAL;
2816
2817 if (param->u.wpa_ie.len) {
2818 buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len,
2819 GFP_KERNEL);
2820 if (buf == NULL)
2821 return -ENOMEM;
2822
2823 kfree(ieee->wpa_ie);
2824 ieee->wpa_ie = buf;
2825 ieee->wpa_ie_len = param->u.wpa_ie.len;
2826 } else {
2827 kfree(ieee->wpa_ie);
2828 ieee->wpa_ie = NULL;
2829 ieee->wpa_ie_len = 0;
2830 }
2831
2832 ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
2833 return 0;
2834}
2835
2836#define AUTH_ALG_OPEN_SYSTEM 0x1
2837#define AUTH_ALG_SHARED_KEY 0x2
2838
2839static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
2840{
2841
2842 struct ieee80211_security sec = {
2843 .flags = SEC_AUTH_MODE,
2844 };
2845
2846 if (value & AUTH_ALG_SHARED_KEY) {
2847 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
2848 ieee->open_wep = 0;
2849 ieee->auth_mode = 1;
2850 } else if (value & AUTH_ALG_OPEN_SYSTEM){
2851 sec.auth_mode = WLAN_AUTH_OPEN;
2852 ieee->open_wep = 1;
2853 ieee->auth_mode = 0;
2854 }
2855 else if (value & IW_AUTH_ALG_LEAP){
2856 sec.auth_mode = WLAN_AUTH_LEAP;
2857 ieee->open_wep = 1;
2858 ieee->auth_mode = 2;
2859 }
2860
2861
2862 if (ieee->set_security)
2863 ieee->set_security(ieee->dev, &sec);
2864
2865
2866
2867 return 0;
2868}
2869
2870static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
2871{
2872 int ret=0;
2873 unsigned long flags;
2874
2875 switch (name) {
2876 case IEEE_PARAM_WPA_ENABLED:
2877 ret = ieee80211_wpa_enable(ieee, value);
2878 break;
2879
2880 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2881 ieee->tkip_countermeasures=value;
2882 break;
2883
2884 case IEEE_PARAM_DROP_UNENCRYPTED: {
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896 struct ieee80211_security sec = {
2897 .flags = SEC_ENABLED,
2898 .enabled = value,
2899 };
2900 ieee->drop_unencrypted = value;
2901
2902
2903
2904 if (!value) {
2905 sec.flags |= SEC_LEVEL;
2906 sec.level = SEC_LEVEL_0;
2907 }
2908 else {
2909 sec.flags |= SEC_LEVEL;
2910 sec.level = SEC_LEVEL_1;
2911 }
2912 if (ieee->set_security)
2913 ieee->set_security(ieee->dev, &sec);
2914 break;
2915 }
2916
2917 case IEEE_PARAM_PRIVACY_INVOKED:
2918 ieee->privacy_invoked=value;
2919 break;
2920
2921 case IEEE_PARAM_AUTH_ALGS:
2922 ret = ieee80211_wpa_set_auth_algs(ieee, value);
2923 break;
2924
2925 case IEEE_PARAM_IEEE_802_1X:
2926 ieee->ieee802_1x=value;
2927 break;
2928 case IEEE_PARAM_WPAX_SELECT:
2929
2930 spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags);
2931 ieee->wpax_type_set = 1;
2932 ieee->wpax_type_notify = value;
2933 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags);
2934 break;
2935
2936 default:
2937 printk("Unknown WPA param: %d\n",name);
2938 ret = -EOPNOTSUPP;
2939 }
2940
2941 return ret;
2942}
2943
2944
2945
2946static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
2947 struct ieee_param *param, int param_len)
2948{
2949 int ret = 0;
2950
2951 struct ieee80211_crypto_ops *ops;
2952 struct ieee80211_crypt_data **crypt;
2953
2954 struct ieee80211_security sec = {
2955 .flags = 0,
2956 };
2957
2958 param->u.crypt.err = 0;
2959 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
2960
2961 if (param_len !=
2962 (int) ((char *) param->u.crypt.key - (char *) param) +
2963 param->u.crypt.key_len) {
2964 printk("Len mismatch %d, %d\n", param_len,
2965 param->u.crypt.key_len);
2966 return -EINVAL;
2967 }
2968 if (is_broadcast_ether_addr(param->sta_addr)) {
2969 if (param->u.crypt.idx >= WEP_KEYS)
2970 return -EINVAL;
2971 crypt = &ieee->crypt[param->u.crypt.idx];
2972 } else {
2973 return -EINVAL;
2974 }
2975
2976 if (strcmp(param->u.crypt.alg, "none") == 0) {
2977 if (crypt) {
2978 sec.enabled = 0;
2979
2980
2981 sec.level = SEC_LEVEL_0;
2982 sec.flags |= SEC_ENABLED | SEC_LEVEL;
2983 ieee80211_crypt_delayed_deinit(ieee, crypt);
2984 }
2985 goto done;
2986 }
2987 sec.enabled = 1;
2988
2989
2990 sec.flags |= SEC_ENABLED;
2991
2992
2993 if (!(ieee->host_encrypt || ieee->host_decrypt) &&
2994 strcmp(param->u.crypt.alg, "TKIP"))
2995 goto skip_host_crypt;
2996
2997 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
2998 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
2999 request_module("ieee80211_crypt_wep");
3000 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3001
3002 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
3003 request_module("ieee80211_crypt_tkip");
3004 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3005 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
3006 request_module("ieee80211_crypt_ccmp");
3007 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3008 }
3009 if (ops == NULL) {
3010 printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
3011 param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
3012 ret = -EINVAL;
3013 goto done;
3014 }
3015
3016 if (*crypt == NULL || (*crypt)->ops != ops) {
3017 struct ieee80211_crypt_data *new_crypt;
3018
3019 ieee80211_crypt_delayed_deinit(ieee, crypt);
3020
3021 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
3022 if (new_crypt == NULL) {
3023 ret = -ENOMEM;
3024 goto done;
3025 }
3026 new_crypt->ops = ops;
3027 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
3028 new_crypt->priv =
3029 new_crypt->ops->init(param->u.crypt.idx);
3030
3031 if (new_crypt->priv == NULL) {
3032 kfree(new_crypt);
3033 param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
3034 ret = -EINVAL;
3035 goto done;
3036 }
3037
3038 *crypt = new_crypt;
3039 }
3040
3041 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
3042 (*crypt)->ops->set_key(param->u.crypt.key,
3043 param->u.crypt.key_len, param->u.crypt.seq,
3044 (*crypt)->priv) < 0) {
3045 printk("key setting failed\n");
3046 param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
3047 ret = -EINVAL;
3048 goto done;
3049 }
3050
3051 skip_host_crypt:
3052 if (param->u.crypt.set_tx) {
3053 ieee->tx_keyidx = param->u.crypt.idx;
3054 sec.active_key = param->u.crypt.idx;
3055 sec.flags |= SEC_ACTIVE_KEY;
3056 } else
3057 sec.flags &= ~SEC_ACTIVE_KEY;
3058
3059 if (param->u.crypt.alg != NULL) {
3060 memcpy(sec.keys[param->u.crypt.idx],
3061 param->u.crypt.key,
3062 param->u.crypt.key_len);
3063 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
3064 sec.flags |= (1 << param->u.crypt.idx);
3065
3066 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3067 sec.flags |= SEC_LEVEL;
3068 sec.level = SEC_LEVEL_1;
3069 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3070 sec.flags |= SEC_LEVEL;
3071 sec.level = SEC_LEVEL_2;
3072 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3073 sec.flags |= SEC_LEVEL;
3074 sec.level = SEC_LEVEL_3;
3075 }
3076 }
3077 done:
3078 if (ieee->set_security)
3079 ieee->set_security(ieee->dev, &sec);
3080
3081
3082
3083
3084
3085
3086 if (ieee->reset_on_keychange &&
3087 ieee->iw_mode != IW_MODE_INFRA &&
3088 ieee->reset_port &&
3089 ieee->reset_port(ieee->dev)) {
3090 printk("reset_port failed\n");
3091 param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
3092 return -EINVAL;
3093 }
3094
3095 return ret;
3096}
3097
3098static inline struct sk_buff *ieee80211_disassociate_skb(
3099 struct ieee80211_network *beacon,
3100 struct ieee80211_device *ieee,
3101 u8 asRsn)
3102{
3103 struct sk_buff *skb;
3104 struct ieee80211_disassoc *disass;
3105
3106 skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc));
3107 if (!skb)
3108 return NULL;
3109
3110 disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc));
3111 disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
3112 disass->header.duration_id = 0;
3113
3114 memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
3115 memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
3116 memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
3117
3118 disass->reason = cpu_to_le16(asRsn);
3119 return skb;
3120}
3121
3122
3123void
3124SendDisassociation(
3125 struct ieee80211_device *ieee,
3126 u8 *asSta,
3127 u8 asRsn
3128)
3129{
3130 struct ieee80211_network *beacon = &ieee->current_network;
3131 struct sk_buff *skb;
3132 skb = ieee80211_disassociate_skb(beacon,ieee,asRsn);
3133 if (skb) {
3134 softmac_mgmt_xmit(skb, ieee);
3135
3136 }
3137}
3138EXPORT_SYMBOL(SendDisassociation);
3139
3140int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
3141{
3142 struct ieee_param *param;
3143 int ret=0;
3144
3145 mutex_lock(&ieee->wx_mutex);
3146
3147
3148 if (p->length < sizeof(struct ieee_param) || !p->pointer) {
3149 ret = -EINVAL;
3150 goto out;
3151 }
3152
3153 param = memdup_user(p->pointer, p->length);
3154 if (IS_ERR(param)) {
3155 ret = PTR_ERR(param);
3156 goto out;
3157 }
3158
3159 switch (param->cmd) {
3160
3161 case IEEE_CMD_SET_WPA_PARAM:
3162 ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
3163 param->u.wpa_param.value);
3164 break;
3165
3166 case IEEE_CMD_SET_WPA_IE:
3167 ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
3168 break;
3169
3170 case IEEE_CMD_SET_ENCRYPTION:
3171 ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
3172 break;
3173
3174 case IEEE_CMD_MLME:
3175 ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
3176 param->u.mlme.reason_code);
3177 break;
3178
3179 default:
3180 printk("Unknown WPA supplicant request: %d\n",param->cmd);
3181 ret = -EOPNOTSUPP;
3182 break;
3183 }
3184
3185 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
3186 ret = -EFAULT;
3187
3188 kfree(param);
3189out:
3190 mutex_unlock(&ieee->wx_mutex);
3191
3192 return ret;
3193}
3194EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
3195
3196void notify_wx_assoc_event(struct ieee80211_device *ieee)
3197{
3198 union iwreq_data wrqu;
3199 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3200 if (ieee->state == IEEE80211_LINKED)
3201 memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
3202 else
3203 eth_zero_addr(wrqu.ap_addr.sa_data);
3204 wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
3205}
3206EXPORT_SYMBOL(notify_wx_assoc_event);
3207