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