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