aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/rtl8192e/rtllib_softmac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/rtl8192e/rtllib_softmac.c')
-rw-r--r--drivers/staging/rtl8192e/rtllib_softmac.c4150
1 files changed, 4150 insertions, 0 deletions
diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c
new file mode 100644
index 00000000000..a843de99ed3
--- /dev/null
+++ b/drivers/staging/rtl8192e/rtllib_softmac.c
@@ -0,0 +1,4150 @@
1/* IEEE 802.11 SoftMAC layer
2 * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
3 *
4 * Mostly extracted from the rtl8180-sa2400 driver for the
5 * in-kernel generic ieee802.11 stack.
6 *
7 * Few lines might be stolen from other part of the rtllib
8 * stack. Copyright who own it's copyright
9 *
10 * WPA code stolen from the ipw2200 driver.
11 * Copyright who own it's copyright.
12 *
13 * released under the GPL
14 */
15
16
17#include "rtllib.h"
18#include "rtl_core.h"
19
20#include <linux/random.h>
21#include <linux/delay.h>
22#include <linux/version.h>
23#include <asm/uaccess.h>
24#ifdef ENABLE_DOT11D
25#include "dot11d.h"
26#endif
27
28#ifdef RTK_DMP_PLATFORM
29#include <linux/usb_setting.h>
30#endif
31extern void _setup_timer( struct timer_list*, void*, unsigned long );
32u8 rsn_authen_cipher_suite[16][4] = {
33 {0x00,0x0F,0xAC,0x00},
34 {0x00,0x0F,0xAC,0x01},
35 {0x00,0x0F,0xAC,0x02},
36 {0x00,0x0F,0xAC,0x03},
37 {0x00,0x0F,0xAC,0x04},
38 {0x00,0x0F,0xAC,0x05},
39};
40
41short rtllib_is_54g(struct rtllib_network *net)
42{
43 return ((net->rates_ex_len > 0) || (net->rates_len > 4));
44}
45
46short rtllib_is_shortslot(struct rtllib_network net)
47{
48 return (net.capability & WLAN_CAPABILITY_SHORT_SLOT_TIME);
49}
50
51/* returns the total length needed for pleacing the RATE MFIE
52 * tag and the EXTENDED RATE MFIE tag if needed.
53 * It encludes two bytes per tag for the tag itself and its len
54 */
55unsigned int rtllib_MFIE_rate_len(struct rtllib_device *ieee)
56{
57 unsigned int rate_len = 0;
58
59 if (ieee->modulation & RTLLIB_CCK_MODULATION)
60 rate_len = RTLLIB_CCK_RATE_LEN + 2;
61
62 if (ieee->modulation & RTLLIB_OFDM_MODULATION)
63
64 rate_len += RTLLIB_OFDM_RATE_LEN + 2;
65
66 return rate_len;
67}
68
69/* pleace the MFIE rate, tag to the memory (double) poined.
70 * Then it updates the pointer so that
71 * it points after the new MFIE tag added.
72 */
73void rtllib_MFIE_Brate(struct rtllib_device *ieee, u8 **tag_p)
74{
75 u8 *tag = *tag_p;
76
77 if (ieee->modulation & RTLLIB_CCK_MODULATION){
78 *tag++ = MFIE_TYPE_RATES;
79 *tag++ = 4;
80 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_1MB;
81 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_2MB;
82 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_5MB;
83 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_11MB;
84 }
85
86 /* We may add an option for custom rates that specific HW might support */
87 *tag_p = tag;
88}
89
90void rtllib_MFIE_Grate(struct rtllib_device *ieee, u8 **tag_p)
91{
92 u8 *tag = *tag_p;
93
94 if (ieee->modulation & RTLLIB_OFDM_MODULATION){
95
96 *tag++ = MFIE_TYPE_RATES_EX;
97 *tag++ = 8;
98 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_6MB;
99 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_9MB;
100 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_12MB;
101 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_18MB;
102 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_24MB;
103 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_36MB;
104 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_48MB;
105 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_54MB;
106
107 }
108
109 /* We may add an option for custom rates that specific HW might support */
110 *tag_p = tag;
111}
112
113void rtllib_WMM_Info(struct rtllib_device *ieee, u8 **tag_p) {
114 u8 *tag = *tag_p;
115
116 *tag++ = MFIE_TYPE_GENERIC;
117 *tag++ = 7;
118 *tag++ = 0x00;
119 *tag++ = 0x50;
120 *tag++ = 0xf2;
121 *tag++ = 0x02;
122 *tag++ = 0x00;
123 *tag++ = 0x01;
124#ifdef SUPPORT_USPD
125 if (ieee->current_network.wmm_info & 0x80) {
126 *tag++ = 0x0f|MAX_SP_Len;
127 } else {
128 *tag++ = MAX_SP_Len;
129 }
130#else
131 *tag++ = MAX_SP_Len;
132#endif
133 *tag_p = tag;
134}
135
136void rtllib_TURBO_Info(struct rtllib_device *ieee, u8 **tag_p) {
137 u8 *tag = *tag_p;
138
139 *tag++ = MFIE_TYPE_GENERIC;
140 *tag++ = 7;
141 *tag++ = 0x00;
142 *tag++ = 0xe0;
143 *tag++ = 0x4c;
144 *tag++ = 0x01;
145 *tag++ = 0x02;
146 *tag++ = 0x11;
147 *tag++ = 0x00;
148
149 *tag_p = tag;
150 printk(KERN_ALERT "This is enable turbo mode IE process\n");
151}
152
153void enqueue_mgmt(struct rtllib_device *ieee, struct sk_buff *skb)
154{
155 int nh;
156 nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
157
158/*
159 * if the queue is full but we have newer frames then
160 * just overwrites the oldest.
161 *
162 * if (nh == ieee->mgmt_queue_tail)
163 * return -1;
164 */
165 ieee->mgmt_queue_head = nh;
166 ieee->mgmt_queue_ring[nh] = skb;
167
168}
169
170struct sk_buff *dequeue_mgmt(struct rtllib_device *ieee)
171{
172 struct sk_buff *ret;
173
174 if (ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
175 return NULL;
176
177 ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
178
179 ieee->mgmt_queue_tail =
180 (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
181
182 return ret;
183}
184
185void init_mgmt_queue(struct rtllib_device *ieee)
186{
187 ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
188}
189
190
191u8
192MgntQuery_TxRateExcludeCCKRates(struct rtllib_device *ieee)
193{
194 u16 i;
195 u8 QueryRate = 0;
196 u8 BasicRate;
197
198
199 for ( i = 0; i < ieee->current_network.rates_len; i++)
200 {
201 BasicRate = ieee->current_network.rates[i]&0x7F;
202 if (!rtllib_is_cck_rate(BasicRate))
203 {
204 if (QueryRate == 0)
205 {
206 QueryRate = BasicRate;
207 }
208 else
209 {
210 if (BasicRate < QueryRate)
211 {
212 QueryRate = BasicRate;
213 }
214 }
215 }
216 }
217
218 if (QueryRate == 0)
219 {
220 QueryRate = 12;
221 printk("No BasicRate found!!\n");
222 }
223 return QueryRate;
224}
225
226u8 MgntQuery_MgntFrameTxRate(struct rtllib_device *ieee)
227{
228 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
229 u8 rate;
230
231 if (pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M)
232 rate = 0x0c;
233 else
234 rate = ieee->basic_rate & 0x7f;
235
236 if (rate == 0){
237 if (ieee->mode == IEEE_A||
238 ieee->mode== IEEE_N_5G||
239 (ieee->mode== IEEE_N_24G&&!pHTInfo->bCurSuppCCK))
240 rate = 0x0c;
241 else
242 rate = 0x02;
243 }
244
245 return rate;
246}
247
248
249void rtllib_sta_wakeup(struct rtllib_device *ieee, short nl);
250
251inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee)
252{
253 unsigned long flags;
254 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
255 struct rtllib_hdr_3addr *header=
256 (struct rtllib_hdr_3addr *) skb->data;
257
258 cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8);
259 spin_lock_irqsave(&ieee->lock, flags);
260
261 /* called with 2nd param 0, no mgmt lock required */
262 rtllib_sta_wakeup(ieee,0);
263
264 if (header->frame_ctl == RTLLIB_STYPE_BEACON)
265 tcb_desc->queue_index = BEACON_QUEUE;
266 else
267 tcb_desc->queue_index = MGNT_QUEUE;
268
269 if (ieee->disable_mgnt_queue)
270 tcb_desc->queue_index = HIGH_QUEUE;
271
272 tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
273 tcb_desc->RATRIndex = 7;
274 tcb_desc->bTxDisableRateFallBack = 1;
275 tcb_desc->bTxUseDriverAssingedRate = 1;
276 if (single) {
277 if (ieee->queue_stop){
278 enqueue_mgmt(ieee,skb);
279 }else{
280 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
281
282 if (ieee->seq_ctrl[0] == 0xFFF)
283 ieee->seq_ctrl[0] = 0;
284 else
285 ieee->seq_ctrl[0]++;
286
287 /* avoid watchdog triggers */
288 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
289 }
290
291 spin_unlock_irqrestore(&ieee->lock, flags);
292 }else{
293 spin_unlock_irqrestore(&ieee->lock, flags);
294 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
295
296 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
297
298 if (ieee->seq_ctrl[0] == 0xFFF)
299 ieee->seq_ctrl[0] = 0;
300 else
301 ieee->seq_ctrl[0]++;
302
303 /* check wether the managed packet queued greater than 5 */
304 if (!ieee->check_nic_enough_desc(ieee->dev,tcb_desc->queue_index)||\
305 (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)||\
306 (ieee->queue_stop) ) {
307 /* insert the skb packet to the management queue */
308 /* as for the completion function, it does not need
309 * to check it any more.
310 * */
311 printk("%s():insert to waitqueue, queue_index:%d!\n",__func__,tcb_desc->queue_index);
312 skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb);
313 } else {
314 ieee->softmac_hard_start_xmit(skb,ieee->dev);
315 }
316 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
317 }
318}
319
320inline void softmac_ps_mgmt_xmit(struct sk_buff *skb,
321 struct rtllib_device *ieee)
322{
323 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
324 struct rtllib_hdr_3addr *header =
325 (struct rtllib_hdr_3addr *) skb->data;
326 u16 fc,type,stype;
327 cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8);
328
329 fc = header->frame_ctl;
330 type = WLAN_FC_GET_TYPE(fc);
331 stype = WLAN_FC_GET_STYPE(fc);
332
333
334 if (stype != RTLLIB_STYPE_PSPOLL)
335 tcb_desc->queue_index = MGNT_QUEUE;
336 else
337 tcb_desc->queue_index = HIGH_QUEUE;
338
339 if (ieee->disable_mgnt_queue)
340 tcb_desc->queue_index = HIGH_QUEUE;
341
342
343 tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
344 tcb_desc->RATRIndex = 7;
345 tcb_desc->bTxDisableRateFallBack = 1;
346 tcb_desc->bTxUseDriverAssingedRate = 1;
347 if (single) {
348 if (type != RTLLIB_FTYPE_CTL) {
349 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
350
351 if (ieee->seq_ctrl[0] == 0xFFF)
352 ieee->seq_ctrl[0] = 0;
353 else
354 ieee->seq_ctrl[0]++;
355
356 }
357 /* avoid watchdog triggers */
358 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
359
360 } else {
361 if (type != RTLLIB_FTYPE_CTL) {
362 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
363
364 if (ieee->seq_ctrl[0] == 0xFFF)
365 ieee->seq_ctrl[0] = 0;
366 else
367 ieee->seq_ctrl[0]++;
368 }
369 ieee->softmac_hard_start_xmit(skb,ieee->dev);
370
371 }
372}
373
374inline struct sk_buff *rtllib_probe_req(struct rtllib_device *ieee)
375{
376 unsigned int len,rate_len;
377 u8 *tag;
378 struct sk_buff *skb;
379 struct rtllib_probe_request *req;
380
381 len = ieee->current_network.ssid_len;
382
383 rate_len = rtllib_MFIE_rate_len(ieee);
384
385#ifdef USB_USE_ALIGNMENT
386 u32 Tmpaddr;
387 int alignment;
388 skb = dev_alloc_skb(sizeof(struct rtllib_probe_request) +
389 2 + len + rate_len + ieee->tx_headroom + USB_512B_ALIGNMENT_SIZE);
390#else
391 skb = dev_alloc_skb(sizeof(struct rtllib_probe_request) +
392 2 + len + rate_len + ieee->tx_headroom);
393#endif
394
395 if (!skb)
396 return NULL;
397
398#ifdef USB_USE_ALIGNMENT
399 Tmpaddr = (u32)skb->data;
400 alignment = Tmpaddr & 0x1ff;
401 skb_reserve(skb,(USB_512B_ALIGNMENT_SIZE - alignment));
402#endif
403
404 skb_reserve(skb, ieee->tx_headroom);
405
406 req = (struct rtllib_probe_request *) skb_put(skb,sizeof(struct rtllib_probe_request));
407 req->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_PROBE_REQ);
408 req->header.duration_id = 0;
409
410 memset(req->header.addr1, 0xff, ETH_ALEN);
411 memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
412 memset(req->header.addr3, 0xff, ETH_ALEN);
413
414 tag = (u8 *) skb_put(skb,len+2+rate_len);
415
416 *tag++ = MFIE_TYPE_SSID;
417 *tag++ = len;
418 memcpy(tag, ieee->current_network.ssid, len);
419 tag += len;
420
421 rtllib_MFIE_Brate(ieee,&tag);
422 rtllib_MFIE_Grate(ieee,&tag);
423
424 return skb;
425}
426
427struct sk_buff *rtllib_get_beacon_(struct rtllib_device *ieee);
428
429void rtllib_send_beacon(struct rtllib_device *ieee)
430{
431 struct sk_buff *skb;
432 if (!ieee->ieee_up)
433 return;
434 skb = rtllib_get_beacon_(ieee);
435
436 if (skb){
437 softmac_mgmt_xmit(skb, ieee);
438 ieee->softmac_stats.tx_beacons++;
439 }
440
441 if (ieee->beacon_txing && ieee->ieee_up){
442 mod_timer(&ieee->beacon_timer,jiffies+(MSECS(ieee->current_network.beacon_interval-5)));
443 }
444}
445
446
447void rtllib_send_beacon_cb(unsigned long _ieee)
448{
449 struct rtllib_device *ieee =
450 (struct rtllib_device *) _ieee;
451 unsigned long flags;
452
453 spin_lock_irqsave(&ieee->beacon_lock, flags);
454 rtllib_send_beacon(ieee);
455 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
456}
457
458/*
459 * Description:
460 * Enable network monitor mode, all rx packets will be received.
461 */
462void rtllib_EnableNetMonitorMode(struct net_device* dev,
463 bool bInitState)
464{
465 struct rtllib_device* ieee = netdev_priv_rsl(dev);
466
467 printk("========>Enter Monitor Mode\n");
468
469 ieee->AllowAllDestAddrHandler(dev, true, !bInitState);
470}
471
472
473/*
474 * Description:
475 * Disable network network monitor mode, only packets destinated to
476 * us will be received.
477 */
478void rtllib_DisableNetMonitorMode(struct net_device* dev,
479 bool bInitState)
480{
481 struct rtllib_device* ieee = netdev_priv_rsl(dev);
482
483 printk("========>Exit Monitor Mode\n");
484
485 ieee->AllowAllDestAddrHandler(dev, false, !bInitState);
486}
487
488
489/*
490 * Description:
491 * This enables the specialized promiscuous mode required by Intel.
492 * In this mode, Intel intends to hear traffics from/to other STAs in the same BSS.
493 * Therefore we don't have to disable checking BSSID and we only need to allow all dest.
494 * BUT: if we enable checking BSSID then we can't recv packets from other STA.
495 */
496void rtllib_EnableIntelPromiscuousMode(struct net_device* dev,
497 bool bInitState)
498{
499 bool bFilterOutNonAssociatedBSSID = false;
500
501 struct rtllib_device* ieee = netdev_priv_rsl(dev);
502
503 printk("========>Enter Intel Promiscuous Mode\n");
504
505 ieee->AllowAllDestAddrHandler(dev, true, !bInitState);
506 ieee->SetHwRegHandler(dev, HW_VAR_CECHK_BSSID, (u8*)&bFilterOutNonAssociatedBSSID);
507
508 ieee->bNetPromiscuousMode = true;
509}
510
511
512/*
513 * Description:
514 * This disables the specialized promiscuous mode required by Intel.
515 * See MgntEnableIntelPromiscuousMode for detail.
516 */
517void rtllib_DisableIntelPromiscuousMode(struct net_device* dev,
518 bool bInitState)
519{
520 bool bFilterOutNonAssociatedBSSID = true;
521
522 struct rtllib_device* ieee = netdev_priv_rsl(dev);
523
524 printk("========>Exit Intel Promiscuous Mode\n");
525
526 ieee->AllowAllDestAddrHandler(dev, false, !bInitState);
527 ieee->SetHwRegHandler(dev, HW_VAR_CECHK_BSSID, (u8*)&bFilterOutNonAssociatedBSSID);
528
529 ieee->bNetPromiscuousMode = false;
530}
531
532void rtllib_send_probe(struct rtllib_device *ieee, u8 is_mesh)
533{
534 struct sk_buff *skb;
535 skb = rtllib_probe_req(ieee);
536 if (skb){
537 softmac_mgmt_xmit(skb, ieee);
538 ieee->softmac_stats.tx_probe_rq++;
539 }
540}
541
542
543void rtllib_send_probe_requests(struct rtllib_device *ieee, u8 is_mesh)
544{
545 if (ieee->active_scan && (ieee->softmac_features &
546 IEEE_SOFTMAC_PROBERQ)) {
547 rtllib_send_probe(ieee, 0);
548 rtllib_send_probe(ieee, 0);
549 }
550}
551
552void rtllib_softmac_hint11d_wq(void *data)
553{
554#ifdef CONFIG_CRDA
555 struct rtllib_device *ieee = container_of_dwork_rsl(data, struct rtllib_device, softmac_hint11d_wq);
556 PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
557 struct wireless_dev *wdev = &ieee->wdev;
558
559 regulatory_hint_11d(wdev->wiphy, pDot11dInfo->CountryIeBuf, pDot11dInfo->CountryIeLen);
560#endif
561}
562
563void rtllib_update_active_chan_map(struct rtllib_device *ieee)
564{
565#ifdef ENABLE_DOT11D
566 memcpy(ieee->active_channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
567#else
568 memcpy(ieee->active_channel_map, ieee->channel_map, MAX_CHANNEL_NUMBER+1);
569#endif
570}
571
572/* this performs syncro scan blocking the caller until all channels
573 * in the allowed channel map has been checked.
574 */
575void rtllib_softmac_scan_syncro(struct rtllib_device *ieee, u8 is_mesh)
576{
577 short ch = 0;
578
579 rtllib_update_active_chan_map(ieee);
580
581 ieee->be_scan_inprogress = true;
582
583 down(&ieee->scan_sem);
584
585 while(1)
586 {
587
588 do {
589 ch++;
590 if (ch > MAX_CHANNEL_NUMBER)
591 goto out; /* scan completed */
592 } while(!ieee->active_channel_map[ch]);
593
594 /* this fuction can be called in two situations
595 * 1- We have switched to ad-hoc mode and we are
596 * performing a complete syncro scan before conclude
597 * there are no interesting cell and to create a
598 * new one. In this case the link state is
599 * RTLLIB_NOLINK until we found an interesting cell.
600 * If so the ieee8021_new_net, called by the RX path
601 * will set the state to RTLLIB_LINKED, so we stop
602 * scanning
603 * 2- We are linked and the root uses run iwlist scan.
604 * So we switch to RTLLIB_LINKED_SCANNING to remember
605 * that we are still logically linked (not interested in
606 * new network events, despite for updating the net list,
607 * but we are temporarly 'unlinked' as the driver shall
608 * not filter RX frames and the channel is changing.
609 * So the only situation in witch are interested is to check
610 * if the state become LINKED because of the #1 situation
611 */
612
613 if (ieee->state == RTLLIB_LINKED)
614 goto out;
615 if (ieee->sync_scan_hurryup){
616 printk("============>sync_scan_hurryup out\n");
617 goto out;
618 }
619
620 ieee->set_chan(ieee->dev, ch);
621 if (ieee->active_channel_map[ch] == 1)
622 rtllib_send_probe_requests(ieee, 0);
623
624 /* this prevent excessive time wait when we
625 * need to wait for a syncro scan to end..
626 */
627 msleep_interruptible_rsl(RTLLIB_SOFTMAC_SCAN_TIME);
628 }
629out:
630 ieee->actscanning = false;
631 ieee->sync_scan_hurryup = 0;
632
633 if (ieee->state >= RTLLIB_LINKED){
634#ifdef ENABLE_DOT11D
635 if (IS_DOT11D_ENABLE(ieee))
636 DOT11D_ScanComplete(ieee);
637#endif
638 }
639 up(&ieee->scan_sem);
640
641 ieee->be_scan_inprogress = false;
642
643#ifndef FOR_MOBLIN
644 {
645 union iwreq_data wrqu;
646 memset(&wrqu, 0, sizeof(wrqu));
647 wireless_send_event(ieee->dev,SIOCGIWSCAN,&wrqu,NULL);
648 }
649#endif
650}
651
652void rtllib_softmac_scan_wq(void *data)
653{
654 struct rtllib_device *ieee = container_of_dwork_rsl(data, struct rtllib_device, softmac_scan_wq);
655 u8 last_channel = ieee->current_network.channel;
656
657 rtllib_update_active_chan_map(ieee);
658
659 if (!ieee->ieee_up)
660 return;
661 if (rtllib_act_scanning(ieee,true) == true)
662 return;
663
664 down(&ieee->scan_sem);
665
666 if (ieee->eRFPowerState == eRfOff)
667 {
668 printk("======>%s():rf state is eRfOff, return\n",__func__);
669 goto out1;
670 }
671
672 do{
673 ieee->current_network.channel =
674 (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
675 if (ieee->scan_watch_dog++ > MAX_CHANNEL_NUMBER)
676 {
677 if (!ieee->active_channel_map[ieee->current_network.channel])
678 ieee->current_network.channel = 6;
679 goto out; /* no good chans */
680 }
681 } while(!ieee->active_channel_map[ieee->current_network.channel]);
682
683 if (ieee->scanning_continue == 0 )
684 goto out;
685
686 ieee->set_chan(ieee->dev, ieee->current_network.channel);
687
688 if (ieee->active_channel_map[ieee->current_network.channel] == 1)
689 rtllib_send_probe_requests(ieee, 0);
690
691 queue_delayed_work_rsl(ieee->wq, &ieee->softmac_scan_wq, MSECS(RTLLIB_SOFTMAC_SCAN_TIME));
692
693 up(&ieee->scan_sem);
694 return;
695
696out:
697#ifdef ENABLE_DOT11D
698 if (IS_DOT11D_ENABLE(ieee))
699 DOT11D_ScanComplete(ieee);
700#endif
701 ieee->current_network.channel = last_channel;
702
703out1:
704 ieee->actscanning = false;
705 ieee->scan_watch_dog = 0;
706 ieee->scanning_continue = 0;
707 up(&ieee->scan_sem);
708}
709
710
711
712void rtllib_beacons_start(struct rtllib_device *ieee)
713{
714 unsigned long flags;
715 spin_lock_irqsave(&ieee->beacon_lock,flags);
716
717 ieee->beacon_txing = 1;
718 rtllib_send_beacon(ieee);
719
720 spin_unlock_irqrestore(&ieee->beacon_lock,flags);
721}
722
723void rtllib_beacons_stop(struct rtllib_device *ieee)
724{
725 unsigned long flags;
726
727 spin_lock_irqsave(&ieee->beacon_lock,flags);
728
729 ieee->beacon_txing = 0;
730 del_timer_sync(&ieee->beacon_timer);
731
732 spin_unlock_irqrestore(&ieee->beacon_lock,flags);
733
734}
735
736
737void rtllib_stop_send_beacons(struct rtllib_device *ieee)
738{
739 if (ieee->stop_send_beacons)
740 ieee->stop_send_beacons(ieee->dev);
741 if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
742 rtllib_beacons_stop(ieee);
743}
744
745
746void rtllib_start_send_beacons(struct rtllib_device *ieee)
747{
748 if (ieee->start_send_beacons)
749 ieee->start_send_beacons(ieee->dev);
750 if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
751 rtllib_beacons_start(ieee);
752}
753
754
755void rtllib_softmac_stop_scan(struct rtllib_device *ieee)
756{
757
758
759 down(&ieee->scan_sem);
760 ieee->scan_watch_dog = 0;
761 if (ieee->scanning_continue == 1){
762 ieee->scanning_continue = 0;
763 ieee->actscanning = 0;
764
765#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,40)
766#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,67)
767 cancel_delayed_work(&ieee->softmac_scan_wq);
768#endif
769#else
770 del_timer_sync(&ieee->scan_timer);
771#endif
772 }
773
774 up(&ieee->scan_sem);
775}
776
777void rtllib_stop_scan(struct rtllib_device *ieee)
778{
779 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
780 rtllib_softmac_stop_scan(ieee);
781 }else{
782 if (ieee->rtllib_stop_hw_scan)
783 ieee->rtllib_stop_hw_scan(ieee->dev);
784 }
785}
786
787void rtllib_stop_scan_syncro(struct rtllib_device *ieee)
788{
789 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
790 ieee->sync_scan_hurryup = 1;
791 }else{
792 if (ieee->rtllib_stop_hw_scan)
793 ieee->rtllib_stop_hw_scan(ieee->dev);
794 }
795}
796
797bool rtllib_act_scanning(struct rtllib_device *ieee, bool sync_scan)
798{
799 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
800 if (sync_scan){
801 return ieee->be_scan_inprogress;
802 }else{
803 return (ieee->actscanning ||ieee->be_scan_inprogress);
804 }
805 }else{
806 return test_bit(STATUS_SCANNING, &ieee->status);
807 }
808}
809
810/* called with ieee->lock held */
811void rtllib_start_scan(struct rtllib_device *ieee)
812{
813 RT_TRACE(COMP_DBG, "===>%s()\n",__func__);
814 if (ieee->rtllib_ips_leave_wq != NULL)
815 ieee->rtllib_ips_leave_wq(ieee->dev);
816
817
818#ifdef ENABLE_DOT11D
819 if (IS_DOT11D_ENABLE(ieee) )
820 {
821 if (IS_COUNTRY_IE_VALID(ieee))
822 {
823 RESET_CIE_WATCHDOG(ieee);
824 }
825 }
826#endif
827 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) {
828 if (ieee->scanning_continue == 0) {
829 ieee->actscanning = true;
830 ieee->scanning_continue = 1;
831 queue_delayed_work_rsl(ieee->wq, &ieee->softmac_scan_wq, 0);
832 }
833 } else {
834 if (ieee->rtllib_start_hw_scan)
835 ieee->rtllib_start_hw_scan(ieee->dev);
836 }
837
838}
839
840#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,40)
841void rtllib_softmac_scan_cb(unsigned long _dev)
842{
843 unsigned long flags;
844 struct rtllib_device *ieee = (struct rtllib_device *)_dev;
845
846 spin_lock_irqsave(&ieee->lock, flags);
847 rtllib_start_scan(ieee);
848 spin_unlock_irqrestore(&ieee->lock, flags);
849}
850#endif
851
852/* called with wx_sem held */
853void rtllib_start_scan_syncro(struct rtllib_device *ieee, u8 is_mesh)
854{
855#ifdef ENABLE_DOT11D
856 if (IS_DOT11D_ENABLE(ieee) )
857 {
858 if (IS_COUNTRY_IE_VALID(ieee))
859 {
860 RESET_CIE_WATCHDOG(ieee);
861 }
862 }
863#endif
864 ieee->sync_scan_hurryup = 0;
865 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
866 rtllib_softmac_scan_syncro(ieee, is_mesh);
867 }else{
868 if (ieee->rtllib_start_hw_scan)
869 ieee->rtllib_start_hw_scan(ieee->dev);
870 }
871
872}
873
874inline struct sk_buff *rtllib_authentication_req(struct rtllib_network *beacon,
875 struct rtllib_device *ieee, int challengelen,u8 * daddr)
876{
877 struct sk_buff *skb;
878 struct rtllib_authentication *auth;
879 int len = 0;
880 len = sizeof(struct rtllib_authentication) + challengelen + ieee->tx_headroom + 4;
881#ifdef USB_USE_ALIGNMENT
882 u32 Tmpaddr;
883 int alignment;
884 skb = dev_alloc_skb(len + USB_512B_ALIGNMENT_SIZE);
885#else
886 skb = dev_alloc_skb(len);
887#endif
888
889 if (!skb) return NULL;
890
891#ifdef USB_USE_ALIGNMENT
892 Tmpaddr = (u32)skb->data;
893 alignment = Tmpaddr & 0x1ff;
894 skb_reserve(skb,(USB_512B_ALIGNMENT_SIZE - alignment));
895#endif
896
897 skb_reserve(skb, ieee->tx_headroom);
898
899 auth = (struct rtllib_authentication *)
900 skb_put(skb, sizeof(struct rtllib_authentication));
901
902 auth->header.frame_ctl = RTLLIB_STYPE_AUTH;
903 if (challengelen) auth->header.frame_ctl |= RTLLIB_FCTL_WEP;
904
905 auth->header.duration_id = 0x013a;
906 memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
907 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
908 memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
909 if (ieee->auth_mode == 0)
910 auth->algorithm = WLAN_AUTH_OPEN;
911 else if (ieee->auth_mode == 1)
912 auth->algorithm = WLAN_AUTH_SHARED_KEY;
913 else if (ieee->auth_mode == 2)
914 auth->algorithm = WLAN_AUTH_OPEN;
915 auth->transaction = cpu_to_le16(ieee->associate_seq);
916 ieee->associate_seq++;
917
918 auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
919
920 return skb;
921
922}
923
924void constructWMMIE(u8* wmmie, u8* wmm_len,u8 oui_subtype)
925{
926 u8 szQoSOUI[] ={221, 0, 0x00, 0x50, 0xf2, 0x02, 0, 1};
927
928 if (oui_subtype == OUI_SUBTYPE_QOS_CAPABI)
929 {
930 szQoSOUI[0] = 46;
931 szQoSOUI[1] = *wmm_len;
932 memcpy(wmmie,szQoSOUI,3);
933 *wmm_len = 3;
934 }
935 else
936 {
937 szQoSOUI[1] = *wmm_len + 6;
938 szQoSOUI[6] = oui_subtype;
939 memcpy(wmmie, szQoSOUI, 8);
940 *(wmmie+8) = 0;
941 *wmm_len = 9;
942 }
943}
944
945static struct sk_buff* rtllib_probe_resp(struct rtllib_device *ieee, u8 *dest)
946{
947 u8 *tag;
948 int beacon_size;
949 struct rtllib_probe_response *beacon_buf;
950 struct sk_buff *skb = NULL;
951 int encrypt;
952 int atim_len,erp_len;
953 struct rtllib_crypt_data* crypt;
954
955 char *ssid = ieee->current_network.ssid;
956 int ssid_len = ieee->current_network.ssid_len;
957 int rate_len = ieee->current_network.rates_len+2;
958 int rate_ex_len = ieee->current_network.rates_ex_len;
959 int wpa_ie_len = ieee->wpa_ie_len;
960 u8 erpinfo_content = 0;
961
962 u8* tmp_ht_cap_buf = NULL;
963 u8 tmp_ht_cap_len = 0;
964 u8* tmp_ht_info_buf = NULL;
965 u8 tmp_ht_info_len = 0;
966 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
967 u8* tmp_generic_ie_buf = NULL;
968 u8 tmp_generic_ie_len = 0;
969
970 if (rate_ex_len > 0)
971 rate_ex_len+=2;
972
973 if (ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
974 atim_len = 4;
975 else
976 atim_len = 0;
977
978 if ((ieee->current_network.mode == IEEE_G)
979 ||( ieee->current_network.mode == IEEE_N_24G && ieee->pHTInfo->bCurSuppCCK)) {
980 erp_len = 3;
981 erpinfo_content = 0;
982 if (ieee->current_network.buseprotection)
983 erpinfo_content |= ERP_UseProtection;
984 }
985 else
986 erp_len = 0;
987
988 crypt = ieee->crypt[ieee->tx_keyidx];
989 encrypt = ieee->host_encrypt && crypt && crypt->ops &&
990 ((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len));
991 if (ieee->pHTInfo->bCurrentHTSupport){
992 tmp_ht_cap_buf =(u8*) &(ieee->pHTInfo->SelfHTCap);
993 tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
994 tmp_ht_info_buf =(u8*) &(ieee->pHTInfo->SelfHTInfo);
995 tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo);
996 HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len,encrypt, false);
997 HTConstructInfoElement(ieee,tmp_ht_info_buf,&tmp_ht_info_len, encrypt);
998
999
1000 if (pHTInfo->bRegRT2RTAggregation)
1001 {
1002 tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
1003 tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer);
1004 HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len);
1005 }
1006 }
1007
1008 beacon_size = sizeof(struct rtllib_probe_response)+2+
1009 ssid_len
1010 +3
1011 +rate_len
1012 +rate_ex_len
1013 +atim_len
1014 +erp_len
1015 +wpa_ie_len
1016 +ieee->tx_headroom;
1017#ifdef USB_USE_ALIGNMENT
1018 u32 Tmpaddr=0;
1019 int alignment=0;
1020 skb = dev_alloc_skb(beacon_size + USB_512B_ALIGNMENT_SIZE);
1021#else
1022 skb = dev_alloc_skb(beacon_size);
1023#endif
1024 if (!skb)
1025 return NULL;
1026
1027#ifdef USB_USE_ALIGNMENT
1028 Tmpaddr = (u32)skb->data;
1029 alignment = Tmpaddr & 0x1ff;
1030 skb_reserve(skb,(USB_512B_ALIGNMENT_SIZE - alignment));
1031#endif
1032
1033 skb_reserve(skb, ieee->tx_headroom);
1034
1035 beacon_buf = (struct rtllib_probe_response*) skb_put(skb, (beacon_size - ieee->tx_headroom));
1036 memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
1037 memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1038 memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
1039
1040 beacon_buf->header.duration_id = 0;
1041 beacon_buf->beacon_interval =
1042 cpu_to_le16(ieee->current_network.beacon_interval);
1043 beacon_buf->capability =
1044 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
1045 beacon_buf->capability |=
1046 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE);
1047
1048 if (ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT_TIME))
1049 cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT_TIME));
1050
1051 crypt = ieee->crypt[ieee->tx_keyidx];
1052 if (encrypt)
1053 beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1054
1055
1056 beacon_buf->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_PROBE_RESP);
1057 beacon_buf->info_element[0].id = MFIE_TYPE_SSID;
1058 beacon_buf->info_element[0].len = ssid_len;
1059
1060 tag = (u8*) beacon_buf->info_element[0].data;
1061
1062 memcpy(tag, ssid, ssid_len);
1063
1064 tag += ssid_len;
1065
1066 *(tag++) = MFIE_TYPE_RATES;
1067 *(tag++) = rate_len-2;
1068 memcpy(tag,ieee->current_network.rates,rate_len-2);
1069 tag+=rate_len-2;
1070
1071 *(tag++) = MFIE_TYPE_DS_SET;
1072 *(tag++) = 1;
1073 *(tag++) = ieee->current_network.channel;
1074
1075 if (atim_len){
1076 u16 val16;
1077 *(tag++) = MFIE_TYPE_IBSS_SET;
1078 *(tag++) = 2;
1079 val16 = cpu_to_le16(ieee->current_network.atim_window);
1080 memcpy((u8 *)tag, (u8 *)&val16, 2);
1081 tag+=2;
1082 }
1083
1084 if (erp_len){
1085 *(tag++) = MFIE_TYPE_ERP;
1086 *(tag++) = 1;
1087 *(tag++) = erpinfo_content;
1088 }
1089#if defined(RTL8192U) || defined(RTL8192SU) || defined(RTL8192SE)
1090 if (tmp_ht_cap_len){
1091 *(tag++) = MFIE_TYPE_HT_CAP;
1092 *(tag++) = tmp_ht_cap_len - 2;
1093 memcpy(tag, tmp_ht_cap_buf, tmp_ht_cap_len - 2);
1094 tag += tmp_ht_cap_len - 2;
1095 }
1096#endif
1097 if (rate_ex_len){
1098 *(tag++) = MFIE_TYPE_RATES_EX;
1099 *(tag++) = rate_ex_len-2;
1100 memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
1101 tag+=rate_ex_len-2;
1102 }
1103
1104#if defined(RTL8192U) || defined(RTL8192SU) || defined(RTL8192SE)
1105 if (tmp_ht_info_len){
1106 *(tag++) = MFIE_TYPE_HT_INFO;
1107 *(tag++) = tmp_ht_info_len - 2;
1108 memcpy(tag, tmp_ht_info_buf, tmp_ht_info_len -2);
1109 tag += tmp_ht_info_len - 2;
1110 }
1111#endif
1112
1113 if (wpa_ie_len)
1114 {
1115 if (ieee->iw_mode == IW_MODE_ADHOC)
1116 {
1117 memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
1118 }
1119 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
1120 tag += ieee->wpa_ie_len;
1121 }
1122
1123#if defined(RTL8192U) || defined(RTL8192SU) || defined(RTL8192SE)
1124 if (tmp_generic_ie_len)
1125 {
1126 (*tag++) = 0xdd;
1127 (*tag++) = tmp_generic_ie_len - 2;
1128 memcpy(tag,tmp_generic_ie_buf,tmp_generic_ie_len -2);
1129 tag += tmp_generic_ie_len -2;
1130
1131 }
1132#endif
1133
1134#if defined(RTL8192U) || defined(RTL8192SU) || defined(RTL8192SE)
1135 if (wmm_len) {
1136 memcpy(tag,wmmie,wmm_len);
1137 tag += wmm_len;
1138 }
1139#endif
1140 return skb;
1141}
1142
1143struct sk_buff* rtllib_assoc_resp(struct rtllib_device *ieee, u8 *dest)
1144{
1145 struct sk_buff *skb;
1146 u8* tag;
1147
1148 struct rtllib_crypt_data* crypt;
1149 struct rtllib_assoc_response_frame *assoc;
1150 short encrypt;
1151
1152 unsigned int rate_len = rtllib_MFIE_rate_len(ieee);
1153 int len = sizeof(struct rtllib_assoc_response_frame) + rate_len + ieee->tx_headroom;
1154
1155#ifdef USB_USE_ALIGNMENT
1156 u32 Tmpaddr=0;
1157 int alignment=0;
1158 skb = dev_alloc_skb(len + USB_512B_ALIGNMENT_SIZE);
1159#else
1160 skb = dev_alloc_skb(len);
1161#endif
1162
1163 if (!skb)
1164 return NULL;
1165
1166#ifdef USB_USE_ALIGNMENT
1167 Tmpaddr = (u32)skb->data;
1168 alignment = Tmpaddr & 0x1ff;
1169 skb_reserve(skb,(USB_512B_ALIGNMENT_SIZE - alignment));
1170#endif
1171
1172 skb_reserve(skb, ieee->tx_headroom);
1173
1174 assoc = (struct rtllib_assoc_response_frame *)
1175 skb_put(skb,sizeof(struct rtllib_assoc_response_frame));
1176
1177 assoc->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_ASSOC_RESP);
1178 memcpy(assoc->header.addr1, dest,ETH_ALEN);
1179 memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
1180 memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1181 assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
1182 WLAN_CAPABILITY_ESS : WLAN_CAPABILITY_IBSS);
1183
1184
1185 if (ieee->short_slot)
1186 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);
1187
1188 if (ieee->host_encrypt)
1189 crypt = ieee->crypt[ieee->tx_keyidx];
1190 else
1191 crypt = NULL;
1192
1193 encrypt = ( crypt && crypt->ops);
1194
1195 if (encrypt)
1196 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1197
1198 assoc->status = 0;
1199 assoc->aid = cpu_to_le16(ieee->assoc_id);
1200 if (ieee->assoc_id == 0x2007)
1201 ieee->assoc_id=0;
1202 else
1203 ieee->assoc_id++;
1204
1205 tag = (u8*) skb_put(skb, rate_len);
1206 rtllib_MFIE_Brate(ieee, &tag);
1207 rtllib_MFIE_Grate(ieee, &tag);
1208
1209 return skb;
1210}
1211
1212struct sk_buff* rtllib_auth_resp(struct rtllib_device *ieee,int status, u8 *dest)
1213{
1214 struct sk_buff *skb = NULL;
1215 struct rtllib_authentication *auth;
1216 int len = ieee->tx_headroom + sizeof(struct rtllib_authentication)+1;
1217#ifdef USB_USE_ALIGNMENT
1218 u32 Tmpaddr=0;
1219 int alignment=0;
1220 skb = dev_alloc_skb(len + USB_512B_ALIGNMENT_SIZE);
1221#else
1222 skb = dev_alloc_skb(len);
1223#endif
1224 if (!skb)
1225 return NULL;
1226
1227 skb->len = sizeof(struct rtllib_authentication);
1228
1229#ifdef USB_USE_ALIGNMENT
1230 Tmpaddr = (u32)skb->data;
1231 alignment = Tmpaddr & 0x1ff;
1232 skb_reserve(skb,(USB_512B_ALIGNMENT_SIZE - alignment));
1233#endif
1234
1235 skb_reserve(skb, ieee->tx_headroom);
1236
1237 auth = (struct rtllib_authentication *)
1238 skb_put(skb, sizeof(struct rtllib_authentication));
1239
1240 auth->status = cpu_to_le16(status);
1241 auth->transaction = cpu_to_le16(2);
1242 auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
1243
1244 memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
1245 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1246 memcpy(auth->header.addr1, dest, ETH_ALEN);
1247 auth->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_AUTH);
1248 return skb;
1249
1250
1251}
1252
1253struct sk_buff* rtllib_null_func(struct rtllib_device *ieee,short pwr)
1254{
1255 struct sk_buff *skb;
1256 struct rtllib_hdr_3addr* hdr;
1257
1258#ifdef USB_USE_ALIGNMENT
1259 u32 Tmpaddr=0;
1260 int alignment=0;
1261 skb = dev_alloc_skb(sizeof(struct rtllib_hdr_3addr) + ieee->tx_headroom + USB_512B_ALIGNMENT_SIZE);
1262#else
1263 skb = dev_alloc_skb(sizeof(struct rtllib_hdr_3addr)+ieee->tx_headroom);
1264#endif
1265 if (!skb)
1266 return NULL;
1267
1268#ifdef USB_USE_ALIGNMENT
1269 Tmpaddr = (u32)skb->data;
1270 alignment = Tmpaddr & 0x1ff;
1271 skb_reserve(skb,(USB_512B_ALIGNMENT_SIZE - alignment));
1272#endif
1273 skb_reserve(skb, ieee->tx_headroom);
1274
1275 hdr = (struct rtllib_hdr_3addr*)skb_put(skb,sizeof(struct rtllib_hdr_3addr));
1276
1277 memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
1278 memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
1279 memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
1280
1281 hdr->frame_ctl = cpu_to_le16(RTLLIB_FTYPE_DATA |
1282 RTLLIB_STYPE_NULLFUNC | RTLLIB_FCTL_TODS |
1283 (pwr ? RTLLIB_FCTL_PM:0));
1284
1285 return skb;
1286
1287
1288}
1289
1290struct sk_buff* rtllib_pspoll_func(struct rtllib_device *ieee)
1291{
1292 struct sk_buff *skb;
1293 struct rtllib_pspoll_hdr* hdr;
1294
1295#ifdef USB_USE_ALIGNMENT
1296 u32 Tmpaddr=0;
1297 int alignment=0;
1298 skb = dev_alloc_skb(sizeof(struct rtllib_pspoll_hdr) + ieee->tx_headroom + USB_512B_ALIGNMENT_SIZE);
1299#else
1300 skb = dev_alloc_skb(sizeof(struct rtllib_pspoll_hdr)+ieee->tx_headroom);
1301#endif
1302 if (!skb)
1303 return NULL;
1304
1305#ifdef USB_USE_ALIGNMENT
1306 Tmpaddr = (u32)skb->data;
1307 alignment = Tmpaddr & 0x1ff;
1308 skb_reserve(skb,(USB_512B_ALIGNMENT_SIZE - alignment));
1309#endif
1310 skb_reserve(skb, ieee->tx_headroom);
1311
1312 hdr = (struct rtllib_pspoll_hdr*)skb_put(skb,sizeof(struct rtllib_pspoll_hdr));
1313
1314 memcpy(hdr->bssid, ieee->current_network.bssid, ETH_ALEN);
1315 memcpy(hdr->ta, ieee->dev->dev_addr, ETH_ALEN);
1316
1317 hdr->aid = cpu_to_le16(ieee->assoc_id | 0xc000);
1318 hdr->frame_ctl = cpu_to_le16(RTLLIB_FTYPE_CTL |RTLLIB_STYPE_PSPOLL | RTLLIB_FCTL_PM);
1319
1320 return skb;
1321
1322}
1323
1324void rtllib_resp_to_assoc_rq(struct rtllib_device *ieee, u8* dest)
1325{
1326 struct sk_buff *buf = rtllib_assoc_resp(ieee, dest);
1327
1328 if (buf)
1329 softmac_mgmt_xmit(buf, ieee);
1330}
1331
1332
1333void rtllib_resp_to_auth(struct rtllib_device *ieee, int s, u8* dest)
1334{
1335 struct sk_buff *buf = rtllib_auth_resp(ieee, s, dest);
1336
1337 if (buf)
1338 softmac_mgmt_xmit(buf, ieee);
1339}
1340
1341
1342void rtllib_resp_to_probe(struct rtllib_device *ieee, u8 *dest)
1343{
1344
1345 struct sk_buff *buf = rtllib_probe_resp(ieee, dest);
1346 if (buf)
1347 softmac_mgmt_xmit(buf, ieee);
1348}
1349
1350
1351inline int SecIsInPMKIDList(struct rtllib_device *ieee, u8 *bssid)
1352{
1353 int i = 0;
1354
1355 do
1356 {
1357 if ((ieee->PMKIDList[i].bUsed) && (memcmp(ieee->PMKIDList[i].Bssid, bssid, ETH_ALEN) == 0))
1358 {
1359 break;
1360 }
1361 else
1362 {
1363 i++;
1364 }
1365 } while (i < NUM_PMKID_CACHE);
1366
1367 if (i == NUM_PMKID_CACHE)
1368 {
1369 i = -1;
1370 }
1371 else
1372 {
1373 }
1374
1375 return (i);
1376
1377}
1378
1379
1380inline struct sk_buff *rtllib_association_req(struct rtllib_network *beacon,struct rtllib_device *ieee)
1381{
1382 struct sk_buff *skb;
1383
1384 struct rtllib_assoc_request_frame *hdr;
1385 u8 *tag, *ies;
1386 int i;
1387 u8* ht_cap_buf = NULL;
1388 u8 ht_cap_len=0;
1389 u8* realtek_ie_buf=NULL;
1390 u8 realtek_ie_len=0;
1391 int wpa_ie_len= ieee->wpa_ie_len;
1392 int wps_ie_len = ieee->wps_ie_len;
1393 unsigned int ckip_ie_len=0;
1394 unsigned int ccxrm_ie_len=0;
1395 unsigned int cxvernum_ie_len=0;
1396 struct rtllib_crypt_data* crypt;
1397 int encrypt;
1398 int PMKCacheIdx;
1399
1400 unsigned int rate_len = (beacon->rates_len?(beacon->rates_len+2):0) + (beacon->rates_ex_len?(beacon->rates_ex_len)+2:0);
1401
1402 unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
1403 unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
1404
1405 int len = 0;
1406 crypt = ieee->crypt[ieee->tx_keyidx];
1407 if (crypt != NULL) {
1408 encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len));
1409 } else {
1410 encrypt = 0;
1411 }
1412
1413#ifdef ENABLE_TKIP11N
1414 if (ieee->bForcedBgMode == true)
1415#else
1416 if ((ieee->rtllib_ap_sec_type && (ieee->rtllib_ap_sec_type(ieee)&SEC_ALG_TKIP)) ||(ieee->bForcedBgMode == true))
1417#endif
1418 {
1419 ieee->pHTInfo->bEnableHT = 0;
1420 ieee->mode = WIRELESS_MODE_G;
1421 }
1422
1423 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1424 {
1425 ht_cap_buf = (u8*)&(ieee->pHTInfo->SelfHTCap);
1426 ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
1427 HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt, true);
1428 if (ieee->pHTInfo->bCurrentRT2RTAggregation) {
1429 realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
1430 realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer);
1431 HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len);
1432
1433 }
1434 }
1435
1436 if (beacon->bCkipSupported)
1437 {
1438 ckip_ie_len = 30+2;
1439 }
1440 if (beacon->bCcxRmEnable)
1441 {
1442 ccxrm_ie_len = 6+2;
1443 }
1444 if ( beacon->BssCcxVerNumber >= 2 )
1445 {
1446 cxvernum_ie_len = 5+2;
1447 }
1448
1449 PMKCacheIdx = SecIsInPMKIDList(ieee, ieee->current_network.bssid);
1450 if (PMKCacheIdx >= 0)
1451 {
1452 wpa_ie_len += 18;
1453 printk("[PMK cache]: WPA2 IE length: %x\n", wpa_ie_len);
1454 }
1455 len = sizeof(struct rtllib_assoc_request_frame)+ 2
1456 + beacon->ssid_len
1457 + rate_len
1458 + wpa_ie_len
1459 + wps_ie_len
1460 + wmm_info_len
1461 + turbo_info_len
1462 + ht_cap_len
1463 + realtek_ie_len
1464 + ckip_ie_len
1465 + ccxrm_ie_len
1466 + cxvernum_ie_len
1467 + ieee->tx_headroom;
1468
1469#ifdef USB_USE_ALIGNMENT
1470 u32 Tmpaddr=0;
1471 int alignment=0;
1472 skb = dev_alloc_skb(len + USB_512B_ALIGNMENT_SIZE);
1473#else
1474 skb = dev_alloc_skb(len);
1475#endif
1476
1477 if (!skb)
1478 return NULL;
1479
1480#ifdef USB_USE_ALIGNMENT
1481 Tmpaddr = (u32)skb->data;
1482 alignment = Tmpaddr & 0x1ff;
1483 skb_reserve(skb,(USB_512B_ALIGNMENT_SIZE - alignment));
1484#endif
1485
1486 skb_reserve(skb, ieee->tx_headroom);
1487
1488 hdr = (struct rtllib_assoc_request_frame *)
1489 skb_put(skb, sizeof(struct rtllib_assoc_request_frame)+2);
1490
1491
1492 hdr->header.frame_ctl = RTLLIB_STYPE_ASSOC_REQ;
1493 hdr->header.duration_id= 37;
1494 memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
1495 memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1496 memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
1497
1498 memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);
1499
1500 hdr->capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
1501 if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
1502 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1503
1504 if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1505 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
1506
1507 if (ieee->short_slot && (beacon->capability&WLAN_CAPABILITY_SHORT_SLOT_TIME))
1508 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);
1509
1510
1511 hdr->listen_interval = beacon->listen_interval;
1512
1513 hdr->info_element[0].id = MFIE_TYPE_SSID;
1514
1515 hdr->info_element[0].len = beacon->ssid_len;
1516 tag = skb_put(skb, beacon->ssid_len);
1517 memcpy(tag, beacon->ssid, beacon->ssid_len);
1518
1519 tag = skb_put(skb, rate_len);
1520
1521 if (beacon->rates_len){
1522 *tag++ = MFIE_TYPE_RATES;
1523 *tag++ = beacon->rates_len;
1524 for (i=0;i<beacon->rates_len;i++){
1525 *tag++ = beacon->rates[i];
1526 }
1527 }
1528
1529 if (beacon->rates_ex_len){
1530 *tag++ = MFIE_TYPE_RATES_EX;
1531 *tag++ = beacon->rates_ex_len;
1532 for (i=0;i<beacon->rates_ex_len;i++){
1533 *tag++ = beacon->rates_ex[i];
1534 }
1535 }
1536
1537 if ( beacon->bCkipSupported )
1538 {
1539 static u8 AironetIeOui[] = {0x00, 0x01, 0x66};
1540 u8 CcxAironetBuf[30];
1541 OCTET_STRING osCcxAironetIE;
1542
1543 memset(CcxAironetBuf, 0,30);
1544 osCcxAironetIE.Octet = CcxAironetBuf;
1545 osCcxAironetIE.Length = sizeof(CcxAironetBuf);
1546 memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui));
1547
1548 osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |= (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ;
1549 tag = skb_put(skb, ckip_ie_len);
1550 *tag++ = MFIE_TYPE_AIRONET;
1551 *tag++ = osCcxAironetIE.Length;
1552 memcpy(tag,osCcxAironetIE.Octet,osCcxAironetIE.Length);
1553 tag += osCcxAironetIE.Length;
1554 }
1555
1556 if (beacon->bCcxRmEnable)
1557 {
1558 static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
1559 OCTET_STRING osCcxRmCap;
1560
1561 osCcxRmCap.Octet = CcxRmCapBuf;
1562 osCcxRmCap.Length = sizeof(CcxRmCapBuf);
1563 tag = skb_put(skb,ccxrm_ie_len);
1564 *tag++ = MFIE_TYPE_GENERIC;
1565 *tag++ = osCcxRmCap.Length;
1566 memcpy(tag,osCcxRmCap.Octet,osCcxRmCap.Length);
1567 tag += osCcxRmCap.Length;
1568 }
1569
1570 if ( beacon->BssCcxVerNumber >= 2 )
1571 {
1572 u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
1573 OCTET_STRING osCcxVerNum;
1574 CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
1575 osCcxVerNum.Octet = CcxVerNumBuf;
1576 osCcxVerNum.Length = sizeof(CcxVerNumBuf);
1577 tag = skb_put(skb,cxvernum_ie_len);
1578 *tag++ = MFIE_TYPE_GENERIC;
1579 *tag++ = osCcxVerNum.Length;
1580 memcpy(tag,osCcxVerNum.Octet,osCcxVerNum.Length);
1581 tag += osCcxVerNum.Length;
1582 }
1583 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
1584 if (ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC)
1585 {
1586 tag = skb_put(skb, ht_cap_len);
1587 *tag++ = MFIE_TYPE_HT_CAP;
1588 *tag++ = ht_cap_len - 2;
1589 memcpy(tag, ht_cap_buf,ht_cap_len -2);
1590 tag += ht_cap_len -2;
1591 }
1592 }
1593
1594
1595 if (wpa_ie_len){
1596 tag = skb_put(skb, ieee->wpa_ie_len);
1597 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
1598
1599 if (PMKCacheIdx >= 0)
1600 {
1601 tag = skb_put(skb, 18);
1602 *tag = 1;
1603 *(tag + 1) = 0;
1604 memcpy((tag + 2), &ieee->PMKIDList[PMKCacheIdx].PMKID, 16);
1605 }
1606 }
1607 if (wmm_info_len) {
1608 tag = skb_put(skb,wmm_info_len);
1609 rtllib_WMM_Info(ieee, &tag);
1610 }
1611
1612 if (wps_ie_len && ieee->wps_ie) {
1613 tag = skb_put(skb, wps_ie_len);
1614 memcpy(tag, ieee->wps_ie, wps_ie_len);
1615 }
1616
1617 tag = skb_put(skb,turbo_info_len);
1618 if (turbo_info_len)
1619 rtllib_TURBO_Info(ieee, &tag);
1620
1621 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
1622 if (ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC)
1623 {
1624 tag = skb_put(skb, ht_cap_len);
1625 *tag++ = MFIE_TYPE_GENERIC;
1626 *tag++ = ht_cap_len - 2;
1627 memcpy(tag, ht_cap_buf,ht_cap_len - 2);
1628 tag += ht_cap_len -2;
1629 }
1630
1631 if (ieee->pHTInfo->bCurrentRT2RTAggregation){
1632 tag = skb_put(skb, realtek_ie_len);
1633 *tag++ = MFIE_TYPE_GENERIC;
1634 *tag++ = realtek_ie_len - 2;
1635 memcpy(tag, realtek_ie_buf,realtek_ie_len -2 );
1636 }
1637 }
1638
1639 if (ieee->assocreq_ies){
1640 kfree(ieee->assocreq_ies);
1641 ieee->assocreq_ies = NULL;
1642 }
1643 ies = &(hdr->info_element[0].id);
1644 ieee->assocreq_ies_len = (skb->data + skb->len) - ies;
1645 ieee->assocreq_ies = kmalloc(ieee->assocreq_ies_len, GFP_ATOMIC);
1646 if (ieee->assocreq_ies)
1647 memcpy(ieee->assocreq_ies, ies, ieee->assocreq_ies_len);
1648 else{
1649 printk("%s()Warning: can't alloc memory for assocreq_ies\n", __func__);
1650 ieee->assocreq_ies_len = 0;
1651 }
1652
1653 return skb;
1654}
1655
1656void rtllib_associate_abort(struct rtllib_device *ieee)
1657{
1658
1659 unsigned long flags;
1660 spin_lock_irqsave(&ieee->lock, flags);
1661
1662 ieee->associate_seq++;
1663
1664 /* don't scan, and avoid to have the RX path possibily
1665 * try again to associate. Even do not react to AUTH or
1666 * ASSOC response. Just wait for the retry wq to be scheduled.
1667 * Here we will check if there are good nets to associate
1668 * with, so we retry or just get back to NO_LINK and scanning
1669 */
1670 if (ieee->state == RTLLIB_ASSOCIATING_AUTHENTICATING){
1671 RTLLIB_DEBUG_MGMT("Authentication failed\n");
1672 ieee->softmac_stats.no_auth_rs++;
1673 }else{
1674 RTLLIB_DEBUG_MGMT("Association failed\n");
1675 ieee->softmac_stats.no_ass_rs++;
1676 }
1677
1678 ieee->state = RTLLIB_ASSOCIATING_RETRY;
1679
1680 queue_delayed_work_rsl(ieee->wq, &ieee->associate_retry_wq, \
1681 RTLLIB_SOFTMAC_ASSOC_RETRY_TIME);
1682
1683 spin_unlock_irqrestore(&ieee->lock, flags);
1684}
1685
1686void rtllib_associate_abort_cb(unsigned long dev)
1687{
1688 rtllib_associate_abort((struct rtllib_device *) dev);
1689}
1690
1691void rtllib_associate_step1(struct rtllib_device *ieee,u8 * daddr)
1692{
1693 struct rtllib_network *beacon = &ieee->current_network;
1694 struct sk_buff *skb;
1695
1696 RTLLIB_DEBUG_MGMT("Stopping scan\n");
1697
1698 ieee->softmac_stats.tx_auth_rq++;
1699
1700 skb=rtllib_authentication_req(beacon, ieee, 0,daddr);
1701
1702 if (!skb)
1703 rtllib_associate_abort(ieee);
1704 else{
1705 ieee->state = RTLLIB_ASSOCIATING_AUTHENTICATING ;
1706 RTLLIB_DEBUG_MGMT("Sending authentication request\n");
1707 softmac_mgmt_xmit(skb, ieee);
1708 if (!timer_pending(&ieee->associate_timer)){
1709 ieee->associate_timer.expires = jiffies + (HZ / 2);
1710 add_timer(&ieee->associate_timer);
1711 }
1712 }
1713}
1714
1715void rtllib_auth_challenge(struct rtllib_device *ieee, u8 *challenge, int chlen)
1716{
1717 u8 *c;
1718 struct sk_buff *skb;
1719 struct rtllib_network *beacon = &ieee->current_network;
1720
1721 ieee->associate_seq++;
1722 ieee->softmac_stats.tx_auth_rq++;
1723
1724 skb = rtllib_authentication_req(beacon, ieee, chlen+2,beacon->bssid);
1725
1726 if (!skb)
1727 rtllib_associate_abort(ieee);
1728 else{
1729 c = skb_put(skb, chlen+2);
1730 *(c++) = MFIE_TYPE_CHALLENGE;
1731 *(c++) = chlen;
1732 memcpy(c, challenge, chlen);
1733
1734 RTLLIB_DEBUG_MGMT("Sending authentication challenge response\n");
1735
1736 rtllib_encrypt_fragment(ieee, skb, sizeof(struct rtllib_hdr_3addr ));
1737
1738 softmac_mgmt_xmit(skb, ieee);
1739 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1740 }
1741 kfree(challenge);
1742}
1743
1744void rtllib_associate_step2(struct rtllib_device *ieee)
1745{
1746 struct sk_buff* skb;
1747 struct rtllib_network *beacon = &ieee->current_network;
1748
1749 del_timer_sync(&ieee->associate_timer);
1750
1751 RTLLIB_DEBUG_MGMT("Sending association request\n");
1752
1753 ieee->softmac_stats.tx_ass_rq++;
1754 skb=rtllib_association_req(beacon, ieee);
1755 if (!skb)
1756 rtllib_associate_abort(ieee);
1757 else{
1758 softmac_mgmt_xmit(skb, ieee);
1759 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1760 }
1761}
1762
1763#define CANCELLED 2
1764void rtllib_associate_complete_wq(void *data)
1765{
1766 struct rtllib_device *ieee = (struct rtllib_device *)container_of_work_rsl(data, struct rtllib_device, associate_complete_wq);
1767 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(ieee->PowerSaveControl));
1768 printk(KERN_INFO "Associated successfully\n");
1769 if (ieee->is_silent_reset == 0){
1770 printk("normal associate\n");
1771 notify_wx_assoc_event(ieee);
1772 }
1773
1774 netif_carrier_on(ieee->dev);
1775 ieee->is_roaming = false;
1776 if (rtllib_is_54g(&ieee->current_network) &&
1777 (ieee->modulation & RTLLIB_OFDM_MODULATION)){
1778
1779 ieee->rate = 108;
1780 printk(KERN_INFO"Using G rates:%d\n", ieee->rate);
1781 }else{
1782 ieee->rate = 22;
1783 ieee->SetWirelessMode(ieee->dev, IEEE_B);
1784 printk(KERN_INFO"Using B rates:%d\n", ieee->rate);
1785 }
1786 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1787 {
1788 printk("Successfully associated, ht enabled\n");
1789 HTOnAssocRsp(ieee);
1790 } else {
1791 printk("Successfully associated, ht not enabled(%d, %d)\n",
1792 ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
1793 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1794 }
1795 ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500);
1796 if (ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
1797 {
1798 ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
1799 ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
1800 }
1801 pPSC->LpsIdleCount = 0;
1802 ieee->link_change(ieee->dev);
1803
1804 if (ieee->is_silent_reset == 1) {
1805 printk("silent reset associate\n");
1806 ieee->is_silent_reset = 0;
1807 }
1808
1809 if (ieee->data_hard_resume)
1810 ieee->data_hard_resume(ieee->dev);
1811
1812#ifdef RTK_DMP_PLATFORM
1813 kobject_hotplug(&ieee->dev->class_dev.kobj, KOBJ_LINKUP);
1814#endif
1815}
1816
1817static void rtllib_sta_send_associnfo(struct rtllib_device *ieee)
1818{
1819 char *buf;
1820 size_t len;
1821 int i;
1822 union iwreq_data wrqu;
1823
1824 return;
1825
1826
1827 buf = kmalloc(50 + 2 * (ieee->assocreq_ies_len + ieee->assocresp_ies_len), GFP_ATOMIC);
1828 if (!buf)
1829 return;
1830
1831 len = sprintf(buf, "ASSOCINFO(");
1832 if (ieee->assocreq_ies) {
1833 len += sprintf(buf + len, "ReqIEs=");
1834 for (i = 0; i < ieee->assocreq_ies_len; i++) {
1835 len += sprintf(buf + len, "%02x", ieee->assocreq_ies[i]);
1836 }
1837 }
1838 if (ieee->assocresp_ies) {
1839 if (ieee->assocreq_ies)
1840 len += sprintf(buf + len, " ");
1841 len += sprintf(buf + len, "RespIEs=");
1842 for (i = 0; i < ieee->assocresp_ies_len; i++) {
1843 len += sprintf(buf + len, "%02x", ieee->assocresp_ies[i]);
1844 }
1845 }
1846 len += sprintf(buf + len, ")");
1847
1848 if (len > IW_CUSTOM_MAX) {
1849 len = sprintf(buf, "ASSOCRESPIE=");
1850 for (i = 0; i < ieee->assocresp_ies_len; i++) {
1851 len += sprintf(buf + len, "%02x", ieee->assocresp_ies[i]);
1852 }
1853 }
1854
1855 if (len <= IW_CUSTOM_MAX) {
1856 memset(&wrqu, 0, sizeof(wrqu));
1857 wrqu.data.length = len;
1858 wireless_send_event(ieee->dev, IWEVCUSTOM, &wrqu, buf);
1859 }
1860
1861 kfree(buf);
1862}
1863
1864void rtllib_associate_complete(struct rtllib_device *ieee)
1865{
1866 del_timer_sync(&ieee->associate_timer);
1867
1868 ieee->state = RTLLIB_LINKED;
1869 rtllib_sta_send_associnfo(ieee);
1870
1871 queue_work_rsl(ieee->wq, &ieee->associate_complete_wq);
1872}
1873
1874void rtllib_associate_procedure_wq(void *data)
1875{
1876 struct rtllib_device *ieee = container_of_dwork_rsl(data, struct rtllib_device, associate_procedure_wq);
1877 rtllib_stop_scan_syncro(ieee);
1878 if (ieee->rtllib_ips_leave != NULL)
1879 ieee->rtllib_ips_leave(ieee->dev);
1880 down(&ieee->wx_sem);
1881
1882 if (ieee->data_hard_stop)
1883 ieee->data_hard_stop(ieee->dev);
1884
1885 rtllib_stop_scan(ieee);
1886 RT_TRACE(COMP_DBG, "===>%s(), chan:%d\n", __func__, ieee->current_network.channel);
1887 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1888 if (ieee->eRFPowerState == eRfOff)
1889 {
1890 RT_TRACE(COMP_DBG, "=============>%s():Rf state is eRfOff, schedule ipsleave wq again,return\n",__func__);
1891 if (ieee->rtllib_ips_leave_wq != NULL)
1892 ieee->rtllib_ips_leave_wq(ieee->dev);
1893 up(&ieee->wx_sem);
1894 return;
1895 }
1896 ieee->associate_seq = 1;
1897
1898 rtllib_associate_step1(ieee, ieee->current_network.bssid);
1899
1900 up(&ieee->wx_sem);
1901}
1902
1903inline void rtllib_softmac_new_net(struct rtllib_device *ieee, struct rtllib_network *net)
1904{
1905 u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
1906 int tmp_ssid_len = 0;
1907
1908 short apset,ssidset,ssidbroad,apmatch,ssidmatch;
1909
1910 /* we are interested in new new only if we are not associated
1911 * and we are not associating / authenticating
1912 */
1913 if (ieee->state != RTLLIB_NOLINK)
1914 return;
1915
1916 if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_ESS))
1917 return;
1918
1919 if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
1920 return;
1921
1922 if ((ieee->iw_mode == IW_MODE_ADHOC) && (net->channel > ieee->ibss_maxjoin_chal)) {
1923 return;
1924 }
1925 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC)
1926 {
1927 /* if the user specified the AP MAC, we need also the essid
1928 * This could be obtained by beacons or, if the network does not
1929 * broadcast it, it can be put manually.
1930 */
1931 apset = ieee->wap_set;
1932 ssidset = ieee->ssid_set;
1933 ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0');
1934 apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
1935 if (!ssidbroad){
1936 ssidmatch = (ieee->current_network.ssid_len == net->hidden_ssid_len)&&\
1937 (!strncmp(ieee->current_network.ssid, net->hidden_ssid, net->hidden_ssid_len));
1938 if (net->hidden_ssid_len > 0)
1939 {
1940 strncpy(net->ssid, net->hidden_ssid, net->hidden_ssid_len);
1941 net->ssid_len = net->hidden_ssid_len;
1942 ssidbroad = 1;
1943 }
1944 }
1945 else
1946 ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\
1947 (!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
1948
1949 if ( /* if the user set the AP check if match.
1950 * if the network does not broadcast essid we check the user supplyed ANY essid
1951 * if the network does broadcast and the user does not set essid it is OK
1952 * if the network does broadcast and the user did set essid chech if essid match
1953 */
1954 ( apset && apmatch &&
1955 ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) )
1956 /* if the ap is not set, check that the user set the bssid
1957 * and the network does bradcast and that those two bssid matches
1958 */
1959 || (!apset && ssidset && ssidbroad && ssidmatch) || (ieee->is_roaming && ssidset && ssidbroad && ssidmatch)
1960 ){
1961 /* if the essid is hidden replace it with the
1962 * essid provided by the user.
1963 */
1964 if (!ssidbroad){
1965 strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
1966 tmp_ssid_len = ieee->current_network.ssid_len;
1967 }
1968 memcpy(&ieee->current_network, net, sizeof(struct rtllib_network));
1969 if (!ssidbroad){
1970 strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
1971 ieee->current_network.ssid_len = tmp_ssid_len;
1972 }
1973 printk(KERN_INFO"Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d, mode:%x cur_net.flags:0x%x\n",ieee->current_network.ssid,ieee->current_network.channel, ieee->current_network.qos_data.supported, ieee->pHTInfo->bEnableHT, ieee->current_network.bssht.bdSupportHT, ieee->current_network.mode, ieee->current_network.flags);
1974
1975 if ((rtllib_act_scanning(ieee, false)) && !(ieee->softmac_features & IEEE_SOFTMAC_SCAN)){
1976 rtllib_stop_scan_syncro(ieee);
1977 }
1978
1979 ieee->hwscan_ch_bk = ieee->current_network.channel;
1980 HTResetIOTSetting(ieee->pHTInfo);
1981 ieee->wmm_acm = 0;
1982 if (ieee->iw_mode == IW_MODE_INFRA) {
1983 /* Join the network for the first time */
1984 ieee->AsocRetryCount = 0;
1985 if ((ieee->current_network.qos_data.supported == 1) &&
1986 ieee->current_network.bssht.bdSupportHT)
1987 HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network));
1988 else
1989 ieee->pHTInfo->bCurrentHTSupport = false;
1990
1991 ieee->state = RTLLIB_ASSOCIATING;
1992 if (ieee->LedControlHandler != NULL)
1993 ieee->LedControlHandler(ieee->dev, LED_CTL_START_TO_LINK);
1994 queue_delayed_work_rsl(ieee->wq, &ieee->associate_procedure_wq, 0);
1995 } else {
1996 if (rtllib_is_54g(&ieee->current_network) &&
1997 (ieee->modulation & RTLLIB_OFDM_MODULATION)){
1998 ieee->rate = 108;
1999 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2000 printk(KERN_INFO"Using G rates\n");
2001 }else{
2002 ieee->rate = 22;
2003 ieee->SetWirelessMode(ieee->dev, IEEE_B);
2004 printk(KERN_INFO"Using B rates\n");
2005 }
2006 memset(ieee->dot11HTOperationalRateSet, 0, 16);
2007 ieee->state = RTLLIB_LINKED;
2008 }
2009
2010 }
2011 }
2012
2013}
2014
2015void rtllib_softmac_check_all_nets(struct rtllib_device *ieee)
2016{
2017 unsigned long flags;
2018 struct rtllib_network *target;
2019
2020 spin_lock_irqsave(&ieee->lock, flags);
2021
2022 list_for_each_entry(target, &ieee->network_list, list) {
2023
2024 /* if the state become different that NOLINK means
2025 * we had found what we are searching for
2026 */
2027
2028 if (ieee->state != RTLLIB_NOLINK)
2029 break;
2030
2031 if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
2032 rtllib_softmac_new_net(ieee, target);
2033 }
2034
2035 spin_unlock_irqrestore(&ieee->lock, flags);
2036
2037}
2038
2039
2040static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen)
2041{
2042 struct rtllib_authentication *a;
2043 u8 *t;
2044 if (skb->len < (sizeof(struct rtllib_authentication)-sizeof(struct rtllib_info_element))){
2045 RTLLIB_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
2046 return 0xcafe;
2047 }
2048 *challenge = NULL;
2049 a = (struct rtllib_authentication*) skb->data;
2050 if (skb->len > (sizeof(struct rtllib_authentication) +3)){
2051 t = skb->data + sizeof(struct rtllib_authentication);
2052
2053 if (*(t++) == MFIE_TYPE_CHALLENGE){
2054 *chlen = *(t++);
2055 *challenge = (u8*)kmalloc(*chlen, GFP_ATOMIC);
2056 memcpy(*challenge, t, *chlen);
2057 }
2058 }
2059
2060 return cpu_to_le16(a->status);
2061
2062}
2063
2064
2065int auth_rq_parse(struct sk_buff *skb,u8* dest)
2066{
2067 struct rtllib_authentication *a;
2068
2069 if (skb->len < (sizeof(struct rtllib_authentication)-sizeof(struct rtllib_info_element))){
2070 RTLLIB_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
2071 return -1;
2072 }
2073 a = (struct rtllib_authentication*) skb->data;
2074
2075 memcpy(dest,a->header.addr2, ETH_ALEN);
2076
2077 if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
2078 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
2079
2080 return WLAN_STATUS_SUCCESS;
2081}
2082
2083static short probe_rq_parse(struct rtllib_device *ieee, struct sk_buff *skb, u8 *src)
2084{
2085 u8 *tag;
2086 u8 *skbend;
2087 u8 *ssid=NULL;
2088 u8 ssidlen = 0;
2089
2090 struct rtllib_hdr_3addr *header =
2091 (struct rtllib_hdr_3addr *) skb->data;
2092
2093 if (skb->len < sizeof (struct rtllib_hdr_3addr ))
2094 return -1; /* corrupted */
2095 if ((memcmp(header->addr3,ieee->current_network.bssid,ETH_ALEN) != 0)&&
2096 (memcmp(header->addr3,"\xff\xff\xff\xff\xff\xff",ETH_ALEN) != 0)) {
2097 return -1;
2098 }
2099
2100 if (memcmp(header->addr3,ieee->current_network.bssid,ETH_ALEN) == 0) {
2101 }
2102
2103 if (memcmp(header->addr3,"\xff\xff\xff\xff\xff\xff",ETH_ALEN) == 0) {
2104 }
2105 memcpy(src,header->addr2, ETH_ALEN);
2106
2107 skbend = (u8*)skb->data + skb->len;
2108
2109 tag = skb->data + sizeof (struct rtllib_hdr_3addr );
2110
2111 while (tag+1 < skbend){
2112 if (*tag == 0){
2113 ssid = tag+2;
2114 ssidlen = *(tag+1);
2115 break;
2116 }
2117 tag++; /* point to the len field */
2118 tag = tag + *(tag); /* point to the last data byte of the tag */
2119 tag++; /* point to the next tag */
2120 }
2121
2122 if (ssidlen == 0) return 1;
2123
2124 if (!ssid) return 1; /* ssid not found in tagged param */
2125 return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
2126
2127}
2128
2129int assoc_rq_parse(struct sk_buff *skb,u8* dest)
2130{
2131 struct rtllib_assoc_request_frame *a;
2132
2133 if (skb->len < (sizeof(struct rtllib_assoc_request_frame) -
2134 sizeof(struct rtllib_info_element))) {
2135
2136 RTLLIB_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
2137 return -1;
2138 }
2139
2140 a = (struct rtllib_assoc_request_frame*) skb->data;
2141
2142 memcpy(dest,a->header.addr2,ETH_ALEN);
2143
2144 return 0;
2145}
2146
2147static inline u16 assoc_parse(struct rtllib_device *ieee, struct sk_buff *skb, int *aid)
2148{
2149 struct rtllib_assoc_response_frame *response_head;
2150 u16 status_code;
2151
2152 if (skb->len < sizeof(struct rtllib_assoc_response_frame)){
2153 RTLLIB_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
2154 return 0xcafe;
2155 }
2156
2157 response_head = (struct rtllib_assoc_response_frame*) skb->data;
2158 *aid = le16_to_cpu(response_head->aid) & 0x3fff;
2159
2160 status_code = le16_to_cpu(response_head->status);
2161 if ((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \
2162 status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&&
2163 ((ieee->mode == IEEE_G) &&
2164 (ieee->current_network.mode == IEEE_N_24G) &&
2165 (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) {
2166 ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
2167 }else {
2168 ieee->AsocRetryCount = 0;
2169 }
2170
2171 return le16_to_cpu(response_head->status);
2172}
2173
2174void rtllib_rx_probe_rq(struct rtllib_device *ieee, struct sk_buff *skb)
2175{
2176 u8 dest[ETH_ALEN];
2177#if defined(RTL8192U) || defined(RTL8192SU) || defined(RTL8192SE)
2178 struct sta_info *psta = NULL;
2179#endif
2180 ieee->softmac_stats.rx_probe_rq++;
2181 if (probe_rq_parse(ieee, skb, dest) > 0){
2182 ieee->softmac_stats.tx_probe_rs++;
2183 rtllib_resp_to_probe(ieee, dest);
2184#if defined(RTL8192U) || defined(RTL8192SU) || defined(RTL8192SE)
2185 if (ieee->iw_mode == IW_MODE_ADHOC){
2186 psta = GetStaInfo(ieee, dest);
2187 if (NULL != psta)
2188 psta->LastActiveTime = jiffies;
2189 }
2190#endif
2191 }
2192}
2193
2194static inline void rtllib_rx_auth_rq(struct rtllib_device *ieee, struct sk_buff *skb)
2195{
2196 u8 dest[ETH_ALEN];
2197 int status;
2198 ieee->softmac_stats.rx_auth_rq++;
2199
2200 if ((status = auth_rq_parse(skb, dest))!= -1){
2201 rtllib_resp_to_auth(ieee, status, dest);
2202 }
2203
2204}
2205
2206static inline void rtllib_rx_assoc_rq(struct rtllib_device *ieee, struct sk_buff *skb)
2207{
2208
2209 u8 dest[ETH_ALEN];
2210
2211 ieee->softmac_stats.rx_ass_rq++;
2212 if (assoc_rq_parse(skb,dest) != -1){
2213 rtllib_resp_to_assoc_rq(ieee, dest);
2214 }
2215
2216 printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest));
2217}
2218
2219
2220void rtllib_sta_ps_send_null_frame(struct rtllib_device *ieee, short pwr)
2221{
2222
2223 struct sk_buff *buf = rtllib_null_func(ieee, pwr);
2224
2225 if (buf)
2226 softmac_ps_mgmt_xmit(buf, ieee);
2227
2228}
2229
2230void rtllib_sta_ps_send_pspoll_frame(struct rtllib_device *ieee)
2231{
2232
2233 struct sk_buff *buf = rtllib_pspoll_func(ieee);
2234
2235 if (buf)
2236 softmac_ps_mgmt_xmit(buf, ieee);
2237
2238}
2239
2240short rtllib_sta_ps_sleep(struct rtllib_device *ieee, u32 *time_h, u32 *time_l)
2241{
2242 int timeout = ieee->ps_timeout;
2243 u8 dtim;
2244 PRT_POWER_SAVE_CONTROL pPSC = (PRT_POWER_SAVE_CONTROL)(&(ieee->PowerSaveControl));
2245 /*if (ieee->ps == RTLLIB_PS_DISABLED ||
2246 ieee->iw_mode != IW_MODE_INFRA ||
2247 ieee->state != RTLLIB_LINKED)
2248
2249 return 0;
2250 */
2251
2252 if (ieee->LPSDelayCnt)
2253 {
2254 ieee->LPSDelayCnt --;
2255 return 0;
2256 }
2257
2258 dtim = ieee->current_network.dtim_data;
2259 if (!(dtim & RTLLIB_DTIM_VALID))
2260 return 0;
2261 timeout = ieee->current_network.beacon_interval;
2262 ieee->current_network.dtim_data = RTLLIB_DTIM_INVALID;
2263 /* there's no need to nofity AP that I find you buffered with broadcast packet */
2264 if (dtim & (RTLLIB_DTIM_UCAST & ieee->ps))
2265 return 2;
2266
2267 if (!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout))){
2268 return 0;
2269 }
2270 if (!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout))){
2271 return 0;
2272 }
2273 if ((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
2274 (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
2275 return 0;
2276
2277 if (time_l){
2278 if (ieee->bAwakePktSent == true) {
2279 pPSC->LPSAwakeIntvl = 1;
2280 } else {
2281 u8 MaxPeriod = 1;
2282
2283 if (pPSC->LPSAwakeIntvl == 0)
2284 pPSC->LPSAwakeIntvl = 1;
2285 if (pPSC->RegMaxLPSAwakeIntvl == 0)
2286 MaxPeriod = 1;
2287 else if (pPSC->RegMaxLPSAwakeIntvl == 0xFF)
2288 MaxPeriod = ieee->current_network.dtim_period;
2289 else
2290 MaxPeriod = pPSC->RegMaxLPSAwakeIntvl;
2291 pPSC->LPSAwakeIntvl = (pPSC->LPSAwakeIntvl >= MaxPeriod) ? MaxPeriod : (pPSC->LPSAwakeIntvl + 1);
2292 }
2293 {
2294 u8 LPSAwakeIntvl_tmp = 0;
2295 u8 period = ieee->current_network.dtim_period;
2296 u8 count = ieee->current_network.tim.tim_count;
2297 if (count == 0 ) {
2298 if (pPSC->LPSAwakeIntvl > period)
2299 LPSAwakeIntvl_tmp = period + (pPSC->LPSAwakeIntvl - period) -((pPSC->LPSAwakeIntvl-period)%period);
2300 else
2301 LPSAwakeIntvl_tmp = pPSC->LPSAwakeIntvl;
2302
2303 } else {
2304 if (pPSC->LPSAwakeIntvl > ieee->current_network.tim.tim_count)
2305 LPSAwakeIntvl_tmp = count + (pPSC->LPSAwakeIntvl - count) -((pPSC->LPSAwakeIntvl-count)%period);
2306 else
2307 LPSAwakeIntvl_tmp = pPSC->LPSAwakeIntvl;
2308 }
2309
2310 *time_l = ieee->current_network.last_dtim_sta_time[0]
2311 + MSECS(ieee->current_network.beacon_interval * LPSAwakeIntvl_tmp);
2312 }
2313 }
2314
2315 if (time_h) {
2316 *time_h = ieee->current_network.last_dtim_sta_time[1];
2317 if (time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
2318 *time_h += 1;
2319 }
2320
2321 return 1;
2322
2323
2324}
2325
2326inline void rtllib_sta_ps(struct rtllib_device *ieee)
2327{
2328
2329 u32 th,tl;
2330 short sleep;
2331
2332 unsigned long flags,flags2;
2333
2334 spin_lock_irqsave(&ieee->lock, flags);
2335
2336 if ((ieee->ps == RTLLIB_PS_DISABLED ||
2337 ieee->iw_mode != IW_MODE_INFRA ||
2338 ieee->state != RTLLIB_LINKED)){
2339
2340 RT_TRACE(COMP_DBG, "=====>%s(): no need to ps,wake up!! ieee->ps is %d,ieee->iw_mode is %d,ieee->state is %d\n",
2341 __func__,ieee->ps,ieee->iw_mode,ieee->state);
2342 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
2343
2344 rtllib_sta_wakeup(ieee, 1);
2345
2346 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
2347 }
2348
2349 sleep = rtllib_sta_ps_sleep(ieee,&th, &tl);
2350 /* 2 wake, 1 sleep, 0 do nothing */
2351 if (sleep == 0)
2352 {
2353 goto out;
2354 }
2355 if (sleep == 1){
2356 if (ieee->sta_sleep == LPS_IS_SLEEP){
2357 ieee->enter_sleep_state(ieee->dev,th,tl);
2358 }
2359
2360 else if (ieee->sta_sleep == LPS_IS_WAKE){
2361 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
2362
2363 if (ieee->ps_is_queue_empty(ieee->dev)){
2364 ieee->sta_sleep = LPS_WAIT_NULL_DATA_SEND;
2365 ieee->ack_tx_to_ieee = 1;
2366 rtllib_sta_ps_send_null_frame(ieee,1);
2367 ieee->ps_th = th;
2368 ieee->ps_tl = tl;
2369 }
2370 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
2371
2372 }
2373
2374 ieee->bAwakePktSent = false;
2375
2376 }else if (sleep == 2){
2377 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
2378
2379 rtllib_sta_wakeup(ieee,1);
2380
2381 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
2382 }
2383
2384out:
2385 spin_unlock_irqrestore(&ieee->lock, flags);
2386
2387}
2388
2389void rtllib_sta_wakeup(struct rtllib_device *ieee, short nl)
2390{
2391 if (ieee->sta_sleep == LPS_IS_WAKE){
2392 if (nl){
2393 if (ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING)
2394 {
2395 ieee->ack_tx_to_ieee = 1;
2396 rtllib_sta_ps_send_null_frame(ieee, 0);
2397 }
2398 else
2399 {
2400 ieee->ack_tx_to_ieee = 1;
2401 rtllib_sta_ps_send_pspoll_frame(ieee);
2402 }
2403 }
2404 return;
2405
2406 }
2407
2408 if (ieee->sta_sleep == LPS_IS_SLEEP)
2409 ieee->sta_wake_up(ieee->dev);
2410 if (nl){
2411 /*
2412 ieee->ack_tx_to_ieee = 1;
2413 printk("%s(3): notify AP we are awaked ++++++++++ SendNullFunctionData\n", __func__);
2414 rtllib_sta_ps_send_null_frame(ieee, 0);
2415 */
2416 if (ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING)
2417 {
2418 ieee->ack_tx_to_ieee = 1;
2419 rtllib_sta_ps_send_null_frame(ieee, 0);
2420 }
2421 else
2422 {
2423 ieee->ack_tx_to_ieee = 1;
2424 ieee->polling = true;
2425 rtllib_sta_ps_send_pspoll_frame(ieee);
2426 }
2427
2428 } else {
2429 ieee->sta_sleep = LPS_IS_WAKE;
2430 ieee->polling = false;
2431 }
2432}
2433
2434void rtllib_ps_tx_ack(struct rtllib_device *ieee, short success)
2435{
2436 unsigned long flags,flags2;
2437
2438 spin_lock_irqsave(&ieee->lock, flags);
2439
2440 if (ieee->sta_sleep == LPS_WAIT_NULL_DATA_SEND){
2441 /* Null frame with PS bit set */
2442 if (success){
2443 ieee->sta_sleep = LPS_IS_SLEEP;
2444 ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
2445 }
2446 /* if the card report not success we can't be sure the AP
2447 * has not RXed so we can't assume the AP believe us awake
2448 */
2449 } else {/* 21112005 - tx again null without PS bit if lost */
2450
2451 if ((ieee->sta_sleep == LPS_IS_WAKE) && !success){
2452 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
2453 if (ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING)
2454 {
2455 rtllib_sta_ps_send_null_frame(ieee, 0);
2456 }
2457 else
2458 {
2459 rtllib_sta_ps_send_pspoll_frame(ieee);
2460 }
2461 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
2462 }
2463 }
2464 spin_unlock_irqrestore(&ieee->lock, flags);
2465}
2466
2467void rtllib_process_action(struct rtllib_device* ieee, struct sk_buff* skb)
2468{
2469 struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *) skb->data;
2470 u8* act = rtllib_get_payload((struct rtllib_hdr *)header);
2471 u8 category = 0;
2472
2473 if (act == NULL) {
2474 RTLLIB_DEBUG(RTLLIB_DL_ERR, "error to get payload of action frame\n");
2475 return;
2476 }
2477
2478 category = *act;
2479 act ++;
2480 switch (category) {
2481 case ACT_CAT_BA:
2482 switch (*act) {
2483 case ACT_ADDBAREQ:
2484 rtllib_rx_ADDBAReq(ieee, skb);
2485 break;
2486 case ACT_ADDBARSP:
2487 rtllib_rx_ADDBARsp(ieee, skb);
2488 break;
2489 case ACT_DELBA:
2490 rtllib_rx_DELBA(ieee, skb);
2491 break;
2492 }
2493 break;
2494 default:
2495 break;
2496 }
2497 return;
2498}
2499
2500inline int rtllib_rx_assoc_resp(struct rtllib_device *ieee, struct sk_buff *skb, struct rtllib_rx_stats *rx_stats)
2501{
2502 u16 errcode;
2503 int aid;
2504 u8* ies;
2505 struct rtllib_assoc_response_frame *assoc_resp;
2506 struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *) skb->data;
2507
2508 RTLLIB_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
2509 WLAN_FC_GET_STYPE(header->frame_ctl));
2510
2511 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2512 ieee->state == RTLLIB_ASSOCIATING_AUTHENTICATED &&
2513 (ieee->iw_mode == IW_MODE_INFRA))
2514 {
2515 if (0 == (errcode=assoc_parse(ieee,skb, &aid))){
2516 struct rtllib_network *network = kzalloc(sizeof(struct rtllib_network), GFP_ATOMIC);
2517
2518 if (!network)
2519 return 1;
2520 memset(network,0,sizeof(*network));
2521 ieee->state=RTLLIB_LINKED;
2522 ieee->assoc_id = aid;
2523 ieee->softmac_stats.rx_ass_ok++;
2524 /* station support qos */
2525 /* Let the register setting defaultly with Legacy station */
2526 assoc_resp = (struct rtllib_assoc_response_frame*)skb->data;
2527 if (ieee->current_network.qos_data.supported == 1) {
2528 if (rtllib_parse_info_param(ieee,assoc_resp->info_element,\
2529 rx_stats->len - sizeof(*assoc_resp),\
2530 network,rx_stats)){
2531 kfree(network);
2532 return 1;
2533 }
2534 else
2535 {
2536 memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
2537 memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
2538 }
2539 if (ieee->handle_assoc_response != NULL)
2540 ieee->handle_assoc_response(ieee->dev, (struct rtllib_assoc_response_frame*)header, network);
2541 kfree(network);
2542 }
2543
2544 if (ieee->assocresp_ies){
2545 kfree(ieee->assocresp_ies);
2546 ieee->assocresp_ies = NULL;
2547 }
2548 ies = &(assoc_resp->info_element[0].id);
2549 ieee->assocresp_ies_len = (skb->data + skb->len) - ies;
2550 ieee->assocresp_ies = kmalloc(ieee->assocresp_ies_len, GFP_ATOMIC);
2551 if (ieee->assocresp_ies)
2552 memcpy(ieee->assocresp_ies, ies, ieee->assocresp_ies_len);
2553 else{
2554 printk("%s()Warning: can't alloc memory for assocresp_ies\n", __func__);
2555 ieee->assocresp_ies_len = 0;
2556 }
2557 rtllib_associate_complete(ieee);
2558 } else {
2559 /* aid could not been allocated */
2560 ieee->softmac_stats.rx_ass_err++;
2561 printk(
2562 "Association response status code 0x%x\n",
2563 errcode);
2564 RTLLIB_DEBUG_MGMT(
2565 "Association response status code 0x%x\n",
2566 errcode);
2567 if (ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
2568 queue_delayed_work_rsl(ieee->wq, &ieee->associate_procedure_wq, 0);
2569 } else {
2570 rtllib_associate_abort(ieee);
2571 }
2572 }
2573 }
2574
2575 return 0;
2576}
2577
2578inline int rtllib_rx_auth(struct rtllib_device *ieee, struct sk_buff *skb, struct rtllib_rx_stats *rx_stats)
2579{
2580 u16 errcode;
2581 u8* challenge;
2582 int chlen=0;
2583 bool bSupportNmode = true, bHalfSupportNmode = false;
2584
2585 if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){
2586 if (ieee->state == RTLLIB_ASSOCIATING_AUTHENTICATING &&
2587 (ieee->iw_mode == IW_MODE_INFRA)) {
2588 RTLLIB_DEBUG_MGMT("Received authentication response");
2589
2590 if (0 == (errcode=auth_parse(skb, &challenge, &chlen))) {
2591 if (ieee->open_wep || !challenge){
2592 ieee->state = RTLLIB_ASSOCIATING_AUTHENTICATED;
2593 ieee->softmac_stats.rx_auth_rs_ok++;
2594 if (!(ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE))
2595 {
2596 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
2597 {
2598 if (IsHTHalfNmodeAPs(ieee))
2599 {
2600 bSupportNmode = true;
2601 bHalfSupportNmode = true;
2602 }
2603 else
2604 {
2605 bSupportNmode = false;
2606 bHalfSupportNmode = false;
2607 }
2608 }
2609 }
2610 /* Dummy wirless mode setting to avoid encryption issue */
2611 if (bSupportNmode) {
2612 ieee->SetWirelessMode(ieee->dev, \
2613 ieee->current_network.mode);
2614 }else{
2615 /*TODO*/
2616 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2617 }
2618
2619 if (ieee->current_network.mode == IEEE_N_24G && bHalfSupportNmode == true)
2620 {
2621 printk("===============>entern half N mode\n");
2622 ieee->bHalfWirelessN24GMode = true;
2623 }
2624 else
2625 ieee->bHalfWirelessN24GMode = false;
2626
2627 rtllib_associate_step2(ieee);
2628 }else{
2629 rtllib_auth_challenge(ieee, challenge, chlen);
2630 }
2631 }else{
2632 ieee->softmac_stats.rx_auth_rs_err++;
2633 RTLLIB_DEBUG_MGMT("Authentication respose status code 0x%x",errcode);
2634
2635 printk("Authentication respose status code 0x%x",errcode);
2636 rtllib_associate_abort(ieee);
2637 }
2638
2639 }else if (ieee->iw_mode == IW_MODE_MASTER){
2640 rtllib_rx_auth_rq(ieee, skb);
2641 }
2642 }
2643
2644 return 0;
2645}
2646
2647inline int rtllib_rx_deauth(struct rtllib_device *ieee, struct sk_buff *skb)
2648{
2649 struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *) skb->data;
2650
2651 if (memcmp(header->addr3, ieee->current_network.bssid, ETH_ALEN) != 0)
2652 return 0;
2653
2654 /* FIXME for now repeat all the association procedure
2655 * both for disassociation and deauthentication
2656 */
2657 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2658 ieee->state == RTLLIB_LINKED &&
2659 (ieee->iw_mode == IW_MODE_INFRA)) {
2660 printk(KERN_INFO "==========>received disassoc/deauth(%x) "
2661 "frame, reason code:%x\n",
2662 WLAN_FC_GET_STYPE(header->frame_ctl),
2663 ((struct rtllib_disassoc*)skb->data)->reason);
2664 ieee->state = RTLLIB_ASSOCIATING;
2665 ieee->softmac_stats.reassoc++;
2666 ieee->is_roaming = true;
2667 ieee->LinkDetectInfo.bBusyTraffic = false;
2668 rtllib_disassociate(ieee);
2669 RemovePeerTS(ieee, header->addr2);
2670 if (ieee->LedControlHandler != NULL)
2671 ieee->LedControlHandler(ieee->dev, LED_CTL_START_TO_LINK);
2672
2673 if (!(ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_CCMP|SEC_ALG_TKIP)))
2674 queue_delayed_work_rsl(ieee->wq, &ieee->associate_procedure_wq, 5);
2675 }
2676
2677 return 0;
2678}
2679
2680inline int rtllib_rx_frame_softmac(struct rtllib_device *ieee, struct sk_buff *skb,
2681 struct rtllib_rx_stats *rx_stats, u16 type,
2682 u16 stype)
2683{
2684 struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *) skb->data;
2685
2686 if (!ieee->proto_started)
2687 return 0;
2688
2689 switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
2690
2691 case RTLLIB_STYPE_ASSOC_RESP:
2692 case RTLLIB_STYPE_REASSOC_RESP:
2693
2694 if (rtllib_rx_assoc_resp(ieee, skb, rx_stats) == 1)
2695 return 1;
2696
2697 break;
2698
2699 case RTLLIB_STYPE_ASSOC_REQ:
2700 case RTLLIB_STYPE_REASSOC_REQ:
2701
2702 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2703 ieee->iw_mode == IW_MODE_MASTER)
2704
2705 rtllib_rx_assoc_rq(ieee, skb);
2706 break;
2707
2708 case RTLLIB_STYPE_AUTH:
2709
2710 rtllib_rx_auth(ieee, skb, rx_stats);
2711
2712 break;
2713 case RTLLIB_STYPE_DISASSOC:
2714 case RTLLIB_STYPE_DEAUTH:
2715
2716 rtllib_rx_deauth(ieee, skb);
2717
2718 break;
2719
2720 case RTLLIB_STYPE_MANAGE_ACT:
2721 rtllib_process_action(ieee,skb);
2722 break;
2723#ifdef COMPATIBLE_WITH_RALINK_MESH
2724 case RTLLIB_STYPE_MESH_ACT:
2725 rtllib_process_action_mesh(ieee,skb,rx_stats);
2726 break;
2727#endif
2728 default:
2729 return -1;
2730 break;
2731 }
2732
2733 return 0;
2734}
2735
2736/* following are for a simplier TX queue management.
2737 * Instead of using netif_[stop/wake]_queue the driver
2738 * will uses these two function (plus a reset one), that
2739 * will internally uses the kernel netif_* and takes
2740 * care of the ieee802.11 fragmentation.
2741 * So the driver receives a fragment per time and might
2742 * call the stop function when it want without take care
2743 * to have enought room to TX an entire packet.
2744 * This might be useful if each fragment need it's own
2745 * descriptor, thus just keep a total free memory > than
2746 * the max fragmentation treshold is not enought.. If the
2747 * ieee802.11 stack passed a TXB struct then you needed
2748 * to keep N free descriptors where
2749 * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
2750 * In this way you need just one and the 802.11 stack
2751 * will take care of buffering fragments and pass them to
2752 * to the driver later, when it wakes the queue.
2753 */
2754void rtllib_softmac_xmit(struct rtllib_txb *txb, struct rtllib_device *ieee)
2755{
2756
2757 unsigned int queue_index = txb->queue_index;
2758 unsigned long flags;
2759 int i;
2760 cb_desc *tcb_desc = NULL;
2761 unsigned long queue_len = 0;
2762
2763 spin_lock_irqsave(&ieee->lock,flags);
2764
2765 /* called with 2nd parm 0, no tx mgmt lock required */
2766 rtllib_sta_wakeup(ieee,0);
2767
2768 /* update the tx status */
2769 tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
2770 if (tcb_desc->bMulticast) {
2771 ieee->stats.multicast++;
2772 }
2773#if 1
2774 /* if xmit available, just xmit it immediately, else just insert it to the wait queue */
2775 for (i = 0; i < txb->nr_frags; i++) {
2776#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2777 queue_len = skb_queue_len(&ieee->skb_drv_aggQ[queue_index]);
2778#else
2779 queue_len = skb_queue_len(&ieee->skb_waitQ[queue_index]);
2780#endif
2781 if ((queue_len != 0) ||\
2782 (!ieee->check_nic_enough_desc(ieee->dev,queue_index))||\
2783 (ieee->queue_stop)) {
2784 /* insert the skb packet to the wait queue */
2785 /* as for the completion function, it does not need
2786 * to check it any more.
2787 * */
2788#ifdef WIFI_TEST
2789 if (1)
2790#else
2791 if (queue_len < 200)
2792#endif
2793 {
2794#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2795 skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]);
2796#else
2797 skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
2798#endif
2799 }else{
2800 kfree_skb(txb->fragments[i]);
2801 }
2802 }else{
2803 ieee->softmac_data_hard_start_xmit(
2804 txb->fragments[i],
2805 ieee->dev,ieee->rate);
2806 }
2807 }
2808#endif
2809 rtllib_txb_free(txb);
2810
2811 spin_unlock_irqrestore(&ieee->lock,flags);
2812
2813}
2814
2815/* called with ieee->lock acquired */
2816void rtllib_resume_tx(struct rtllib_device *ieee)
2817{
2818 int i;
2819 for (i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
2820
2821 if (ieee->queue_stop){
2822 ieee->tx_pending.frag = i;
2823 return;
2824 }else{
2825
2826 ieee->softmac_data_hard_start_xmit(
2827 ieee->tx_pending.txb->fragments[i],
2828 ieee->dev,ieee->rate);
2829 ieee->stats.tx_packets++;
2830 }
2831 }
2832
2833 rtllib_txb_free(ieee->tx_pending.txb);
2834 ieee->tx_pending.txb = NULL;
2835}
2836
2837
2838void rtllib_reset_queue(struct rtllib_device *ieee)
2839{
2840 unsigned long flags;
2841
2842 spin_lock_irqsave(&ieee->lock,flags);
2843 init_mgmt_queue(ieee);
2844 if (ieee->tx_pending.txb){
2845 rtllib_txb_free(ieee->tx_pending.txb);
2846 ieee->tx_pending.txb = NULL;
2847 }
2848 ieee->queue_stop = 0;
2849 spin_unlock_irqrestore(&ieee->lock,flags);
2850
2851}
2852
2853void rtllib_wake_queue(struct rtllib_device *ieee)
2854{
2855
2856 unsigned long flags;
2857 struct sk_buff *skb;
2858 struct rtllib_hdr_3addr *header;
2859
2860 spin_lock_irqsave(&ieee->lock,flags);
2861 if (! ieee->queue_stop) goto exit;
2862
2863 ieee->queue_stop = 0;
2864
2865 if (ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){
2866 while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
2867
2868 header = (struct rtllib_hdr_3addr *) skb->data;
2869
2870 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2871
2872 if (ieee->seq_ctrl[0] == 0xFFF)
2873 ieee->seq_ctrl[0] = 0;
2874 else
2875 ieee->seq_ctrl[0]++;
2876
2877 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
2878 }
2879 }
2880 if (!ieee->queue_stop && ieee->tx_pending.txb)
2881 rtllib_resume_tx(ieee);
2882
2883 if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){
2884 ieee->softmac_stats.swtxawake++;
2885 netif_wake_queue(ieee->dev);
2886 }
2887
2888exit :
2889 spin_unlock_irqrestore(&ieee->lock,flags);
2890}
2891
2892
2893void rtllib_stop_queue(struct rtllib_device *ieee)
2894{
2895
2896 if (! netif_queue_stopped(ieee->dev)){
2897 netif_stop_queue(ieee->dev);
2898 ieee->softmac_stats.swtxstop++;
2899 }
2900 ieee->queue_stop = 1;
2901
2902}
2903
2904void rtllib_stop_all_queues(struct rtllib_device *ieee)
2905{
2906#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)
2907 unsigned int i;
2908 for (i=0; i < ieee->dev->num_tx_queues; i++)
2909 netdev_get_tx_queue(ieee->dev,i)->trans_start = jiffies;
2910#else
2911 ieee->dev->trans_start = jiffies;
2912#endif
2913
2914#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
2915 netif_carrier_off(ieee->dev);
2916#else
2917 netif_tx_stop_all_queues(ieee->dev);
2918#endif
2919}
2920
2921void rtllib_wake_all_queues(struct rtllib_device *ieee)
2922{
2923#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
2924 netif_carrier_on(ieee->dev);
2925#else
2926 netif_tx_wake_all_queues(ieee->dev);
2927#endif
2928}
2929
2930inline void rtllib_randomize_cell(struct rtllib_device *ieee)
2931{
2932
2933 get_random_bytes(ieee->current_network.bssid, ETH_ALEN);
2934
2935 /* an IBSS cell address must have the two less significant
2936 * bits of the first byte = 2
2937 */
2938 ieee->current_network.bssid[0] &= ~0x01;
2939 ieee->current_network.bssid[0] |= 0x02;
2940}
2941
2942/* called in user context only */
2943void rtllib_start_master_bss(struct rtllib_device *ieee)
2944{
2945 ieee->assoc_id = 1;
2946
2947 if (ieee->current_network.ssid_len == 0){
2948 strncpy(ieee->current_network.ssid,
2949 RTLLIB_DEFAULT_TX_ESSID,
2950 IW_ESSID_MAX_SIZE);
2951
2952 ieee->current_network.ssid_len = strlen(RTLLIB_DEFAULT_TX_ESSID);
2953 ieee->ssid_set = 1;
2954 }
2955
2956 memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
2957
2958 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2959 ieee->state = RTLLIB_LINKED;
2960 ieee->link_change(ieee->dev);
2961 notify_wx_assoc_event(ieee);
2962
2963 if (ieee->data_hard_resume)
2964 ieee->data_hard_resume(ieee->dev);
2965
2966 netif_carrier_on(ieee->dev);
2967}
2968
2969void rtllib_start_monitor_mode(struct rtllib_device *ieee)
2970{
2971 /* reset hardware status */
2972 if (ieee->raw_tx){
2973 if (ieee->data_hard_resume)
2974 ieee->data_hard_resume(ieee->dev);
2975
2976 netif_carrier_on(ieee->dev);
2977 }
2978}
2979
2980void rtllib_start_ibss_wq(void *data)
2981{
2982 struct rtllib_device *ieee = container_of_dwork_rsl(data, struct rtllib_device, start_ibss_wq);
2983 /* iwconfig mode ad-hoc will schedule this and return
2984 * on the other hand this will block further iwconfig SET
2985 * operations because of the wx_sem hold.
2986 * Anyway some most set operations set a flag to speed-up
2987 * (abort) this wq (when syncro scanning) before sleeping
2988 * on the semaphore
2989 */
2990 if (!ieee->proto_started){
2991 printk("==========oh driver down return\n");
2992 return;
2993 }
2994 down(&ieee->wx_sem);
2995
2996 if (ieee->current_network.ssid_len == 0){
2997 strcpy(ieee->current_network.ssid,RTLLIB_DEFAULT_TX_ESSID);
2998 ieee->current_network.ssid_len = strlen(RTLLIB_DEFAULT_TX_ESSID);
2999 ieee->ssid_set = 1;
3000 }
3001
3002 ieee->state = RTLLIB_NOLINK;
3003#ifdef ADHOC_11N
3004 ieee->mode = IEEE_N_24G;
3005#else
3006 ieee->mode = IEEE_G;
3007#endif
3008 /* check if we have this cell in our network list */
3009 rtllib_softmac_check_all_nets(ieee);
3010
3011
3012 /* if not then the state is not linked. Maybe the user swithced to
3013 * ad-hoc mode just after being in monitor mode, or just after
3014 * being very few time in managed mode (so the card have had no
3015 * time to scan all the chans..) or we have just run up the iface
3016 * after setting ad-hoc mode. So we have to give another try..
3017 * Here, in ibss mode, should be safe to do this without extra care
3018 * (in bss mode we had to make sure no-one tryed to associate when
3019 * we had just checked the ieee->state and we was going to start the
3020 * scan) beacause in ibss mode the rtllib_new_net function, when
3021 * finds a good net, just set the ieee->state to RTLLIB_LINKED,
3022 * so, at worst, we waste a bit of time to initiate an unneeded syncro
3023 * scan, that will stop at the first round because it sees the state
3024 * associated.
3025 */
3026 if (ieee->state == RTLLIB_NOLINK)
3027 rtllib_start_scan_syncro(ieee, 0);
3028
3029 /* the network definitively is not here.. create a new cell */
3030 if (ieee->state == RTLLIB_NOLINK){
3031 printk("creating new IBSS cell\n");
3032 ieee->current_network.channel = ieee->IbssStartChnl;
3033 if (!ieee->wap_set)
3034 rtllib_randomize_cell(ieee);
3035
3036 if (ieee->modulation & RTLLIB_CCK_MODULATION){
3037
3038 ieee->current_network.rates_len = 4;
3039
3040 ieee->current_network.rates[0] = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_1MB;
3041 ieee->current_network.rates[1] = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_2MB;
3042 ieee->current_network.rates[2] = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_5MB;
3043 ieee->current_network.rates[3] = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_11MB;
3044
3045 }else
3046 ieee->current_network.rates_len = 0;
3047
3048 if (ieee->modulation & RTLLIB_OFDM_MODULATION){
3049 ieee->current_network.rates_ex_len = 8;
3050
3051 /*ieee->current_network.rates_ex[0] = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_6MB;
3052 ieee->current_network.rates_ex[1] = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_9MB;
3053 ieee->current_network.rates_ex[2] = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_12MB;
3054 ieee->current_network.rates_ex[3] = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_18MB;
3055 ieee->current_network.rates_ex[4] = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_24MB;
3056 ieee->current_network.rates_ex[5] = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_36MB;
3057 ieee->current_network.rates_ex[6] = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_48MB;
3058 ieee->current_network.rates_ex[7] = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_54MB;*/
3059
3060 ieee->current_network.rates_ex[0] = RTLLIB_OFDM_RATE_6MB;
3061 ieee->current_network.rates_ex[1] = RTLLIB_OFDM_RATE_9MB;
3062 ieee->current_network.rates_ex[2] = RTLLIB_OFDM_RATE_12MB;
3063 ieee->current_network.rates_ex[3] = RTLLIB_OFDM_RATE_18MB;
3064 ieee->current_network.rates_ex[4] = RTLLIB_OFDM_RATE_24MB;
3065 ieee->current_network.rates_ex[5] = RTLLIB_OFDM_RATE_36MB;
3066 ieee->current_network.rates_ex[6] = RTLLIB_OFDM_RATE_48MB;
3067 ieee->current_network.rates_ex[7] = RTLLIB_OFDM_RATE_54MB;
3068
3069 ieee->rate = 108;
3070 }else{
3071 ieee->current_network.rates_ex_len = 0;
3072 ieee->rate = 22;
3073 }
3074
3075#if defined(RTL8192U) || defined(RTL8192SU) || defined(RTL8192SE)
3076#ifdef ADHOC_11N
3077 ieee->current_network.qos_data.supported = 1;
3078#else
3079 ieee->current_network.qos_data.supported = 0;
3080#endif
3081 ieee->SetWirelessMode(ieee->dev, ieee->mode);
3082#else
3083 ieee->current_network.qos_data.supported = 0;
3084 ieee->SetWirelessMode(ieee->dev, IEEE_G);
3085#endif
3086 ieee->current_network.mode = ieee->mode;
3087 ieee->current_network.atim_window = 0;
3088 ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
3089 }
3090
3091 printk("%s(): ieee->mode = %d\n", __func__, ieee->mode);
3092 if ((ieee->mode == IEEE_N_24G) || (ieee->mode == IEEE_N_5G))
3093 HTUseDefaultSetting(ieee);
3094 else
3095 ieee->pHTInfo->bCurrentHTSupport = false;
3096
3097 ieee->SetHwRegHandler(ieee->dev, HW_VAR_MEDIA_STATUS, (u8 *)(&ieee->state));
3098
3099 ieee->state = RTLLIB_LINKED;
3100 ieee->link_change(ieee->dev);
3101
3102 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
3103 if (ieee->LedControlHandler != NULL)
3104 ieee->LedControlHandler(ieee->dev,LED_CTL_LINK);
3105
3106 rtllib_start_send_beacons(ieee);
3107
3108 notify_wx_assoc_event(ieee);
3109
3110 if (ieee->data_hard_resume)
3111 ieee->data_hard_resume(ieee->dev);
3112
3113 netif_carrier_on(ieee->dev);
3114
3115 up(&ieee->wx_sem);
3116}
3117
3118inline void rtllib_start_ibss(struct rtllib_device *ieee)
3119{
3120 queue_delayed_work_rsl(ieee->wq, &ieee->start_ibss_wq, MSECS(150));
3121}
3122
3123/* this is called only in user context, with wx_sem held */
3124void rtllib_start_bss(struct rtllib_device *ieee)
3125{
3126 unsigned long flags;
3127#ifdef ENABLE_DOT11D
3128 if (IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
3129 {
3130 if (! ieee->bGlobalDomain)
3131 {
3132 return;
3133 }
3134 }
3135#endif
3136 /* check if we have already found the net we
3137 * are interested in (if any).
3138 * if not (we are disassociated and we are not
3139 * in associating / authenticating phase) start the background scanning.
3140 */
3141 rtllib_softmac_check_all_nets(ieee);
3142
3143 /* ensure no-one start an associating process (thus setting
3144 * the ieee->state to rtllib_ASSOCIATING) while we
3145 * have just cheked it and we are going to enable scan.
3146 * The rtllib_new_net function is always called with
3147 * lock held (from both rtllib_softmac_check_all_nets and
3148 * the rx path), so we cannot be in the middle of such function
3149 */
3150 spin_lock_irqsave(&ieee->lock, flags);
3151
3152 if (ieee->state == RTLLIB_NOLINK) {
3153 rtllib_start_scan(ieee);
3154 }
3155 spin_unlock_irqrestore(&ieee->lock, flags);
3156}
3157
3158void rtllib_link_change_wq(void *data)
3159{
3160 struct rtllib_device *ieee = container_of_dwork_rsl(data, struct rtllib_device, link_change_wq);
3161 ieee->link_change(ieee->dev);
3162}
3163/* called only in userspace context */
3164void rtllib_disassociate(struct rtllib_device *ieee)
3165{
3166 netif_carrier_off(ieee->dev);
3167 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
3168 rtllib_reset_queue(ieee);
3169
3170 if (ieee->data_hard_stop)
3171 ieee->data_hard_stop(ieee->dev);
3172#ifdef ENABLE_DOT11D
3173 if (IS_DOT11D_ENABLE(ieee))
3174 Dot11d_Reset(ieee);
3175#endif
3176 ieee->state = RTLLIB_NOLINK;
3177 ieee->is_set_key = false;
3178 ieee->wap_set = 0;
3179
3180 queue_delayed_work_rsl(ieee->wq, &ieee->link_change_wq, 0);
3181
3182
3183#ifndef FOR_ANDROID_X86
3184 notify_wx_assoc_event(ieee);
3185#endif
3186}
3187
3188void rtllib_associate_retry_wq(void *data)
3189{
3190 struct rtllib_device *ieee = container_of_dwork_rsl(data, struct rtllib_device, associate_retry_wq);
3191 unsigned long flags;
3192
3193 down(&ieee->wx_sem);
3194 if (!ieee->proto_started)
3195 goto exit;
3196
3197 if (ieee->state != RTLLIB_ASSOCIATING_RETRY)
3198 goto exit;
3199
3200 /* until we do not set the state to RTLLIB_NOLINK
3201 * there are no possibility to have someone else trying
3202 * to start an association procdure (we get here with
3203 * ieee->state = RTLLIB_ASSOCIATING).
3204 * When we set the state to RTLLIB_NOLINK it is possible
3205 * that the RX path run an attempt to associate, but
3206 * both rtllib_softmac_check_all_nets and the
3207 * RX path works with ieee->lock held so there are no
3208 * problems. If we are still disassociated then start a scan.
3209 * the lock here is necessary to ensure no one try to start
3210 * an association procedure when we have just checked the
3211 * state and we are going to start the scan.
3212 */
3213 ieee->beinretry = true;
3214 ieee->state = RTLLIB_NOLINK;
3215
3216 rtllib_softmac_check_all_nets(ieee);
3217
3218 spin_lock_irqsave(&ieee->lock, flags);
3219
3220 if (ieee->state == RTLLIB_NOLINK)
3221 {
3222 rtllib_start_scan(ieee);
3223 }
3224 spin_unlock_irqrestore(&ieee->lock, flags);
3225
3226 ieee->beinretry = false;
3227exit:
3228 up(&ieee->wx_sem);
3229}
3230
3231struct sk_buff *rtllib_get_beacon_(struct rtllib_device *ieee)
3232{
3233 u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
3234
3235 struct sk_buff *skb;
3236 struct rtllib_probe_response *b;
3237 skb = rtllib_probe_resp(ieee, broadcast_addr);
3238
3239 if (!skb)
3240 return NULL;
3241
3242 b = (struct rtllib_probe_response *) skb->data;
3243 b->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_BEACON);
3244
3245 return skb;
3246
3247}
3248
3249struct sk_buff *rtllib_get_beacon(struct rtllib_device *ieee)
3250{
3251 struct sk_buff *skb;
3252 struct rtllib_probe_response *b;
3253
3254 skb = rtllib_get_beacon_(ieee);
3255 if (!skb)
3256 return NULL;
3257
3258 b = (struct rtllib_probe_response *) skb->data;
3259 b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
3260
3261 if (ieee->seq_ctrl[0] == 0xFFF)
3262 ieee->seq_ctrl[0] = 0;
3263 else
3264 ieee->seq_ctrl[0]++;
3265
3266 return skb;
3267}
3268
3269void rtllib_softmac_stop_protocol(struct rtllib_device *ieee, u8 mesh_flag, u8 shutdown)
3270{
3271 rtllib_stop_scan_syncro(ieee);
3272 down(&ieee->wx_sem);
3273 rtllib_stop_protocol(ieee,shutdown);
3274 up(&ieee->wx_sem);
3275}
3276
3277
3278void rtllib_stop_protocol(struct rtllib_device *ieee, u8 shutdown)
3279{
3280 if (!ieee->proto_started)
3281 return;
3282
3283 if (shutdown){
3284 ieee->proto_started = 0;
3285 ieee->proto_stoppping = 1;
3286 if (ieee->rtllib_ips_leave != NULL)
3287 ieee->rtllib_ips_leave(ieee->dev);
3288 }
3289
3290 rtllib_stop_send_beacons(ieee);
3291 del_timer_sync(&ieee->associate_timer);
3292 cancel_delayed_work(&ieee->associate_retry_wq);
3293 cancel_delayed_work(&ieee->start_ibss_wq);
3294 cancel_delayed_work(&ieee->link_change_wq);
3295 rtllib_stop_scan(ieee);
3296
3297 if (ieee->state <= RTLLIB_ASSOCIATING_AUTHENTICATED)
3298 ieee->state = RTLLIB_NOLINK;
3299
3300 if (ieee->state == RTLLIB_LINKED){
3301 if (ieee->iw_mode == IW_MODE_INFRA)
3302 SendDisassociation(ieee,1,deauth_lv_ss);
3303 rtllib_disassociate(ieee);
3304 }
3305
3306 if (shutdown){
3307 RemoveAllTS(ieee);
3308 ieee->proto_stoppping = 0;
3309 }
3310 if (ieee->assocreq_ies) {
3311 kfree(ieee->assocreq_ies);
3312 ieee->assocreq_ies = NULL;
3313 ieee->assocreq_ies_len = 0;
3314 }
3315 if (ieee->assocresp_ies) {
3316 kfree(ieee->assocresp_ies);
3317 ieee->assocresp_ies = NULL;
3318 ieee->assocresp_ies_len = 0;
3319 }
3320}
3321
3322void rtllib_softmac_start_protocol(struct rtllib_device *ieee, u8 mesh_flag)
3323{
3324 down(&ieee->wx_sem);
3325 rtllib_start_protocol(ieee);
3326 up(&ieee->wx_sem);
3327}
3328
3329void rtllib_start_protocol(struct rtllib_device *ieee)
3330{
3331 short ch = 0;
3332 int i = 0;
3333
3334 rtllib_update_active_chan_map(ieee);
3335
3336 if (ieee->proto_started)
3337 return;
3338
3339 ieee->proto_started = 1;
3340
3341 if (ieee->current_network.channel == 0) {
3342 do {
3343 ch++;
3344 if (ch > MAX_CHANNEL_NUMBER)
3345 return; /* no channel found */
3346 } while(!ieee->active_channel_map[ch]);
3347 ieee->current_network.channel = ch;
3348 }
3349
3350 if (ieee->current_network.beacon_interval == 0)
3351 ieee->current_network.beacon_interval = 100;
3352
3353 for (i = 0; i < 17; i++) {
3354 ieee->last_rxseq_num[i] = -1;
3355 ieee->last_rxfrag_num[i] = -1;
3356 ieee->last_packet_time[i] = 0;
3357 }
3358
3359 if (ieee->UpdateBeaconInterruptHandler)
3360 ieee->UpdateBeaconInterruptHandler(ieee->dev, false);
3361
3362 ieee->wmm_acm = 0;
3363 /* if the user set the MAC of the ad-hoc cell and then
3364 * switch to managed mode, shall we make sure that association
3365 * attempts does not fail just because the user provide the essid
3366 * and the nic is still checking for the AP MAC ??
3367 */
3368 if (ieee->iw_mode == IW_MODE_INFRA) {
3369 rtllib_start_bss(ieee);
3370 } else if (ieee->iw_mode == IW_MODE_ADHOC) {
3371 if (ieee->UpdateBeaconInterruptHandler)
3372 ieee->UpdateBeaconInterruptHandler(ieee->dev, true);
3373
3374 rtllib_start_ibss(ieee);
3375
3376 } else if (ieee->iw_mode == IW_MODE_MASTER) {
3377 rtllib_start_master_bss(ieee);
3378 } else if (ieee->iw_mode == IW_MODE_MONITOR) {
3379 rtllib_start_monitor_mode(ieee);
3380 }
3381}
3382
3383void rtllib_softmac_init(struct rtllib_device *ieee)
3384{
3385 int i;
3386 memset(&ieee->current_network, 0, sizeof(struct rtllib_network));
3387
3388 ieee->state = RTLLIB_NOLINK;
3389 for (i = 0; i < 5; i++) {
3390 ieee->seq_ctrl[i] = 0;
3391 }
3392#ifdef ENABLE_DOT11D
3393 ieee->pDot11dInfo = kmalloc(sizeof(struct rt_dot11d_info), GFP_ATOMIC);
3394 if (!ieee->pDot11dInfo)
3395 RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc memory for DOT11D\n");
3396 memset(ieee->pDot11dInfo, 0, sizeof(struct rt_dot11d_info));
3397#endif
3398 ieee->LinkDetectInfo.SlotIndex = 0;
3399 ieee->LinkDetectInfo.SlotNum = 2;
3400 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
3401 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
3402 ieee->LinkDetectInfo.NumTxOkInPeriod =0;
3403 ieee->LinkDetectInfo.NumRxOkInPeriod =0;
3404 ieee->LinkDetectInfo.NumRxUnicastOkInPeriod=0;
3405 ieee->bIsAggregateFrame = false;
3406 ieee->assoc_id = 0;
3407 ieee->queue_stop = 0;
3408 ieee->scanning_continue = 0;
3409 ieee->softmac_features = 0;
3410 ieee->wap_set = 0;
3411 ieee->ssid_set = 0;
3412 ieee->proto_started = 0;
3413 ieee->proto_stoppping = 0;
3414 ieee->basic_rate = RTLLIB_DEFAULT_BASIC_RATE;
3415 ieee->rate = 22;
3416 ieee->ps = RTLLIB_PS_DISABLED;
3417 ieee->sta_sleep = LPS_IS_WAKE;
3418
3419 ieee->Regdot11HTOperationalRateSet[0]= 0xff;
3420 ieee->Regdot11HTOperationalRateSet[1]= 0xff;
3421 ieee->Regdot11HTOperationalRateSet[4]= 0x01;
3422
3423 ieee->Regdot11TxHTOperationalRateSet[0]= 0xff;
3424 ieee->Regdot11TxHTOperationalRateSet[1]= 0xff;
3425 ieee->Regdot11TxHTOperationalRateSet[4]= 0x01;
3426
3427 ieee->FirstIe_InScan = false;
3428 ieee->actscanning = false;
3429 ieee->beinretry = false;
3430 ieee->is_set_key = false;
3431 init_mgmt_queue(ieee);
3432
3433 ieee->sta_edca_param[0] = 0x0000A403;
3434 ieee->sta_edca_param[1] = 0x0000A427;
3435 ieee->sta_edca_param[2] = 0x005E4342;
3436 ieee->sta_edca_param[3] = 0x002F3262;
3437 ieee->aggregation = true;
3438 ieee->enable_rx_imm_BA = 1;
3439#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,40)
3440 _setup_timer(&ieee->scan_timer,
3441 rtllib_softmac_scan_cb,
3442 (unsigned long) ieee);
3443#endif
3444 ieee->tx_pending.txb = NULL;
3445
3446 _setup_timer(&ieee->associate_timer,
3447 rtllib_associate_abort_cb,
3448 (unsigned long) ieee);
3449
3450 _setup_timer(&ieee->beacon_timer,
3451 rtllib_send_beacon_cb,
3452 (unsigned long) ieee);
3453
3454#if defined(RTL8192U) || defined(RTL8192SU) || defined(RTL8192SE)
3455 _setup_timer(&ieee->ibss_wait_timer,
3456 rtllib_ibss_wait_timeout,
3457 (unsigned long) ieee);
3458#endif
3459
3460#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3461#ifdef PF_SYNCTHREAD
3462 ieee->wq = create_workqueue(DRV_NAME,0);
3463#else
3464 ieee->wq = create_workqueue(DRV_NAME);
3465#endif
3466#endif
3467
3468 INIT_DELAYED_WORK_RSL(&ieee->link_change_wq,(void*)rtllib_link_change_wq,ieee);
3469 INIT_DELAYED_WORK_RSL(&ieee->start_ibss_wq,(void*)rtllib_start_ibss_wq,ieee);
3470 INIT_WORK_RSL(&ieee->associate_complete_wq, (void*)rtllib_associate_complete_wq,ieee);
3471 INIT_DELAYED_WORK_RSL(&ieee->associate_procedure_wq, (void*)rtllib_associate_procedure_wq,ieee);
3472 INIT_DELAYED_WORK_RSL(&ieee->softmac_scan_wq,(void*)rtllib_softmac_scan_wq,ieee);
3473 INIT_DELAYED_WORK_RSL(&ieee->softmac_hint11d_wq,(void*)rtllib_softmac_hint11d_wq,ieee);
3474 INIT_DELAYED_WORK_RSL(&ieee->associate_retry_wq, (void*)rtllib_associate_retry_wq,ieee);
3475 INIT_WORK_RSL(&ieee->wx_sync_scan_wq,(void*)rtllib_wx_sync_scan_wq,ieee);
3476
3477 sema_init(&ieee->wx_sem, 1);
3478 sema_init(&ieee->scan_sem, 1);
3479 sema_init(&ieee->ips_sem,1);
3480
3481 spin_lock_init(&ieee->mgmt_tx_lock);
3482 spin_lock_init(&ieee->beacon_lock);
3483
3484 tasklet_init(&ieee->ps_task,
3485 (void(*)(unsigned long)) rtllib_sta_ps,
3486 (unsigned long)ieee);
3487
3488}
3489
3490void rtllib_softmac_free(struct rtllib_device *ieee)
3491{
3492 down(&ieee->wx_sem);
3493#ifdef ENABLE_DOT11D
3494 if (NULL != ieee->pDot11dInfo)
3495 {
3496 kfree(ieee->pDot11dInfo);
3497 ieee->pDot11dInfo = NULL;
3498 }
3499#endif
3500 del_timer_sync(&ieee->associate_timer);
3501
3502#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3503 cancel_delayed_work(&ieee->associate_retry_wq);
3504 destroy_workqueue(ieee->wq);
3505#endif
3506
3507 up(&ieee->wx_sem);
3508}
3509
3510/********************************************************
3511 * Start of WPA code. *
3512 * this is stolen from the ipw2200 driver *
3513 ********************************************************/
3514
3515
3516static int rtllib_wpa_enable(struct rtllib_device *ieee, int value)
3517{
3518 /* This is called when wpa_supplicant loads and closes the driver
3519 * interface. */
3520 printk("%s WPA\n",value ? "enabling" : "disabling");
3521 ieee->wpa_enabled = value;
3522 memset(ieee->ap_mac_addr, 0, 6);
3523 return 0;
3524}
3525
3526
3527void rtllib_wpa_assoc_frame(struct rtllib_device *ieee, char *wpa_ie, int wpa_ie_len)
3528{
3529 /* make sure WPA is enabled */
3530 rtllib_wpa_enable(ieee, 1);
3531
3532 rtllib_disassociate(ieee);
3533}
3534
3535
3536static int rtllib_wpa_mlme(struct rtllib_device *ieee, int command, int reason)
3537{
3538
3539 int ret = 0;
3540
3541 switch (command) {
3542 case IEEE_MLME_STA_DEAUTH:
3543 break;
3544
3545 case IEEE_MLME_STA_DISASSOC:
3546 rtllib_disassociate(ieee);
3547 break;
3548
3549 default:
3550 printk("Unknown MLME request: %d\n", command);
3551 ret = -EOPNOTSUPP;
3552 }
3553
3554 return ret;
3555}
3556
3557
3558static int rtllib_wpa_set_wpa_ie(struct rtllib_device *ieee,
3559 struct ieee_param *param, int plen)
3560{
3561 u8 *buf;
3562
3563 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
3564 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
3565 return -EINVAL;
3566
3567 if (param->u.wpa_ie.len) {
3568 buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
3569 if (buf == NULL)
3570 return -ENOMEM;
3571
3572 memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
3573 kfree(ieee->wpa_ie);
3574 ieee->wpa_ie = buf;
3575 ieee->wpa_ie_len = param->u.wpa_ie.len;
3576 } else {
3577 kfree(ieee->wpa_ie);
3578 ieee->wpa_ie = NULL;
3579 ieee->wpa_ie_len = 0;
3580 }
3581
3582 rtllib_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
3583 return 0;
3584}
3585
3586#define AUTH_ALG_OPEN_SYSTEM 0x1
3587#define AUTH_ALG_SHARED_KEY 0x2
3588#define AUTH_ALG_LEAP 0x4
3589static int rtllib_wpa_set_auth_algs(struct rtllib_device *ieee, int value)
3590{
3591
3592 struct rtllib_security sec = {
3593 .flags = SEC_AUTH_MODE,
3594 };
3595 int ret = 0;
3596
3597 if (value & AUTH_ALG_SHARED_KEY) {
3598 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
3599 ieee->open_wep = 0;
3600 ieee->auth_mode = 1;
3601 } else if (value & AUTH_ALG_OPEN_SYSTEM){
3602 sec.auth_mode = WLAN_AUTH_OPEN;
3603 ieee->open_wep = 1;
3604 ieee->auth_mode = 0;
3605 }
3606 else if (value & AUTH_ALG_LEAP){
3607 sec.auth_mode = WLAN_AUTH_LEAP >> 6;
3608 ieee->open_wep = 1;
3609 ieee->auth_mode = 2;
3610 }
3611
3612
3613 if (ieee->set_security)
3614 ieee->set_security(ieee->dev, &sec);
3615
3616 return ret;
3617}
3618
3619static int rtllib_wpa_set_param(struct rtllib_device *ieee, u8 name, u32 value)
3620{
3621 int ret=0;
3622 unsigned long flags;
3623
3624 switch (name) {
3625 case IEEE_PARAM_WPA_ENABLED:
3626 ret = rtllib_wpa_enable(ieee, value);
3627 break;
3628
3629 case IEEE_PARAM_TKIP_COUNTERMEASURES:
3630 ieee->tkip_countermeasures=value;
3631 break;
3632
3633 case IEEE_PARAM_DROP_UNENCRYPTED:
3634 {
3635 /* HACK:
3636 *
3637 * wpa_supplicant calls set_wpa_enabled when the driver
3638 * is loaded and unloaded, regardless of if WPA is being
3639 * used. No other calls are made which can be used to
3640 * determine if encryption will be used or not prior to
3641 * association being expected. If encryption is not being
3642 * used, drop_unencrypted is set to false, else true -- we
3643 * can use this to determine if the CAP_PRIVACY_ON bit should
3644 * be set.
3645 */
3646 struct rtllib_security sec = {
3647 .flags = SEC_ENABLED,
3648 .enabled = value,
3649 };
3650 ieee->drop_unencrypted = value;
3651 /* We only change SEC_LEVEL for open mode. Others
3652 * are set by ipw_wpa_set_encryption.
3653 */
3654 if (!value) {
3655 sec.flags |= SEC_LEVEL;
3656 sec.level = SEC_LEVEL_0;
3657 }
3658 else {
3659 sec.flags |= SEC_LEVEL;
3660 sec.level = SEC_LEVEL_1;
3661 }
3662 if (ieee->set_security)
3663 ieee->set_security(ieee->dev, &sec);
3664 break;
3665 }
3666
3667 case IEEE_PARAM_PRIVACY_INVOKED:
3668 ieee->privacy_invoked=value;
3669 break;
3670
3671 case IEEE_PARAM_AUTH_ALGS:
3672 ret = rtllib_wpa_set_auth_algs(ieee, value);
3673 break;
3674
3675 case IEEE_PARAM_IEEE_802_1X:
3676 ieee->ieee802_1x=value;
3677 break;
3678 case IEEE_PARAM_WPAX_SELECT:
3679 spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
3680 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
3681 break;
3682
3683 default:
3684 printk("Unknown WPA param: %d\n",name);
3685 ret = -EOPNOTSUPP;
3686 }
3687
3688 return ret;
3689}
3690
3691/* implementation borrowed from hostap driver */
3692static int rtllib_wpa_set_encryption(struct rtllib_device *ieee,
3693 struct ieee_param *param, int param_len, u8 is_mesh)
3694{
3695 int ret = 0;
3696 struct rtllib_crypto_ops *ops;
3697 struct rtllib_crypt_data **crypt;
3698
3699 struct rtllib_security sec = {
3700 .flags = 0,
3701 };
3702
3703 param->u.crypt.err = 0;
3704 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
3705
3706 if (param_len !=
3707 (int) ((char *) param->u.crypt.key - (char *) param) +
3708 param->u.crypt.key_len) {
3709 printk("Len mismatch %d, %d\n", param_len,
3710 param->u.crypt.key_len);
3711 return -EINVAL;
3712 }
3713 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3714 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3715 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3716 if (param->u.crypt.idx >= WEP_KEYS)
3717 return -EINVAL;
3718 crypt = &ieee->crypt[param->u.crypt.idx];
3719 } else {
3720 return -EINVAL;
3721 }
3722
3723 if (strcmp(param->u.crypt.alg, "none") == 0) {
3724 if (crypt) {
3725 sec.enabled = 0;
3726 sec.level = SEC_LEVEL_0;
3727 sec.flags |= SEC_ENABLED | SEC_LEVEL;
3728 rtllib_crypt_delayed_deinit(ieee, crypt);
3729 }
3730 goto done;
3731 }
3732 sec.enabled = 1;
3733 sec.flags |= SEC_ENABLED;
3734
3735 /* IPW HW cannot build TKIP MIC, host decryption still needed. */
3736 if (!(ieee->host_encrypt || ieee->host_decrypt) &&
3737 strcmp(param->u.crypt.alg, "TKIP"))
3738 goto skip_host_crypt;
3739
3740 ops = rtllib_get_crypto_ops(param->u.crypt.alg);
3741 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
3742 request_module("rtllib_crypt_wep");
3743 ops = rtllib_get_crypto_ops(param->u.crypt.alg);
3744 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
3745 request_module("rtllib_crypt_tkip");
3746 ops = rtllib_get_crypto_ops(param->u.crypt.alg);
3747 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
3748 request_module("rtllib_crypt_ccmp");
3749 ops = rtllib_get_crypto_ops(param->u.crypt.alg);
3750 }
3751 if (ops == NULL) {
3752 printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
3753 param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
3754 ret = -EINVAL;
3755 goto done;
3756 }
3757 if (*crypt == NULL || (*crypt)->ops != ops) {
3758 struct rtllib_crypt_data *new_crypt;
3759
3760 rtllib_crypt_delayed_deinit(ieee, crypt);
3761
3762 new_crypt = (struct rtllib_crypt_data *)
3763 kmalloc(sizeof(*new_crypt), GFP_KERNEL);
3764 if (new_crypt == NULL) {
3765 ret = -ENOMEM;
3766 goto done;
3767 }
3768 memset(new_crypt, 0, sizeof(struct rtllib_crypt_data));
3769 new_crypt->ops = ops;
3770 if (new_crypt->ops)
3771 new_crypt->priv =
3772 new_crypt->ops->init(param->u.crypt.idx);
3773
3774 if (new_crypt->priv == NULL) {
3775 kfree(new_crypt);
3776 param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
3777 ret = -EINVAL;
3778 goto done;
3779 }
3780
3781 *crypt = new_crypt;
3782 }
3783
3784 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
3785 (*crypt)->ops->set_key(param->u.crypt.key,
3786 param->u.crypt.key_len, param->u.crypt.seq,
3787 (*crypt)->priv) < 0) {
3788 printk("key setting failed\n");
3789 param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
3790 ret = -EINVAL;
3791 goto done;
3792 }
3793
3794 skip_host_crypt:
3795 if (param->u.crypt.set_tx) {
3796 ieee->tx_keyidx = param->u.crypt.idx;
3797 sec.active_key = param->u.crypt.idx;
3798 sec.flags |= SEC_ACTIVE_KEY;
3799 } else
3800 sec.flags &= ~SEC_ACTIVE_KEY;
3801
3802 if (param->u.crypt.alg != NULL) {
3803 memcpy(sec.keys[param->u.crypt.idx],
3804 param->u.crypt.key,
3805 param->u.crypt.key_len);
3806 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
3807 sec.flags |= (1 << param->u.crypt.idx);
3808
3809 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3810 sec.flags |= SEC_LEVEL;
3811 sec.level = SEC_LEVEL_1;
3812 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3813 sec.flags |= SEC_LEVEL;
3814 sec.level = SEC_LEVEL_2;
3815 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3816 sec.flags |= SEC_LEVEL;
3817 sec.level = SEC_LEVEL_3;
3818 }
3819 }
3820 done:
3821 if (ieee->set_security)
3822 ieee->set_security(ieee->dev, &sec);
3823
3824 /* Do not reset port if card is in Managed mode since resetting will
3825 * generate new IEEE 802.11 authentication which may end up in looping
3826 * with IEEE 802.1X. If your hardware requires a reset after WEP
3827 * configuration (for example... Prism2), implement the reset_port in
3828 * the callbacks structures used to initialize the 802.11 stack. */
3829 if (ieee->reset_on_keychange &&
3830 ieee->iw_mode != IW_MODE_INFRA &&
3831 ieee->reset_port &&
3832 ieee->reset_port(ieee->dev)) {
3833 printk("reset_port failed\n");
3834 param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
3835 return -EINVAL;
3836 }
3837
3838 return ret;
3839}
3840
3841inline struct sk_buff *rtllib_disauth_skb( struct rtllib_network *beacon,
3842 struct rtllib_device *ieee, u16 asRsn)
3843{
3844 struct sk_buff *skb;
3845 struct rtllib_disauth *disauth;
3846#ifdef USB_USE_ALIGNMENT
3847 u32 Tmpaddr=0;
3848 int alignment=0;
3849 int len = sizeof(struct rtllib_disauth) + ieee->tx_headroom + USB_512B_ALIGNMENT_SIZE;
3850#else
3851 int len = sizeof(struct rtllib_disauth) + ieee->tx_headroom;
3852
3853#endif
3854 skb = dev_alloc_skb(len);
3855 if (!skb) {
3856 return NULL;
3857 }
3858
3859#ifdef USB_USE_ALIGNMENT
3860 Tmpaddr = (u32)skb->data;
3861 alignment = Tmpaddr & 0x1ff;
3862 skb_reserve(skb,(USB_512B_ALIGNMENT_SIZE - alignment));
3863#endif
3864 skb_reserve(skb, ieee->tx_headroom);
3865
3866 disauth = (struct rtllib_disauth *) skb_put(skb,sizeof(struct rtllib_disauth));
3867 disauth->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_DEAUTH);
3868 disauth->header.duration_id = 0;
3869
3870 memcpy(disauth->header.addr1, beacon->bssid, ETH_ALEN);
3871 memcpy(disauth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
3872 memcpy(disauth->header.addr3, beacon->bssid, ETH_ALEN);
3873
3874 disauth->reason = cpu_to_le16(asRsn);
3875 return skb;
3876}
3877
3878inline struct sk_buff *rtllib_disassociate_skb( struct rtllib_network *beacon,
3879 struct rtllib_device *ieee, u16 asRsn)
3880{
3881 struct sk_buff *skb;
3882 struct rtllib_disassoc *disass;
3883#ifdef USB_USE_ALIGNMENT
3884 u32 Tmpaddr=0;
3885 int alignment=0;
3886 int len = sizeof(struct rtllib_disassoc) + ieee->tx_headroom + USB_512B_ALIGNMENT_SIZE;
3887#else
3888 int len = sizeof(struct rtllib_disassoc) + ieee->tx_headroom;
3889#endif
3890 skb = dev_alloc_skb(len);
3891
3892 if (!skb) {
3893 return NULL;
3894 }
3895
3896#ifdef USB_USE_ALIGNMENT
3897 Tmpaddr = (u32)skb->data;
3898 alignment = Tmpaddr & 0x1ff;
3899 skb_reserve(skb,(USB_512B_ALIGNMENT_SIZE - alignment));
3900#endif
3901 skb_reserve(skb, ieee->tx_headroom);
3902
3903 disass = (struct rtllib_disassoc *) skb_put(skb,sizeof(struct rtllib_disassoc));
3904 disass->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_DISASSOC);
3905 disass->header.duration_id = 0;
3906
3907 memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
3908 memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
3909 memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
3910
3911 disass->reason = cpu_to_le16(asRsn);
3912 return skb;
3913}
3914
3915void SendDisassociation(struct rtllib_device *ieee, bool deauth, u16 asRsn)
3916{
3917 struct rtllib_network *beacon = &ieee->current_network;
3918 struct sk_buff *skb;
3919
3920 if (deauth) {
3921 skb = rtllib_disauth_skb(beacon,ieee,asRsn);
3922 } else {
3923 skb = rtllib_disassociate_skb(beacon,ieee,asRsn);
3924 }
3925
3926 if (skb){
3927 softmac_mgmt_xmit(skb, ieee);
3928 }
3929}
3930
3931u8 rtllib_ap_sec_type(struct rtllib_device *ieee)
3932{
3933 static u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04};
3934 static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
3935 int wpa_ie_len= ieee->wpa_ie_len;
3936 struct rtllib_crypt_data* crypt;
3937 int encrypt;
3938
3939 crypt = ieee->crypt[ieee->tx_keyidx];
3940 encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) ||\
3941 (ieee->host_encrypt && crypt && crypt->ops && \
3942 (0 == strcmp(crypt->ops->name,"WEP")));
3943
3944 /* simply judge */
3945 if (encrypt && (wpa_ie_len == 0)) {
3946 return SEC_ALG_WEP;
3947 } else if ((wpa_ie_len != 0)) {
3948 if (((ieee->wpa_ie[0] == 0xdd) && (!memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) ||
3949 ((ieee->wpa_ie[0] == 0x30) && (!memcmp(&ieee->wpa_ie[10],ccmp_rsn_ie, 4))))
3950 return SEC_ALG_CCMP;
3951 else
3952 return SEC_ALG_TKIP;
3953 } else {
3954 return SEC_ALG_NONE;
3955 }
3956}
3957
3958int rtllib_wpa_supplicant_ioctl(struct rtllib_device *ieee, struct iw_point *p, u8 is_mesh)
3959{
3960 struct ieee_param *param;
3961 int ret=0;
3962
3963 down(&ieee->wx_sem);
3964
3965 if (p->length < sizeof(struct ieee_param) || !p->pointer){
3966 ret = -EINVAL;
3967 goto out;
3968 }
3969
3970 param = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
3971 if (param == NULL){
3972 ret = -ENOMEM;
3973 goto out;
3974 }
3975 if (copy_from_user(param, p->pointer, p->length)) {
3976 kfree(param);
3977 ret = -EFAULT;
3978 goto out;
3979 }
3980
3981 switch (param->cmd) {
3982
3983 case IEEE_CMD_SET_WPA_PARAM:
3984 ret = rtllib_wpa_set_param(ieee, param->u.wpa_param.name,
3985 param->u.wpa_param.value);
3986 break;
3987
3988 case IEEE_CMD_SET_WPA_IE:
3989 ret = rtllib_wpa_set_wpa_ie(ieee, param, p->length);
3990 break;
3991
3992 case IEEE_CMD_SET_ENCRYPTION:
3993 ret = rtllib_wpa_set_encryption(ieee, param, p->length, 0);
3994 break;
3995
3996 case IEEE_CMD_MLME:
3997 ret = rtllib_wpa_mlme(ieee, param->u.mlme.command,
3998 param->u.mlme.reason_code);
3999 break;
4000
4001 default:
4002 printk("Unknown WPA supplicant request: %d\n",param->cmd);
4003 ret = -EOPNOTSUPP;
4004 break;
4005 }
4006
4007 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
4008 ret = -EFAULT;
4009
4010 kfree(param);
4011out:
4012 up(&ieee->wx_sem);
4013
4014 return ret;
4015}
4016
4017void
4018rtllib_MgntDisconnectIBSS(struct rtllib_device* rtllib)
4019{
4020 u8 OpMode;
4021 u8 i;
4022 bool bFilterOutNonAssociatedBSSID = false;
4023
4024 rtllib->state = RTLLIB_NOLINK;
4025
4026 for (i=0;i<6;i++) rtllib->current_network.bssid[i]= 0x55;
4027
4028 rtllib->OpMode = RT_OP_MODE_NO_LINK;
4029 rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_BSSID, rtllib->current_network.bssid);
4030 OpMode = RT_OP_MODE_NO_LINK;
4031 rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_MEDIA_STATUS, &OpMode);
4032 rtllib_stop_send_beacons(rtllib);
4033
4034 bFilterOutNonAssociatedBSSID = false;
4035 rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_CECHK_BSSID, (u8*)(&bFilterOutNonAssociatedBSSID));
4036 notify_wx_assoc_event(rtllib);
4037
4038}
4039
4040void
4041rtllib_MlmeDisassociateRequest(
4042 struct rtllib_device* rtllib,
4043 u8* asSta,
4044 u8 asRsn
4045 )
4046{
4047 u8 i;
4048 u8 OpMode;
4049
4050 RemovePeerTS(rtllib, asSta);
4051
4052
4053 if (memcpy(rtllib->current_network.bssid,asSta,6) == 0)
4054 {
4055 rtllib->state = RTLLIB_NOLINK;
4056
4057 for (i=0;i<6;i++) rtllib->current_network.bssid[i] = 0x22;
4058 OpMode = RT_OP_MODE_NO_LINK;
4059 rtllib->OpMode = RT_OP_MODE_NO_LINK;
4060 rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_MEDIA_STATUS, (u8 *)(&OpMode) );
4061 rtllib_disassociate(rtllib);
4062
4063 rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_BSSID, rtllib->current_network.bssid);
4064
4065 }
4066
4067}
4068
4069void
4070rtllib_MgntDisconnectAP(
4071 struct rtllib_device* rtllib,
4072 u8 asRsn
4073)
4074{
4075 bool bFilterOutNonAssociatedBSSID = false;
4076
4077
4078#ifdef TO_DO
4079 if ( pMgntInfo->SecurityInfo.AuthMode > RT_802_11AuthModeAutoSwitch ||
4080 (pMgntInfo->bAPSuportCCKM && pMgntInfo->bCCX8021xenable) )
4081 {
4082 SecClearAllKeys(rtllib->dev);
4083 RT_TRACE(COMP_SEC, DBG_LOUD,("======>CCKM clear key..."))
4084 }
4085#endif
4086 bFilterOutNonAssociatedBSSID = false;
4087 rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_CECHK_BSSID, (u8*)(&bFilterOutNonAssociatedBSSID));
4088 rtllib_MlmeDisassociateRequest( rtllib, rtllib->current_network.bssid, asRsn );
4089
4090 rtllib->state = RTLLIB_NOLINK;
4091}
4092
4093bool
4094rtllib_MgntDisconnect(
4095 struct rtllib_device* rtllib,
4096 u8 asRsn
4097)
4098{
4099 if (rtllib->ps != RTLLIB_PS_DISABLED)
4100 {
4101#ifndef RTL8190P
4102 rtllib->sta_wake_up(rtllib->dev);
4103#endif
4104 }
4105
4106#ifdef TO_DO
4107 if (pMgntInfo->mActingAsAp)
4108 {
4109 RT_TRACE(COMP_MLME, DBG_LOUD, ("MgntDisconnect() ===> AP_DisassociateAllStation\n"));
4110 AP_DisassociateAllStation(rtllib->dev, unspec_reason);
4111 return true;
4112 }
4113#endif
4114
4115 if ( rtllib->state == RTLLIB_LINKED )
4116 {
4117 if ( rtllib->iw_mode == IW_MODE_ADHOC )
4118 {
4119 rtllib_MgntDisconnectIBSS(rtllib);
4120 }
4121 if ( rtllib->iw_mode == IW_MODE_INFRA )
4122 {
4123#ifdef TO_DO_LIST
4124 SecClearAllKeys(Adapter);
4125#endif
4126 rtllib_MgntDisconnectAP(rtllib, asRsn);
4127 }
4128
4129 }
4130
4131 return true;
4132}
4133
4134void notify_wx_assoc_event(struct rtllib_device *ieee)
4135{
4136 union iwreq_data wrqu;
4137
4138 if (ieee->cannot_notify)
4139 return;
4140
4141 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
4142 if (ieee->state == RTLLIB_LINKED)
4143 memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
4144 else{
4145
4146 printk("%s(): Tell user space disconnected\n",__func__);
4147 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
4148 }
4149 wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
4150}