1 /* IEEE 802.11 SoftMAC layer
2 * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
4 * Mostly extracted from the rtl8180-sa2400 driver for the
5 * in-kernel generic ieee802.11 stack.
7 * Few lines might be stolen from other part of the ieee80211
8 * stack. Copyright who own it's copyright
10 * WPA code stolen from the ipw2200 driver.
11 * Copyright who own it's copyright.
13 * released under the GPL
17 #include "ieee80211.h"
19 #include <linux/random.h>
20 #include <linux/delay.h>
21 #include <linux/version.h>
22 #include <asm/uaccess.h>
27 u8 rsn_authen_cipher_suite
[16][4] = {
28 {0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved
29 {0x00,0x0F,0xAC,0x01}, //WEP-40 //RSNA default
30 {0x00,0x0F,0xAC,0x02}, //TKIP //NONE //{used just as default}
31 {0x00,0x0F,0xAC,0x03}, //WRAP-historical
32 {0x00,0x0F,0xAC,0x04}, //CCMP
33 {0x00,0x0F,0xAC,0x05}, //WEP-104
36 short ieee80211_is_54g(struct ieee80211_network net
)
38 return ((net
.rates_ex_len
> 0) || (net
.rates_len
> 4));
41 short ieee80211_is_shortslot(struct ieee80211_network net
)
43 return (net
.capability
& WLAN_CAPABILITY_SHORT_SLOT
);
46 /* returns the total length needed for pleacing the RATE MFIE
47 * tag and the EXTENDED RATE MFIE tag if needed.
48 * It encludes two bytes per tag for the tag itself and its len
50 unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device
*ieee
)
52 unsigned int rate_len
= 0;
54 if (ieee
->modulation
& IEEE80211_CCK_MODULATION
)
55 rate_len
= IEEE80211_CCK_RATE_LEN
+ 2;
57 if (ieee
->modulation
& IEEE80211_OFDM_MODULATION
)
59 rate_len
+= IEEE80211_OFDM_RATE_LEN
+ 2;
64 /* pleace the MFIE rate, tag to the memory (double) poined.
65 * Then it updates the pointer so that
66 * it points after the new MFIE tag added.
68 void ieee80211_MFIE_Brate(struct ieee80211_device
*ieee
, u8
**tag_p
)
72 if (ieee
->modulation
& IEEE80211_CCK_MODULATION
){
73 *tag
++ = MFIE_TYPE_RATES
;
75 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_1MB
;
76 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_2MB
;
77 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_5MB
;
78 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_11MB
;
81 /* We may add an option for custom rates that specific HW might support */
85 void ieee80211_MFIE_Grate(struct ieee80211_device
*ieee
, u8
**tag_p
)
89 if (ieee
->modulation
& IEEE80211_OFDM_MODULATION
){
91 *tag
++ = MFIE_TYPE_RATES_EX
;
93 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_6MB
;
94 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_9MB
;
95 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_12MB
;
96 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_18MB
;
97 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_24MB
;
98 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_36MB
;
99 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_48MB
;
100 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_54MB
;
104 /* We may add an option for custom rates that specific HW might support */
109 void ieee80211_WMM_Info(struct ieee80211_device
*ieee
, u8
**tag_p
) {
112 *tag
++ = MFIE_TYPE_GENERIC
; //0
121 if(ieee
->current_network
.wmm_info
& 0x80) {
122 *tag
++ = 0x0f|MAX_SP_Len
;
133 void ieee80211_TURBO_Info(struct ieee80211_device
*ieee
, u8
**tag_p
) {
136 *tag
++ = MFIE_TYPE_GENERIC
; //0
147 printk(KERN_ALERT
"This is enable turbo mode IE process\n");
151 void enqueue_mgmt(struct ieee80211_device
*ieee
, struct sk_buff
*skb
)
154 nh
= (ieee
->mgmt_queue_head
+1) % MGMT_QUEUE_NUM
;
157 * if the queue is full but we have newer frames then
158 * just overwrites the oldest.
160 * if (nh == ieee->mgmt_queue_tail)
163 ieee
->mgmt_queue_head
= nh
;
164 ieee
->mgmt_queue_ring
[nh
] = skb
;
169 struct sk_buff
*dequeue_mgmt(struct ieee80211_device
*ieee
)
173 if(ieee
->mgmt_queue_tail
== ieee
->mgmt_queue_head
)
176 ret
= ieee
->mgmt_queue_ring
[ieee
->mgmt_queue_tail
];
178 ieee
->mgmt_queue_tail
=
179 (ieee
->mgmt_queue_tail
+1) % MGMT_QUEUE_NUM
;
184 void init_mgmt_queue(struct ieee80211_device
*ieee
)
186 ieee
->mgmt_queue_tail
= ieee
->mgmt_queue_head
= 0;
190 void ieee80211_sta_wakeup(struct ieee80211_device
*ieee
, short nl
);
192 inline void softmac_mgmt_xmit(struct sk_buff
*skb
, struct ieee80211_device
*ieee
)
195 short single
= ieee
->softmac_features
& IEEE_SOFTMAC_SINGLE_QUEUE
;
196 struct ieee80211_hdr_3addr
*header
=
197 (struct ieee80211_hdr_3addr
*) skb
->data
;
200 spin_lock_irqsave(&ieee
->lock
, flags
);
202 /* called with 2nd param 0, no mgmt lock required */
203 ieee80211_sta_wakeup(ieee
,0);
206 if(ieee
->queue_stop
){
208 enqueue_mgmt(ieee
,skb
);
210 header
->seq_ctl
= cpu_to_le16(ieee
->seq_ctrl
[0]<<4);
212 if (ieee
->seq_ctrl
[0] == 0xFFF)
213 ieee
->seq_ctrl
[0] = 0;
217 /* avoid watchdog triggers */
218 ieee
->dev
->trans_start
= jiffies
;
219 ieee
->softmac_data_hard_start_xmit(skb
,ieee
->dev
,ieee
->basic_rate
);
222 spin_unlock_irqrestore(&ieee
->lock
, flags
);
224 spin_unlock_irqrestore(&ieee
->lock
, flags
);
225 spin_lock_irqsave(&ieee
->mgmt_tx_lock
, flags
);
227 header
->seq_ctl
= cpu_to_le16(ieee
->seq_ctrl
[0] << 4);
229 if (ieee
->seq_ctrl
[0] == 0xFFF)
230 ieee
->seq_ctrl
[0] = 0;
234 /* avoid watchdog triggers */
235 ieee
->dev
->trans_start
= jiffies
;
236 ieee
->softmac_hard_start_xmit(skb
,ieee
->dev
);
238 spin_unlock_irqrestore(&ieee
->mgmt_tx_lock
, flags
);
243 inline void softmac_ps_mgmt_xmit(struct sk_buff
*skb
, struct ieee80211_device
*ieee
)
246 short single
= ieee
->softmac_features
& IEEE_SOFTMAC_SINGLE_QUEUE
;
247 struct ieee80211_hdr_3addr
*header
=
248 (struct ieee80211_hdr_3addr
*) skb
->data
;
253 header
->seq_ctl
= cpu_to_le16(ieee
->seq_ctrl
[0] << 4);
255 if (ieee
->seq_ctrl
[0] == 0xFFF)
256 ieee
->seq_ctrl
[0] = 0;
260 /* avoid watchdog triggers */
261 ieee
->dev
->trans_start
= jiffies
;
262 ieee
->softmac_data_hard_start_xmit(skb
,ieee
->dev
,ieee
->basic_rate
);
266 header
->seq_ctl
= cpu_to_le16(ieee
->seq_ctrl
[0] << 4);
268 if (ieee
->seq_ctrl
[0] == 0xFFF)
269 ieee
->seq_ctrl
[0] = 0;
273 /* avoid watchdog triggers */
274 ieee
->dev
->trans_start
= jiffies
;
275 ieee
->softmac_hard_start_xmit(skb
,ieee
->dev
);
278 // dev_kfree_skb_any(skb);//edit by thomas
280 //by amy for power save
281 inline struct sk_buff
*ieee80211_disassociate_skb(
282 struct ieee80211_network
*beacon
,
283 struct ieee80211_device
*ieee
,
287 struct ieee80211_disassoc_frame
*disass
;
289 skb
= dev_alloc_skb(sizeof(struct ieee80211_disassoc_frame
));
293 disass
= (struct ieee80211_disassoc_frame
*) skb_put(skb
,sizeof(struct ieee80211_disassoc_frame
));
294 disass
->header
.frame_ctl
= cpu_to_le16(IEEE80211_STYPE_DISASSOC
);
295 disass
->header
.duration_id
= 0;
297 memcpy(disass
->header
.addr1
, beacon
->bssid
, ETH_ALEN
);
298 memcpy(disass
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
299 memcpy(disass
->header
.addr3
, beacon
->bssid
, ETH_ALEN
);
301 disass
->reasoncode
= asRsn
;
306 struct ieee80211_device
*ieee
,
311 struct ieee80211_network
*beacon
= &ieee
->current_network
;
313 skb
= ieee80211_disassociate_skb(beacon
,ieee
,asRsn
);
315 softmac_mgmt_xmit(skb
, ieee
);
316 //dev_kfree_skb_any(skb);//edit by thomas
320 //by amy for power save
321 inline struct sk_buff
*ieee80211_probe_req(struct ieee80211_device
*ieee
)
323 unsigned int len
,rate_len
;
326 struct ieee80211_probe_request
*req
;
328 #ifdef _RTL8187_EXT_PATCH_
330 if(ieee
->ext_patch_ieee80211_probe_req_1
)
331 extMore
= ieee
->ext_patch_ieee80211_probe_req_1(ieee
);
334 len
= ieee
->current_network
.ssid_len
;
336 rate_len
= ieee80211_MFIE_rate_len(ieee
);
338 #ifdef _RTL8187_EXT_PATCH_
341 skb
= dev_alloc_skb(sizeof(struct ieee80211_probe_request
) +
343 #ifdef _RTL8187_EXT_PATCH_
345 skb
= dev_alloc_skb(sizeof(struct ieee80211_probe_request
) +
346 2 + len
+ rate_len
+128); // MESHID + CAP
352 req
= (struct ieee80211_probe_request
*) skb_put(skb
,sizeof(struct ieee80211_probe_request
));
353 req
->header
.frame_ctl
= cpu_to_le16(IEEE80211_STYPE_PROBE_REQ
);
354 req
->header
.duration_id
= 0; //FIXME: is this OK ?
356 memset(req
->header
.addr1
, 0xff, ETH_ALEN
);
357 memcpy(req
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
358 memset(req
->header
.addr3
, 0xff, ETH_ALEN
);
360 tag
= (u8
*) skb_put(skb
,len
+2+rate_len
);
362 *tag
++ = MFIE_TYPE_SSID
;
364 memcpy(tag
, ieee
->current_network
.ssid
, len
);
366 ieee80211_MFIE_Brate(ieee
,&tag
);
367 ieee80211_MFIE_Grate(ieee
,&tag
);
369 #ifdef _RTL8187_EXT_PATCH_
371 ieee
->ext_patch_ieee80211_probe_req_2(ieee
, skb
, tag
);
376 struct sk_buff
*ieee80211_get_beacon_(struct ieee80211_device
*ieee
);
378 //#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
379 //void ext_ieee80211_send_beacon_wq(struct work_struct *work)
381 // struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ext_send_beacon_wq);
383 void ext_ieee80211_send_beacon_wq(struct ieee80211_device
*ieee
)
389 //unsigned long flags;
391 skb
= ieee80211_get_beacon_(ieee
);
394 softmac_mgmt_xmit(skb
, ieee
);
395 ieee
->softmac_stats
.tx_beacons
++;
396 dev_kfree_skb_any(skb
);//edit by thomas
400 //printk(KERN_WARNING "[1] beacon sending!\n");
401 ieee
->beacon_timer
.expires
= jiffies
+
402 (MSECS( ieee
->current_network
.beacon_interval
-5));
404 //spin_lock_irqsave(&ieee->beacon_lock,flags);
405 if(ieee
->beacon_txing
)
406 add_timer(&ieee
->beacon_timer
);
407 //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
410 void ieee80211_send_beacon(struct ieee80211_device
*ieee
)
414 //unsigned long flags;
416 skb
= ieee80211_get_beacon_(ieee
);
419 softmac_mgmt_xmit(skb
, ieee
);
420 ieee
->softmac_stats
.tx_beacons
++;
421 dev_kfree_skb_any(skb
);//edit by thomas
424 //printk(KERN_WARNING "[1] beacon sending!\n");
425 ieee
->beacon_timer
.expires
= jiffies
+
426 (MSECS( ieee
->current_network
.beacon_interval
-5));
428 //spin_lock_irqsave(&ieee->beacon_lock,flags);
429 if(ieee
->beacon_txing
)
430 add_timer(&ieee
->beacon_timer
);
431 //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
435 void ieee80211_send_beacon_cb(unsigned long _ieee
)
437 struct ieee80211_device
*ieee
=
438 (struct ieee80211_device
*) _ieee
;
441 spin_lock_irqsave(&ieee
->beacon_lock
, flags
);
442 ieee80211_send_beacon(ieee
);
443 spin_unlock_irqrestore(&ieee
->beacon_lock
, flags
);
446 #ifdef _RTL8187_EXT_PATCH_
448 inline struct sk_buff
*ieee80211_probe_req_with_SSID(struct ieee80211_device
*ieee
, char *ssid
, int len_ssid
)
450 unsigned int len
,rate_len
;
453 struct ieee80211_probe_request
*req
;
455 #ifdef _RTL8187_EXT_PATCH_
457 if(ieee
->ext_patch_ieee80211_probe_req_1
)
458 extMore
= ieee
->ext_patch_ieee80211_probe_req_1(ieee
);
463 rate_len
= ieee80211_MFIE_rate_len(ieee
);
465 #ifdef _RTL8187_EXT_PATCH_
468 skb
= dev_alloc_skb(sizeof(struct ieee80211_probe_request
) +
470 #ifdef _RTL8187_EXT_PATCH_
472 skb
= dev_alloc_skb(sizeof(struct ieee80211_probe_request
) +
473 2 + len
+ rate_len
+128); // MESHID + CAP
479 req
= (struct ieee80211_probe_request
*) skb_put(skb
,sizeof(struct ieee80211_probe_request
));
480 req
->header
.frame_ctl
= cpu_to_le16(IEEE80211_STYPE_PROBE_REQ
);
481 req
->header
.duration_id
= 0; //FIXME: is this OK ?
483 memset(req
->header
.addr1
, 0xff, ETH_ALEN
);
484 memcpy(req
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
485 memset(req
->header
.addr3
, 0xff, ETH_ALEN
);
487 tag
= (u8
*) skb_put(skb
,len
+2+rate_len
);
489 *tag
++ = MFIE_TYPE_SSID
;
493 memcpy(tag
, ssid
, len
);
497 ieee80211_MFIE_Brate(ieee
,&tag
);
498 ieee80211_MFIE_Grate(ieee
,&tag
);
500 #ifdef _RTL8187_EXT_PATCH_
502 ieee
->ext_patch_ieee80211_probe_req_2(ieee
, skb
, tag
);
507 #endif // _RTL8187_EXT_PATCH_
510 void ieee80211_send_probe(struct ieee80211_device
*ieee
)
514 #ifdef _RTL8187_EXT_PATCH_
515 if(ieee
->iw_mode
== ieee
->iw_ext_mode
)
516 skb
= ieee80211_probe_req_with_SSID(ieee
, NULL
, 0);
519 skb
= ieee80211_probe_req(ieee
);
521 softmac_mgmt_xmit(skb
, ieee
);
522 ieee
->softmac_stats
.tx_probe_rq
++;
523 //dev_kfree_skb_any(skb);//edit by thomas
527 void ieee80211_send_probe_requests(struct ieee80211_device
*ieee
)
529 if (ieee
->active_scan
&& (ieee
->softmac_features
& IEEE_SOFTMAC_PROBERQ
)){
530 ieee80211_send_probe(ieee
);
531 ieee80211_send_probe(ieee
);
535 /* this performs syncro scan blocking the caller until all channels
536 * in the allowed channel map has been checked.
538 void ieee80211_softmac_scan_syncro(struct ieee80211_device
*ieee
)
542 u8 channel_map
[MAX_CHANNEL_NUMBER
+1];
543 memcpy(channel_map
, GET_DOT11D_INFO(ieee
)->channel_map
, MAX_CHANNEL_NUMBER
+1);
545 down(&ieee
->scan_sem
);
546 // printk("==================> Sync scan\n");
547 // dump_chnl_map(channel_map);
554 if (ch
> MAX_CHANNEL_NUMBER
)
555 goto out
; /* scan completed */
558 }while(!channel_map
[ch
]);
560 }while(!ieee
->channel_map
[ch
]);
562 /* this fuction can be called in two situations
563 * 1- We have switched to ad-hoc mode and we are
564 * performing a complete syncro scan before conclude
565 * there are no interesting cell and to create a
566 * new one. In this case the link state is
567 * IEEE80211_NOLINK until we found an interesting cell.
568 * If so the ieee8021_new_net, called by the RX path
569 * will set the state to IEEE80211_LINKED, so we stop
571 * 2- We are linked and the root uses run iwlist scan.
572 * So we switch to IEEE80211_LINKED_SCANNING to remember
573 * that we are still logically linked (not interested in
574 * new network events, despite for updating the net list,
575 * but we are temporarly 'unlinked' as the driver shall
576 * not filter RX frames and the channel is changing.
577 * So the only situation in witch are interested is to check
578 * if the state become LINKED because of the #1 situation
581 if (ieee
->state
== IEEE80211_LINKED
)
584 ieee
->set_chan(ieee
->dev
, ch
);
585 // printk("=====>channel=%d ",ch);
587 if(channel_map
[ch
] == 1)
590 // printk("====send probe request\n");
591 ieee80211_send_probe_requests(ieee
);
593 /* this prevent excessive time wait when we
594 * need to wait for a syncro scan to end..
596 if (ieee
->sync_scan_hurryup
)
600 msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME
);
604 ieee
->sync_scan_hurryup
= 0;
607 if(IS_DOT11D_ENABLE(ieee
))
608 DOT11D_ScanComplete(ieee
);
612 void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device
*ieee
)
615 unsigned int watch_dog
= 0;
617 u8 channel_map
[MAX_CHANNEL_NUMBER
+1];
618 memcpy(channel_map
, GET_DOT11D_INFO(ieee
)->channel_map
, MAX_CHANNEL_NUMBER
+1);
620 down(&ieee
->scan_sem
);
621 ch
= ieee
->current_network
.channel
;
622 // if(ieee->sync_scan_hurryup)
625 // printk("stop scan sync\n");
628 // printk("=======hh===============>ips scan\n");
631 /* this fuction can be called in two situations
632 * 1- We have switched to ad-hoc mode and we are
633 * performing a complete syncro scan before conclude
634 * there are no interesting cell and to create a
635 * new one. In this case the link state is
636 * IEEE80211_NOLINK until we found an interesting cell.
637 * If so the ieee8021_new_net, called by the RX path
638 * will set the state to IEEE80211_LINKED, so we stop
640 * 2- We are linked and the root uses run iwlist scan.
641 * So we switch to IEEE80211_LINKED_SCANNING to remember
642 * that we are still logically linked (not interested in
643 * new network events, despite for updating the net list,
644 * but we are temporarly 'unlinked' as the driver shall
645 * not filter RX frames and the channel is changing.
646 * So the only situation in witch are interested is to check
647 * if the state become LINKED because of the #1 situation
649 if (ieee
->state
== IEEE80211_LINKED
)
654 if(channel_map
[ieee
->current_network
.channel
] > 0)
657 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
658 // printk("======>channel=%d ",ieee->current_network.channel);
661 if(channel_map
[ieee
->current_network
.channel
] == 1)
664 // printk("====send probe request\n");
665 ieee80211_send_probe_requests(ieee
);
667 /* this prevent excessive time wait when we
668 * need to wait for a syncro scan to end..
670 // if (ieee->sync_scan_hurryup)
673 msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME
);
676 if (watch_dog
++ >= MAX_CHANNEL_NUMBER
)
677 // if (++watch_dog >= 15);//MAX_CHANNEL_NUMBER) //YJ,modified,080630
678 goto out
; /* scan completed */
680 ieee
->current_network
.channel
= (ieee
->current_network
.channel
+ 1)%MAX_CHANNEL_NUMBER
;
682 }while(!channel_map
[ieee
->current_network
.channel
]);
684 }while(!ieee
->channel_map
[ieee
->current_network
.channel
]);
688 //ieee->sync_scan_hurryup = 0;
689 //ieee->set_chan(ieee->dev, ch);
690 //ieee->current_network.channel = ch;
691 ieee
->actscanning
= false;
694 if(IS_DOT11D_ENABLE(ieee
))
695 DOT11D_ScanComplete(ieee
);
701 /* called both by wq with ieee->lock held */
702 void ieee80211_softmac_scan(struct ieee80211_device
*ieee
)
707 ieee
->current_network
.channel
=
708 (ieee
->current_network
.channel
+ 1) % MAX_CHANNEL_NUMBER
;
709 if (watchdog
++ > MAX_CHANNEL_NUMBER
)
710 return; /* no good chans */
712 }while(!ieee
->channel_map
[ieee
->current_network
.channel
]);
715 schedule_work(&ieee
->softmac_scan_wq
);
719 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
720 void ieee80211_softmac_scan_wq(struct work_struct
*work
)
722 struct delayed_work
*dwork
= container_of(work
, struct delayed_work
, work
);
723 struct ieee80211_device
*ieee
= container_of(dwork
, struct ieee80211_device
, softmac_scan_wq
);
725 void ieee80211_softmac_scan_wq(struct ieee80211_device
*ieee
)
728 static short watchdog
= 0;
730 u8 channel_map
[MAX_CHANNEL_NUMBER
+1];
731 memcpy(channel_map
, GET_DOT11D_INFO(ieee
)->channel_map
, MAX_CHANNEL_NUMBER
+1);
733 // printk("ieee80211_softmac_scan_wq ENABLE_IPS\n");
734 // printk("in %s\n",__func__);
735 down(&ieee
->scan_sem
);
738 ieee
->current_network
.channel
=
739 (ieee
->current_network
.channel
+ 1) % MAX_CHANNEL_NUMBER
;
740 if (watchdog
++ > MAX_CHANNEL_NUMBER
)
741 goto out
; /* no good chans */
744 }while(!channel_map
[ieee
->current_network
.channel
]);
746 }while(!ieee
->channel_map
[ieee
->current_network
.channel
]);
749 //printk("current_network.channel:%d\n", ieee->current_network.channel);
750 if (ieee
->scanning
== 0 )
752 printk("error out, scanning = 0\n");
755 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
757 if(channel_map
[ieee
->current_network
.channel
] == 1)
759 ieee80211_send_probe_requests(ieee
);
761 queue_delayed_work(ieee
->wq
, &ieee
->softmac_scan_wq
, IEEE80211_SOFTMAC_SCAN_TIME
);
765 ieee
->actscanning
= false;
771 if(IS_DOT11D_ENABLE(ieee
))
772 DOT11D_ScanComplete(ieee
);
777 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
778 void ieee80211_softmac_scan_wq(struct work_struct
*work
)
780 struct delayed_work
*dwork
= container_of(work
, struct delayed_work
, work
);
781 struct ieee80211_device
*ieee
= container_of(work
, struct ieee80211_device
, softmac_scan_wq
);
783 void ieee80211_softmac_scan_wq(struct ieee80211_device
*ieee
)
789 u8 channel_map
[MAX_CHANNEL_NUMBER
+1];
790 memcpy(channel_map
, GET_DOT11D_INFO(ieee
)->channel_map
, MAX_CHANNEL_NUMBER
+1);
792 // printk("enter scan wq,watchdog is %d\n",watchdog);
793 down(&ieee
->scan_sem
);
796 ieee
->current_network
.channel
=
797 (ieee
->current_network
.channel
+ 1) % MAX_CHANNEL_NUMBER
;
798 if (watchdog
++ > MAX_CHANNEL_NUMBER
)
799 goto out
; /* no good chans */
802 }while(!channel_map
[ieee
->current_network
.channel
]);
804 }while(!ieee
->channel_map
[ieee
->current_network
.channel
]);
807 // printk("current_network.channel:%d\n", ieee->current_network.channel);
808 if (ieee
->scanning
== 0 )
810 printk("error out, scanning = 0\n");
813 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
815 if(channel_map
[ieee
->current_network
.channel
] == 1)
817 ieee80211_send_probe_requests(ieee
);
819 queue_delayed_work(ieee
->wq
, &ieee
->softmac_scan_wq
, IEEE80211_SOFTMAC_SCAN_TIME
);
823 if(IS_DOT11D_ENABLE(ieee
))
824 DOT11D_ScanComplete(ieee
);
829 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
830 void ieee80211_softmac_scan_cb(unsigned long _dev
)
833 struct ieee80211_device
*ieee
= (struct ieee80211_device
*)_dev
;
835 spin_lock_irqsave(&ieee
->lock
, flags
);
836 ieee80211_softmac_scan(ieee
);
837 spin_unlock_irqrestore(&ieee
->lock
, flags
);
842 void ieee80211_beacons_start(struct ieee80211_device
*ieee
)
846 spin_lock_irqsave(&ieee
->beacon_lock
,flags
);
848 ieee
->beacon_txing
= 1;
849 ieee80211_send_beacon(ieee
);
851 spin_unlock_irqrestore(&ieee
->beacon_lock
,flags
);
854 void ieee80211_beacons_stop(struct ieee80211_device
*ieee
)
858 spin_lock_irqsave(&ieee
->beacon_lock
,flags
);
860 ieee
->beacon_txing
= 0;
861 del_timer_sync(&ieee
->beacon_timer
);
863 spin_unlock_irqrestore(&ieee
->beacon_lock
,flags
);
868 void ieee80211_stop_send_beacons(struct ieee80211_device
*ieee
)
870 if(ieee
->stop_send_beacons
)
871 ieee
->stop_send_beacons(ieee
->dev
);
872 if (ieee
->softmac_features
& IEEE_SOFTMAC_BEACONS
)
873 ieee80211_beacons_stop(ieee
);
877 void ieee80211_start_send_beacons(struct ieee80211_device
*ieee
)
879 if(ieee
->start_send_beacons
)
880 ieee
->start_send_beacons(ieee
->dev
);
881 if(ieee
->softmac_features
& IEEE_SOFTMAC_BEACONS
)
882 ieee80211_beacons_start(ieee
);
886 void ieee80211_softmac_stop_scan(struct ieee80211_device
*ieee
)
888 // unsigned long flags;
890 //ieee->sync_scan_hurryup = 1;
892 down(&ieee
->scan_sem
);
893 // spin_lock_irqsave(&ieee->lock, flags);
895 if (ieee
->scanning
== 1){
897 //del_timer_sync(&ieee->scan_timer);
898 cancel_delayed_work(&ieee
->softmac_scan_wq
);
901 // spin_unlock_irqrestore(&ieee->lock, flags);
905 void ieee80211_stop_scan(struct ieee80211_device
*ieee
)
907 if (ieee
->softmac_features
& IEEE_SOFTMAC_SCAN
)
908 ieee80211_softmac_stop_scan(ieee
);
910 ieee
->stop_scan(ieee
->dev
);
913 /* called with ieee->lock held */
914 void ieee80211_start_scan(struct ieee80211_device
*ieee
)
917 if(IS_DOT11D_ENABLE(ieee
) )
919 if(IS_COUNTRY_IE_VALID(ieee
))
921 RESET_CIE_WATCHDOG(ieee
);
925 if (ieee
->softmac_features
& IEEE_SOFTMAC_SCAN
){
926 if (ieee
->scanning
== 0)
929 //ieee80211_softmac_scan(ieee);
930 // queue_work(ieee->wq, &ieee->softmac_scan_wq);
931 //care this,1203,2007,by lawrence
933 queue_delayed_work(ieee
->wq
, &ieee
->softmac_scan_wq
,0);
937 ieee
->start_scan(ieee
->dev
);
941 /* called with wx_sem held */
942 void ieee80211_start_scan_syncro(struct ieee80211_device
*ieee
)
945 if(IS_DOT11D_ENABLE(ieee
) )
947 if(IS_COUNTRY_IE_VALID(ieee
))
949 RESET_CIE_WATCHDOG(ieee
);
953 ieee
->sync_scan_hurryup
= 0;
955 if (ieee
->softmac_features
& IEEE_SOFTMAC_SCAN
)
956 ieee80211_softmac_scan_syncro(ieee
);
958 ieee
->scan_syncro(ieee
->dev
);
962 inline struct sk_buff
*ieee80211_authentication_req(struct ieee80211_network
*beacon
,
963 struct ieee80211_device
*ieee
, int challengelen
)
966 struct ieee80211_authentication
*auth
;
968 skb
= dev_alloc_skb(sizeof(struct ieee80211_authentication
) + challengelen
);
970 if (!skb
) return NULL
;
972 auth
= (struct ieee80211_authentication
*)
973 skb_put(skb
, sizeof(struct ieee80211_authentication
));
975 auth
->header
.frame_ctl
= IEEE80211_STYPE_AUTH
;
976 if (challengelen
) auth
->header
.frame_ctl
|= IEEE80211_FCTL_WEP
;
978 auth
->header
.duration_id
= 0x013a; //FIXME
980 memcpy(auth
->header
.addr1
, beacon
->bssid
, ETH_ALEN
);
981 memcpy(auth
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
982 memcpy(auth
->header
.addr3
, beacon
->bssid
, ETH_ALEN
);
984 auth
->algorithm
= ieee
->open_wep
? WLAN_AUTH_OPEN
: WLAN_AUTH_SHARED_KEY
;
986 auth
->transaction
= cpu_to_le16(ieee
->associate_seq
);
987 ieee
->associate_seq
++;
989 auth
->status
= cpu_to_le16(WLAN_STATUS_SUCCESS
);
995 static struct sk_buff
* ieee80211_probe_resp(struct ieee80211_device
*ieee
, u8
*dest
)
999 struct ieee80211_probe_response
*beacon_buf
;
1000 struct sk_buff
*skb
;
1002 int atim_len
,erp_len
;
1003 struct ieee80211_crypt_data
* crypt
;
1005 char *ssid
= ieee
->current_network
.ssid
;
1006 int ssid_len
= ieee
->current_network
.ssid_len
;
1007 int rate_len
= ieee
->current_network
.rates_len
+2;
1008 int rate_ex_len
= ieee
->current_network
.rates_ex_len
;
1009 int wpa_ie_len
= ieee
->wpa_ie_len
;
1010 if(rate_ex_len
> 0) rate_ex_len
+=2;
1012 if(ieee
->current_network
.capability
& WLAN_CAPABILITY_IBSS
)
1017 if(ieee80211_is_54g(ieee
->current_network
))
1022 beacon_size
= sizeof(struct ieee80211_probe_response
)+
1031 skb
= dev_alloc_skb(beacon_size
);
1036 beacon_buf
= (struct ieee80211_probe_response
*) skb_put(skb
, beacon_size
);
1038 memcpy (beacon_buf
->header
.addr1
, dest
,ETH_ALEN
);
1039 memcpy (beacon_buf
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
1040 memcpy (beacon_buf
->header
.addr3
, ieee
->current_network
.bssid
, ETH_ALEN
);
1042 beacon_buf
->header
.duration_id
= 0; //FIXME
1043 beacon_buf
->beacon_interval
=
1044 cpu_to_le16(ieee
->current_network
.beacon_interval
);
1045 beacon_buf
->capability
=
1046 cpu_to_le16(ieee
->current_network
.capability
& WLAN_CAPABILITY_IBSS
);
1048 if(ieee
->short_slot
&& (ieee
->current_network
.capability
& WLAN_CAPABILITY_SHORT_SLOT
))
1049 cpu_to_le16((beacon_buf
->capability
|= WLAN_CAPABILITY_SHORT_SLOT
));
1051 crypt
= ieee
->crypt
[ieee
->tx_keyidx
];
1053 encrypt
= ieee
->host_encrypt
&& crypt
&& crypt
->ops
&&
1054 ((0 == strcmp(crypt
->ops
->name
, "WEP")) || wpa_ie_len
);
1057 beacon_buf
->capability
|= cpu_to_le16(WLAN_CAPABILITY_PRIVACY
);
1060 beacon_buf
->header
.frame_ctl
= cpu_to_le16(IEEE80211_STYPE_PROBE_RESP
);
1062 beacon_buf
->info_element
.id
= MFIE_TYPE_SSID
;
1063 beacon_buf
->info_element
.len
= ssid_len
;
1065 tag
= (u8
*) beacon_buf
->info_element
.data
;
1067 memcpy(tag
, ssid
, ssid_len
);
1071 *(tag
++) = MFIE_TYPE_RATES
;
1072 *(tag
++) = rate_len
-2;
1073 memcpy(tag
,ieee
->current_network
.rates
,rate_len
-2);
1076 *(tag
++) = MFIE_TYPE_DS_SET
;
1078 *(tag
++) = ieee
->current_network
.channel
;
1081 *(tag
++) = MFIE_TYPE_IBSS_SET
;
1083 *((u16
*)(tag
)) = cpu_to_le16(ieee
->current_network
.atim_window
);
1088 *(tag
++) = MFIE_TYPE_ERP
;
1094 *(tag
++) = MFIE_TYPE_RATES_EX
;
1095 *(tag
++) = rate_ex_len
-2;
1096 memcpy(tag
,ieee
->current_network
.rates_ex
,rate_ex_len
-2);
1102 if (ieee
->iw_mode
== IW_MODE_ADHOC
)
1103 {//as Windows will set pairwise key same as the group key which is not allowed in Linux, so set this for IOT issue. WB 2008.07.07
1104 memcpy(&ieee
->wpa_ie
[14], &ieee
->wpa_ie
[8], 4);
1107 memcpy(tag
, ieee
->wpa_ie
, ieee
->wpa_ie_len
);
1110 skb
->dev
= ieee
->dev
;
1113 #ifdef _RTL8187_EXT_PATCH_
1114 struct sk_buff
* ieee80211_ext_probe_resp_by_net(struct ieee80211_device
*ieee
, u8
*dest
, struct ieee80211_network
*net
)
1118 struct ieee80211_probe_response
*beacon_buf
;
1119 struct sk_buff
*skb
;
1121 int atim_len
,erp_len
;
1122 struct ieee80211_crypt_data
* crypt
;
1123 u8 broadcast_addr
[] = {0xff,0xff,0xff,0xff,0xff,0xff};
1124 int wpa_ie_len
= ieee
->wpa_ie_len
;
1125 char *ssid
= net
->ssid
;
1126 int ssid_len
= net
->ssid_len
;
1128 int rate_len
= ieee
->current_network
.rates_len
+2;
1129 int rate_ex_len
= ieee
->current_network
.rates_ex_len
;
1130 if(rate_ex_len
> 0) rate_ex_len
+=2;
1132 if( ieee
->meshScanMode
&4)
1133 ieee
->current_network
.channel
= ieee
->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee
);
1134 if( ieee
->meshScanMode
&6)
1137 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
1138 queue_work(ieee
->wq
, &ieee
->ext_stop_scan_wq
);
1140 schedule_task(&ieee
->ext_stop_scan_wq
);
1143 if(ieee
->current_network
.capability
& WLAN_CAPABILITY_IBSS
) // use current_network here
1148 if(ieee80211_is_54g(*net
))
1153 beacon_size
= sizeof(struct ieee80211_probe_response
)+
1161 skb
= dev_alloc_skb(beacon_size
+196);
1166 beacon_buf
= (struct ieee80211_probe_response
*) skb_put(skb
, beacon_size
);
1168 memcpy (beacon_buf
->header
.addr1
, dest
,ETH_ALEN
);
1169 memcpy (beacon_buf
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
1170 memcpy (beacon_buf
->header
.addr3
, ieee
->current_network
.bssid
, ETH_ALEN
);
1172 beacon_buf
->header
.duration_id
= 0; //FIXME
1174 beacon_buf
->beacon_interval
=
1175 cpu_to_le16(ieee
->current_network
.beacon_interval
); // use current_network here
1176 beacon_buf
->capability
=
1177 cpu_to_le16(ieee
->current_network
.capability
& WLAN_CAPABILITY_IBSS
);
1179 if(ieee
->short_slot
&& (ieee
->current_network
.capability
& WLAN_CAPABILITY_SHORT_SLOT
))
1180 cpu_to_le16((beacon_buf
->capability
|= WLAN_CAPABILITY_SHORT_SLOT
));
1182 crypt
= ieee
->crypt
[ieee
->tx_keyidx
];
1184 encrypt
= ieee
->host_encrypt
&& crypt
&& crypt
->ops
&&
1185 ((0 == strcmp(crypt
->ops
->name
, "WEP"))||wpa_ie_len
);
1188 beacon_buf
->capability
|= cpu_to_le16(WLAN_CAPABILITY_PRIVACY
);
1191 beacon_buf
->header
.frame_ctl
= cpu_to_le16(IEEE80211_STYPE_PROBE_RESP
);
1193 beacon_buf
->info_element
.id
= MFIE_TYPE_SSID
;
1194 beacon_buf
->info_element
.len
= ssid_len
;
1196 tag
= (u8
*) beacon_buf
->info_element
.data
;
1198 // brocad cast / probe rsp
1199 if(memcmp(dest
, broadcast_addr
, ETH_ALEN
))
1200 memcpy(tag
, ssid
, ssid_len
);
1206 //get_bssrate_set(priv, _SUPPORTEDRATES_IE_, &pbssrate, &bssrate_len);
1207 //pbuf = set_ie(pbuf, _SUPPORTEDRATES_IE_, bssrate_len, pbssrate, &frlen);
1209 *(tag
++) = MFIE_TYPE_RATES
;
1210 *(tag
++) = rate_len
-2;
1211 memcpy(tag
,ieee
->current_network
.rates
,rate_len
-2);
1214 *(tag
++) = MFIE_TYPE_DS_SET
;
1216 *(tag
++) = ieee
->current_network
.channel
; // use current_network here
1220 *(tag
++) = MFIE_TYPE_IBSS_SET
;
1222 *((u16
*)(tag
)) = cpu_to_le16(ieee
->current_network
.atim_window
); // use current_network here
1227 *(tag
++) = MFIE_TYPE_ERP
;
1233 *(tag
++) = MFIE_TYPE_RATES_EX
;
1234 *(tag
++) = rate_ex_len
-2;
1235 memcpy(tag
,ieee
->current_network
.rates_ex
,rate_ex_len
-2);
1239 memcpy(tag
, ieee
->wpa_ie
, ieee
->wpa_ie_len
);
1241 skb
->dev
= ieee
->dev
;
1244 #endif // _RTL8187_EXT_PATCH_
1246 struct sk_buff
* ieee80211_assoc_resp(struct ieee80211_device
*ieee
, u8
*dest
)
1248 struct sk_buff
*skb
;
1251 struct ieee80211_crypt_data
* crypt
;
1252 struct ieee80211_assoc_response_frame
*assoc
;
1255 unsigned int rate_len
= ieee80211_MFIE_rate_len(ieee
);
1256 int len
= sizeof(struct ieee80211_assoc_response_frame
) + rate_len
;
1258 skb
= dev_alloc_skb(len
);
1263 assoc
= (struct ieee80211_assoc_response_frame
*)
1264 skb_put(skb
,sizeof(struct ieee80211_assoc_response_frame
));
1266 assoc
->header
.frame_ctl
= cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP
);
1267 memcpy(assoc
->header
.addr1
, dest
,ETH_ALEN
);
1268 memcpy(assoc
->header
.addr3
, ieee
->dev
->dev_addr
, ETH_ALEN
);
1269 memcpy(assoc
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
1270 assoc
->capability
= cpu_to_le16(ieee
->iw_mode
== IW_MODE_MASTER
?
1271 WLAN_CAPABILITY_BSS
: WLAN_CAPABILITY_IBSS
);
1274 if(ieee
->short_slot
)
1275 assoc
->capability
|= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT
);
1277 if (ieee
->host_encrypt
)
1278 crypt
= ieee
->crypt
[ieee
->tx_keyidx
];
1281 encrypt
= ( crypt
&& crypt
->ops
);
1284 assoc
->capability
|= cpu_to_le16(WLAN_CAPABILITY_PRIVACY
);
1287 assoc
->aid
= cpu_to_le16(ieee
->assoc_id
);
1288 if (ieee
->assoc_id
== 0x2007) ieee
->assoc_id
=0;
1289 else ieee
->assoc_id
++;
1291 tag
= (u8
*) skb_put(skb
, rate_len
);
1293 ieee80211_MFIE_Brate(ieee
, &tag
);
1294 ieee80211_MFIE_Grate(ieee
, &tag
);
1299 struct sk_buff
* ieee80211_auth_resp(struct ieee80211_device
*ieee
,int status
, u8
*dest
)
1301 struct sk_buff
*skb
;
1302 struct ieee80211_authentication
*auth
;
1304 skb
= dev_alloc_skb(sizeof(struct ieee80211_authentication
)+1);
1309 skb
->len
= sizeof(struct ieee80211_authentication
);
1311 auth
= (struct ieee80211_authentication
*)skb
->data
;
1313 auth
->status
= cpu_to_le16(status
);
1314 auth
->transaction
= cpu_to_le16(2);
1315 auth
->algorithm
= cpu_to_le16(WLAN_AUTH_OPEN
);
1317 #ifdef _RTL8187_EXT_PATCH_
1318 if(ieee
->iw_mode
== ieee
->iw_ext_mode
)
1319 memcpy(auth
->header
.addr3
, dest
, ETH_ALEN
);
1321 memcpy(auth
->header
.addr3
, ieee
->dev
->dev_addr
, ETH_ALEN
);
1323 memcpy(auth
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
1324 memcpy(auth
->header
.addr1
, dest
, ETH_ALEN
);
1325 auth
->header
.frame_ctl
= cpu_to_le16(IEEE80211_STYPE_AUTH
);
1331 struct sk_buff
* ieee80211_null_func(struct ieee80211_device
*ieee
,short pwr
)
1333 struct sk_buff
*skb
;
1334 struct ieee80211_hdr_3addr
* hdr
;
1336 skb
= dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr
));
1341 hdr
= (struct ieee80211_hdr_3addr
*)skb_put(skb
,sizeof(struct ieee80211_hdr_3addr
));
1343 memcpy(hdr
->addr1
, ieee
->current_network
.bssid
, ETH_ALEN
);
1344 memcpy(hdr
->addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
1345 memcpy(hdr
->addr3
, ieee
->current_network
.bssid
, ETH_ALEN
);
1347 hdr
->frame_ctl
= cpu_to_le16(IEEE80211_FTYPE_DATA
|
1348 IEEE80211_STYPE_NULLFUNC
| IEEE80211_FCTL_TODS
|
1349 (pwr
? IEEE80211_FCTL_PM
:0));
1357 void ieee80211_resp_to_assoc_rq(struct ieee80211_device
*ieee
, u8
* dest
)
1359 struct sk_buff
*buf
= ieee80211_assoc_resp(ieee
, dest
);
1362 softmac_mgmt_xmit(buf
, ieee
);
1363 dev_kfree_skb_any(buf
);//edit by thomas
1368 void ieee80211_resp_to_auth(struct ieee80211_device
*ieee
, int s
, u8
* dest
)
1370 struct sk_buff
*buf
= ieee80211_auth_resp(ieee
, s
, dest
);
1373 softmac_mgmt_xmit(buf
, ieee
);
1374 dev_kfree_skb_any(buf
);//edit by thomas
1379 void ieee80211_resp_to_probe(struct ieee80211_device
*ieee
, u8
*dest
)
1382 struct sk_buff
*buf
= ieee80211_probe_resp(ieee
, dest
);
1385 softmac_mgmt_xmit(buf
, ieee
);
1386 dev_kfree_skb_any(buf
);//edit by thomas
1391 inline struct sk_buff
*ieee80211_association_req(struct ieee80211_network
*beacon
,struct ieee80211_device
*ieee
)
1393 struct sk_buff
*skb
;
1394 //unsigned long flags;
1396 struct ieee80211_assoc_request_frame
*hdr
;
1398 //short info_addr = 0;
1400 //u16 suite_count = 0;
1401 //u8 suit_select = 0;
1402 unsigned int wpa_len
= beacon
->wpa_ie_len
;
1403 //struct net_device *dev = ieee->dev;
1404 //union iwreq_data wrqu;
1408 // for testing purpose
1409 unsigned int rsn_len
= beacon
->rsn_ie_len
;
1411 unsigned int rsn_len
= beacon
->rsn_ie_len
- 4;
1413 unsigned int rate_len
= ieee80211_MFIE_rate_len(ieee
);
1414 unsigned int wmm_info_len
= beacon
->QoS_Enable
?9:0;
1416 unsigned int turbo_info_len
= beacon
->Turbo_Enable
?9:0;
1419 u8 encry_proto
= ieee
->wpax_type_notify
& 0xff;
1420 //u8 pairwise_type = (ieee->wpax_type_notify >> 8) & 0xff;
1421 //u8 authen_type = (ieee->wpax_type_notify >> 16) & 0xff;
1425 //[0] Notify type of encryption: WPA/WPA2
1426 //[1] pair wise type
1428 if(ieee
->wpax_type_set
) {
1429 if (IEEE_PROTO_WPA
== encry_proto
) {
1431 } else if (IEEE_PROTO_RSN
== encry_proto
) {
1436 len
= sizeof(struct ieee80211_assoc_request_frame
)+
1437 + beacon
->ssid_len
//essid tagged val
1438 + rate_len
//rates tagged val
1444 len
= sizeof(struct ieee80211_assoc_request_frame
)+
1445 + beacon
->ssid_len
//essid tagged val
1446 + rate_len
//rates tagged val
1452 #ifdef _RTL8187_EXT_PATCH_
1453 if(ieee
->iw_mode
== ieee
->iw_ext_mode
)
1454 skb
= dev_alloc_skb(len
+256); // stanley
1457 skb
= dev_alloc_skb(len
);
1462 hdr
= (struct ieee80211_assoc_request_frame
*)
1463 skb_put(skb
, sizeof(struct ieee80211_assoc_request_frame
));
1466 hdr
->header
.frame_ctl
= IEEE80211_STYPE_ASSOC_REQ
;
1467 hdr
->header
.duration_id
= 37; //FIXME
1468 memcpy(hdr
->header
.addr1
, beacon
->bssid
, ETH_ALEN
);
1469 memcpy(hdr
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
1470 memcpy(hdr
->header
.addr3
, beacon
->bssid
, ETH_ALEN
);
1471 memcpy(ieee
->ap_mac_addr
, beacon
->bssid
, ETH_ALEN
);//for HW security, John
1473 hdr
->capability
= cpu_to_le16(WLAN_CAPABILITY_BSS
);
1474 if (beacon
->capability
& WLAN_CAPABILITY_PRIVACY
)
1475 hdr
->capability
|= cpu_to_le16(WLAN_CAPABILITY_PRIVACY
);
1476 if (beacon
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
1477 hdr
->capability
|= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE
);
1479 if(ieee
->short_slot
)
1480 hdr
->capability
|= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT
);
1482 #ifdef _RTL8187_EXT_PATCH_
1483 if((ieee
->iw_mode
== ieee
->iw_ext_mode
) && ieee
->ext_patch_ieee80211_association_req_1
)
1484 ieee
->ext_patch_ieee80211_association_req_1(hdr
);
1487 hdr
->listen_interval
= 0xa; //FIXME
1489 hdr
->info_element
.id
= MFIE_TYPE_SSID
;
1491 hdr
->info_element
.len
= beacon
->ssid_len
;
1492 tag
= skb_put(skb
, beacon
->ssid_len
);
1493 memcpy(tag
, beacon
->ssid
, beacon
->ssid_len
);
1495 tag
= skb_put(skb
, rate_len
);
1497 ieee80211_MFIE_Brate(ieee
, &tag
);
1498 ieee80211_MFIE_Grate(ieee
, &tag
);
1500 //add rsn==0 condition for ap's mix security mode(wpa+wpa2), john2007.8.9
1501 //choose AES encryption as default algorithm while using mixed mode
1505 tag
= skb_put(skb
,wpa_len
);
1510 //{add by david. 2006.8.31
1511 //fix linksys compatibility bug
1513 if(wpa_len
> 24) {//22+2, mean include the capability
1514 beacon
->wpa_ie
[wpa_len
- 2] = 0;
1516 //multicast cipher OUI
1517 if( beacon
->wpa_ie
[11]==0x2 ){ //0x0050f202 is the oui of tkip
1518 ieee
->broadcast_key_type
= KEY_TYPE_TKIP
;
1520 else if( beacon
->wpa_ie
[11]==0x4 ){//0x0050f204 is the oui of ccmp
1521 ieee
->broadcast_key_type
= KEY_TYPE_CCMP
;
1523 //unicast cipher OUI
1524 if( beacon
->wpa_ie
[14]==0
1525 && beacon
->wpa_ie
[15]==0x50
1526 && beacon
->wpa_ie
[16]==0xf2
1527 && beacon
->wpa_ie
[17]==0x2 ){ //0x0050f202 is the oui of tkip
1528 ieee
->pairwise_key_type
= KEY_TYPE_TKIP
;
1531 else if( beacon
->wpa_ie
[14]==0
1532 && beacon
->wpa_ie
[15]==0x50
1533 && beacon
->wpa_ie
[16]==0xf2
1534 && beacon
->wpa_ie
[17]==0x4 ){//0x0050f204 is the oui of ccmp
1535 ieee
->pairwise_key_type
= KEY_TYPE_CCMP
;
1537 //indicate the wpa_ie content to WPA_SUPPLICANT
1538 buff
= kmalloc(IW_CUSTOM_MAX
, GFP_ATOMIC
);
1539 memset(buff
, 0, IW_CUSTOM_MAX
);
1541 p
+= sprintf(p
, "ASSOCINFO(ReqIEs=");
1542 for(i
=0;i
<wpa_len
;i
++){
1543 p
+= sprintf(p
, "%02x", beacon
->wpa_ie
[i
]);
1545 p
+= sprintf(p
, ")");
1546 memset(&wrqu
, 0, sizeof(wrqu
) );
1547 wrqu
.data
.length
= p
- buff
;
1549 wireless_send_event(dev
, IWEVCUSTOM
, &wrqu
, buff
);
1550 memcpy(tag
,beacon
->wpa_ie
,wpa_len
);
1557 if( beacon
->rsn_ie
[4]==0x0 &&
1558 beacon
->rsn_ie
[5]==0xf &&
1559 beacon
->rsn_ie
[6]==0xac){
1561 switch(beacon
->rsn_ie
[7]){
1563 ieee
->broadcast_key_type
= KEY_TYPE_WEP40
;
1566 ieee
->broadcast_key_type
= KEY_TYPE_TKIP
;
1569 ieee
->broadcast_key_type
= KEY_TYPE_CCMP
;
1572 ieee
->broadcast_key_type
= KEY_TYPE_WEP104
;
1575 printk("fault suite type in RSN broadcast key\n");
1580 if( beacon
->rsn_ie
[10]==0x0 &&
1581 beacon
->rsn_ie
[11]==0xf &&
1582 beacon
->rsn_ie
[12]==0xac){
1583 if(beacon
->rsn_ie
[8]==1){//not mixed mode
1584 switch(beacon
->rsn_ie
[13]){
1586 ieee
->pairwise_key_type
= KEY_TYPE_TKIP
;
1589 ieee
->pairwise_key_type
= KEY_TYPE_CCMP
;
1592 printk("fault suite type in RSN pairwise key\n");
1596 else if(beacon
->rsn_ie
[8]==2){//mixed mode
1597 ieee
->pairwise_key_type
= KEY_TYPE_CCMP
;
1603 tag
= skb_put(skb
,22);
1604 memcpy(tag
,(beacon
->rsn_ie
+ info_addr
),8);
1609 spin_lock_irqsave(&ieee
->wpax_suitlist_lock
,flags
);
1610 for (i
= 0; i
< 2; i
++) {
1614 suite_count
= beacon
->rsn_ie
[info_addr
] + \
1615 (beacon
->rsn_ie
[info_addr
+ 1] << 8);
1617 if(1 == suite_count
) {
1618 memcpy(tag
,(beacon
->rsn_ie
+ info_addr
),4);
1621 // if the wpax_type_notify has been set by the application,
1622 // just use it, otherwise just use the default one.
1623 if(ieee
->wpax_type_set
) {
1624 suit_select
= ((0 == i
) ? pairwise_type
:authen_type
)&0x0f ;
1625 memcpy(tag
,rsn_authen_cipher_suite
[suit_select
],4);
1627 //default set as ccmp, or none authentication
1629 memcpy(tag
,rsn_authen_cipher_suite
[4],4);
1631 memcpy(tag
,rsn_authen_cipher_suite
[2],4);
1636 info_addr
+= (suite_count
* 4);
1640 spin_unlock_irqrestore(&ieee
->wpax_suitlist_lock
,flags
);
1643 tag
[1] = beacon
->rsn_ie
[info_addr
+1];
1646 tag
= skb_put(skb
,rsn_len
);
1650 if( beacon
->rsn_ie
[4]==0x0 &&
1651 beacon
->rsn_ie
[5]==0xf &&
1652 beacon
->rsn_ie
[6]==0xac){
1653 switch(beacon
->rsn_ie
[7]){
1655 ieee
->broadcast_key_type
= KEY_TYPE_WEP40
;
1658 ieee
->broadcast_key_type
= KEY_TYPE_TKIP
;
1661 ieee
->broadcast_key_type
= KEY_TYPE_CCMP
;
1664 ieee
->broadcast_key_type
= KEY_TYPE_WEP104
;
1667 printk("fault suite type in RSN broadcast key\n");
1671 if( beacon
->rsn_ie
[10]==0x0 &&
1672 beacon
->rsn_ie
[11]==0xf &&
1673 beacon
->rsn_ie
[12]==0xac){
1674 if(beacon
->rsn_ie
[8]==1){//not mixed mode
1675 switch(beacon
->rsn_ie
[13]){
1677 ieee
->pairwise_key_type
= KEY_TYPE_TKIP
;
1680 ieee
->pairwise_key_type
= KEY_TYPE_CCMP
;
1683 printk("fault suite type in RSN pairwise key\n");
1688 else if(beacon
->rsn_ie
[8]==2){//mixed mode
1689 ieee
->pairwise_key_type
= KEY_TYPE_CCMP
;
1694 beacon
->rsn_ie
[rsn_len
- 2] = 0;
1695 memcpy(tag
,beacon
->rsn_ie
,rsn_len
);
1699 tag
= skb_put(skb
,ieee
->wpa_ie_len
);
1700 memcpy(tag
,ieee
->wpa_ie
,ieee
->wpa_ie_len
);
1702 tag
= skb_put(skb
,wmm_info_len
);
1704 ieee80211_WMM_Info(ieee
, &tag
);
1707 tag
= skb_put(skb
,turbo_info_len
);
1708 if(turbo_info_len
) {
1709 ieee80211_TURBO_Info(ieee
, &tag
);
1713 #ifdef _RTL8187_EXT_PATCH_
1714 if((ieee
->iw_mode
== ieee
->iw_ext_mode
) && ieee
->ext_patch_ieee80211_association_req_2
)
1715 ieee
->ext_patch_ieee80211_association_req_2(ieee
, beacon
, skb
);
1721 void ieee80211_associate_abort(struct ieee80211_device
*ieee
)
1724 unsigned long flags
;
1725 spin_lock_irqsave(&ieee
->lock
, flags
);
1727 ieee
->associate_seq
++;
1729 /* don't scan, and avoid to have the RX path possibily
1730 * try again to associate. Even do not react to AUTH or
1731 * ASSOC response. Just wait for the retry wq to be scheduled.
1732 * Here we will check if there are good nets to associate
1733 * with, so we retry or just get back to NO_LINK and scanning
1735 if (ieee
->state
== IEEE80211_ASSOCIATING_AUTHENTICATING
){
1736 IEEE80211_DEBUG_MGMT("Authentication failed\n");
1737 ieee
->softmac_stats
.no_auth_rs
++;
1739 IEEE80211_DEBUG_MGMT("Association failed\n");
1740 ieee
->softmac_stats
.no_ass_rs
++;
1743 ieee
->state
= IEEE80211_ASSOCIATING_RETRY
;
1745 queue_delayed_work(ieee
->wq
, &ieee
->associate_retry_wq
,IEEE80211_SOFTMAC_ASSOC_RETRY_TIME
);
1747 spin_unlock_irqrestore(&ieee
->lock
, flags
);
1750 void ieee80211_associate_abort_cb(unsigned long dev
)
1752 ieee80211_associate_abort((struct ieee80211_device
*) dev
);
1756 void ieee80211_associate_step1(struct ieee80211_device
*ieee
)
1758 struct ieee80211_network
*beacon
= &ieee
->current_network
;
1759 struct sk_buff
*skb
;
1761 IEEE80211_DEBUG_MGMT("Stopping scan\n");
1762 ieee
->softmac_stats
.tx_auth_rq
++;
1763 skb
=ieee80211_authentication_req(beacon
, ieee
, 0);
1764 #ifdef _RTL8187_EXT_PATCH_
1765 if(ieee
->iw_mode
== ieee
->iw_ext_mode
) {
1767 softmac_mgmt_xmit(skb
, ieee
);
1773 ieee80211_associate_abort(ieee
);
1776 ieee
->state
= IEEE80211_ASSOCIATING_AUTHENTICATING
;
1777 IEEE80211_DEBUG_MGMT("Sending authentication request\n");
1778 //printk("---Sending authentication request\n");
1779 softmac_mgmt_xmit(skb
, ieee
);
1780 //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
1781 if(!timer_pending(&ieee
->associate_timer
)){
1782 ieee
->associate_timer
.expires
= jiffies
+ (HZ
/ 2);
1783 add_timer(&ieee
->associate_timer
);
1785 //If call dev_kfree_skb_any,a warning will ocur....
1786 //KERNEL: assertion (!atomic_read(&skb->users)) failed at net/core/dev.c (1708)
1787 //So ... 1204 by lawrence.
1788 //printk("\nIn %s,line %d call kfree skb.",__func__,__LINE__);
1789 //dev_kfree_skb_any(skb);//edit by thomas
1793 void ieee80211_auth_challenge(struct ieee80211_device
*ieee
, u8
*challenge
, int chlen
)
1796 struct sk_buff
*skb
;
1797 struct ieee80211_network
*beacon
= &ieee
->current_network
;
1798 // int hlen = sizeof(struct ieee80211_authentication);
1799 del_timer_sync(&ieee
->associate_timer
);
1800 ieee
->associate_seq
++;
1801 ieee
->softmac_stats
.tx_auth_rq
++;
1803 skb
= ieee80211_authentication_req(beacon
, ieee
, chlen
+2);
1805 ieee80211_associate_abort(ieee
);
1807 c
= skb_put(skb
, chlen
+2);
1808 *(c
++) = MFIE_TYPE_CHALLENGE
;
1810 memcpy(c
, challenge
, chlen
);
1812 IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
1814 ieee80211_encrypt_fragment(ieee
, skb
, sizeof(struct ieee80211_hdr_3addr
));
1816 softmac_mgmt_xmit(skb
, ieee
);
1817 if (!timer_pending(&ieee
->associate_timer
)){
1818 //printk("=========>add timer again, to crash\n");
1819 ieee
->associate_timer
.expires
= jiffies
+ (HZ
/ 2);
1820 add_timer(&ieee
->associate_timer
);
1822 dev_kfree_skb_any(skb
);//edit by thomas
1827 #ifdef _RTL8187_EXT_PATCH_
1829 // based on ieee80211_assoc_resp
1830 struct sk_buff
* ieee80211_assoc_resp_by_net(struct ieee80211_device
*ieee
, u8
*dest
, unsigned short status
, struct ieee80211_network
*pstat
, int pkt_type
)
1832 struct sk_buff
*skb
;
1835 struct ieee80211_crypt_data
* crypt
;
1836 struct ieee80211_assoc_response_frame
*assoc
;
1839 unsigned int rate_len
= ieee80211_MFIE_rate_len(ieee
);
1840 int len
= sizeof(struct ieee80211_assoc_response_frame
) + rate_len
;
1842 if(ieee
->iw_mode
== ieee
->iw_ext_mode
)
1843 skb
= dev_alloc_skb(len
+256); // stanley
1845 skb
= dev_alloc_skb(len
);
1850 assoc
= (struct ieee80211_assoc_response_frame
*)
1851 skb_put(skb
,sizeof(struct ieee80211_assoc_response_frame
));
1853 assoc
->header
.frame_ctl
= cpu_to_le16(pkt_type
);
1855 memcpy(assoc
->header
.addr1
, dest
,ETH_ALEN
);
1856 memcpy(assoc
->header
.addr3
, ieee
->dev
->dev_addr
, ETH_ALEN
);
1857 memcpy(assoc
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
1858 assoc
->capability
= cpu_to_le16(ieee
->iw_mode
== IW_MODE_MASTER
?
1859 WLAN_CAPABILITY_BSS
: WLAN_CAPABILITY_IBSS
);
1861 if((ieee
->iw_mode
== ieee
->iw_ext_mode
) && ieee
->ext_patch_ieee80211_assoc_resp_by_net_1
)
1862 ieee
->ext_patch_ieee80211_assoc_resp_by_net_1(assoc
);
1864 if(ieee
->short_slot
)
1865 assoc
->capability
|= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT
);
1867 if (ieee
->host_encrypt
)
1868 crypt
= ieee
->crypt
[ieee
->tx_keyidx
];
1871 encrypt
= ( crypt
&& crypt
->ops
);
1874 assoc
->capability
|= cpu_to_le16(WLAN_CAPABILITY_PRIVACY
);
1877 assoc
->aid
= cpu_to_le16(ieee
->assoc_id
);
1878 if (ieee
->assoc_id
== 0x2007) ieee
->assoc_id
=0;
1879 else ieee
->assoc_id
++;
1881 assoc
->info_element
.id
= 230; // Stanley, an unused id (just a hot fix)
1882 assoc
->info_element
.len
= 0;
1884 tag
= (u8
*) skb_put(skb
, rate_len
);
1886 ieee80211_MFIE_Brate(ieee
, &tag
);
1887 ieee80211_MFIE_Grate(ieee
, &tag
);
1889 if((ieee
->iw_mode
== ieee
->iw_ext_mode
) && ieee
->ext_patch_ieee80211_assoc_resp_by_net_2
)
1890 ieee
->ext_patch_ieee80211_assoc_resp_by_net_2(ieee
, pstat
, pkt_type
, skb
);
1895 // based on ieee80211_resp_to_assoc_rq
1896 void ieee80211_ext_issue_assoc_rsp(struct ieee80211_device
*ieee
, u8
*dest
, unsigned short status
, struct ieee80211_network
*pstat
, int pkt_type
)
1898 struct sk_buff
*buf
= ieee80211_assoc_resp_by_net(ieee
, dest
, status
, pstat
, pkt_type
);
1901 softmac_mgmt_xmit(buf
, ieee
);
1904 // based on ieee80211_associate_step2
1905 void ieee80211_ext_issue_assoc_req(struct ieee80211_device
*ieee
, struct ieee80211_network
*pstat
)
1908 struct sk_buff
* skb
;
1910 // printk("@@@@@ ieee80211_ext_issue_assoc_req on channel: %d\n", ieee->current_network.channel);
1912 ieee
->softmac_stats
.tx_ass_rq
++;
1913 skb
=ieee80211_association_req(pstat
, ieee
);
1915 softmac_mgmt_xmit(skb
, ieee
);
1918 void ieee80211_ext_issue_disassoc(struct ieee80211_device
*ieee
, struct ieee80211_network
*pstat
, int reason
, unsigned char extReason
)
1921 // printk("@@@@@ ieee80211_ext_issue_disassoc\n");
1924 #endif // _RTL8187_EXT_PATCH_
1926 void ieee80211_associate_step2(struct ieee80211_device
*ieee
)
1928 struct sk_buff
* skb
;
1929 struct ieee80211_network
*beacon
= &ieee
->current_network
;
1931 del_timer_sync(&ieee
->associate_timer
);
1933 IEEE80211_DEBUG_MGMT("Sending association request\n");
1934 ieee
->softmac_stats
.tx_ass_rq
++;
1935 skb
=ieee80211_association_req(beacon
, ieee
);
1937 ieee80211_associate_abort(ieee
);
1939 softmac_mgmt_xmit(skb
, ieee
);
1940 if (!timer_pending(&ieee
->associate_timer
)){
1941 ieee
->associate_timer
.expires
= jiffies
+ (HZ
/ 2);
1942 add_timer(&ieee
->associate_timer
);
1944 //dev_kfree_skb_any(skb);//edit by thomas
1948 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
1949 void ieee80211_associate_complete_wq(struct work_struct
*work
)
1951 struct ieee80211_device
*ieee
= container_of(work
, struct ieee80211_device
, associate_complete_wq
);
1953 void ieee80211_associate_complete_wq(struct ieee80211_device
*ieee
)
1956 printk(KERN_INFO
"Associated successfully\n");
1957 if(ieee80211_is_54g(ieee
->current_network
) &&
1958 (ieee
->modulation
& IEEE80211_OFDM_MODULATION
)){
1961 printk(KERN_INFO
"Using G rates\n");
1964 printk(KERN_INFO
"Using B rates\n");
1966 ieee
->link_change(ieee
->dev
);
1967 notify_wx_assoc_event(ieee
);
1968 if (ieee
->data_hard_resume
)
1969 ieee
->data_hard_resume(ieee
->dev
);
1970 netif_carrier_on(ieee
->dev
);
1973 void ieee80211_associate_complete(struct ieee80211_device
*ieee
)
1976 del_timer_sync(&ieee
->associate_timer
);
1978 for(i
= 0; i
< 6; i
++) {
1979 //ieee->seq_ctrl[i] = 0;
1981 ieee
->state
= IEEE80211_LINKED
;
1982 IEEE80211_DEBUG_MGMT("Successfully associated\n");
1984 queue_work(ieee
->wq
, &ieee
->associate_complete_wq
);
1987 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
1988 void ieee80211_associate_procedure_wq(struct work_struct
*work
)
1990 struct ieee80211_device
*ieee
= container_of(work
, struct ieee80211_device
, associate_procedure_wq
);
1992 void ieee80211_associate_procedure_wq(struct ieee80211_device
*ieee
)
1995 ieee
->sync_scan_hurryup
= 1;
1996 down(&ieee
->wx_sem
);
1998 if (ieee
->data_hard_stop
)
1999 ieee
->data_hard_stop(ieee
->dev
);
2001 ieee80211_stop_scan(ieee
);
2002 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
2004 ieee
->associate_seq
= 1;
2005 ieee80211_associate_step1(ieee
);
2009 #ifdef _RTL8187_EXT_PATCH_
2010 // based on ieee80211_associate_procedure_wq
2012 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
2013 void ieee80211_ext_stop_scan_wq(struct work_struct
*work
)
2015 struct ieee80211_device
*ieee
= container_of(work
, struct ieee80211_device
, ext_stop_scan_wq
);
2017 void ieee80211_ext_stop_scan_wq(struct ieee80211_device
*ieee
)
2020 if (ieee
->scanning
== 0)
2022 if((ieee
->iw_mode
== ieee
->iw_ext_mode
) && ieee
->ext_patch_ieee80211_ext_stop_scan_wq_set_channel
2023 && ( ieee
->current_network
.channel
== ieee
->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee
) ) )
2027 ieee
->sync_scan_hurryup
= 1;
2029 down(&ieee
->wx_sem
);
2031 // printk("@@@@@@@@@@ ieee80211_ext_stop_scan_wq\n");
2032 if (ieee
->data_hard_stop
)
2033 ieee
->data_hard_stop(ieee
->dev
);
2035 ieee80211_stop_scan(ieee
);
2038 if((ieee
->iw_mode
== ieee
->iw_ext_mode
) && ieee
->ext_patch_ieee80211_ext_stop_scan_wq_set_channel
)
2039 ieee
->set_chan(ieee
->dev
, ieee
->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee
));
2041 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
2047 void ieee80211_ext_send_11s_beacon(struct ieee80211_device
*ieee
)
2049 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
2050 queue_work(ieee
->wq
, &ieee
->ext_send_beacon_wq
);
2052 schedule_task(&ieee
->ext_send_beacon_wq
);
2057 #endif // _RTL8187_EXT_PATCH_
2059 inline void ieee80211_softmac_new_net(struct ieee80211_device
*ieee
, struct ieee80211_network
*net
)
2061 u8 tmp_ssid
[IW_ESSID_MAX_SIZE
+1];
2062 int tmp_ssid_len
= 0;
2064 short apset
,ssidset
,ssidbroad
,apmatch
,ssidmatch
;
2066 /* we are interested in new new only if we are not associated
2067 * and we are not associating / authenticating
2069 if (ieee
->state
!= IEEE80211_NOLINK
)
2072 if ((ieee
->iw_mode
== IW_MODE_INFRA
) && !(net
->capability
& WLAN_CAPABILITY_BSS
))
2075 if ((ieee
->iw_mode
== IW_MODE_ADHOC
) && !(net
->capability
& WLAN_CAPABILITY_IBSS
))
2079 if (ieee
->iw_mode
== IW_MODE_INFRA
|| ieee
->iw_mode
== IW_MODE_ADHOC
){
2080 /* if the user specified the AP MAC, we need also the essid
2081 * This could be obtained by beacons or, if the network does not
2082 * broadcast it, it can be put manually.
2084 apset
= ieee
->wap_set
;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
2085 ssidset
= ieee
->ssid_set
;//ieee->current_network.ssid[0] != '\0';
2086 ssidbroad
= !(net
->ssid_len
== 0 || net
->ssid
[0]== '\0');
2087 apmatch
= (memcmp(ieee
->current_network
.bssid
, net
->bssid
, ETH_ALEN
)==0);
2089 if(ieee
->current_network
.ssid_len
!= net
->ssid_len
)
2092 ssidmatch
= (0==strncmp(ieee
->current_network
.ssid
, net
->ssid
, net
->ssid_len
));
2094 //printk("cur: %s, %d, net:%s, %d\n", ieee->current_network.ssid, ieee->current_network.ssid_len, net->ssid, net->ssid_len);
2095 //printk("apset=%d apmatch=%d ssidset=%d ssidbroad=%d ssidmatch=%d\n",apset,apmatch,ssidset,ssidbroad,ssidmatch);
2097 if ( /* if the user set the AP check if match.
2098 * if the network does not broadcast essid we check the user supplyed ANY essid
2099 * if the network does broadcast and the user does not set essid it is OK
2100 * if the network does broadcast and the user did set essid chech if essid match
2102 ( apset
&& apmatch
&&
2103 ((ssidset
&& ssidbroad
&& ssidmatch
) || (ssidbroad
&& !ssidset
) || (!ssidbroad
&& ssidset
)) ) ||
2104 /* if the ap is not set, check that the user set the bssid
2105 * and the network does bradcast and that those two bssid matches
2107 (!apset
&& ssidset
&& ssidbroad
&& ssidmatch
)
2111 /* if the essid is hidden replace it with the
2112 * essid provided by the user.
2115 strncpy(tmp_ssid
, ieee
->current_network
.ssid
, IW_ESSID_MAX_SIZE
);
2116 tmp_ssid_len
= ieee
->current_network
.ssid_len
;
2118 memcpy(&ieee
->current_network
, net
, sizeof(struct ieee80211_network
));
2121 strncpy(ieee
->current_network
.ssid
, tmp_ssid
, IW_ESSID_MAX_SIZE
);
2122 ieee
->current_network
.ssid_len
= tmp_ssid_len
;
2124 printk(KERN_INFO
"Linking with %s: channel is %d\n",ieee
->current_network
.ssid
,ieee
->current_network
.channel
);
2126 if (ieee
->iw_mode
== IW_MODE_INFRA
){
2127 ieee
->state
= IEEE80211_ASSOCIATING
;
2128 ieee
->beinretry
= false;
2129 queue_work(ieee
->wq
, &ieee
->associate_procedure_wq
);
2131 if(ieee80211_is_54g(ieee
->current_network
) &&
2132 (ieee
->modulation
& IEEE80211_OFDM_MODULATION
)){
2134 printk(KERN_INFO
"Using G rates\n");
2137 printk(KERN_INFO
"Using B rates\n");
2139 ieee
->state
= IEEE80211_LINKED
;
2140 ieee
->beinretry
= false;
2148 void ieee80211_softmac_check_all_nets(struct ieee80211_device
*ieee
)
2150 unsigned long flags
;
2151 struct ieee80211_network
*target
;
2153 spin_lock_irqsave(&ieee
->lock
, flags
);
2154 list_for_each_entry(target
, &ieee
->network_list
, list
) {
2156 /* if the state become different that NOLINK means
2157 * we had found what we are searching for
2160 if (ieee
->state
!= IEEE80211_NOLINK
)
2163 if (ieee
->scan_age
== 0 || time_after(target
->last_scanned
+ ieee
->scan_age
, jiffies
))
2164 ieee80211_softmac_new_net(ieee
, target
);
2167 spin_unlock_irqrestore(&ieee
->lock
, flags
);
2172 static inline u16
auth_parse(struct sk_buff
*skb
, u8
** challenge
, int *chlen
)
2174 struct ieee80211_authentication
*a
;
2176 if (skb
->len
< (sizeof(struct ieee80211_authentication
)-sizeof(struct ieee80211_info_element
))){
2177 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb
->len
);
2181 a
= (struct ieee80211_authentication
*) skb
->data
;
2182 if(skb
->len
> (sizeof(struct ieee80211_authentication
) +3)){
2183 t
= skb
->data
+ sizeof(struct ieee80211_authentication
);
2185 if(*(t
++) == MFIE_TYPE_CHALLENGE
){
2187 *challenge
= (u8
*)kmalloc(*chlen
, GFP_ATOMIC
);
2188 memcpy(*challenge
, t
, *chlen
);
2192 return cpu_to_le16(a
->status
);
2197 int auth_rq_parse(struct sk_buff
*skb
,u8
* dest
)
2199 struct ieee80211_authentication
*a
;
2201 if (skb
->len
< (sizeof(struct ieee80211_authentication
)-sizeof(struct ieee80211_info_element
))){
2202 IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb
->len
);
2205 a
= (struct ieee80211_authentication
*) skb
->data
;
2207 memcpy(dest
,a
->header
.addr2
, ETH_ALEN
);
2209 if (le16_to_cpu(a
->algorithm
) != WLAN_AUTH_OPEN
)
2210 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
2212 return WLAN_STATUS_SUCCESS
;
2215 static short probe_rq_parse(struct ieee80211_device
*ieee
, struct sk_buff
*skb
, u8
*src
)
2222 struct ieee80211_hdr_3addr
*header
=
2223 (struct ieee80211_hdr_3addr
*) skb
->data
;
2225 if (skb
->len
< sizeof (struct ieee80211_hdr_3addr
))
2226 return -1; /* corrupted */
2228 memcpy(src
,header
->addr2
, ETH_ALEN
);
2230 skbend
= (u8
*)skb
->data
+ skb
->len
;
2232 tag
= skb
->data
+ sizeof (struct ieee80211_hdr_3addr
);
2234 while (tag
+1 < skbend
){
2240 tag
++; /* point to the len field */
2241 tag
= tag
+ *(tag
); /* point to the last data byte of the tag */
2242 tag
++; /* point to the next tag */
2245 //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
2246 if (ssidlen
== 0) return 1;
2248 if (!ssid
) return 1; /* ssid not found in tagged param */
2249 return (!strncmp(ssid
, ieee
->current_network
.ssid
, ssidlen
));
2253 int assoc_rq_parse(struct sk_buff
*skb
,u8
* dest
)
2255 struct ieee80211_assoc_request_frame
*a
;
2257 if (skb
->len
< (sizeof(struct ieee80211_assoc_request_frame
) -
2258 sizeof(struct ieee80211_info_element
))) {
2260 IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb
->len
);
2264 a
= (struct ieee80211_assoc_request_frame
*) skb
->data
;
2266 memcpy(dest
,a
->header
.addr2
,ETH_ALEN
);
2271 static inline u16
assoc_parse(struct sk_buff
*skb
, int *aid
)
2273 struct ieee80211_assoc_response_frame
*a
;
2274 if (skb
->len
< sizeof(struct ieee80211_assoc_response_frame
)){
2275 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb
->len
);
2279 a
= (struct ieee80211_assoc_response_frame
*) skb
->data
;
2280 *aid
= le16_to_cpu(a
->aid
) & 0x3fff;
2281 return le16_to_cpu(a
->status
);
2285 ieee80211_rx_probe_rq(struct ieee80211_device
*ieee
, struct sk_buff
*skb
)
2289 //IEEE80211DMESG("Rx probe");
2290 ieee
->softmac_stats
.rx_probe_rq
++;
2291 //DMESG("Dest is "MACSTR, MAC2STR(dest));
2292 if (probe_rq_parse(ieee
, skb
, dest
)){
2293 //IEEE80211DMESG("Was for me!");
2294 ieee
->softmac_stats
.tx_probe_rs
++;
2295 ieee80211_resp_to_probe(ieee
, dest
);
2300 ieee80211_rx_auth_rq(struct ieee80211_device
*ieee
, struct sk_buff
*skb
)
2304 //IEEE80211DMESG("Rx probe");
2305 ieee
->softmac_stats
.rx_auth_rq
++;
2307 if ((status
= auth_rq_parse(skb
, dest
))!= -1){
2308 ieee80211_resp_to_auth(ieee
, status
, dest
);
2310 //DMESG("Dest is "MACSTR, MAC2STR(dest));
2315 ieee80211_rx_assoc_rq(struct ieee80211_device
*ieee
, struct sk_buff
*skb
)
2319 //unsigned long flags;
2321 ieee
->softmac_stats
.rx_ass_rq
++;
2322 if (assoc_rq_parse(skb
,dest
) != -1){
2323 ieee80211_resp_to_assoc_rq(ieee
, dest
);
2326 printk(KERN_INFO
"New client associated: "MAC_FMT
"\n", MAC_ARG(dest
));
2329 spin_lock_irqsave(&ieee
->lock
,flags
);
2330 add_associate(ieee
,dest
);
2331 spin_unlock_irqrestore(&ieee
->lock
,flags
);
2337 void ieee80211_sta_ps_send_null_frame(struct ieee80211_device
*ieee
, short pwr
)
2340 struct sk_buff
*buf
= ieee80211_null_func(ieee
, pwr
);
2343 softmac_ps_mgmt_xmit(buf
, ieee
);
2348 short ieee80211_sta_ps_sleep(struct ieee80211_device
*ieee
, u32
*time_h
, u32
*time_l
)
2351 int timeout
= ieee
->ps_timeout
;
2356 /*if(ieee->ps == IEEE80211_PS_DISABLED ||
2357 ieee->iw_mode != IW_MODE_INFRA ||
2358 ieee->state != IEEE80211_LINKED)
2362 dtim
= ieee
->current_network
.dtim_data
;
2365 if(!(dtim
& IEEE80211_DTIM_VALID
))
2368 timeout
= ieee
->current_network
.beacon_interval
;
2370 //printk("VALID\n");
2371 ieee
->current_network
.dtim_data
= IEEE80211_DTIM_INVALID
;
2373 if(dtim
& ((IEEE80211_DTIM_UCAST
| IEEE80211_DTIM_MBCAST
)& ieee
->ps
))
2376 if(!time_after(jiffies
, ieee
->dev
->trans_start
+ MSECS(timeout
)))
2379 if(!time_after(jiffies
, ieee
->last_rx_ps_time
+ MSECS(timeout
)))
2382 if((ieee
->softmac_features
& IEEE_SOFTMAC_SINGLE_QUEUE
) &&
2383 (ieee
->mgmt_queue_tail
!= ieee
->mgmt_queue_head
))
2387 *time_l
= ieee
->current_network
.last_dtim_sta_time
[0]
2388 + (ieee
->current_network
.beacon_interval
2389 * ieee
->current_network
.dtim_period
) * 1000;
2393 *time_l
= ieee
->current_network
.last_dtim_sta_time
[0]
2394 + MSECS((ieee
->current_network
.beacon_interval
));
2395 //* ieee->current_network.dtim_period));
2396 //printk("beacon_interval:%x, dtim_period:%x, totol to Msecs:%x, HZ:%x\n", ieee->current_network.beacon_interval, ieee->current_network.dtim_period, MSECS(((ieee->current_network.beacon_interval * ieee->current_network.dtim_period))), HZ);
2401 *time_h
= ieee
->current_network
.last_dtim_sta_time
[1];
2402 if(time_l
&& *time_l
< ieee
->current_network
.last_dtim_sta_time
[0])
2411 inline void ieee80211_sta_ps(struct ieee80211_device
*ieee
)
2417 unsigned long flags
,flags2
;
2419 spin_lock_irqsave(&ieee
->lock
, flags
);
2421 if((ieee
->ps
== IEEE80211_PS_DISABLED
||
2423 ieee
->iw_mode
!= IW_MODE_INFRA
||
2424 ieee
->state
!= IEEE80211_LINKED
)){
2426 //#warning CHECK_LOCK_HERE
2427 spin_lock_irqsave(&ieee
->mgmt_tx_lock
, flags2
);
2429 ieee80211_sta_wakeup(ieee
, 1);
2431 spin_unlock_irqrestore(&ieee
->mgmt_tx_lock
, flags2
);
2434 sleep
= ieee80211_sta_ps_sleep(ieee
,&th
, &tl
);
2435 // printk("===>%s,%d[2 wake, 1 sleep, 0 do nothing], ieee->sta_sleep = %d\n",__func__, sleep,ieee->sta_sleep);
2436 /* 2 wake, 1 sleep, 0 do nothing */
2442 if(ieee
->sta_sleep
== 1)
2443 ieee
->enter_sleep_state(ieee
->dev
,th
,tl
);
2445 else if(ieee
->sta_sleep
== 0){
2446 // printk("send null 1\n");
2447 spin_lock_irqsave(&ieee
->mgmt_tx_lock
, flags2
);
2449 if(ieee
->ps_is_queue_empty(ieee
->dev
)){
2452 ieee
->sta_sleep
= 2;
2454 ieee
->ps_request_tx_ack(ieee
->dev
);
2456 ieee80211_sta_ps_send_null_frame(ieee
,1);
2461 spin_unlock_irqrestore(&ieee
->mgmt_tx_lock
, flags2
);
2466 }else if(sleep
== 2){
2467 //#warning CHECK_LOCK_HERE
2468 spin_lock_irqsave(&ieee
->mgmt_tx_lock
, flags2
);
2470 // printk("send wakeup packet\n");
2471 ieee80211_sta_wakeup(ieee
,1);
2473 spin_unlock_irqrestore(&ieee
->mgmt_tx_lock
, flags2
);
2477 spin_unlock_irqrestore(&ieee
->lock
, flags
);
2481 void ieee80211_sta_wakeup(struct ieee80211_device
*ieee
, short nl
)
2483 if(ieee
->sta_sleep
== 0){
2485 // printk("Warning: driver is probably failing to report TX ps error\n");
2486 ieee
->ps_request_tx_ack(ieee
->dev
);
2487 ieee80211_sta_ps_send_null_frame(ieee
, 0);
2493 if(ieee
->sta_sleep
== 1)
2494 ieee
->sta_wake_up(ieee
->dev
);
2496 ieee
->sta_sleep
= 0;
2499 ieee
->ps_request_tx_ack(ieee
->dev
);
2500 ieee80211_sta_ps_send_null_frame(ieee
, 0);
2504 void ieee80211_ps_tx_ack(struct ieee80211_device
*ieee
, short success
)
2506 unsigned long flags
,flags2
;
2508 spin_lock_irqsave(&ieee
->lock
, flags
);
2509 if(ieee
->sta_sleep
== 2){
2510 /* Null frame with PS bit set */
2513 // printk("==================> %s::enter sleep state\n",__func__);
2514 ieee
->sta_sleep
= 1;
2515 ieee
->enter_sleep_state(ieee
->dev
,ieee
->ps_th
,ieee
->ps_tl
);
2517 /* if the card report not success we can't be sure the AP
2518 * has not RXed so we can't assume the AP believe us awake
2521 /* 21112005 - tx again null without PS bit if lost */
2524 if((ieee
->sta_sleep
== 0) && !success
){
2525 spin_lock_irqsave(&ieee
->mgmt_tx_lock
, flags2
);
2526 ieee80211_sta_ps_send_null_frame(ieee
, 0);
2527 spin_unlock_irqrestore(&ieee
->mgmt_tx_lock
, flags2
);
2530 spin_unlock_irqrestore(&ieee
->lock
, flags
);
2534 ieee80211_rx_frame_softmac(struct ieee80211_device
*ieee
, struct sk_buff
*skb
,
2535 struct ieee80211_rx_stats
*rx_stats
, u16 type
,
2538 struct ieee80211_hdr_3addr
*header
= (struct ieee80211_hdr_3addr
*) skb
->data
;
2543 struct ieee80211_assoc_response_frame
*assoc_resp
;
2544 struct ieee80211_info_element
*info_element
;
2546 if(!ieee
->proto_started
)
2549 if(ieee
->sta_sleep
|| (ieee
->ps
!= IEEE80211_PS_DISABLED
&&
2550 ieee
->iw_mode
== IW_MODE_INFRA
&&
2551 ieee
->state
== IEEE80211_LINKED
))
2553 tasklet_schedule(&ieee
->ps_task
);
2555 if(WLAN_FC_GET_STYPE(header
->frame_ctl
) != IEEE80211_STYPE_PROBE_RESP
&&
2556 WLAN_FC_GET_STYPE(header
->frame_ctl
) != IEEE80211_STYPE_BEACON
)
2557 ieee
->last_rx_ps_time
= jiffies
;
2559 switch (WLAN_FC_GET_STYPE(header
->frame_ctl
)) {
2561 case IEEE80211_STYPE_ASSOC_RESP
:
2562 case IEEE80211_STYPE_REASSOC_RESP
:
2564 IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
2565 WLAN_FC_GET_STYPE(header
->frame_ctl
));
2566 if ((ieee
->softmac_features
& IEEE_SOFTMAC_ASSOCIATE
) &&
2567 ieee
->state
== IEEE80211_ASSOCIATING_AUTHENTICATED
&&
2568 ieee
->iw_mode
== IW_MODE_INFRA
){
2569 if (0 == (errcode
=assoc_parse(skb
, &aid
))){
2572 ieee
->state
=IEEE80211_LINKED
;
2573 ieee
->assoc_id
= aid
;
2574 ieee
->softmac_stats
.rx_ass_ok
++;
2576 //printk(KERN_WARNING "nic_type = %s", (rx_stats->nic_type == 1)?"rtl8187":"rtl8187B");
2577 if(1 == rx_stats
->nic_type
) //card type is 8187
2579 goto associate_complete
;
2581 assoc_resp
= (struct ieee80211_assoc_response_frame
*)skb
->data
;
2582 info_element
= &assoc_resp
->info_element
;
2583 left
= skb
->len
- ((void*)info_element
- (void*)assoc_resp
);
2585 while (left
>= sizeof(struct ieee80211_info_element_hdr
)) {
2586 if (sizeof(struct ieee80211_info_element_hdr
) + info_element
->len
> left
) {
2587 printk(KERN_WARNING
"[re]associate reeponse error!");
2590 switch (info_element
->id
) {
2591 case MFIE_TYPE_GENERIC
:
2592 IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n", info_element
->len
);
2593 if (info_element
->len
>= 8 &&
2594 info_element
->data
[0] == 0x00 &&
2595 info_element
->data
[1] == 0x50 &&
2596 info_element
->data
[2] == 0xf2 &&
2597 info_element
->data
[3] == 0x02 &&
2598 info_element
->data
[4] == 0x01) {
2599 // Not care about version at present.
2600 //WMM Parameter Element
2601 memcpy(ieee
->current_network
.wmm_param
,(u8
*)(info_element
->data\
2602 + 8),(info_element
->len
- 8));
2604 if (((ieee
->current_network
.wmm_info
^info_element
->data
[6])& \
2605 0x0f)||(!ieee
->init_wmmparam_flag
)) {
2606 //refresh paramete element for current network
2607 // update the register parameter for hardware
2608 ieee
->init_wmmparam_flag
= 1;
2609 queue_work(ieee
->wq
, &ieee
->wmm_param_update_wq
);
2612 //update info_element for current network
2613 ieee
->current_network
.wmm_info
= info_element
->data
[6];
2617 //nothing to do at present!!!
2621 left
-= sizeof(struct ieee80211_info_element_hdr
) +
2623 info_element
= (struct ieee80211_info_element
*)
2624 &info_element
->data
[info_element
->len
];
2626 if(!ieee
->init_wmmparam_flag
) //legacy AP, reset the AC_xx_param register
2628 queue_work(ieee
->wq
,&ieee
->wmm_param_update_wq
);
2629 ieee
->init_wmmparam_flag
= 1;//indicate AC_xx_param upated since last associate
2632 ieee80211_associate_complete(ieee
);
2634 ieee
->softmac_stats
.rx_ass_err
++;
2635 IEEE80211_DEBUG_MGMT(
2636 "Association response status code 0x%x\n",
2638 ieee80211_associate_abort(ieee
);
2641 #ifdef _RTL8187_EXT_PATCH_
2642 else if ((ieee
->iw_mode
== ieee
->iw_ext_mode
) && ieee
->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp
)
2644 ieee
->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp(ieee
, skb
);
2649 case IEEE80211_STYPE_ASSOC_REQ
:
2650 case IEEE80211_STYPE_REASSOC_REQ
:
2652 if ((ieee
->softmac_features
& IEEE_SOFTMAC_ASSOCIATE
) &&
2653 ieee
->iw_mode
== IW_MODE_MASTER
)
2655 ieee80211_rx_assoc_rq(ieee
, skb
);
2656 #ifdef _RTL8187_EXT_PATCH_
2657 else if ((ieee
->iw_mode
== ieee
->iw_ext_mode
) && ieee
->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req
)
2659 ieee
->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req(ieee
, skb
);
2664 case IEEE80211_STYPE_AUTH
:
2666 #ifdef _RTL8187_EXT_PATCH_
2667 printk("IEEE80211_STYPE_AUTH\n");
2668 if((ieee
->iw_mode
== ieee
->iw_ext_mode
) && ieee
->ext_patch_ieee80211_rx_frame_softmac_on_auth
)
2669 if( ieee
->ext_patch_ieee80211_rx_frame_softmac_on_auth(ieee
, skb
, rx_stats
) );
2671 if (ieee
->softmac_features
& IEEE_SOFTMAC_ASSOCIATE
){
2672 if (ieee
->state
== IEEE80211_ASSOCIATING_AUTHENTICATING
&&
2673 ieee
->iw_mode
== IW_MODE_INFRA
){
2675 IEEE80211_DEBUG_MGMT("Received authentication response");
2677 if (0 == (errcode
=auth_parse(skb
, &challenge
, &chlen
))){
2678 if(ieee
->open_wep
|| !challenge
){
2679 ieee
->state
= IEEE80211_ASSOCIATING_AUTHENTICATED
;
2680 ieee
->softmac_stats
.rx_auth_rs_ok
++;
2682 ieee80211_associate_step2(ieee
);
2684 ieee80211_auth_challenge(ieee
, challenge
, chlen
);
2687 ieee
->softmac_stats
.rx_auth_rs_err
++;
2688 IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode
);
2689 ieee80211_associate_abort(ieee
);
2692 }else if (ieee
->iw_mode
== IW_MODE_MASTER
){
2693 ieee80211_rx_auth_rq(ieee
, skb
);
2698 case IEEE80211_STYPE_PROBE_REQ
:
2700 if ((ieee
->softmac_features
& IEEE_SOFTMAC_PROBERS
) &&
2701 ((ieee
->iw_mode
== IW_MODE_ADHOC
||
2702 ieee
->iw_mode
== IW_MODE_MASTER
) &&
2703 ieee
->state
== IEEE80211_LINKED
))
2705 ieee80211_rx_probe_rq(ieee
, skb
);
2708 case IEEE80211_STYPE_DISASSOC
:
2709 case IEEE80211_STYPE_DEAUTH
:
2710 #ifdef _RTL8187_EXT_PATCH_
2711 printk("IEEE80211_STYPE_DEAUTH\n");
2712 if((ieee
->iw_mode
== ieee
->iw_ext_mode
) && ieee
->ext_patch_ieee80211_rx_frame_softmac_on_deauth
)
2713 if( ieee
->ext_patch_ieee80211_rx_frame_softmac_on_deauth(ieee
, skb
, rx_stats
) ) ;
2715 /* FIXME for now repeat all the association procedure
2716 * both for disassociation and deauthentication
2718 if ((ieee
->softmac_features
& IEEE_SOFTMAC_ASSOCIATE
) &&
2719 (ieee
->state
== IEEE80211_LINKED
) &&
2720 (ieee
->iw_mode
== IW_MODE_INFRA
) &&
2721 (!memcmp(header
->addr2
,ieee
->current_network
.bssid
,ETH_ALEN
))){
2722 ieee
->state
= IEEE80211_ASSOCIATING
;
2723 ieee
->softmac_stats
.reassoc
++;
2725 //notify_wx_assoc_event(ieee); //YJ,del,080828, do not notify os here
2726 queue_work(ieee
->wq
, &ieee
->associate_procedure_wq
);
2736 //dev_kfree_skb_any(skb);
2742 /* following are for a simplier TX queue management.
2743 * Instead of using netif_[stop/wake]_queue the driver
2744 * will uses these two function (plus a reset one), that
2745 * will internally uses the kernel netif_* and takes
2746 * care of the ieee802.11 fragmentation.
2747 * So the driver receives a fragment per time and might
2748 * call the stop function when it want without take care
2749 * to have enought room to TX an entire packet.
2750 * This might be useful if each fragment need it's own
2751 * descriptor, thus just keep a total free memory > than
2752 * the max fragmentation treshold is not enought.. If the
2753 * ieee802.11 stack passed a TXB struct then you needed
2754 * to keep N free descriptors where
2755 * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
2756 * In this way you need just one and the 802.11 stack
2757 * will take care of buffering fragments and pass them to
2758 * to the driver later, when it wakes the queue.
2761 void ieee80211_softmac_xmit(struct ieee80211_txb
*txb
, struct ieee80211_device
*ieee
)
2765 unsigned long flags
;
2767 #ifdef _RTL8187_EXT_PATCH_
2768 int rate
= ieee
->rate
;
2771 spin_lock_irqsave(&ieee
->lock
,flags
);
2773 if(ieee
->queue_stop
){
2774 IEEE80211DMESG("EE: IEEE hard_start_xmit invoked when kernel queue should be stopped");
2775 netif_stop_queue(ieee
->dev
);
2776 ieee
->ieee_stats
.swtxstop
++;
2777 //dev_kfree_skb_any(skb);
2782 ieee
->stats
.tx_bytes
+=skb
->len
;
2785 txb
=ieee80211_skb_to_txb(ieee
,skb
);
2789 IEEE80211DMESG("WW: IEEE stack failed to provide txb");
2790 //dev_kfree_skb_any(skb);
2796 #ifdef _RTL8187_EXT_PATCH_
2797 if((ieee
->iw_mode
== ieee
->iw_ext_mode
) && ieee
->ext_patch_ieee80211_softmac_xmit_get_rate
&& txb
->nr_frags
)
2799 rate
= ieee
->ext_patch_ieee80211_softmac_xmit_get_rate(ieee
, txb
->fragments
[0]);
2802 /* called with 2nd parm 0, no tx mgmt lock required */
2803 ieee80211_sta_wakeup(ieee
,0);
2805 for(i
= 0; i
< txb
->nr_frags
; i
++) {
2807 if (ieee
->queue_stop
){
2808 ieee
->tx_pending
.txb
= txb
;
2809 ieee
->tx_pending
.frag
= i
;
2812 ieee
->softmac_data_hard_start_xmit(
2814 #ifdef _RTL8187_EXT_PATCH_
2817 ieee
->dev
,ieee
->rate
);
2819 //(i+1)<txb->nr_frags);
2820 ieee
->stats
.tx_packets
++;
2821 ieee
->stats
.tx_bytes
+= txb
->fragments
[i
]->len
;
2822 ieee
->dev
->trans_start
= jiffies
;
2826 ieee80211_txb_free(txb
);
2829 spin_unlock_irqrestore(&ieee
->lock
,flags
);
2833 /* called with ieee->lock acquired */
2834 void ieee80211_resume_tx(struct ieee80211_device
*ieee
)
2837 for(i
= ieee
->tx_pending
.frag
; i
< ieee
->tx_pending
.txb
->nr_frags
; i
++) {
2839 if (ieee
->queue_stop
){
2840 ieee
->tx_pending
.frag
= i
;
2844 ieee
->softmac_data_hard_start_xmit(
2845 ieee
->tx_pending
.txb
->fragments
[i
],
2846 ieee
->dev
,ieee
->rate
);
2847 //(i+1)<ieee->tx_pending.txb->nr_frags);
2848 ieee
->stats
.tx_packets
++;
2849 ieee
->dev
->trans_start
= jiffies
;
2854 ieee80211_txb_free(ieee
->tx_pending
.txb
);
2855 ieee
->tx_pending
.txb
= NULL
;
2859 void ieee80211_reset_queue(struct ieee80211_device
*ieee
)
2861 unsigned long flags
;
2863 spin_lock_irqsave(&ieee
->lock
,flags
);
2864 init_mgmt_queue(ieee
);
2865 if (ieee
->tx_pending
.txb
){
2866 ieee80211_txb_free(ieee
->tx_pending
.txb
);
2867 ieee
->tx_pending
.txb
= NULL
;
2869 ieee
->queue_stop
= 0;
2870 spin_unlock_irqrestore(&ieee
->lock
,flags
);
2874 void ieee80211_wake_queue(struct ieee80211_device
*ieee
)
2877 unsigned long flags
;
2878 struct sk_buff
*skb
;
2879 struct ieee80211_hdr_3addr
*header
;
2881 spin_lock_irqsave(&ieee
->lock
,flags
);
2882 if (! ieee
->queue_stop
) goto exit
;
2884 ieee
->queue_stop
= 0;
2886 if(ieee
->softmac_features
& IEEE_SOFTMAC_SINGLE_QUEUE
){
2887 while (!ieee
->queue_stop
&& (skb
= dequeue_mgmt(ieee
))){
2889 header
= (struct ieee80211_hdr_3addr
*) skb
->data
;
2891 header
->seq_ctl
= cpu_to_le16(ieee
->seq_ctrl
[0] << 4);
2893 if (ieee
->seq_ctrl
[0] == 0xFFF)
2894 ieee
->seq_ctrl
[0] = 0;
2896 ieee
->seq_ctrl
[0]++;
2898 //printk(KERN_ALERT "ieee80211_wake_queue \n");
2899 ieee
->softmac_data_hard_start_xmit(skb
,ieee
->dev
,ieee
->basic_rate
);
2900 dev_kfree_skb_any(skb
);//edit by thomas
2903 if (!ieee
->queue_stop
&& ieee
->tx_pending
.txb
)
2904 ieee80211_resume_tx(ieee
);
2906 if (!ieee
->queue_stop
&& netif_queue_stopped(ieee
->dev
)){
2907 ieee
->softmac_stats
.swtxawake
++;
2908 netif_wake_queue(ieee
->dev
);
2912 spin_unlock_irqrestore(&ieee
->lock
,flags
);
2916 void ieee80211_stop_queue(struct ieee80211_device
*ieee
)
2918 //unsigned long flags;
2919 //spin_lock_irqsave(&ieee->lock,flags);
2921 if (! netif_queue_stopped(ieee
->dev
)){
2922 netif_stop_queue(ieee
->dev
);
2923 ieee
->softmac_stats
.swtxstop
++;
2925 ieee
->queue_stop
= 1;
2926 //spin_unlock_irqrestore(&ieee->lock,flags);
2931 inline void ieee80211_randomize_cell(struct ieee80211_device
*ieee
)
2934 get_random_bytes(ieee
->current_network
.bssid
, ETH_ALEN
);
2936 /* an IBSS cell address must have the two less significant
2937 * bits of the first byte = 2
2939 ieee
->current_network
.bssid
[0] &= ~0x01;
2940 ieee
->current_network
.bssid
[0] |= 0x02;
2943 /* called in user context only */
2944 void ieee80211_start_master_bss(struct ieee80211_device
*ieee
)
2948 if (ieee
->current_network
.ssid_len
== 0){
2949 strncpy(ieee
->current_network
.ssid
,
2950 IEEE80211_DEFAULT_TX_ESSID
,
2953 ieee
->current_network
.ssid_len
= strlen(IEEE80211_DEFAULT_TX_ESSID
);
2957 memcpy(ieee
->current_network
.bssid
, ieee
->dev
->dev_addr
, ETH_ALEN
);
2959 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
2960 ieee
->state
= IEEE80211_LINKED
;
2961 ieee
->link_change(ieee
->dev
);
2962 notify_wx_assoc_event(ieee
);
2964 if (ieee
->data_hard_resume
)
2965 ieee
->data_hard_resume(ieee
->dev
);
2967 netif_carrier_on(ieee
->dev
);
2970 void ieee80211_start_monitor_mode(struct ieee80211_device
*ieee
)
2974 if (ieee
->data_hard_resume
)
2975 ieee
->data_hard_resume(ieee
->dev
);
2977 netif_carrier_on(ieee
->dev
);
2980 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2981 void ieee80211_start_ibss_wq(struct work_struct
*work
)
2983 struct delayed_work
*dwork
= container_of(work
, struct delayed_work
, work
);
2984 struct ieee80211_device
*ieee
= container_of(dwork
, struct ieee80211_device
, start_ibss_wq
);
2986 void ieee80211_start_ibss_wq(struct ieee80211_device
*ieee
)
2990 /* iwconfig mode ad-hoc will schedule this and return
2991 * on the other hand this will block further iwconfig SET
2992 * operations because of the wx_sem hold.
2993 * Anyway some most set operations set a flag to speed-up
2994 * (abort) this wq (when syncro scanning) before sleeping
2998 down(&ieee
->wx_sem
);
3001 if (ieee
->current_network
.ssid_len
== 0){
3002 strcpy(ieee
->current_network
.ssid
,IEEE80211_DEFAULT_TX_ESSID
);
3003 ieee
->current_network
.ssid_len
= strlen(IEEE80211_DEFAULT_TX_ESSID
);
3007 /* check if we have this cell in our network list */
3008 ieee80211_softmac_check_all_nets(ieee
);
3010 #ifdef ENABLE_DOT11D
3011 if(ieee
->state
== IEEE80211_NOLINK
)
3012 ieee
->current_network
.channel
= 10;
3014 /* if not then the state is not linked. Maybe the user swithced to
3015 * ad-hoc mode just after being in monitor mode, or just after
3016 * being very few time in managed mode (so the card have had no
3017 * time to scan all the chans..) or we have just run up the iface
3018 * after setting ad-hoc mode. So we have to give another try..
3019 * Here, in ibss mode, should be safe to do this without extra care
3020 * (in bss mode we had to make sure no-one tryed to associate when
3021 * we had just checked the ieee->state and we was going to start the
3022 * scan) beacause in ibss mode the ieee80211_new_net function, when
3023 * finds a good net, just set the ieee->state to IEEE80211_LINKED,
3024 * so, at worst, we waste a bit of time to initiate an unneeded syncro
3025 * scan, that will stop at the first round because it sees the state
3028 if (ieee
->state
== IEEE80211_NOLINK
)
3029 ieee80211_start_scan_syncro(ieee
);
3031 /* the network definitively is not here.. create a new cell */
3032 if (ieee
->state
== IEEE80211_NOLINK
){
3033 printk("creating new IBSS cell\n");
3035 ieee80211_randomize_cell(ieee
);
3037 if(ieee
->modulation
& IEEE80211_CCK_MODULATION
){
3039 ieee
->current_network
.rates_len
= 4;
3041 ieee
->current_network
.rates
[0] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_1MB
;
3042 ieee
->current_network
.rates
[1] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_2MB
;
3043 ieee
->current_network
.rates
[2] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_5MB
;
3044 ieee
->current_network
.rates
[3] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_11MB
;
3047 ieee
->current_network
.rates_len
= 0;
3049 if(ieee
->modulation
& IEEE80211_OFDM_MODULATION
){
3050 ieee
->current_network
.rates_ex_len
= 8;
3052 ieee
->current_network
.rates_ex
[0] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_6MB
;
3053 ieee
->current_network
.rates_ex
[1] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_9MB
;
3054 ieee
->current_network
.rates_ex
[2] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_12MB
;
3055 ieee
->current_network
.rates_ex
[3] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_18MB
;
3056 ieee
->current_network
.rates_ex
[4] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_24MB
;
3057 ieee
->current_network
.rates_ex
[5] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_36MB
;
3058 ieee
->current_network
.rates_ex
[6] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_48MB
;
3059 ieee
->current_network
.rates_ex
[7] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_54MB
;
3063 ieee
->current_network
.rates_ex_len
= 0;
3067 // By default, WMM function will be disabled in IBSS mode
3068 ieee
->current_network
.QoS_Enable
= 0;
3070 ieee
->current_network
.atim_window
= 0;
3071 ieee
->current_network
.capability
= WLAN_CAPABILITY_IBSS
;
3072 if(ieee
->short_slot
)
3073 ieee
->current_network
.capability
|= WLAN_CAPABILITY_SHORT_SLOT
;
3077 ieee
->state
= IEEE80211_LINKED
;
3078 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
3079 ieee
->link_change(ieee
->dev
);
3081 notify_wx_assoc_event(ieee
);
3083 ieee80211_start_send_beacons(ieee
);
3084 printk(KERN_WARNING
"after sending beacon packet!\n");
3086 if (ieee
->data_hard_resume
)
3087 ieee
->data_hard_resume(ieee
->dev
);
3089 netif_carrier_on(ieee
->dev
);
3093 inline void ieee80211_start_ibss(struct ieee80211_device
*ieee
)
3095 queue_delayed_work(ieee
->wq
, &ieee
->start_ibss_wq
, 100);
3098 /* this is called only in user context, with wx_sem held */
3099 void ieee80211_start_bss(struct ieee80211_device
*ieee
)
3101 unsigned long flags
;
3102 #ifdef ENABLE_DOT11D
3104 // Ref: 802.11d 11.1.3.3
3105 // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
3107 if(IS_DOT11D_ENABLE(ieee
) && !IS_COUNTRY_IE_VALID(ieee
))
3109 if(! ieee
->bGlobalDomain
)
3115 /* check if we have already found the net we
3116 * are interested in (if any).
3117 * if not (we are disassociated and we are not
3118 * in associating / authenticating phase) start the background scanning.
3120 ieee80211_softmac_check_all_nets(ieee
);
3122 /* ensure no-one start an associating process (thus setting
3123 * the ieee->state to ieee80211_ASSOCIATING) while we
3124 * have just cheked it and we are going to enable scan.
3125 * The ieee80211_new_net function is always called with
3126 * lock held (from both ieee80211_softmac_check_all_nets and
3127 * the rx path), so we cannot be in the middle of such function
3129 spin_lock_irqsave(&ieee
->lock
, flags
);
3132 // printk("start bss ENABLE_IPS\n");
3134 if (ieee
->state
== IEEE80211_NOLINK
){
3135 ieee
->actscanning
= true;
3136 ieee80211_start_scan(ieee
);
3139 spin_unlock_irqrestore(&ieee
->lock
, flags
);
3142 /* called only in userspace context */
3143 void ieee80211_disassociate(struct ieee80211_device
*ieee
)
3145 netif_carrier_off(ieee
->dev
);
3147 if (ieee
->softmac_features
& IEEE_SOFTMAC_TX_QUEUE
)
3148 ieee80211_reset_queue(ieee
);
3150 if (ieee
->data_hard_stop
)
3151 ieee
->data_hard_stop(ieee
->dev
);
3153 #ifdef ENABLE_DOT11D
3154 if(IS_DOT11D_ENABLE(ieee
))
3157 ieee
->state
= IEEE80211_NOLINK
;
3158 ieee
->link_change(ieee
->dev
);
3159 notify_wx_assoc_event(ieee
);
3162 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
3163 void ieee80211_associate_retry_wq(struct work_struct
*work
)
3165 struct delayed_work
*dwork
= container_of(work
, struct delayed_work
, work
);
3166 struct ieee80211_device
*ieee
= container_of(dwork
, struct ieee80211_device
, associate_retry_wq
);
3168 void ieee80211_associate_retry_wq(struct ieee80211_device
*ieee
)
3171 unsigned long flags
;
3172 down(&ieee
->wx_sem
);
3173 if(!ieee
->proto_started
)
3175 if(ieee
->state
!= IEEE80211_ASSOCIATING_RETRY
)
3177 /* until we do not set the state to IEEE80211_NOLINK
3178 * there are no possibility to have someone else trying
3179 * to start an association procdure (we get here with
3180 * ieee->state = IEEE80211_ASSOCIATING).
3181 * When we set the state to IEEE80211_NOLINK it is possible
3182 * that the RX path run an attempt to associate, but
3183 * both ieee80211_softmac_check_all_nets and the
3184 * RX path works with ieee->lock held so there are no
3185 * problems. If we are still disassociated then start a scan.
3186 * the lock here is necessary to ensure no one try to start
3187 * an association procedure when we have just checked the
3188 * state and we are going to start the scan.
3190 ieee
->state
= IEEE80211_NOLINK
;
3191 ieee
->beinretry
= true;
3192 ieee80211_softmac_check_all_nets(ieee
);
3194 spin_lock_irqsave(&ieee
->lock
, flags
);
3196 if(ieee
->state
== IEEE80211_NOLINK
){
3197 ieee
->beinretry
= false;
3198 ieee
->actscanning
= true;
3199 ieee80211_start_scan(ieee
);
3201 //YJ,add,080828, notify os here
3202 if(ieee
->state
== IEEE80211_NOLINK
)
3204 notify_wx_assoc_event(ieee
);
3207 spin_unlock_irqrestore(&ieee
->lock
, flags
);
3213 struct sk_buff
*ieee80211_get_beacon_(struct ieee80211_device
*ieee
)
3215 u8 broadcast_addr
[] = {0xff,0xff,0xff,0xff,0xff,0xff};
3217 struct sk_buff
*skb
= NULL
;
3218 struct ieee80211_probe_response
*b
;
3221 #ifdef _RTL8187_EXT_PATCH_
3222 if((ieee
->iw_mode
== ieee
->iw_ext_mode
) && ieee
->ext_patch_get_beacon_get_probersp
)
3223 skb
= ieee
->ext_patch_get_beacon_get_probersp(ieee
, broadcast_addr
, &(ieee
->current_network
));
3225 skb
= ieee80211_probe_resp(ieee
, broadcast_addr
);
3227 skb
= ieee80211_probe_resp(ieee
, broadcast_addr
);
3233 b
= (struct ieee80211_probe_response
*) skb
->data
;
3234 b
->header
.frame_ctl
= cpu_to_le16(IEEE80211_STYPE_BEACON
);
3240 struct sk_buff
*ieee80211_get_beacon(struct ieee80211_device
*ieee
)
3242 struct sk_buff
*skb
;
3243 struct ieee80211_probe_response
*b
;
3245 skb
= ieee80211_get_beacon_(ieee
);
3249 b
= (struct ieee80211_probe_response
*) skb
->data
;
3250 b
->header
.seq_ctrl
= cpu_to_le16(ieee
->seq_ctrl
[0] << 4);
3252 if (ieee
->seq_ctrl
[0] == 0xFFF)
3253 ieee
->seq_ctrl
[0] = 0;
3255 ieee
->seq_ctrl
[0]++;
3260 void ieee80211_softmac_stop_protocol(struct ieee80211_device
*ieee
)
3262 ieee
->sync_scan_hurryup
= 1;
3263 down(&ieee
->wx_sem
);
3264 ieee80211_stop_protocol(ieee
);
3269 void ieee80211_stop_protocol(struct ieee80211_device
*ieee
)
3271 if (!ieee
->proto_started
)
3274 ieee
->proto_started
= 0;
3276 #ifdef _RTL8187_EXT_PATCH_
3277 if(ieee
->ext_patch_ieee80211_stop_protocol
)
3278 ieee
->ext_patch_ieee80211_stop_protocol(ieee
);
3279 //if call queue_delayed_work,can call this,or do nothing..
3280 //edit by lawrence,20071118
3281 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3282 // cancel_delayed_work(&ieee->ext_stop_scan_wq);
3283 // cancel_delayed_work(&ieee->ext_send_beacon_wq);
3285 #endif // _RTL8187_EXT_PATCH_
3287 ieee80211_stop_send_beacons(ieee
);
3288 if((ieee
->iw_mode
== IW_MODE_INFRA
)&&(ieee
->state
== IEEE80211_LINKED
)) {
3289 SendDisassociation(ieee
,NULL
,WLAN_REASON_DISASSOC_STA_HAS_LEFT
);
3291 del_timer_sync(&ieee
->associate_timer
);
3292 cancel_delayed_work(&ieee
->associate_retry_wq
);
3293 cancel_delayed_work(&ieee
->start_ibss_wq
);
3294 ieee80211_stop_scan(ieee
);
3296 ieee80211_disassociate(ieee
);
3299 void ieee80211_softmac_start_protocol(struct ieee80211_device
*ieee
)
3301 ieee
->sync_scan_hurryup
= 0;
3302 down(&ieee
->wx_sem
);
3303 ieee80211_start_protocol(ieee
);
3307 void ieee80211_start_protocol(struct ieee80211_device
*ieee
)
3312 if (ieee
->proto_started
)
3315 ieee
->proto_started
= 1;
3317 if (ieee
->current_network
.channel
== 0){
3320 if (ch
> MAX_CHANNEL_NUMBER
)
3321 return; /* no channel found */
3323 #ifdef ENABLE_DOT11D
3324 }while(!GET_DOT11D_INFO(ieee
)->channel_map
[ch
]);
3326 }while(!ieee
->channel_map
[ch
]);
3329 ieee
->current_network
.channel
= ch
;
3332 if (ieee
->current_network
.beacon_interval
== 0)
3333 ieee
->current_network
.beacon_interval
= 100;
3334 ieee
->set_chan(ieee
->dev
,ieee
->current_network
.channel
);
3336 for(i
= 0; i
< 17; i
++) {
3337 ieee
->last_rxseq_num
[i
] = -1;
3338 ieee
->last_rxfrag_num
[i
] = -1;
3339 ieee
->last_packet_time
[i
] = 0;
3342 ieee
->init_wmmparam_flag
= 0;//reinitialize AC_xx_PARAM registers.
3345 /* if the user set the MAC of the ad-hoc cell and then
3346 * switch to managed mode, shall we make sure that association
3347 * attempts does not fail just because the user provide the essid
3348 * and the nic is still checking for the AP MAC ??
3350 switch (ieee
->iw_mode
) {
3352 ieee
->iw_mode
= IW_MODE_INFRA
;
3353 //not set break here intentionly
3355 ieee80211_start_bss(ieee
);
3359 ieee80211_start_ibss(ieee
);
3362 case IW_MODE_MASTER
:
3363 ieee80211_start_master_bss(ieee
);
3366 case IW_MODE_MONITOR
:
3367 ieee80211_start_monitor_mode(ieee
);
3371 #ifdef _RTL8187_EXT_PATCH_
3372 if((ieee
->iw_mode
== ieee
->iw_ext_mode
) &&\
3373 ieee
->ext_patch_ieee80211_start_protocol
&&\
3374 ieee
->ext_patch_ieee80211_start_protocol(ieee
)) {
3375 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
3376 queue_work(ieee
->wq
, &ieee
->ext_stop_scan_wq
);
3378 // By default, WMM function will be disabled in
3380 ieee
->current_network
.QoS_Enable
= 0;
3382 if(ieee
->modulation
& IEEE80211_CCK_MODULATION
){
3383 ieee
->current_network
.rates_len
= 4;
3384 ieee
->current_network
.rates
[0] = \
3385 IEEE80211_BASIC_RATE_MASK
| \
3386 IEEE80211_CCK_RATE_1MB
;
3387 ieee
->current_network
.rates
[1] = \
3388 IEEE80211_BASIC_RATE_MASK
|\
3389 IEEE80211_CCK_RATE_2MB
;
3390 ieee
->current_network
.rates
[2] = \
3391 IEEE80211_BASIC_RATE_MASK
|\
3392 IEEE80211_CCK_RATE_5MB
;
3393 ieee
->current_network
.rates
[3] = \
3394 IEEE80211_BASIC_RATE_MASK
|\
3395 IEEE80211_CCK_RATE_11MB
;
3397 ieee
->current_network
.rates_len
= 0;
3399 if(ieee
->modulation
& IEEE80211_OFDM_MODULATION
){
3400 ieee
->current_network
.rates_ex_len
= 8;
3401 ieee
->current_network
.rates_ex
[0] = \
3402 IEEE80211_BASIC_RATE_MASK
|\
3403 IEEE80211_OFDM_RATE_6MB
;
3404 ieee
->current_network
.rates_ex
[1] = \
3405 IEEE80211_BASIC_RATE_MASK
|\
3406 IEEE80211_OFDM_RATE_9MB
;
3407 ieee
->current_network
.rates_ex
[2] = \
3408 IEEE80211_BASIC_RATE_MASK
|\
3409 IEEE80211_OFDM_RATE_12MB
;
3410 ieee
->current_network
.rates_ex
[3] = \
3411 IEEE80211_BASIC_RATE_MASK
| \
3412 IEEE80211_OFDM_RATE_18MB
;
3413 ieee
->current_network
.rates_ex
[4] =\
3414 IEEE80211_BASIC_RATE_MASK
|\
3415 IEEE80211_OFDM_RATE_24MB
;
3416 ieee
->current_network
.rates_ex
[5] =\
3417 IEEE80211_BASIC_RATE_MASK
|\
3418 IEEE80211_OFDM_RATE_36MB
;
3419 ieee
->current_network
.rates_ex
[6] = \
3420 IEEE80211_BASIC_RATE_MASK
|\
3421 IEEE80211_OFDM_RATE_48MB
;
3422 ieee
->current_network
.rates_ex
[7] =\
3423 IEEE80211_BASIC_RATE_MASK
|\
3424 IEEE80211_OFDM_RATE_54MB
;
3427 ieee
->current_network
.rates_ex_len
= 0;
3432 spin_lock_irqsave(&ieee->lock, flags);
3433 if (ieee->state == IEEE80211_NOLINK)
3434 ieee80211_start_scan(ieee);
3435 // ieee->set_chan(ieee->dev, 8);
3437 spin_unlock_irqrestore(&ieee->lock, flags);
3439 memcpy(ieee
->current_network
.bssid
, ieee
->dev
->dev_addr
,\
3441 ieee
->link_change(ieee
->dev
);
3442 notify_wx_assoc_event(ieee
);
3444 if (ieee
->data_hard_resume
)
3445 ieee
->data_hard_resume(ieee
->dev
);
3447 netif_carrier_on(ieee
->dev
);
3449 ieee
->iw_mode
= IW_MODE_INFRA
;
3450 ieee80211_start_bss(ieee
);
3453 ieee
->iw_mode
= IW_MODE_INFRA
;
3454 ieee80211_start_bss(ieee
);
3462 #define DRV_NAME "Ieee80211"
3463 void ieee80211_softmac_init(struct ieee80211_device
*ieee
)
3466 memset(&ieee
->current_network
, 0, sizeof(struct ieee80211_network
));
3468 ieee
->state
= IEEE80211_NOLINK
;
3469 ieee
->sync_scan_hurryup
= 0;
3470 for(i
= 0; i
< 5; i
++) {
3471 ieee
->seq_ctrl
[i
] = 0;
3475 ieee
->queue_stop
= 0;
3477 ieee
->softmac_features
= 0; //so IEEE2100-like driver are happy
3480 ieee
->proto_started
= 0;
3481 ieee
->basic_rate
= IEEE80211_DEFAULT_BASIC_RATE
;
3484 ieee
->ps
= IEEE80211_PS_MBCAST
|IEEE80211_PS_UNICAST
;
3486 // ieee->ps = IEEE80211_PS_DISABLED;
3488 ieee
->sta_sleep
= 0;
3490 ieee
->bInactivePs
= false;
3491 ieee
->actscanning
= false;
3492 ieee
->ListenInterval
= 2;
3493 ieee
->NumRxDataInPeriod
= 0; //YJ,add,080828
3494 ieee
->NumRxBcnInPeriod
= 0; //YJ,add,080828
3495 ieee
->NumRxOkTotal
= 0;//+by amy 080312
3496 ieee
->NumRxUnicast
= 0;//YJ,add,080828,for keep alive
3497 ieee
->beinretry
= false;
3498 ieee
->bHwRadioOff
= false;
3500 #ifdef _RTL8187_EXT_PATCH_
3501 ieee
->iw_ext_mode
= 999;
3504 init_mgmt_queue(ieee
);
3506 init_timer(&ieee
->scan_timer
);
3507 ieee
->scan_timer
.data
= (unsigned long)ieee
;
3508 ieee
->scan_timer
.function
= ieee80211_softmac_scan_cb
;
3510 ieee
->tx_pending
.txb
= NULL
;
3512 init_timer(&ieee
->associate_timer
);
3513 ieee
->associate_timer
.data
= (unsigned long)ieee
;
3514 ieee
->associate_timer
.function
= ieee80211_associate_abort_cb
;
3516 init_timer(&ieee
->beacon_timer
);
3517 ieee
->beacon_timer
.data
= (unsigned long) ieee
;
3518 ieee
->beacon_timer
.function
= ieee80211_send_beacon_cb
;
3520 #ifdef PF_SYNCTHREAD
3521 ieee
->wq
= create_workqueue(DRV_NAME
,0);
3523 ieee
->wq
= create_workqueue(DRV_NAME
);
3525 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)//added by lawrence,070702
3526 INIT_DELAYED_WORK(&ieee
->start_ibss_wq
,(void*) ieee80211_start_ibss_wq
);
3527 INIT_WORK(&ieee
->associate_complete_wq
,(void*) ieee80211_associate_complete_wq
);
3528 INIT_WORK(&ieee
->associate_procedure_wq
,(void*) ieee80211_associate_procedure_wq
);
3529 INIT_DELAYED_WORK(&ieee
->softmac_scan_wq
,(void*) ieee80211_softmac_scan_wq
);
3530 INIT_DELAYED_WORK(&ieee
->associate_retry_wq
,(void*) ieee80211_associate_retry_wq
);
3531 INIT_WORK(&ieee
->wx_sync_scan_wq
,(void*) ieee80211_wx_sync_scan_wq
);
3532 // INIT_WORK(&ieee->watch_dog_wq,(void*) ieee80211_watch_dog_wq);
3533 //added by lawrence,20071118
3534 #ifdef _RTL8187_EXT_PATCH_
3535 INIT_WORK(&ieee
->ext_stop_scan_wq
,(void*) ieee80211_ext_stop_scan_wq
);
3536 //INIT_WORK(&ieee->ext_send_beacon_wq,(void*) ieee80211_beacons_start,ieee);
3537 INIT_WORK(&ieee
->ext_send_beacon_wq
,(void*) ext_ieee80211_send_beacon_wq
);
3538 #endif //_RTL8187_EXT_PATCH_
3540 INIT_WORK(&ieee
->start_ibss_wq
,(void*) ieee80211_start_ibss_wq
,ieee
);
3541 INIT_WORK(&ieee
->associate_retry_wq
,(void*) ieee80211_associate_retry_wq
,ieee
);
3542 INIT_WORK(&ieee
->associate_complete_wq
,(void*) ieee80211_associate_complete_wq
,ieee
);
3543 INIT_WORK(&ieee
->associate_procedure_wq
,(void*) ieee80211_associate_procedure_wq
,ieee
);
3544 INIT_WORK(&ieee
->softmac_scan_wq
,(void*) ieee80211_softmac_scan_wq
,ieee
);
3545 INIT_WORK(&ieee
->wx_sync_scan_wq
,(void*) ieee80211_wx_sync_scan_wq
,ieee
);
3546 // INIT_WORK(&ieee->watch_dog_wq,(void*) ieee80211_watch_dog_wq,ieee);
3547 #ifdef _RTL8187_EXT_PATCH_
3548 INIT_WORK(&ieee
->ext_stop_scan_wq
,(void*) ieee80211_ext_stop_scan_wq
,ieee
);
3549 //INIT_WORK(&ieee->ext_send_beacon_wq,(void*) ieee80211_beacons_start,ieee);
3550 INIT_WORK(&ieee
->ext_send_beacon_wq
,(void*) ext_ieee80211_send_beacon_wq
,ieee
);
3553 sema_init(&ieee
->wx_sem
, 1);
3554 sema_init(&ieee
->scan_sem
, 1);
3556 spin_lock_init(&ieee
->mgmt_tx_lock
);
3557 spin_lock_init(&ieee
->beacon_lock
);
3559 tasklet_init(&ieee
->ps_task
,
3560 (void(*)(unsigned long)) ieee80211_sta_ps
,
3561 (unsigned long)ieee
);
3562 #ifdef ENABLE_DOT11D
3563 ieee
->pDot11dInfo
= kmalloc(sizeof(RT_DOT11D_INFO
), GFP_ATOMIC
);
3567 void ieee80211_softmac_free(struct ieee80211_device
*ieee
)
3569 down(&ieee
->wx_sem
);
3571 del_timer_sync(&ieee
->associate_timer
);
3572 cancel_delayed_work(&ieee
->associate_retry_wq
);
3575 //add for RF power on power of by lizhaoming 080512
3576 cancel_delayed_work(&ieee
->GPIOChangeRFWorkItem
);
3578 #ifdef _RTL8187_EXT_PATCH_
3579 cancel_delayed_work(&ieee
->ext_stop_scan_wq
);
3580 cancel_delayed_work(&ieee
->ext_send_beacon_wq
);
3582 destroy_workqueue(ieee
->wq
);
3583 #ifdef ENABLE_DOT11D
3584 if(NULL
!= ieee
->pDot11dInfo
)
3585 kfree(ieee
->pDot11dInfo
);
3590 /********************************************************
3591 * Start of WPA code. *
3592 * this is stolen from the ipw2200 driver *
3593 ********************************************************/
3596 static int ieee80211_wpa_enable(struct ieee80211_device
*ieee
, int value
)
3598 /* This is called when wpa_supplicant loads and closes the driver
3600 printk("%s WPA\n",value
? "enabling" : "disabling");
3601 ieee
->wpa_enabled
= value
;
3606 void ieee80211_wpa_assoc_frame(struct ieee80211_device
*ieee
, char *wpa_ie
, int wpa_ie_len
)
3608 /* make sure WPA is enabled */
3609 ieee80211_wpa_enable(ieee
, 1);
3611 ieee80211_disassociate(ieee
);
3615 static int ieee80211_wpa_mlme(struct ieee80211_device
*ieee
, int command
, int reason
)
3621 case IEEE_MLME_STA_DEAUTH
:
3625 case IEEE_MLME_STA_DISASSOC
:
3626 ieee80211_disassociate(ieee
);
3630 printk("Unknown MLME request: %d\n", command
);
3638 static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device
*ieee
,
3639 struct ieee_param
*param
, int plen
)
3643 if (param
->u
.wpa_ie
.len
> MAX_WPA_IE_LEN
||
3644 (param
->u
.wpa_ie
.len
&& param
->u
.wpa_ie
.data
== NULL
))
3647 if (param
->u
.wpa_ie
.len
) {
3648 buf
= kmalloc(param
->u
.wpa_ie
.len
, GFP_KERNEL
);
3652 memcpy(buf
, param
->u
.wpa_ie
.data
, param
->u
.wpa_ie
.len
);
3653 kfree(ieee
->wpa_ie
);
3655 ieee
->wpa_ie_len
= param
->u
.wpa_ie
.len
;
3657 kfree(ieee
->wpa_ie
);
3658 ieee
->wpa_ie
= NULL
;
3659 ieee
->wpa_ie_len
= 0;
3662 ieee80211_wpa_assoc_frame(ieee
, ieee
->wpa_ie
, ieee
->wpa_ie_len
);
3666 #define AUTH_ALG_OPEN_SYSTEM 0x1
3667 #define AUTH_ALG_SHARED_KEY 0x2
3669 static int ieee80211_wpa_set_auth_algs(struct ieee80211_device
*ieee
, int value
)
3672 struct ieee80211_security sec
= {
3673 .flags
= SEC_AUTH_MODE
,
3677 if (value
& AUTH_ALG_SHARED_KEY
) {
3678 sec
.auth_mode
= WLAN_AUTH_SHARED_KEY
;
3681 sec
.auth_mode
= WLAN_AUTH_OPEN
;
3685 if (ieee
->set_security
)
3686 ieee
->set_security(ieee
->dev
, &sec
);
3693 static int ieee80211_wpa_set_param(struct ieee80211_device
*ieee
, u8 name
, u32 value
)
3696 unsigned long flags
;
3699 case IEEE_PARAM_WPA_ENABLED
:
3700 ret
= ieee80211_wpa_enable(ieee
, value
);
3703 case IEEE_PARAM_TKIP_COUNTERMEASURES
:
3704 ieee
->tkip_countermeasures
=value
;
3707 case IEEE_PARAM_DROP_UNENCRYPTED
: {
3710 * wpa_supplicant calls set_wpa_enabled when the driver
3711 * is loaded and unloaded, regardless of if WPA is being
3712 * used. No other calls are made which can be used to
3713 * determine if encryption will be used or not prior to
3714 * association being expected. If encryption is not being
3715 * used, drop_unencrypted is set to false, else true -- we
3716 * can use this to determine if the CAP_PRIVACY_ON bit should
3719 struct ieee80211_security sec
= {
3720 .flags
= SEC_ENABLED
,
3723 ieee
->drop_unencrypted
= value
;
3724 /* We only change SEC_LEVEL for open mode. Others
3725 * are set by ipw_wpa_set_encryption.
3728 sec
.flags
|= SEC_LEVEL
;
3729 sec
.level
= SEC_LEVEL_0
;
3732 sec
.flags
|= SEC_LEVEL
;
3733 sec
.level
= SEC_LEVEL_1
;
3735 if (ieee
->set_security
)
3736 ieee
->set_security(ieee
->dev
, &sec
);
3740 case IEEE_PARAM_PRIVACY_INVOKED
:
3741 ieee
->privacy_invoked
=value
;
3744 case IEEE_PARAM_AUTH_ALGS
:
3745 ret
= ieee80211_wpa_set_auth_algs(ieee
, value
);
3748 case IEEE_PARAM_IEEE_802_1X
:
3749 ieee
->ieee802_1x
=value
;
3751 case IEEE_PARAM_WPAX_SELECT
:
3752 // added for WPA2 mixed mode
3753 //printk(KERN_WARNING "------------------------>wpax value = %x\n", value);
3754 spin_lock_irqsave(&ieee
->wpax_suitlist_lock
,flags
);
3755 ieee
->wpax_type_set
= 1;
3756 ieee
->wpax_type_notify
= value
;
3757 spin_unlock_irqrestore(&ieee
->wpax_suitlist_lock
,flags
);
3761 printk("Unknown WPA param: %d\n",name
);
3768 /* implementation borrowed from hostap driver */
3770 static int ieee80211_wpa_set_encryption(struct ieee80211_device
*ieee
,
3771 struct ieee_param
*param
, int param_len
)
3775 struct ieee80211_crypto_ops
*ops
;
3776 struct ieee80211_crypt_data
**crypt
;
3778 struct ieee80211_security sec
= {
3782 param
->u
.crypt
.err
= 0;
3783 param
->u
.crypt
.alg
[IEEE_CRYPT_ALG_NAME_LEN
- 1] = '\0';
3786 (int) ((char *) param
->u
.crypt
.key
- (char *) param
) +
3787 param
->u
.crypt
.key_len
) {
3788 printk("Len mismatch %d, %d\n", param_len
,
3789 param
->u
.crypt
.key_len
);
3792 if (param
->sta_addr
[0] == 0xff && param
->sta_addr
[1] == 0xff &&
3793 param
->sta_addr
[2] == 0xff && param
->sta_addr
[3] == 0xff &&
3794 param
->sta_addr
[4] == 0xff && param
->sta_addr
[5] == 0xff) {
3795 if (param
->u
.crypt
.idx
>= WEP_KEYS
)
3797 crypt
= &ieee
->crypt
[param
->u
.crypt
.idx
];
3802 if (strcmp(param
->u
.crypt
.alg
, "none") == 0) {
3807 sec
.level
= SEC_LEVEL_0
;
3808 sec
.flags
|= SEC_ENABLED
| SEC_LEVEL
;
3809 ieee80211_crypt_delayed_deinit(ieee
, crypt
);
3816 sec
.flags
|= SEC_ENABLED
;
3818 /* IPW HW cannot build TKIP MIC, host decryption still needed. */
3819 if (!(ieee
->host_encrypt
|| ieee
->host_decrypt
) &&
3820 strcmp(param
->u
.crypt
.alg
, "TKIP"))
3821 goto skip_host_crypt
;
3823 ops
= ieee80211_get_crypto_ops(param
->u
.crypt
.alg
);
3824 if (ops
== NULL
&& strcmp(param
->u
.crypt
.alg
, "WEP") == 0) {
3825 request_module("ieee80211_crypt_wep");
3826 ops
= ieee80211_get_crypto_ops(param
->u
.crypt
.alg
);
3827 } else if (ops
== NULL
&& strcmp(param
->u
.crypt
.alg
, "TKIP") == 0) {
3828 request_module("ieee80211_crypt_tkip");
3829 ops
= ieee80211_get_crypto_ops(param
->u
.crypt
.alg
);
3830 } else if (ops
== NULL
&& strcmp(param
->u
.crypt
.alg
, "CCMP") == 0) {
3831 request_module("ieee80211_crypt_ccmp");
3832 ops
= ieee80211_get_crypto_ops(param
->u
.crypt
.alg
);
3835 printk("unknown crypto alg '%s'\n", param
->u
.crypt
.alg
);
3836 param
->u
.crypt
.err
= IEEE_CRYPT_ERR_UNKNOWN_ALG
;
3841 if (*crypt
== NULL
|| (*crypt
)->ops
!= ops
) {
3842 struct ieee80211_crypt_data
*new_crypt
;
3844 ieee80211_crypt_delayed_deinit(ieee
, crypt
);
3846 new_crypt
= (struct ieee80211_crypt_data
*)
3847 kmalloc(sizeof(*new_crypt
), GFP_KERNEL
);
3848 if (new_crypt
== NULL
) {
3852 memset(new_crypt
, 0, sizeof(struct ieee80211_crypt_data
));
3853 new_crypt
->ops
= ops
;
3854 if (new_crypt
->ops
&& try_module_get(new_crypt
->ops
->owner
))
3856 new_crypt
->ops
->init(param
->u
.crypt
.idx
);
3858 if (new_crypt
->priv
== NULL
) {
3860 param
->u
.crypt
.err
= IEEE_CRYPT_ERR_CRYPT_INIT_FAILED
;
3868 if (param
->u
.crypt
.key_len
> 0 && (*crypt
)->ops
->set_key
&&
3869 (*crypt
)->ops
->set_key(param
->u
.crypt
.key
,
3870 param
->u
.crypt
.key_len
, param
->u
.crypt
.seq
,
3871 (*crypt
)->priv
) < 0) {
3872 printk("key setting failed\n");
3873 param
->u
.crypt
.err
= IEEE_CRYPT_ERR_KEY_SET_FAILED
;
3879 if (param
->u
.crypt
.set_tx
) {
3880 ieee
->tx_keyidx
= param
->u
.crypt
.idx
;
3881 sec
.active_key
= param
->u
.crypt
.idx
;
3882 sec
.flags
|= SEC_ACTIVE_KEY
;
3884 sec
.flags
&= ~SEC_ACTIVE_KEY
;
3886 if (param
->u
.crypt
.alg
!= NULL
) {
3887 memcpy(sec
.keys
[param
->u
.crypt
.idx
],
3889 param
->u
.crypt
.key_len
);
3890 sec
.key_sizes
[param
->u
.crypt
.idx
] = param
->u
.crypt
.key_len
;
3891 sec
.flags
|= (1 << param
->u
.crypt
.idx
);
3893 if (strcmp(param
->u
.crypt
.alg
, "WEP") == 0) {
3894 sec
.flags
|= SEC_LEVEL
;
3895 sec
.level
= SEC_LEVEL_1
;
3896 } else if (strcmp(param
->u
.crypt
.alg
, "TKIP") == 0) {
3897 sec
.flags
|= SEC_LEVEL
;
3898 sec
.level
= SEC_LEVEL_2
;
3899 } else if (strcmp(param
->u
.crypt
.alg
, "CCMP") == 0) {
3900 sec
.flags
|= SEC_LEVEL
;
3901 sec
.level
= SEC_LEVEL_3
;
3905 if (ieee
->set_security
)
3906 ieee
->set_security(ieee
->dev
, &sec
);
3908 /* Do not reset port if card is in Managed mode since resetting will
3909 * generate new IEEE 802.11 authentication which may end up in looping
3910 * with IEEE 802.1X. If your hardware requires a reset after WEP
3911 * configuration (for example... Prism2), implement the reset_port in
3912 * the callbacks structures used to initialize the 802.11 stack. */
3913 if (ieee
->reset_on_keychange
&&
3914 ieee
->iw_mode
!= IW_MODE_INFRA
&&
3916 ieee
->reset_port(ieee
->dev
)) {
3917 printk("reset_port failed\n");
3918 param
->u
.crypt
.err
= IEEE_CRYPT_ERR_CARD_CONF_FAILED
;
3925 int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device
*ieee
, struct iw_point
*p
)
3927 struct ieee_param
*param
;
3930 down(&ieee
->wx_sem
);
3931 //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
3933 if (p
->length
< sizeof(struct ieee_param
) || !p
->pointer
){
3938 param
= (struct ieee_param
*)kmalloc(p
->length
, GFP_KERNEL
);
3943 if (copy_from_user(param
, p
->pointer
, p
->length
)) {
3949 switch (param
->cmd
) {
3951 case IEEE_CMD_SET_WPA_PARAM
:
3952 ret
= ieee80211_wpa_set_param(ieee
, param
->u
.wpa_param
.name
,
3953 param
->u
.wpa_param
.value
);
3956 case IEEE_CMD_SET_WPA_IE
:
3957 ret
= ieee80211_wpa_set_wpa_ie(ieee
, param
, p
->length
);
3960 case IEEE_CMD_SET_ENCRYPTION
:
3961 ret
= ieee80211_wpa_set_encryption(ieee
, param
, p
->length
);
3965 ret
= ieee80211_wpa_mlme(ieee
, param
->u
.mlme
.command
,
3966 param
->u
.mlme
.reason_code
);
3970 printk("Unknown WPA supplicant request: %d\n",param
->cmd
);
3975 if (ret
== 0 && copy_to_user(p
->pointer
, param
, p
->length
))
3985 void notify_wx_assoc_event(struct ieee80211_device
*ieee
)
3987 union iwreq_data wrqu
;
3988 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
3989 if (ieee
->state
== IEEE80211_LINKED
)
3990 memcpy(wrqu
.ap_addr
.sa_data
, ieee
->current_network
.bssid
, ETH_ALEN
);
3992 memset(wrqu
.ap_addr
.sa_data
, 0, ETH_ALEN
);
3993 wireless_send_event(ieee
->dev
, SIOCGIWAP
, &wrqu
, NULL
);
3998 EXPORT_SYMBOL(ieee80211_get_beacon
);
3999 EXPORT_SYMBOL(ieee80211_wake_queue
);
4000 EXPORT_SYMBOL(ieee80211_stop_queue
);
4001 EXPORT_SYMBOL(ieee80211_reset_queue
);
4002 EXPORT_SYMBOL(ieee80211_softmac_stop_protocol
);
4003 EXPORT_SYMBOL(ieee80211_softmac_start_protocol
);
4004 EXPORT_SYMBOL(ieee80211_is_shortslot
);
4005 EXPORT_SYMBOL(ieee80211_is_54g
);
4006 EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl
);
4007 EXPORT_SYMBOL(ieee80211_ps_tx_ack
);
4008 EXPORT_SYMBOL(ieee80211_start_protocol
);
4009 EXPORT_SYMBOL(ieee80211_stop_protocol
);
4010 EXPORT_SYMBOL(notify_wx_assoc_event
);
4011 EXPORT_SYMBOL(ieee80211_stop_send_beacons
);
4012 EXPORT_SYMBOL(SendDisassociation
);
4013 EXPORT_SYMBOL(ieee80211_disassociate
);
4014 EXPORT_SYMBOL(ieee80211_start_scan
);
4015 EXPORT_SYMBOL(ieee80211_softmac_ips_scan_syncro
);
4016 #ifdef _RTL8187_EXT_PATCH_
4017 EXPORT_SYMBOL(ieee80211_ext_issue_assoc_req
);
4018 EXPORT_SYMBOL(ieee80211_ext_issue_disassoc
);
4019 EXPORT_SYMBOL(ieee80211_ext_issue_assoc_rsp
);
4020 EXPORT_SYMBOL(softmac_mgmt_xmit
);
4021 EXPORT_SYMBOL(ieee80211_ext_probe_resp_by_net
);
4022 EXPORT_SYMBOL(ieee80211_start_scan
);
4023 EXPORT_SYMBOL(ieee80211_stop_scan
);
4024 EXPORT_SYMBOL(ieee80211_ext_send_11s_beacon
);
4025 EXPORT_SYMBOL(ieee80211_rx_auth_rq
);
4026 EXPORT_SYMBOL(ieee80211_associate_step1
);
4027 #endif // _RTL8187_EXT_PATCH_
4028 EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame
);