1 /* IEEE 802.11 SoftMAC layer
2 * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
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/slab.h>
22 #include <asm/uaccess.h>
23 #include <linux/etherdevice.h>
27 short ieee80211_is_54g(const struct ieee80211_network
*net
)
29 return (net
->rates_ex_len
> 0) || (net
->rates_len
> 4);
32 short ieee80211_is_shortslot(const struct ieee80211_network
*net
)
34 return net
->capability
& WLAN_CAPABILITY_SHORT_SLOT
;
37 /* returns the total length needed for pleacing the RATE MFIE
38 * tag and the EXTENDED RATE MFIE tag if needed.
39 * It encludes two bytes per tag for the tag itself and its len
41 static unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device
*ieee
)
43 unsigned int rate_len
= 0;
45 if (ieee
->modulation
& IEEE80211_CCK_MODULATION
)
46 rate_len
= IEEE80211_CCK_RATE_LEN
+ 2;
48 if (ieee
->modulation
& IEEE80211_OFDM_MODULATION
)
50 rate_len
+= IEEE80211_OFDM_RATE_LEN
+ 2;
55 /* pleace the MFIE rate, tag to the memory (double) poined.
56 * Then it updates the pointer so that
57 * it points after the new MFIE tag added.
59 static void ieee80211_MFIE_Brate(struct ieee80211_device
*ieee
, u8
**tag_p
)
63 if (ieee
->modulation
& IEEE80211_CCK_MODULATION
){
64 *tag
++ = MFIE_TYPE_RATES
;
66 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_1MB
;
67 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_2MB
;
68 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_5MB
;
69 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_11MB
;
72 /* We may add an option for custom rates that specific HW might support */
76 static void ieee80211_MFIE_Grate(struct ieee80211_device
*ieee
, u8
**tag_p
)
80 if (ieee
->modulation
& IEEE80211_OFDM_MODULATION
){
82 *tag
++ = MFIE_TYPE_RATES_EX
;
84 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_6MB
;
85 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_9MB
;
86 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_12MB
;
87 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_18MB
;
88 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_24MB
;
89 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_36MB
;
90 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_48MB
;
91 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_54MB
;
95 /* We may add an option for custom rates that specific HW might support */
100 static void ieee80211_WMM_Info(struct ieee80211_device
*ieee
, u8
**tag_p
)
104 *tag
++ = MFIE_TYPE_GENERIC
; //0
113 if(ieee
->current_network
.wmm_info
& 0x80) {
114 *tag
++ = 0x0f|MAX_SP_Len
;
125 void ieee80211_TURBO_Info(struct ieee80211_device
*ieee
, u8
**tag_p
) {
128 *tag
++ = MFIE_TYPE_GENERIC
; //0
139 printk(KERN_ALERT
"This is enable turbo mode IE process\n");
143 static void enqueue_mgmt(struct ieee80211_device
*ieee
, struct sk_buff
*skb
)
146 nh
= (ieee
->mgmt_queue_head
+1) % MGMT_QUEUE_NUM
;
149 * if the queue is full but we have newer frames then
150 * just overwrites the oldest.
152 * if (nh == ieee->mgmt_queue_tail)
155 ieee
->mgmt_queue_head
= nh
;
156 ieee
->mgmt_queue_ring
[nh
] = skb
;
161 static struct sk_buff
*dequeue_mgmt(struct ieee80211_device
*ieee
)
165 if(ieee
->mgmt_queue_tail
== ieee
->mgmt_queue_head
)
168 ret
= ieee
->mgmt_queue_ring
[ieee
->mgmt_queue_tail
];
170 ieee
->mgmt_queue_tail
=
171 (ieee
->mgmt_queue_tail
+1) % MGMT_QUEUE_NUM
;
176 static void init_mgmt_queue(struct ieee80211_device
*ieee
)
178 ieee
->mgmt_queue_tail
= ieee
->mgmt_queue_head
= 0;
181 static u8
MgntQuery_MgntFrameTxRate(struct ieee80211_device
*ieee
)
183 PRT_HIGH_THROUGHPUT pHTInfo
= ieee
->pHTInfo
;
186 // 2008/01/25 MH For broadcom, MGNT frame set as OFDM 6M.
187 if(pHTInfo
->IOTAction
& HT_IOT_ACT_MGNT_USE_CCK_6M
)
190 rate
= ieee
->basic_rate
& 0x7f;
193 // 2005.01.26, by rcnjko.
194 if(ieee
->mode
== IEEE_A
||
195 ieee
->mode
== IEEE_N_5G
||
196 (ieee
->mode
== IEEE_N_24G
&&!pHTInfo
->bCurSuppCCK
))
203 // Data rate of ProbeReq is already decided. Annie, 2005-03-31
204 if( pMgntInfo->bScanInProgress || (pMgntInfo->bDualModeScanStep!=0) )
206 if(pMgntInfo->dot11CurrentWirelessMode==WIRELESS_MODE_A)
216 void ieee80211_sta_wakeup(struct ieee80211_device
*ieee
, short nl
);
218 inline void softmac_mgmt_xmit(struct sk_buff
*skb
, struct ieee80211_device
*ieee
)
221 short single
= ieee
->softmac_features
& IEEE_SOFTMAC_SINGLE_QUEUE
;
222 struct ieee80211_hdr_3addr
*header
=
223 (struct ieee80211_hdr_3addr
*) skb
->data
;
225 cb_desc
*tcb_desc
= (cb_desc
*)(skb
->cb
+ 8);
226 spin_lock_irqsave(&ieee
->lock
, flags
);
228 /* called with 2nd param 0, no mgmt lock required */
229 ieee80211_sta_wakeup(ieee
,0);
231 tcb_desc
->queue_index
= MGNT_QUEUE
;
232 tcb_desc
->data_rate
= MgntQuery_MgntFrameTxRate(ieee
);
233 tcb_desc
->RATRIndex
= 7;
234 tcb_desc
->bTxDisableRateFallBack
= 1;
235 tcb_desc
->bTxUseDriverAssingedRate
= 1;
238 if(ieee
->queue_stop
){
239 enqueue_mgmt(ieee
,skb
);
241 header
->seq_ctl
= cpu_to_le16(ieee
->seq_ctrl
[0]<<4);
243 if (ieee
->seq_ctrl
[0] == 0xFFF)
244 ieee
->seq_ctrl
[0] = 0;
248 /* avoid watchdog triggers */
249 ieee
->dev
->trans_start
= jiffies
;
250 ieee
->softmac_data_hard_start_xmit(skb
,ieee
->dev
,ieee
->basic_rate
);
251 //dev_kfree_skb_any(skb);//edit by thomas
254 spin_unlock_irqrestore(&ieee
->lock
, flags
);
256 spin_unlock_irqrestore(&ieee
->lock
, flags
);
257 spin_lock_irqsave(&ieee
->mgmt_tx_lock
, flags
);
259 header
->seq_ctl
= cpu_to_le16(ieee
->seq_ctrl
[0] << 4);
261 if (ieee
->seq_ctrl
[0] == 0xFFF)
262 ieee
->seq_ctrl
[0] = 0;
266 /* check whether the managed packet queued greater than 5 */
267 if(!ieee
->check_nic_enough_desc(ieee
->dev
,tcb_desc
->queue_index
)||\
268 (skb_queue_len(&ieee
->skb_waitQ
[tcb_desc
->queue_index
]) != 0)||\
269 (ieee
->queue_stop
) ) {
270 /* insert the skb packet to the management queue */
271 /* as for the completion function, it does not need
272 * to check it any more.
274 printk("%s():insert to waitqueue!\n",__FUNCTION__
);
275 skb_queue_tail(&ieee
->skb_waitQ
[tcb_desc
->queue_index
], skb
);
277 //printk("TX packet!\n");
278 ieee
->softmac_hard_start_xmit(skb
,ieee
->dev
);
279 //dev_kfree_skb_any(skb);//edit by thomas
281 spin_unlock_irqrestore(&ieee
->mgmt_tx_lock
, flags
);
285 inline void softmac_ps_mgmt_xmit(struct sk_buff
*skb
, struct ieee80211_device
*ieee
)
288 short single
= ieee
->softmac_features
& IEEE_SOFTMAC_SINGLE_QUEUE
;
289 struct ieee80211_hdr_3addr
*header
=
290 (struct ieee80211_hdr_3addr
*) skb
->data
;
295 header
->seq_ctl
= cpu_to_le16(ieee
->seq_ctrl
[0] << 4);
297 if (ieee
->seq_ctrl
[0] == 0xFFF)
298 ieee
->seq_ctrl
[0] = 0;
302 /* avoid watchdog triggers */
303 ieee
->dev
->trans_start
= jiffies
;
304 ieee
->softmac_data_hard_start_xmit(skb
,ieee
->dev
,ieee
->basic_rate
);
308 header
->seq_ctl
= cpu_to_le16(ieee
->seq_ctrl
[0] << 4);
310 if (ieee
->seq_ctrl
[0] == 0xFFF)
311 ieee
->seq_ctrl
[0] = 0;
315 ieee
->softmac_hard_start_xmit(skb
,ieee
->dev
);
318 //dev_kfree_skb_any(skb);//edit by thomas
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 len
= ieee
->current_network
.ssid_len
;
330 rate_len
= ieee80211_MFIE_rate_len(ieee
);
332 skb
= dev_alloc_skb(sizeof(struct ieee80211_probe_request
) +
333 2 + len
+ rate_len
+ ieee
->tx_headroom
);
337 skb_reserve(skb
, ieee
->tx_headroom
);
339 req
= (struct ieee80211_probe_request
*) skb_put(skb
,sizeof(struct ieee80211_probe_request
));
340 req
->header
.frame_ctl
= cpu_to_le16(IEEE80211_STYPE_PROBE_REQ
);
341 req
->header
.duration_id
= 0; //FIXME: is this OK ?
343 memset(req
->header
.addr1
, 0xff, ETH_ALEN
);
344 memcpy(req
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
345 memset(req
->header
.addr3
, 0xff, ETH_ALEN
);
347 tag
= (u8
*) skb_put(skb
,len
+2+rate_len
);
349 *tag
++ = MFIE_TYPE_SSID
;
351 memcpy(tag
, ieee
->current_network
.ssid
, len
);
354 ieee80211_MFIE_Brate(ieee
,&tag
);
355 ieee80211_MFIE_Grate(ieee
,&tag
);
359 struct sk_buff
*ieee80211_get_beacon_(struct ieee80211_device
*ieee
);
361 static void ieee80211_send_beacon(struct ieee80211_device
*ieee
)
366 //unsigned long flags;
367 skb
= ieee80211_get_beacon_(ieee
);
370 softmac_mgmt_xmit(skb
, ieee
);
371 ieee
->softmac_stats
.tx_beacons
++;
372 //dev_kfree_skb_any(skb);//edit by thomas
374 // ieee->beacon_timer.expires = jiffies +
375 // (MSECS( ieee->current_network.beacon_interval -5));
377 //spin_lock_irqsave(&ieee->beacon_lock,flags);
378 if(ieee
->beacon_txing
&& ieee
->ieee_up
){
379 // if(!timer_pending(&ieee->beacon_timer))
380 // add_timer(&ieee->beacon_timer);
381 mod_timer(&ieee
->beacon_timer
,jiffies
+(MSECS(ieee
->current_network
.beacon_interval
-5)));
383 //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
387 static void ieee80211_send_beacon_cb(unsigned long _ieee
)
389 struct ieee80211_device
*ieee
=
390 (struct ieee80211_device
*) _ieee
;
393 spin_lock_irqsave(&ieee
->beacon_lock
, flags
);
394 ieee80211_send_beacon(ieee
);
395 spin_unlock_irqrestore(&ieee
->beacon_lock
, flags
);
399 static void ieee80211_send_probe(struct ieee80211_device
*ieee
)
403 skb
= ieee80211_probe_req(ieee
);
405 softmac_mgmt_xmit(skb
, ieee
);
406 ieee
->softmac_stats
.tx_probe_rq
++;
407 //dev_kfree_skb_any(skb);//edit by thomas
411 void ieee80211_send_probe_requests(struct ieee80211_device
*ieee
)
413 if (ieee
->active_scan
&& (ieee
->softmac_features
& IEEE_SOFTMAC_PROBERQ
)){
414 ieee80211_send_probe(ieee
);
415 ieee80211_send_probe(ieee
);
419 /* this performs syncro scan blocking the caller until all channels
420 * in the allowed channel map has been checked.
422 void ieee80211_softmac_scan_syncro(struct ieee80211_device
*ieee
)
425 u8 channel_map
[MAX_CHANNEL_NUMBER
+1];
426 memcpy(channel_map
, GET_DOT11D_INFO(ieee
)->channel_map
, MAX_CHANNEL_NUMBER
+1);
427 down(&ieee
->scan_sem
);
434 if (ch
> MAX_CHANNEL_NUMBER
)
435 goto out
; /* scan completed */
436 }while(!channel_map
[ch
]);
438 /* this function can be called in two situations
439 * 1- We have switched to ad-hoc mode and we are
440 * performing a complete syncro scan before conclude
441 * there are no interesting cell and to create a
442 * new one. In this case the link state is
443 * IEEE80211_NOLINK until we found an interesting cell.
444 * If so the ieee8021_new_net, called by the RX path
445 * will set the state to IEEE80211_LINKED, so we stop
447 * 2- We are linked and the root uses run iwlist scan.
448 * So we switch to IEEE80211_LINKED_SCANNING to remember
449 * that we are still logically linked (not interested in
450 * new network events, despite for updating the net list,
451 * but we are temporarly 'unlinked' as the driver shall
452 * not filter RX frames and the channel is changing.
453 * So the only situation in witch are interested is to check
454 * if the state become LINKED because of the #1 situation
457 if (ieee
->state
== IEEE80211_LINKED
)
459 ieee
->set_chan(ieee
->dev
, ch
);
460 if(channel_map
[ch
] == 1)
461 ieee80211_send_probe_requests(ieee
);
463 /* this prevent excessive time wait when we
464 * need to wait for a syncro scan to end..
466 if(ieee
->state
< IEEE80211_LINKED
)
469 if (ieee
->sync_scan_hurryup
)
473 msleep_interruptible_rsl(IEEE80211_SOFTMAC_SCAN_TIME
);
477 if(ieee
->state
< IEEE80211_LINKED
){
478 ieee
->actscanning
= false;
482 ieee
->sync_scan_hurryup
= 0;
483 if(IS_DOT11D_ENABLE(ieee
))
484 DOT11D_ScanComplete(ieee
);
490 static void ieee80211_softmac_scan_wq(struct work_struct
*work
)
492 struct delayed_work
*dwork
= container_of(work
, struct delayed_work
, work
);
493 struct ieee80211_device
*ieee
= container_of(dwork
, struct ieee80211_device
, softmac_scan_wq
);
494 static short watchdog
;
495 u8 channel_map
[MAX_CHANNEL_NUMBER
+1];
496 memcpy(channel_map
, GET_DOT11D_INFO(ieee
)->channel_map
, MAX_CHANNEL_NUMBER
+1);
499 down(&ieee
->scan_sem
);
501 ieee
->current_network
.channel
=
502 (ieee
->current_network
.channel
+ 1) % MAX_CHANNEL_NUMBER
;
503 if (watchdog
++ > MAX_CHANNEL_NUMBER
)
505 //if current channel is not in channel map, set to default channel.
506 if (!channel_map
[ieee
->current_network
.channel
]) {
507 ieee
->current_network
.channel
= 6;
508 goto out
; /* no good chans */
511 }while(!channel_map
[ieee
->current_network
.channel
]);
512 if (ieee
->scanning
== 0 )
514 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
515 if(channel_map
[ieee
->current_network
.channel
] == 1)
516 ieee80211_send_probe_requests(ieee
);
519 queue_delayed_work(ieee
->wq
, &ieee
->softmac_scan_wq
, IEEE80211_SOFTMAC_SCAN_TIME
);
524 if(IS_DOT11D_ENABLE(ieee
))
525 DOT11D_ScanComplete(ieee
);
526 ieee
->actscanning
= false;
534 static void ieee80211_beacons_start(struct ieee80211_device
*ieee
)
537 spin_lock_irqsave(&ieee
->beacon_lock
,flags
);
539 ieee
->beacon_txing
= 1;
540 ieee80211_send_beacon(ieee
);
542 spin_unlock_irqrestore(&ieee
->beacon_lock
,flags
);
545 static void ieee80211_beacons_stop(struct ieee80211_device
*ieee
)
549 spin_lock_irqsave(&ieee
->beacon_lock
,flags
);
551 ieee
->beacon_txing
= 0;
552 del_timer_sync(&ieee
->beacon_timer
);
554 spin_unlock_irqrestore(&ieee
->beacon_lock
,flags
);
559 void ieee80211_stop_send_beacons(struct ieee80211_device
*ieee
)
561 if(ieee
->stop_send_beacons
)
562 ieee
->stop_send_beacons(ieee
->dev
);
563 if (ieee
->softmac_features
& IEEE_SOFTMAC_BEACONS
)
564 ieee80211_beacons_stop(ieee
);
568 void ieee80211_start_send_beacons(struct ieee80211_device
*ieee
)
570 if(ieee
->start_send_beacons
)
571 ieee
->start_send_beacons(ieee
->dev
,ieee
->basic_rate
);
572 if(ieee
->softmac_features
& IEEE_SOFTMAC_BEACONS
)
573 ieee80211_beacons_start(ieee
);
577 static void ieee80211_softmac_stop_scan(struct ieee80211_device
*ieee
)
579 // unsigned long flags;
581 //ieee->sync_scan_hurryup = 1;
583 down(&ieee
->scan_sem
);
584 // spin_lock_irqsave(&ieee->lock, flags);
586 if (ieee
->scanning
== 1){
589 cancel_delayed_work(&ieee
->softmac_scan_wq
);
592 // spin_unlock_irqrestore(&ieee->lock, flags);
596 void ieee80211_stop_scan(struct ieee80211_device
*ieee
)
598 if (ieee
->softmac_features
& IEEE_SOFTMAC_SCAN
)
599 ieee80211_softmac_stop_scan(ieee
);
601 ieee
->stop_scan(ieee
->dev
);
604 /* called with ieee->lock held */
605 static void ieee80211_start_scan(struct ieee80211_device
*ieee
)
607 if(IS_DOT11D_ENABLE(ieee
) )
609 if(IS_COUNTRY_IE_VALID(ieee
))
611 RESET_CIE_WATCHDOG(ieee
);
614 if (ieee
->softmac_features
& IEEE_SOFTMAC_SCAN
){
615 if (ieee
->scanning
== 0){
617 queue_delayed_work(ieee
->wq
, &ieee
->softmac_scan_wq
, 0);
620 ieee
->start_scan(ieee
->dev
);
624 /* called with wx_sem held */
625 void ieee80211_start_scan_syncro(struct ieee80211_device
*ieee
)
627 if(IS_DOT11D_ENABLE(ieee
) )
629 if(IS_COUNTRY_IE_VALID(ieee
))
631 RESET_CIE_WATCHDOG(ieee
);
634 ieee
->sync_scan_hurryup
= 0;
635 if (ieee
->softmac_features
& IEEE_SOFTMAC_SCAN
)
636 ieee80211_softmac_scan_syncro(ieee
);
638 ieee
->scan_syncro(ieee
->dev
);
642 inline struct sk_buff
*ieee80211_authentication_req(struct ieee80211_network
*beacon
,
643 struct ieee80211_device
*ieee
, int challengelen
)
646 struct ieee80211_authentication
*auth
;
647 int len
= sizeof(struct ieee80211_authentication
) + challengelen
+ ieee
->tx_headroom
;
650 skb
= dev_alloc_skb(len
);
651 if (!skb
) return NULL
;
653 skb_reserve(skb
, ieee
->tx_headroom
);
654 auth
= (struct ieee80211_authentication
*)
655 skb_put(skb
, sizeof(struct ieee80211_authentication
));
657 auth
->header
.frame_ctl
= IEEE80211_STYPE_AUTH
;
658 if (challengelen
) auth
->header
.frame_ctl
|= IEEE80211_FCTL_WEP
;
660 auth
->header
.duration_id
= 0x013a; //FIXME
662 memcpy(auth
->header
.addr1
, beacon
->bssid
, ETH_ALEN
);
663 memcpy(auth
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
664 memcpy(auth
->header
.addr3
, beacon
->bssid
, ETH_ALEN
);
666 //auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
667 if(ieee
->auth_mode
== 0)
668 auth
->algorithm
= WLAN_AUTH_OPEN
;
669 else if(ieee
->auth_mode
== 1)
670 auth
->algorithm
= WLAN_AUTH_SHARED_KEY
;
671 else if(ieee
->auth_mode
== 2)
672 auth
->algorithm
= WLAN_AUTH_OPEN
;//0x80;
673 printk("=================>%s():auth->algorithm is %d\n",__FUNCTION__
,auth
->algorithm
);
674 auth
->transaction
= cpu_to_le16(ieee
->associate_seq
);
675 ieee
->associate_seq
++;
677 auth
->status
= cpu_to_le16(WLAN_STATUS_SUCCESS
);
684 static struct sk_buff
*ieee80211_probe_resp(struct ieee80211_device
*ieee
, u8
*dest
)
688 struct ieee80211_probe_response
*beacon_buf
;
689 struct sk_buff
*skb
= NULL
;
691 int atim_len
,erp_len
;
692 struct ieee80211_crypt_data
*crypt
;
694 char *ssid
= ieee
->current_network
.ssid
;
695 int ssid_len
= ieee
->current_network
.ssid_len
;
696 int rate_len
= ieee
->current_network
.rates_len
+2;
697 int rate_ex_len
= ieee
->current_network
.rates_ex_len
;
698 int wpa_ie_len
= ieee
->wpa_ie_len
;
699 u8 erpinfo_content
= 0;
704 u8 tmp_ht_info_len
=0;
705 PRT_HIGH_THROUGHPUT pHTInfo
= ieee
->pHTInfo
;
706 u8
*tmp_generic_ie_buf
=NULL
;
707 u8 tmp_generic_ie_len
=0;
709 if(rate_ex_len
> 0) rate_ex_len
+=2;
711 if(ieee
->current_network
.capability
& WLAN_CAPABILITY_IBSS
)
716 if(ieee80211_is_54g(&ieee
->current_network
))
722 crypt
= ieee
->crypt
[ieee
->tx_keyidx
];
725 encrypt
= ieee
->host_encrypt
&& crypt
&& crypt
->ops
&&
726 ((0 == strcmp(crypt
->ops
->name
, "WEP") || wpa_ie_len
));
728 tmp_ht_cap_buf
=(u8
*) &(ieee
->pHTInfo
->SelfHTCap
);
729 tmp_ht_cap_len
= sizeof(ieee
->pHTInfo
->SelfHTCap
);
730 tmp_ht_info_buf
=(u8
*) &(ieee
->pHTInfo
->SelfHTInfo
);
731 tmp_ht_info_len
= sizeof(ieee
->pHTInfo
->SelfHTInfo
);
732 HTConstructCapabilityElement(ieee
, tmp_ht_cap_buf
, &tmp_ht_cap_len
,encrypt
);
733 HTConstructInfoElement(ieee
,tmp_ht_info_buf
,&tmp_ht_info_len
, encrypt
);
736 if(pHTInfo
->bRegRT2RTAggregation
)
738 tmp_generic_ie_buf
= ieee
->pHTInfo
->szRT2RTAggBuffer
;
739 tmp_generic_ie_len
= sizeof(ieee
->pHTInfo
->szRT2RTAggBuffer
);
740 HTConstructRT2RTAggElement(ieee
, tmp_generic_ie_buf
, &tmp_generic_ie_len
);
742 // printk("===============>tmp_ht_cap_len is %d,tmp_ht_info_len is %d, tmp_generic_ie_len is %d\n",tmp_ht_cap_len,tmp_ht_info_len,tmp_generic_ie_len);
743 beacon_size
= sizeof(struct ieee80211_probe_response
)+2+
753 // +tmp_generic_ie_len
756 skb
= dev_alloc_skb(beacon_size
);
759 skb_reserve(skb
, ieee
->tx_headroom
);
760 beacon_buf
= (struct ieee80211_probe_response
*) skb_put(skb
, (beacon_size
- ieee
->tx_headroom
));
761 memcpy (beacon_buf
->header
.addr1
, dest
,ETH_ALEN
);
762 memcpy (beacon_buf
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
763 memcpy (beacon_buf
->header
.addr3
, ieee
->current_network
.bssid
, ETH_ALEN
);
765 beacon_buf
->header
.duration_id
= 0; //FIXME
766 beacon_buf
->beacon_interval
=
767 cpu_to_le16(ieee
->current_network
.beacon_interval
);
768 beacon_buf
->capability
=
769 cpu_to_le16(ieee
->current_network
.capability
& WLAN_CAPABILITY_IBSS
);
770 beacon_buf
->capability
|=
771 cpu_to_le16(ieee
->current_network
.capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
); //add short preamble here
773 if(ieee
->short_slot
&& (ieee
->current_network
.capability
& WLAN_CAPABILITY_SHORT_SLOT
))
774 beacon_buf
->capability
|= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT
);
776 crypt
= ieee
->crypt
[ieee
->tx_keyidx
];
778 beacon_buf
->capability
|= cpu_to_le16(WLAN_CAPABILITY_PRIVACY
);
781 beacon_buf
->header
.frame_ctl
= cpu_to_le16(IEEE80211_STYPE_PROBE_RESP
);
782 beacon_buf
->info_element
[0].id
= MFIE_TYPE_SSID
;
783 beacon_buf
->info_element
[0].len
= ssid_len
;
785 tag
= (u8
*) beacon_buf
->info_element
[0].data
;
787 memcpy(tag
, ssid
, ssid_len
);
791 *(tag
++) = MFIE_TYPE_RATES
;
792 *(tag
++) = rate_len
-2;
793 memcpy(tag
,ieee
->current_network
.rates
,rate_len
-2);
796 *(tag
++) = MFIE_TYPE_DS_SET
;
798 *(tag
++) = ieee
->current_network
.channel
;
802 *(tag
++) = MFIE_TYPE_IBSS_SET
;
804 //*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window);
805 val16
= cpu_to_le16(ieee
->current_network
.atim_window
);
806 memcpy((u8
*)tag
, (u8
*)&val16
, 2);
811 *(tag
++) = MFIE_TYPE_ERP
;
813 *(tag
++) = erpinfo_content
;
816 *(tag
++) = MFIE_TYPE_RATES_EX
;
817 *(tag
++) = rate_ex_len
-2;
818 memcpy(tag
,ieee
->current_network
.rates_ex
,rate_ex_len
-2);
824 if (ieee
->iw_mode
== IW_MODE_ADHOC
)
825 {//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
826 memcpy(&ieee
->wpa_ie
[14], &ieee
->wpa_ie
[8], 4);
828 memcpy(tag
, ieee
->wpa_ie
, ieee
->wpa_ie_len
);
832 //skb->dev = ieee->dev;
837 static struct sk_buff
*ieee80211_assoc_resp(struct ieee80211_device
*ieee
,
843 struct ieee80211_crypt_data
*crypt
;
844 struct ieee80211_assoc_response_frame
*assoc
;
847 unsigned int rate_len
= ieee80211_MFIE_rate_len(ieee
);
848 int len
= sizeof(struct ieee80211_assoc_response_frame
) + rate_len
+ ieee
->tx_headroom
;
850 skb
= dev_alloc_skb(len
);
855 skb_reserve(skb
, ieee
->tx_headroom
);
857 assoc
= (struct ieee80211_assoc_response_frame
*)
858 skb_put(skb
,sizeof(struct ieee80211_assoc_response_frame
));
860 assoc
->header
.frame_ctl
= cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP
);
861 memcpy(assoc
->header
.addr1
, dest
,ETH_ALEN
);
862 memcpy(assoc
->header
.addr3
, ieee
->dev
->dev_addr
, ETH_ALEN
);
863 memcpy(assoc
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
864 assoc
->capability
= cpu_to_le16(ieee
->iw_mode
== IW_MODE_MASTER
?
865 WLAN_CAPABILITY_BSS
: WLAN_CAPABILITY_IBSS
);
869 assoc
->capability
|= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT
);
871 if (ieee
->host_encrypt
)
872 crypt
= ieee
->crypt
[ieee
->tx_keyidx
];
875 encrypt
= ( crypt
&& crypt
->ops
);
878 assoc
->capability
|= cpu_to_le16(WLAN_CAPABILITY_PRIVACY
);
881 assoc
->aid
= cpu_to_le16(ieee
->assoc_id
);
882 if (ieee
->assoc_id
== 0x2007) ieee
->assoc_id
=0;
883 else ieee
->assoc_id
++;
885 tag
= (u8
*) skb_put(skb
, rate_len
);
887 ieee80211_MFIE_Brate(ieee
, &tag
);
888 ieee80211_MFIE_Grate(ieee
, &tag
);
893 static struct sk_buff
*ieee80211_auth_resp(struct ieee80211_device
*ieee
,
894 int status
, u8
*dest
)
897 struct ieee80211_authentication
*auth
;
898 int len
= ieee
->tx_headroom
+ sizeof(struct ieee80211_authentication
)+1;
900 skb
= dev_alloc_skb(len
);
905 skb
->len
= sizeof(struct ieee80211_authentication
);
907 auth
= (struct ieee80211_authentication
*)skb
->data
;
909 auth
->status
= cpu_to_le16(status
);
910 auth
->transaction
= cpu_to_le16(2);
911 auth
->algorithm
= cpu_to_le16(WLAN_AUTH_OPEN
);
913 memcpy(auth
->header
.addr3
, ieee
->dev
->dev_addr
, ETH_ALEN
);
914 memcpy(auth
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
915 memcpy(auth
->header
.addr1
, dest
, ETH_ALEN
);
916 auth
->header
.frame_ctl
= cpu_to_le16(IEEE80211_STYPE_AUTH
);
922 static struct sk_buff
*ieee80211_null_func(struct ieee80211_device
*ieee
,
926 struct ieee80211_hdr_3addr
*hdr
;
928 skb
= dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr
));
933 hdr
= (struct ieee80211_hdr_3addr
*)skb_put(skb
,sizeof(struct ieee80211_hdr_3addr
));
935 memcpy(hdr
->addr1
, ieee
->current_network
.bssid
, ETH_ALEN
);
936 memcpy(hdr
->addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
937 memcpy(hdr
->addr3
, ieee
->current_network
.bssid
, ETH_ALEN
);
939 hdr
->frame_ctl
= cpu_to_le16(IEEE80211_FTYPE_DATA
|
940 IEEE80211_STYPE_NULLFUNC
| IEEE80211_FCTL_TODS
|
941 (pwr
? IEEE80211_FCTL_PM
:0));
949 static void ieee80211_resp_to_assoc_rq(struct ieee80211_device
*ieee
, u8
*dest
)
951 struct sk_buff
*buf
= ieee80211_assoc_resp(ieee
, dest
);
954 softmac_mgmt_xmit(buf
, ieee
);
958 static void ieee80211_resp_to_auth(struct ieee80211_device
*ieee
, int s
,
961 struct sk_buff
*buf
= ieee80211_auth_resp(ieee
, s
, dest
);
964 softmac_mgmt_xmit(buf
, ieee
);
968 static void ieee80211_resp_to_probe(struct ieee80211_device
*ieee
, u8
*dest
)
972 struct sk_buff
*buf
= ieee80211_probe_resp(ieee
, dest
);
974 softmac_mgmt_xmit(buf
, ieee
);
978 inline struct sk_buff
*ieee80211_association_req(struct ieee80211_network
*beacon
,struct ieee80211_device
*ieee
)
981 //unsigned long flags;
983 struct ieee80211_assoc_request_frame
*hdr
;
985 //short info_addr = 0;
987 //u16 suite_count = 0;
988 //u8 suit_select = 0;
989 //unsigned int wpa_len = beacon->wpa_ie_len;
991 u8
*ht_cap_buf
= NULL
;
993 u8
*realtek_ie_buf
=NULL
;
995 int wpa_ie_len
= ieee
->wpa_ie_len
;
996 unsigned int ckip_ie_len
=0;
997 unsigned int ccxrm_ie_len
=0;
998 unsigned int cxvernum_ie_len
=0;
999 struct ieee80211_crypt_data
*crypt
;
1002 unsigned int rate_len
= ieee80211_MFIE_rate_len(ieee
);
1003 unsigned int wmm_info_len
= beacon
->qos_data
.supported
?9:0;
1005 unsigned int turbo_info_len
= beacon
->Turbo_Enable
?9:0;
1010 crypt
= ieee
->crypt
[ieee
->tx_keyidx
];
1011 encrypt
= ieee
->host_encrypt
&& crypt
&& crypt
->ops
&& ((0 == strcmp(crypt
->ops
->name
,"WEP") || wpa_ie_len
));
1013 //Include High Throuput capability && Realtek proprietary
1014 if(ieee
->pHTInfo
->bCurrentHTSupport
&&ieee
->pHTInfo
->bEnableHT
)
1016 ht_cap_buf
= (u8
*)&(ieee
->pHTInfo
->SelfHTCap
);
1017 ht_cap_len
= sizeof(ieee
->pHTInfo
->SelfHTCap
);
1018 HTConstructCapabilityElement(ieee
, ht_cap_buf
, &ht_cap_len
, encrypt
);
1019 if(ieee
->pHTInfo
->bCurrentRT2RTAggregation
)
1021 realtek_ie_buf
= ieee
->pHTInfo
->szRT2RTAggBuffer
;
1022 realtek_ie_len
= sizeof( ieee
->pHTInfo
->szRT2RTAggBuffer
);
1023 HTConstructRT2RTAggElement(ieee
, realtek_ie_buf
, &realtek_ie_len
);
1027 if(ieee
->qos_support
){
1028 wmm_info_len
= beacon
->qos_data
.supported
?9:0;
1032 if(beacon
->bCkipSupported
)
1036 if(beacon
->bCcxRmEnable
)
1040 if( beacon
->BssCcxVerNumber
>= 2 )
1042 cxvernum_ie_len
= 5+2;
1045 len
= sizeof(struct ieee80211_assoc_request_frame
)+ 2
1046 + beacon
->ssid_len
//essid tagged val
1047 + rate_len
//rates tagged val
1056 + ieee
->tx_headroom
;
1058 len
= sizeof(struct ieee80211_assoc_request_frame
)+ 2
1059 + beacon
->ssid_len
//essid tagged val
1060 + rate_len
//rates tagged val
1068 + ieee
->tx_headroom
;
1071 skb
= dev_alloc_skb(len
);
1076 skb_reserve(skb
, ieee
->tx_headroom
);
1078 hdr
= (struct ieee80211_assoc_request_frame
*)
1079 skb_put(skb
, sizeof(struct ieee80211_assoc_request_frame
)+2);
1082 hdr
->header
.frame_ctl
= IEEE80211_STYPE_ASSOC_REQ
;
1083 hdr
->header
.duration_id
= 37; //FIXME
1084 memcpy(hdr
->header
.addr1
, beacon
->bssid
, ETH_ALEN
);
1085 memcpy(hdr
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
1086 memcpy(hdr
->header
.addr3
, beacon
->bssid
, ETH_ALEN
);
1088 memcpy(ieee
->ap_mac_addr
, beacon
->bssid
, ETH_ALEN
);//for HW security, John
1090 hdr
->capability
= cpu_to_le16(WLAN_CAPABILITY_BSS
);
1091 if (beacon
->capability
& WLAN_CAPABILITY_PRIVACY
)
1092 hdr
->capability
|= cpu_to_le16(WLAN_CAPABILITY_PRIVACY
);
1094 if (beacon
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
1095 hdr
->capability
|= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE
); //add short_preamble here
1097 if(ieee
->short_slot
)
1098 hdr
->capability
|= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT
);
1099 if (wmm_info_len
) //QOS
1100 hdr
->capability
|= cpu_to_le16(WLAN_CAPABILITY_QOS
);
1102 hdr
->listen_interval
= 0xa; //FIXME
1104 hdr
->info_element
[0].id
= MFIE_TYPE_SSID
;
1106 hdr
->info_element
[0].len
= beacon
->ssid_len
;
1107 tag
= skb_put(skb
, beacon
->ssid_len
);
1108 memcpy(tag
, beacon
->ssid
, beacon
->ssid_len
);
1110 tag
= skb_put(skb
, rate_len
);
1112 ieee80211_MFIE_Brate(ieee
, &tag
);
1113 ieee80211_MFIE_Grate(ieee
, &tag
);
1114 // For CCX 1 S13, CKIP. Added by Annie, 2006-08-14.
1115 if( beacon
->bCkipSupported
)
1117 static u8 AironetIeOui
[] = {0x00, 0x01, 0x66}; // "4500-client"
1118 u8 CcxAironetBuf
[30];
1119 OCTET_STRING osCcxAironetIE
;
1121 memset(CcxAironetBuf
, 0,30);
1122 osCcxAironetIE
.Octet
= CcxAironetBuf
;
1123 osCcxAironetIE
.Length
= sizeof(CcxAironetBuf
);
1125 // Ref. CCX test plan v3.61, 3.2.3.1 step 13.
1126 // We want to make the device type as "4500-client". 060926, by CCW.
1128 memcpy(osCcxAironetIE
.Octet
, AironetIeOui
, sizeof(AironetIeOui
));
1130 // CCX1 spec V1.13, A01.1 CKIP Negotiation (page23):
1131 // "The CKIP negotiation is started with the associate request from the client to the access point,
1132 // containing an Aironet element with both the MIC and KP bits set."
1133 osCcxAironetIE
.Octet
[IE_CISCO_FLAG_POSITION
] |= (SUPPORT_CKIP_PK
|SUPPORT_CKIP_MIC
) ;
1134 tag
= skb_put(skb
, ckip_ie_len
);
1135 *tag
++ = MFIE_TYPE_AIRONET
;
1136 *tag
++ = osCcxAironetIE
.Length
;
1137 memcpy(tag
,osCcxAironetIE
.Octet
,osCcxAironetIE
.Length
);
1138 tag
+= osCcxAironetIE
.Length
;
1141 if(beacon
->bCcxRmEnable
)
1143 static u8 CcxRmCapBuf
[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
1144 OCTET_STRING osCcxRmCap
;
1146 osCcxRmCap
.Octet
= CcxRmCapBuf
;
1147 osCcxRmCap
.Length
= sizeof(CcxRmCapBuf
);
1148 tag
= skb_put(skb
,ccxrm_ie_len
);
1149 *tag
++ = MFIE_TYPE_GENERIC
;
1150 *tag
++ = osCcxRmCap
.Length
;
1151 memcpy(tag
,osCcxRmCap
.Octet
,osCcxRmCap
.Length
);
1152 tag
+= osCcxRmCap
.Length
;
1155 if( beacon
->BssCcxVerNumber
>= 2 )
1157 u8 CcxVerNumBuf
[] = {0x00, 0x40, 0x96, 0x03, 0x00};
1158 OCTET_STRING osCcxVerNum
;
1159 CcxVerNumBuf
[4] = beacon
->BssCcxVerNumber
;
1160 osCcxVerNum
.Octet
= CcxVerNumBuf
;
1161 osCcxVerNum
.Length
= sizeof(CcxVerNumBuf
);
1162 tag
= skb_put(skb
,cxvernum_ie_len
);
1163 *tag
++ = MFIE_TYPE_GENERIC
;
1164 *tag
++ = osCcxVerNum
.Length
;
1165 memcpy(tag
,osCcxVerNum
.Octet
,osCcxVerNum
.Length
);
1166 tag
+= osCcxVerNum
.Length
;
1169 if(ieee
->pHTInfo
->bCurrentHTSupport
&&ieee
->pHTInfo
->bEnableHT
){
1170 if(ieee
->pHTInfo
->ePeerHTSpecVer
!= HT_SPEC_VER_EWC
)
1172 tag
= skb_put(skb
, ht_cap_len
);
1173 *tag
++ = MFIE_TYPE_HT_CAP
;
1174 *tag
++ = ht_cap_len
- 2;
1175 memcpy(tag
, ht_cap_buf
,ht_cap_len
-2);
1176 tag
+= ht_cap_len
-2;
1181 //choose what wpa_supplicant gives to associate.
1182 tag
= skb_put(skb
, wpa_ie_len
);
1184 memcpy(tag
, ieee
->wpa_ie
, ieee
->wpa_ie_len
);
1187 tag
= skb_put(skb
,wmm_info_len
);
1189 ieee80211_WMM_Info(ieee
, &tag
);
1192 tag
= skb_put(skb
,turbo_info_len
);
1193 if(turbo_info_len
) {
1194 ieee80211_TURBO_Info(ieee
, &tag
);
1198 if(ieee
->pHTInfo
->bCurrentHTSupport
&&ieee
->pHTInfo
->bEnableHT
){
1199 if(ieee
->pHTInfo
->ePeerHTSpecVer
== HT_SPEC_VER_EWC
)
1201 tag
= skb_put(skb
, ht_cap_len
);
1202 *tag
++ = MFIE_TYPE_GENERIC
;
1203 *tag
++ = ht_cap_len
- 2;
1204 memcpy(tag
, ht_cap_buf
,ht_cap_len
- 2);
1205 tag
+= ht_cap_len
-2;
1208 if(ieee
->pHTInfo
->bCurrentRT2RTAggregation
){
1209 tag
= skb_put(skb
, realtek_ie_len
);
1210 *tag
++ = MFIE_TYPE_GENERIC
;
1211 *tag
++ = realtek_ie_len
- 2;
1212 memcpy(tag
, realtek_ie_buf
,realtek_ie_len
-2 );
1215 // printk("<=====%s(), %p, %p\n", __FUNCTION__, ieee->dev, ieee->dev->dev_addr);
1216 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
1220 void ieee80211_associate_abort(struct ieee80211_device
*ieee
)
1223 unsigned long flags
;
1224 spin_lock_irqsave(&ieee
->lock
, flags
);
1226 ieee
->associate_seq
++;
1228 /* don't scan, and avoid to have the RX path possibily
1229 * try again to associate. Even do not react to AUTH or
1230 * ASSOC response. Just wait for the retry wq to be scheduled.
1231 * Here we will check if there are good nets to associate
1232 * with, so we retry or just get back to NO_LINK and scanning
1234 if (ieee
->state
== IEEE80211_ASSOCIATING_AUTHENTICATING
){
1235 IEEE80211_DEBUG_MGMT("Authentication failed\n");
1236 ieee
->softmac_stats
.no_auth_rs
++;
1238 IEEE80211_DEBUG_MGMT("Association failed\n");
1239 ieee
->softmac_stats
.no_ass_rs
++;
1242 ieee
->state
= IEEE80211_ASSOCIATING_RETRY
;
1244 queue_delayed_work(ieee
->wq
, &ieee
->associate_retry_wq
, \
1245 IEEE80211_SOFTMAC_ASSOC_RETRY_TIME
);
1247 spin_unlock_irqrestore(&ieee
->lock
, flags
);
1250 static void ieee80211_associate_abort_cb(unsigned long dev
)
1252 ieee80211_associate_abort((struct ieee80211_device
*) dev
);
1256 static void ieee80211_associate_step1(struct ieee80211_device
*ieee
)
1258 struct ieee80211_network
*beacon
= &ieee
->current_network
;
1259 struct sk_buff
*skb
;
1261 IEEE80211_DEBUG_MGMT("Stopping scan\n");
1263 ieee
->softmac_stats
.tx_auth_rq
++;
1264 skb
=ieee80211_authentication_req(beacon
, ieee
, 0);
1267 ieee80211_associate_abort(ieee
);
1269 ieee
->state
= IEEE80211_ASSOCIATING_AUTHENTICATING
;
1270 IEEE80211_DEBUG_MGMT("Sending authentication request\n");
1271 //printk(KERN_WARNING "Sending authentication request\n");
1272 softmac_mgmt_xmit(skb
, ieee
);
1273 //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
1274 if(!timer_pending(&ieee
->associate_timer
)){
1275 ieee
->associate_timer
.expires
= jiffies
+ (HZ
/ 2);
1276 add_timer(&ieee
->associate_timer
);
1278 //dev_kfree_skb_any(skb);//edit by thomas
1282 static void ieee80211_auth_challenge(struct ieee80211_device
*ieee
,
1287 struct sk_buff
*skb
;
1288 struct ieee80211_network
*beacon
= &ieee
->current_network
;
1289 // int hlen = sizeof(struct ieee80211_authentication);
1291 ieee
->associate_seq
++;
1292 ieee
->softmac_stats
.tx_auth_rq
++;
1294 skb
= ieee80211_authentication_req(beacon
, ieee
, chlen
+2);
1296 ieee80211_associate_abort(ieee
);
1298 c
= skb_put(skb
, chlen
+2);
1299 *(c
++) = MFIE_TYPE_CHALLENGE
;
1301 memcpy(c
, challenge
, chlen
);
1303 IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
1305 ieee80211_encrypt_fragment(ieee
, skb
, sizeof(struct ieee80211_hdr_3addr
));
1307 softmac_mgmt_xmit(skb
, ieee
);
1308 mod_timer(&ieee
->associate_timer
, jiffies
+ (HZ
/2));
1309 //dev_kfree_skb_any(skb);//edit by thomas
1314 static void ieee80211_associate_step2(struct ieee80211_device
*ieee
)
1316 struct sk_buff
*skb
;
1317 struct ieee80211_network
*beacon
= &ieee
->current_network
;
1319 del_timer_sync(&ieee
->associate_timer
);
1321 IEEE80211_DEBUG_MGMT("Sending association request\n");
1323 ieee
->softmac_stats
.tx_ass_rq
++;
1324 skb
=ieee80211_association_req(beacon
, ieee
);
1326 ieee80211_associate_abort(ieee
);
1328 softmac_mgmt_xmit(skb
, ieee
);
1329 mod_timer(&ieee
->associate_timer
, jiffies
+ (HZ
/2));
1330 //dev_kfree_skb_any(skb);//edit by thomas
1333 static void ieee80211_associate_complete_wq(struct work_struct
*work
)
1335 struct ieee80211_device
*ieee
= container_of(work
, struct ieee80211_device
, associate_complete_wq
);
1336 printk(KERN_INFO
"Associated successfully\n");
1337 if(ieee80211_is_54g(&ieee
->current_network
) &&
1338 (ieee
->modulation
& IEEE80211_OFDM_MODULATION
)){
1341 printk(KERN_INFO
"Using G rates:%d\n", ieee
->rate
);
1344 printk(KERN_INFO
"Using B rates:%d\n", ieee
->rate
);
1346 if (ieee
->pHTInfo
->bCurrentHTSupport
&&ieee
->pHTInfo
->bEnableHT
)
1348 printk("Successfully associated, ht enabled\n");
1353 printk("Successfully associated, ht not enabled(%d, %d)\n", ieee
->pHTInfo
->bCurrentHTSupport
, ieee
->pHTInfo
->bEnableHT
);
1354 memset(ieee
->dot11HTOperationalRateSet
, 0, 16);
1355 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1357 ieee
->LinkDetectInfo
.SlotNum
= 2 * (1 + ieee
->current_network
.beacon_interval
/500);
1358 // To prevent the immediately calling watch_dog after association.
1359 if(ieee
->LinkDetectInfo
.NumRecvBcnInPeriod
==0||ieee
->LinkDetectInfo
.NumRecvDataInPeriod
==0 )
1361 ieee
->LinkDetectInfo
.NumRecvBcnInPeriod
= 1;
1362 ieee
->LinkDetectInfo
.NumRecvDataInPeriod
= 1;
1364 ieee
->link_change(ieee
->dev
);
1365 if(ieee
->is_silent_reset
== 0){
1366 printk("============>normal associate\n");
1367 notify_wx_assoc_event(ieee
);
1369 else if(ieee
->is_silent_reset
== 1)
1371 printk("==================>silent reset associate\n");
1372 ieee
->is_silent_reset
= 0;
1375 if (ieee
->data_hard_resume
)
1376 ieee
->data_hard_resume(ieee
->dev
);
1377 netif_carrier_on(ieee
->dev
);
1380 static void ieee80211_associate_complete(struct ieee80211_device
*ieee
)
1383 // struct net_device* dev = ieee->dev;
1384 del_timer_sync(&ieee
->associate_timer
);
1386 ieee
->state
= IEEE80211_LINKED
;
1387 //ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet);
1388 queue_work(ieee
->wq
, &ieee
->associate_complete_wq
);
1391 static void ieee80211_associate_procedure_wq(struct work_struct
*work
)
1393 struct ieee80211_device
*ieee
= container_of(work
, struct ieee80211_device
, associate_procedure_wq
);
1394 ieee
->sync_scan_hurryup
= 1;
1395 down(&ieee
->wx_sem
);
1397 if (ieee
->data_hard_stop
)
1398 ieee
->data_hard_stop(ieee
->dev
);
1400 ieee80211_stop_scan(ieee
);
1401 printk("===>%s(), chan:%d\n", __FUNCTION__
, ieee
->current_network
.channel
);
1402 //ieee->set_chan(ieee->dev, ieee->current_network.channel);
1403 HTSetConnectBwMode(ieee
, HT_CHANNEL_WIDTH_20
, HT_EXTCHNL_OFFSET_NO_EXT
);
1405 ieee
->associate_seq
= 1;
1406 ieee80211_associate_step1(ieee
);
1411 inline void ieee80211_softmac_new_net(struct ieee80211_device
*ieee
, struct ieee80211_network
*net
)
1413 u8 tmp_ssid
[IW_ESSID_MAX_SIZE
+1];
1414 int tmp_ssid_len
= 0;
1416 short apset
,ssidset
,ssidbroad
,apmatch
,ssidmatch
;
1418 /* we are interested in new new only if we are not associated
1419 * and we are not associating / authenticating
1421 if (ieee
->state
!= IEEE80211_NOLINK
)
1424 if ((ieee
->iw_mode
== IW_MODE_INFRA
) && !(net
->capability
& WLAN_CAPABILITY_BSS
))
1427 if ((ieee
->iw_mode
== IW_MODE_ADHOC
) && !(net
->capability
& WLAN_CAPABILITY_IBSS
))
1431 if (ieee
->iw_mode
== IW_MODE_INFRA
|| ieee
->iw_mode
== IW_MODE_ADHOC
){
1432 /* if the user specified the AP MAC, we need also the essid
1433 * This could be obtained by beacons or, if the network does not
1434 * broadcast it, it can be put manually.
1436 apset
= ieee
->wap_set
;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
1437 ssidset
= ieee
->ssid_set
;//ieee->current_network.ssid[0] != '\0';
1438 ssidbroad
= !(net
->ssid_len
== 0 || net
->ssid
[0]== '\0');
1439 apmatch
= (memcmp(ieee
->current_network
.bssid
, net
->bssid
, ETH_ALEN
)==0);
1440 ssidmatch
= (ieee
->current_network
.ssid_len
== net
->ssid_len
)&&\
1441 (!strncmp(ieee
->current_network
.ssid
, net
->ssid
, net
->ssid_len
));
1444 if ( /* if the user set the AP check if match.
1445 * if the network does not broadcast essid we check the user supplyed ANY essid
1446 * if the network does broadcast and the user does not set essid it is OK
1447 * if the network does broadcast and the user did set essid chech if essid match
1449 ( apset
&& apmatch
&&
1450 ((ssidset
&& ssidbroad
&& ssidmatch
) || (ssidbroad
&& !ssidset
) || (!ssidbroad
&& ssidset
)) ) ||
1451 /* if the ap is not set, check that the user set the bssid
1452 * and the network does broadcast and that those two bssid matches
1454 (!apset
&& ssidset
&& ssidbroad
&& ssidmatch
)
1456 /* if the essid is hidden replace it with the
1457 * essid provided by the user.
1460 strncpy(tmp_ssid
, ieee
->current_network
.ssid
, IW_ESSID_MAX_SIZE
);
1461 tmp_ssid_len
= ieee
->current_network
.ssid_len
;
1463 memcpy(&ieee
->current_network
, net
, sizeof(struct ieee80211_network
));
1466 strncpy(ieee
->current_network
.ssid
, tmp_ssid
, IW_ESSID_MAX_SIZE
);
1467 ieee
->current_network
.ssid_len
= tmp_ssid_len
;
1469 printk(KERN_INFO
"Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d\n",ieee
->current_network
.ssid
,ieee
->current_network
.channel
, ieee
->current_network
.qos_data
.supported
, ieee
->pHTInfo
->bEnableHT
, ieee
->current_network
.bssht
.bdSupportHT
);
1471 //ieee->pHTInfo->IOTAction = 0;
1472 HTResetIOTSetting(ieee
->pHTInfo
);
1473 if (ieee
->iw_mode
== IW_MODE_INFRA
){
1474 /* Join the network for the first time */
1475 ieee
->AsocRetryCount
= 0;
1476 //for HT by amy 080514
1477 if((ieee
->current_network
.qos_data
.supported
== 1) &&
1478 // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT))
1479 ieee
->current_network
.bssht
.bdSupportHT
)
1480 /*WB, 2008.09.09:bCurrentHTSupport and bEnableHT two flags are going to put together to check whether we are in HT now, so needn't to check bEnableHT flags here. That's is to say we will set to HT support whenever joined AP has the ability to support HT. And whether we are in HT or not, please check bCurrentHTSupport&&bEnableHT now please.*/
1482 // ieee->pHTInfo->bCurrentHTSupport = true;
1483 HTResetSelfAndSavePeerSetting(ieee
, &(ieee
->current_network
));
1487 ieee
->pHTInfo
->bCurrentHTSupport
= false;
1490 ieee
->state
= IEEE80211_ASSOCIATING
;
1491 queue_work(ieee
->wq
, &ieee
->associate_procedure_wq
);
1493 if(ieee80211_is_54g(&ieee
->current_network
) &&
1494 (ieee
->modulation
& IEEE80211_OFDM_MODULATION
)){
1496 ieee
->SetWirelessMode(ieee
->dev
, IEEE_G
);
1497 printk(KERN_INFO
"Using G rates\n");
1500 ieee
->SetWirelessMode(ieee
->dev
, IEEE_B
);
1501 printk(KERN_INFO
"Using B rates\n");
1503 memset(ieee
->dot11HTOperationalRateSet
, 0, 16);
1504 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1505 ieee
->state
= IEEE80211_LINKED
;
1513 void ieee80211_softmac_check_all_nets(struct ieee80211_device
*ieee
)
1515 unsigned long flags
;
1516 struct ieee80211_network
*target
;
1518 spin_lock_irqsave(&ieee
->lock
, flags
);
1520 list_for_each_entry(target
, &ieee
->network_list
, list
) {
1522 /* if the state become different that NOLINK means
1523 * we had found what we are searching for
1526 if (ieee
->state
!= IEEE80211_NOLINK
)
1529 if (ieee
->scan_age
== 0 || time_after(target
->last_scanned
+ ieee
->scan_age
, jiffies
))
1530 ieee80211_softmac_new_net(ieee
, target
);
1533 spin_unlock_irqrestore(&ieee
->lock
, flags
);
1538 static inline u16
auth_parse(struct sk_buff
*skb
, u8
**challenge
, int *chlen
)
1540 struct ieee80211_authentication
*a
;
1542 if (skb
->len
< (sizeof(struct ieee80211_authentication
)-sizeof(struct ieee80211_info_element
))){
1543 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb
->len
);
1547 a
= (struct ieee80211_authentication
*) skb
->data
;
1548 if(skb
->len
> (sizeof(struct ieee80211_authentication
) +3)){
1549 t
= skb
->data
+ sizeof(struct ieee80211_authentication
);
1551 if(*(t
++) == MFIE_TYPE_CHALLENGE
){
1553 *challenge
= kmemdup(t
, *chlen
, GFP_ATOMIC
);
1559 return cpu_to_le16(a
->status
);
1564 static int auth_rq_parse(struct sk_buff
*skb
, u8
*dest
)
1566 struct ieee80211_authentication
*a
;
1568 if (skb
->len
< (sizeof(struct ieee80211_authentication
)-sizeof(struct ieee80211_info_element
))){
1569 IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb
->len
);
1572 a
= (struct ieee80211_authentication
*) skb
->data
;
1574 memcpy(dest
,a
->header
.addr2
, ETH_ALEN
);
1576 if (le16_to_cpu(a
->algorithm
) != WLAN_AUTH_OPEN
)
1577 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
1579 return WLAN_STATUS_SUCCESS
;
1582 static short probe_rq_parse(struct ieee80211_device
*ieee
, struct sk_buff
*skb
, u8
*src
)
1589 struct ieee80211_hdr_3addr
*header
=
1590 (struct ieee80211_hdr_3addr
*) skb
->data
;
1592 if (skb
->len
< sizeof (struct ieee80211_hdr_3addr
))
1593 return -1; /* corrupted */
1595 memcpy(src
,header
->addr2
, ETH_ALEN
);
1597 skbend
= (u8
*)skb
->data
+ skb
->len
;
1599 tag
= skb
->data
+ sizeof (struct ieee80211_hdr_3addr
);
1601 while (tag
+1 < skbend
){
1607 tag
++; /* point to the len field */
1608 tag
= tag
+ *(tag
); /* point to the last data byte of the tag */
1609 tag
++; /* point to the next tag */
1612 //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
1613 if (ssidlen
== 0) return 1;
1615 if (!ssid
) return 1; /* ssid not found in tagged param */
1616 return (!strncmp(ssid
, ieee
->current_network
.ssid
, ssidlen
));
1620 static int assoc_rq_parse(struct sk_buff
*skb
, u8
*dest
)
1622 struct ieee80211_assoc_request_frame
*a
;
1624 if (skb
->len
< (sizeof(struct ieee80211_assoc_request_frame
) -
1625 sizeof(struct ieee80211_info_element
))) {
1627 IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb
->len
);
1631 a
= (struct ieee80211_assoc_request_frame
*) skb
->data
;
1633 memcpy(dest
,a
->header
.addr2
,ETH_ALEN
);
1638 static inline u16
assoc_parse(struct ieee80211_device
*ieee
, struct sk_buff
*skb
, int *aid
)
1640 struct ieee80211_assoc_response_frame
*response_head
;
1643 if (skb
->len
< sizeof(struct ieee80211_assoc_response_frame
)){
1644 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb
->len
);
1648 response_head
= (struct ieee80211_assoc_response_frame
*) skb
->data
;
1649 *aid
= le16_to_cpu(response_head
->aid
) & 0x3fff;
1651 status_code
= le16_to_cpu(response_head
->status
);
1652 if((status_code
==WLAN_STATUS_ASSOC_DENIED_RATES
|| \
1653 status_code
==WLAN_STATUS_CAPS_UNSUPPORTED
)&&
1654 ((ieee
->mode
== IEEE_G
) &&
1655 (ieee
->current_network
.mode
== IEEE_N_24G
) &&
1656 (ieee
->AsocRetryCount
++ < (RT_ASOC_RETRY_LIMIT
-1)))) {
1657 ieee
->pHTInfo
->IOTAction
|= HT_IOT_ACT_PURE_N_MODE
;
1659 ieee
->AsocRetryCount
= 0;
1662 return le16_to_cpu(response_head
->status
);
1666 ieee80211_rx_probe_rq(struct ieee80211_device
*ieee
, struct sk_buff
*skb
)
1670 //IEEE80211DMESG("Rx probe");
1671 ieee
->softmac_stats
.rx_probe_rq
++;
1672 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1673 if (probe_rq_parse(ieee
, skb
, dest
)){
1674 //IEEE80211DMESG("Was for me!");
1675 ieee
->softmac_stats
.tx_probe_rs
++;
1676 ieee80211_resp_to_probe(ieee
, dest
);
1681 ieee80211_rx_auth_rq(struct ieee80211_device
*ieee
, struct sk_buff
*skb
)
1685 //IEEE80211DMESG("Rx probe");
1686 ieee
->softmac_stats
.rx_auth_rq
++;
1688 status
= auth_rq_parse(skb
, dest
);
1690 ieee80211_resp_to_auth(ieee
, status
, dest
);
1692 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1697 ieee80211_rx_assoc_rq(struct ieee80211_device
*ieee
, struct sk_buff
*skb
)
1701 //unsigned long flags;
1703 ieee
->softmac_stats
.rx_ass_rq
++;
1704 if (assoc_rq_parse(skb
,dest
) != -1){
1705 ieee80211_resp_to_assoc_rq(ieee
, dest
);
1708 printk(KERN_INFO
"New client associated: %pM\n", dest
);
1714 static void ieee80211_sta_ps_send_null_frame(struct ieee80211_device
*ieee
,
1718 struct sk_buff
*buf
= ieee80211_null_func(ieee
, pwr
);
1721 softmac_ps_mgmt_xmit(buf
, ieee
);
1726 static short ieee80211_sta_ps_sleep(struct ieee80211_device
*ieee
, u32
*time_h
,
1729 int timeout
= ieee
->ps_timeout
;
1731 /*if(ieee->ps == IEEE80211_PS_DISABLED ||
1732 ieee->iw_mode != IW_MODE_INFRA ||
1733 ieee->state != IEEE80211_LINKED)
1737 dtim
= ieee
->current_network
.dtim_data
;
1739 if(!(dtim
& IEEE80211_DTIM_VALID
))
1741 timeout
= ieee
->current_network
.beacon_interval
; //should we use ps_timeout value or beacon_interval
1742 //printk("VALID\n");
1743 ieee
->current_network
.dtim_data
= IEEE80211_DTIM_INVALID
;
1745 if(dtim
& ((IEEE80211_DTIM_UCAST
| IEEE80211_DTIM_MBCAST
)& ieee
->ps
))
1748 if(!time_after(jiffies
, ieee
->dev
->trans_start
+ MSECS(timeout
)))
1751 if(!time_after(jiffies
, ieee
->last_rx_ps_time
+ MSECS(timeout
)))
1754 if((ieee
->softmac_features
& IEEE_SOFTMAC_SINGLE_QUEUE
) &&
1755 (ieee
->mgmt_queue_tail
!= ieee
->mgmt_queue_head
))
1759 *time_l
= ieee
->current_network
.last_dtim_sta_time
[0]
1760 + (ieee
->current_network
.beacon_interval
1761 * ieee
->current_network
.dtim_period
) * 1000;
1765 *time_h
= ieee
->current_network
.last_dtim_sta_time
[1];
1766 if(time_l
&& *time_l
< ieee
->current_network
.last_dtim_sta_time
[0])
1775 static inline void ieee80211_sta_ps(struct ieee80211_device
*ieee
)
1781 unsigned long flags
,flags2
;
1783 spin_lock_irqsave(&ieee
->lock
, flags
);
1785 if((ieee
->ps
== IEEE80211_PS_DISABLED
||
1786 ieee
->iw_mode
!= IW_MODE_INFRA
||
1787 ieee
->state
!= IEEE80211_LINKED
)){
1789 // #warning CHECK_LOCK_HERE
1790 spin_lock_irqsave(&ieee
->mgmt_tx_lock
, flags2
);
1792 ieee80211_sta_wakeup(ieee
, 1);
1794 spin_unlock_irqrestore(&ieee
->mgmt_tx_lock
, flags2
);
1797 sleep
= ieee80211_sta_ps_sleep(ieee
,&th
, &tl
);
1798 /* 2 wake, 1 sleep, 0 do nothing */
1804 if(ieee
->sta_sleep
== 1)
1805 ieee
->enter_sleep_state(ieee
->dev
,th
,tl
);
1807 else if(ieee
->sta_sleep
== 0){
1808 // printk("send null 1\n");
1809 spin_lock_irqsave(&ieee
->mgmt_tx_lock
, flags2
);
1811 if(ieee
->ps_is_queue_empty(ieee
->dev
)){
1814 ieee
->sta_sleep
= 2;
1816 ieee
->ps_request_tx_ack(ieee
->dev
);
1818 ieee80211_sta_ps_send_null_frame(ieee
,1);
1823 spin_unlock_irqrestore(&ieee
->mgmt_tx_lock
, flags2
);
1828 }else if(sleep
== 2){
1829 //#warning CHECK_LOCK_HERE
1830 spin_lock_irqsave(&ieee
->mgmt_tx_lock
, flags2
);
1832 ieee80211_sta_wakeup(ieee
,1);
1834 spin_unlock_irqrestore(&ieee
->mgmt_tx_lock
, flags2
);
1838 spin_unlock_irqrestore(&ieee
->lock
, flags
);
1842 void ieee80211_sta_wakeup(struct ieee80211_device
*ieee
, short nl
)
1844 if(ieee
->sta_sleep
== 0){
1846 printk("Warning: driver is probably failing to report TX ps error\n");
1847 ieee
->ps_request_tx_ack(ieee
->dev
);
1848 ieee80211_sta_ps_send_null_frame(ieee
, 0);
1854 if(ieee
->sta_sleep
== 1)
1855 ieee
->sta_wake_up(ieee
->dev
);
1857 ieee
->sta_sleep
= 0;
1860 ieee
->ps_request_tx_ack(ieee
->dev
);
1861 ieee80211_sta_ps_send_null_frame(ieee
, 0);
1865 void ieee80211_ps_tx_ack(struct ieee80211_device
*ieee
, short success
)
1867 unsigned long flags
,flags2
;
1869 spin_lock_irqsave(&ieee
->lock
, flags
);
1871 if(ieee
->sta_sleep
== 2){
1872 /* Null frame with PS bit set */
1874 ieee
->sta_sleep
= 1;
1875 ieee
->enter_sleep_state(ieee
->dev
,ieee
->ps_th
,ieee
->ps_tl
);
1877 /* if the card report not success we can't be sure the AP
1878 * has not RXed so we can't assume the AP believe us awake
1881 /* 21112005 - tx again null without PS bit if lost */
1884 if((ieee
->sta_sleep
== 0) && !success
){
1885 spin_lock_irqsave(&ieee
->mgmt_tx_lock
, flags2
);
1886 ieee80211_sta_ps_send_null_frame(ieee
, 0);
1887 spin_unlock_irqrestore(&ieee
->mgmt_tx_lock
, flags2
);
1890 spin_unlock_irqrestore(&ieee
->lock
, flags
);
1892 static void ieee80211_process_action(struct ieee80211_device
*ieee
,
1893 struct sk_buff
*skb
)
1895 struct ieee80211_hdr
*header
= (struct ieee80211_hdr
*)skb
->data
;
1896 u8
*act
= ieee80211_get_payload(header
);
1898 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
1901 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "error to get payload of action frame\n");
1909 if (*act
== ACT_ADDBAREQ
)
1910 ieee80211_rx_ADDBAReq(ieee
, skb
);
1911 else if (*act
== ACT_ADDBARSP
)
1912 ieee80211_rx_ADDBARsp(ieee
, skb
);
1913 else if (*act
== ACT_DELBA
)
1914 ieee80211_rx_DELBA(ieee
, skb
);
1917 // if (net_ratelimit())
1918 // IEEE80211_DEBUG(IEEE80211_DL_BA, "unknown action frame(%d)\n", tmp);
1925 ieee80211_rx_frame_softmac(struct ieee80211_device
*ieee
, struct sk_buff
*skb
,
1926 struct ieee80211_rx_stats
*rx_stats
, u16 type
,
1929 struct ieee80211_hdr_3addr
*header
= (struct ieee80211_hdr_3addr
*) skb
->data
;
1934 struct ieee80211_assoc_response_frame
*assoc_resp
;
1935 // struct ieee80211_info_element *info_element;
1936 bool bSupportNmode
= true, bHalfSupportNmode
= false; //default support N mode, disable halfNmode
1938 if(!ieee
->proto_started
)
1941 if(ieee
->sta_sleep
|| (ieee
->ps
!= IEEE80211_PS_DISABLED
&&
1942 ieee
->iw_mode
== IW_MODE_INFRA
&&
1943 ieee
->state
== IEEE80211_LINKED
))
1945 tasklet_schedule(&ieee
->ps_task
);
1947 if(WLAN_FC_GET_STYPE(header
->frame_ctl
) != IEEE80211_STYPE_PROBE_RESP
&&
1948 WLAN_FC_GET_STYPE(header
->frame_ctl
) != IEEE80211_STYPE_BEACON
)
1949 ieee
->last_rx_ps_time
= jiffies
;
1951 switch (WLAN_FC_GET_STYPE(header
->frame_ctl
)) {
1953 case IEEE80211_STYPE_ASSOC_RESP
:
1954 case IEEE80211_STYPE_REASSOC_RESP
:
1956 IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
1957 WLAN_FC_GET_STYPE(header
->frame_ctl
));
1958 if ((ieee
->softmac_features
& IEEE_SOFTMAC_ASSOCIATE
) &&
1959 ieee
->state
== IEEE80211_ASSOCIATING_AUTHENTICATED
&&
1960 ieee
->iw_mode
== IW_MODE_INFRA
){
1961 struct ieee80211_network network_resp
;
1962 struct ieee80211_network
*network
= &network_resp
;
1964 errcode
= assoc_parse(ieee
, skb
, &aid
);
1966 ieee
->state
=IEEE80211_LINKED
;
1967 ieee
->assoc_id
= aid
;
1968 ieee
->softmac_stats
.rx_ass_ok
++;
1969 /* station support qos */
1970 /* Let the register setting defaultly with Legacy station */
1971 if(ieee
->qos_support
) {
1972 assoc_resp
= (struct ieee80211_assoc_response_frame
*)skb
->data
;
1973 memset(network
, 0, sizeof(*network
));
1974 if (ieee80211_parse_info_param(ieee
,assoc_resp
->info_element
,\
1975 rx_stats
->len
- sizeof(*assoc_resp
),\
1980 { //filling the PeerHTCap. //maybe not necessary as we can get its info from current_network.
1981 memcpy(ieee
->pHTInfo
->PeerHTCapBuf
, network
->bssht
.bdHTCapBuf
, network
->bssht
.bdHTCapLen
);
1982 memcpy(ieee
->pHTInfo
->PeerHTInfoBuf
, network
->bssht
.bdHTInfoBuf
, network
->bssht
.bdHTInfoLen
);
1984 if (ieee
->handle_assoc_response
!= NULL
)
1985 ieee
->handle_assoc_response(ieee
->dev
, (struct ieee80211_assoc_response_frame
*)header
, network
);
1987 ieee80211_associate_complete(ieee
);
1989 /* aid could not been allocated */
1990 ieee
->softmac_stats
.rx_ass_err
++;
1992 "Association response status code 0x%x\n",
1994 IEEE80211_DEBUG_MGMT(
1995 "Association response status code 0x%x\n",
1997 if(ieee
->AsocRetryCount
< RT_ASOC_RETRY_LIMIT
) {
1998 queue_work(ieee
->wq
, &ieee
->associate_procedure_wq
);
2000 ieee80211_associate_abort(ieee
);
2006 case IEEE80211_STYPE_ASSOC_REQ
:
2007 case IEEE80211_STYPE_REASSOC_REQ
:
2009 if ((ieee
->softmac_features
& IEEE_SOFTMAC_ASSOCIATE
) &&
2010 ieee
->iw_mode
== IW_MODE_MASTER
)
2012 ieee80211_rx_assoc_rq(ieee
, skb
);
2015 case IEEE80211_STYPE_AUTH
:
2017 if (ieee
->softmac_features
& IEEE_SOFTMAC_ASSOCIATE
){
2018 if (ieee
->state
== IEEE80211_ASSOCIATING_AUTHENTICATING
&&
2019 ieee
->iw_mode
== IW_MODE_INFRA
){
2021 IEEE80211_DEBUG_MGMT("Received authentication response");
2023 errcode
= auth_parse(skb
, &challenge
, &chlen
);
2025 if(ieee
->open_wep
|| !challenge
){
2026 ieee
->state
= IEEE80211_ASSOCIATING_AUTHENTICATED
;
2027 ieee
->softmac_stats
.rx_auth_rs_ok
++;
2028 if(!(ieee
->pHTInfo
->IOTAction
&HT_IOT_ACT_PURE_N_MODE
))
2030 if (!ieee
->GetNmodeSupportBySecCfg(ieee
->dev
))
2032 // WEP or TKIP encryption
2033 if(IsHTHalfNmodeAPs(ieee
))
2035 bSupportNmode
= true;
2036 bHalfSupportNmode
= true;
2040 bSupportNmode
= false;
2041 bHalfSupportNmode
= false;
2043 printk("==========>to link with AP using SEC(%d, %d)", bSupportNmode
, bHalfSupportNmode
);
2046 /* Dummy wirless mode setting to avoid encryption issue */
2049 ieee
->SetWirelessMode(ieee
->dev
, \
2050 ieee
->current_network
.mode
);
2054 ieee
->SetWirelessMode(ieee
->dev
, IEEE_G
);
2057 if (ieee
->current_network
.mode
== IEEE_N_24G
&& bHalfSupportNmode
== true)
2059 printk("===============>entern half N mode\n");
2060 ieee
->bHalfWirelessN24GMode
= true;
2063 ieee
->bHalfWirelessN24GMode
= false;
2065 ieee80211_associate_step2(ieee
);
2067 ieee80211_auth_challenge(ieee
, challenge
, chlen
);
2070 ieee
->softmac_stats
.rx_auth_rs_err
++;
2071 IEEE80211_DEBUG_MGMT("Authentication response status code 0x%x",errcode
);
2072 ieee80211_associate_abort(ieee
);
2075 }else if (ieee
->iw_mode
== IW_MODE_MASTER
){
2076 ieee80211_rx_auth_rq(ieee
, skb
);
2081 case IEEE80211_STYPE_PROBE_REQ
:
2083 if ((ieee
->softmac_features
& IEEE_SOFTMAC_PROBERS
) &&
2084 ((ieee
->iw_mode
== IW_MODE_ADHOC
||
2085 ieee
->iw_mode
== IW_MODE_MASTER
) &&
2086 ieee
->state
== IEEE80211_LINKED
)){
2087 ieee80211_rx_probe_rq(ieee
, skb
);
2091 case IEEE80211_STYPE_DISASSOC
:
2092 case IEEE80211_STYPE_DEAUTH
:
2093 /* FIXME for now repeat all the association procedure
2094 * both for disassociation and deauthentication
2096 if ((ieee
->softmac_features
& IEEE_SOFTMAC_ASSOCIATE
) &&
2097 ieee
->state
== IEEE80211_LINKED
&&
2098 ieee
->iw_mode
== IW_MODE_INFRA
){
2100 ieee
->state
= IEEE80211_ASSOCIATING
;
2101 ieee
->softmac_stats
.reassoc
++;
2103 notify_wx_assoc_event(ieee
);
2104 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2105 RemovePeerTS(ieee
, header
->addr2
);
2106 queue_work(ieee
->wq
, &ieee
->associate_procedure_wq
);
2109 case IEEE80211_STYPE_MANAGE_ACT
:
2110 ieee80211_process_action(ieee
,skb
);
2117 //dev_kfree_skb_any(skb);
2121 /* following are for a simpler TX queue management.
2122 * Instead of using netif_[stop/wake]_queue the driver
2123 * will uses these two function (plus a reset one), that
2124 * will internally uses the kernel netif_* and takes
2125 * care of the ieee802.11 fragmentation.
2126 * So the driver receives a fragment per time and might
2127 * call the stop function when it want without take care
2128 * to have enought room to TX an entire packet.
2129 * This might be useful if each fragment need it's own
2130 * descriptor, thus just keep a total free memory > than
2131 * the max fragmentation treshold is not enought.. If the
2132 * ieee802.11 stack passed a TXB struct then you needed
2133 * to keep N free descriptors where
2134 * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
2135 * In this way you need just one and the 802.11 stack
2136 * will take care of buffering fragments and pass them to
2137 * to the driver later, when it wakes the queue.
2139 void ieee80211_softmac_xmit(struct ieee80211_txb
*txb
, struct ieee80211_device
*ieee
)
2142 unsigned int queue_index
= txb
->queue_index
;
2143 unsigned long flags
;
2145 cb_desc
*tcb_desc
= NULL
;
2147 spin_lock_irqsave(&ieee
->lock
,flags
);
2149 /* called with 2nd parm 0, no tx mgmt lock required */
2150 ieee80211_sta_wakeup(ieee
,0);
2152 /* update the tx status */
2153 ieee
->stats
.tx_bytes
+= txb
->payload_size
;
2154 ieee
->stats
.tx_packets
++;
2155 tcb_desc
= (cb_desc
*)(txb
->fragments
[0]->cb
+ MAX_DEV_ADDR_SIZE
);
2156 if(tcb_desc
->bMulticast
) {
2157 ieee
->stats
.multicast
++;
2159 /* if xmit available, just xmit it immediately, else just insert it to the wait queue */
2160 for(i
= 0; i
< txb
->nr_frags
; i
++) {
2161 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2162 if ((skb_queue_len(&ieee
->skb_drv_aggQ
[queue_index
]) != 0) ||
2164 if ((skb_queue_len(&ieee
->skb_waitQ
[queue_index
]) != 0) ||
2166 (!ieee
->check_nic_enough_desc(ieee
->dev
,queue_index
))||\
2167 (ieee
->queue_stop
)) {
2168 /* insert the skb packet to the wait queue */
2169 /* as for the completion function, it does not need
2170 * to check it any more.
2172 //printk("error:no descriptor left@queue_index %d\n", queue_index);
2173 //ieee80211_stop_queue(ieee);
2174 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2175 skb_queue_tail(&ieee
->skb_drv_aggQ
[queue_index
], txb
->fragments
[i
]);
2177 skb_queue_tail(&ieee
->skb_waitQ
[queue_index
], txb
->fragments
[i
]);
2180 ieee
->softmac_data_hard_start_xmit(
2182 ieee
->dev
,ieee
->rate
);
2183 //ieee->stats.tx_packets++;
2184 //ieee->stats.tx_bytes += txb->fragments[i]->len;
2185 //ieee->dev->trans_start = jiffies;
2188 ieee80211_txb_free(txb
);
2191 spin_unlock_irqrestore(&ieee
->lock
,flags
);
2195 /* called with ieee->lock acquired */
2196 static void ieee80211_resume_tx(struct ieee80211_device
*ieee
)
2199 for(i
= ieee
->tx_pending
.frag
; i
< ieee
->tx_pending
.txb
->nr_frags
; i
++) {
2201 if (ieee
->queue_stop
){
2202 ieee
->tx_pending
.frag
= i
;
2206 ieee
->softmac_data_hard_start_xmit(
2207 ieee
->tx_pending
.txb
->fragments
[i
],
2208 ieee
->dev
,ieee
->rate
);
2209 //(i+1)<ieee->tx_pending.txb->nr_frags);
2210 ieee
->stats
.tx_packets
++;
2211 ieee
->dev
->trans_start
= jiffies
;
2216 ieee80211_txb_free(ieee
->tx_pending
.txb
);
2217 ieee
->tx_pending
.txb
= NULL
;
2221 void ieee80211_reset_queue(struct ieee80211_device
*ieee
)
2223 unsigned long flags
;
2225 spin_lock_irqsave(&ieee
->lock
,flags
);
2226 init_mgmt_queue(ieee
);
2227 if (ieee
->tx_pending
.txb
){
2228 ieee80211_txb_free(ieee
->tx_pending
.txb
);
2229 ieee
->tx_pending
.txb
= NULL
;
2231 ieee
->queue_stop
= 0;
2232 spin_unlock_irqrestore(&ieee
->lock
,flags
);
2236 void ieee80211_wake_queue(struct ieee80211_device
*ieee
)
2239 unsigned long flags
;
2240 struct sk_buff
*skb
;
2241 struct ieee80211_hdr_3addr
*header
;
2243 spin_lock_irqsave(&ieee
->lock
,flags
);
2244 if (! ieee
->queue_stop
) goto exit
;
2246 ieee
->queue_stop
= 0;
2248 if(ieee
->softmac_features
& IEEE_SOFTMAC_SINGLE_QUEUE
){
2249 while (!ieee
->queue_stop
&& (skb
= dequeue_mgmt(ieee
))){
2251 header
= (struct ieee80211_hdr_3addr
*) skb
->data
;
2253 header
->seq_ctl
= cpu_to_le16(ieee
->seq_ctrl
[0] << 4);
2255 if (ieee
->seq_ctrl
[0] == 0xFFF)
2256 ieee
->seq_ctrl
[0] = 0;
2258 ieee
->seq_ctrl
[0]++;
2260 ieee
->softmac_data_hard_start_xmit(skb
,ieee
->dev
,ieee
->basic_rate
);
2261 //dev_kfree_skb_any(skb);//edit by thomas
2264 if (!ieee
->queue_stop
&& ieee
->tx_pending
.txb
)
2265 ieee80211_resume_tx(ieee
);
2267 if (!ieee
->queue_stop
&& netif_queue_stopped(ieee
->dev
)){
2268 ieee
->softmac_stats
.swtxawake
++;
2269 netif_wake_queue(ieee
->dev
);
2273 spin_unlock_irqrestore(&ieee
->lock
,flags
);
2277 void ieee80211_stop_queue(struct ieee80211_device
*ieee
)
2279 //unsigned long flags;
2280 //spin_lock_irqsave(&ieee->lock,flags);
2282 if (! netif_queue_stopped(ieee
->dev
)){
2283 netif_stop_queue(ieee
->dev
);
2284 ieee
->softmac_stats
.swtxstop
++;
2286 ieee
->queue_stop
= 1;
2287 //spin_unlock_irqrestore(&ieee->lock,flags);
2292 inline void ieee80211_randomize_cell(struct ieee80211_device
*ieee
)
2295 random_ether_addr(ieee
->current_network
.bssid
);
2298 /* called in user context only */
2299 void ieee80211_start_master_bss(struct ieee80211_device
*ieee
)
2303 if (ieee
->current_network
.ssid_len
== 0){
2304 strncpy(ieee
->current_network
.ssid
,
2305 IEEE80211_DEFAULT_TX_ESSID
,
2308 ieee
->current_network
.ssid_len
= strlen(IEEE80211_DEFAULT_TX_ESSID
);
2312 memcpy(ieee
->current_network
.bssid
, ieee
->dev
->dev_addr
, ETH_ALEN
);
2314 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
2315 ieee
->state
= IEEE80211_LINKED
;
2316 ieee
->link_change(ieee
->dev
);
2317 notify_wx_assoc_event(ieee
);
2319 if (ieee
->data_hard_resume
)
2320 ieee
->data_hard_resume(ieee
->dev
);
2322 netif_carrier_on(ieee
->dev
);
2325 static void ieee80211_start_monitor_mode(struct ieee80211_device
*ieee
)
2329 if (ieee
->data_hard_resume
)
2330 ieee
->data_hard_resume(ieee
->dev
);
2332 netif_carrier_on(ieee
->dev
);
2335 static void ieee80211_start_ibss_wq(struct work_struct
*work
)
2338 struct delayed_work
*dwork
= container_of(work
, struct delayed_work
, work
);
2339 struct ieee80211_device
*ieee
= container_of(dwork
, struct ieee80211_device
, start_ibss_wq
);
2340 /* iwconfig mode ad-hoc will schedule this and return
2341 * on the other hand this will block further iwconfig SET
2342 * operations because of the wx_sem hold.
2343 * Anyway some most set operations set a flag to speed-up
2344 * (abort) this wq (when syncro scanning) before sleeping
2347 if(!ieee
->proto_started
){
2348 printk("==========oh driver down return\n");
2351 down(&ieee
->wx_sem
);
2353 if (ieee
->current_network
.ssid_len
== 0){
2354 strcpy(ieee
->current_network
.ssid
,IEEE80211_DEFAULT_TX_ESSID
);
2355 ieee
->current_network
.ssid_len
= strlen(IEEE80211_DEFAULT_TX_ESSID
);
2359 /* check if we have this cell in our network list */
2360 ieee80211_softmac_check_all_nets(ieee
);
2363 // if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK))
2364 if (ieee
->state
== IEEE80211_NOLINK
)
2365 ieee
->current_network
.channel
= 6;
2366 /* if not then the state is not linked. Maybe the user swithced to
2367 * ad-hoc mode just after being in monitor mode, or just after
2368 * being very few time in managed mode (so the card have had no
2369 * time to scan all the chans..) or we have just run up the iface
2370 * after setting ad-hoc mode. So we have to give another try..
2371 * Here, in ibss mode, should be safe to do this without extra care
2372 * (in bss mode we had to make sure no-one tryed to associate when
2373 * we had just checked the ieee->state and we was going to start the
2374 * scan) beacause in ibss mode the ieee80211_new_net function, when
2375 * finds a good net, just set the ieee->state to IEEE80211_LINKED,
2376 * so, at worst, we waste a bit of time to initiate an unneeded syncro
2377 * scan, that will stop at the first round because it sees the state
2380 if (ieee
->state
== IEEE80211_NOLINK
)
2381 ieee80211_start_scan_syncro(ieee
);
2383 /* the network definitively is not here.. create a new cell */
2384 if (ieee
->state
== IEEE80211_NOLINK
){
2385 printk("creating new IBSS cell\n");
2387 ieee80211_randomize_cell(ieee
);
2389 if(ieee
->modulation
& IEEE80211_CCK_MODULATION
){
2391 ieee
->current_network
.rates_len
= 4;
2393 ieee
->current_network
.rates
[0] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_1MB
;
2394 ieee
->current_network
.rates
[1] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_2MB
;
2395 ieee
->current_network
.rates
[2] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_5MB
;
2396 ieee
->current_network
.rates
[3] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_11MB
;
2399 ieee
->current_network
.rates_len
= 0;
2401 if(ieee
->modulation
& IEEE80211_OFDM_MODULATION
){
2402 ieee
->current_network
.rates_ex_len
= 8;
2404 ieee
->current_network
.rates_ex
[0] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_6MB
;
2405 ieee
->current_network
.rates_ex
[1] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_9MB
;
2406 ieee
->current_network
.rates_ex
[2] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_12MB
;
2407 ieee
->current_network
.rates_ex
[3] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_18MB
;
2408 ieee
->current_network
.rates_ex
[4] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_24MB
;
2409 ieee
->current_network
.rates_ex
[5] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_36MB
;
2410 ieee
->current_network
.rates_ex
[6] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_48MB
;
2411 ieee
->current_network
.rates_ex
[7] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_54MB
;
2415 ieee
->current_network
.rates_ex_len
= 0;
2419 // By default, WMM function will be disabled in IBSS mode
2420 ieee
->current_network
.QoS_Enable
= 0;
2421 ieee
->SetWirelessMode(ieee
->dev
, IEEE_G
);
2422 ieee
->current_network
.atim_window
= 0;
2423 ieee
->current_network
.capability
= WLAN_CAPABILITY_IBSS
;
2424 if(ieee
->short_slot
)
2425 ieee
->current_network
.capability
|= WLAN_CAPABILITY_SHORT_SLOT
;
2429 ieee
->state
= IEEE80211_LINKED
;
2431 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
2432 ieee
->link_change(ieee
->dev
);
2434 notify_wx_assoc_event(ieee
);
2436 ieee80211_start_send_beacons(ieee
);
2438 if (ieee
->data_hard_resume
)
2439 ieee
->data_hard_resume(ieee
->dev
);
2440 netif_carrier_on(ieee
->dev
);
2445 inline void ieee80211_start_ibss(struct ieee80211_device
*ieee
)
2447 queue_delayed_work(ieee
->wq
, &ieee
->start_ibss_wq
, 150);
2450 /* this is called only in user context, with wx_sem held */
2451 void ieee80211_start_bss(struct ieee80211_device
*ieee
)
2453 unsigned long flags
;
2455 // Ref: 802.11d 11.1.3.3
2456 // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
2458 if(IS_DOT11D_ENABLE(ieee
) && !IS_COUNTRY_IE_VALID(ieee
))
2460 if(! ieee
->bGlobalDomain
)
2465 /* check if we have already found the net we
2466 * are interested in (if any).
2467 * if not (we are disassociated and we are not
2468 * in associating / authenticating phase) start the background scanning.
2470 ieee80211_softmac_check_all_nets(ieee
);
2472 /* ensure no-one start an associating process (thus setting
2473 * the ieee->state to ieee80211_ASSOCIATING) while we
2474 * have just cheked it and we are going to enable scan.
2475 * The ieee80211_new_net function is always called with
2476 * lock held (from both ieee80211_softmac_check_all_nets and
2477 * the rx path), so we cannot be in the middle of such function
2479 spin_lock_irqsave(&ieee
->lock
, flags
);
2481 if (ieee
->state
== IEEE80211_NOLINK
){
2482 ieee
->actscanning
= true;
2483 ieee80211_start_scan(ieee
);
2485 spin_unlock_irqrestore(&ieee
->lock
, flags
);
2488 /* called only in userspace context */
2489 void ieee80211_disassociate(struct ieee80211_device
*ieee
)
2493 netif_carrier_off(ieee
->dev
);
2494 if (ieee
->softmac_features
& IEEE_SOFTMAC_TX_QUEUE
)
2495 ieee80211_reset_queue(ieee
);
2497 if (ieee
->data_hard_stop
)
2498 ieee
->data_hard_stop(ieee
->dev
);
2499 if(IS_DOT11D_ENABLE(ieee
))
2501 ieee
->state
= IEEE80211_NOLINK
;
2502 ieee
->is_set_key
= false;
2503 ieee
->link_change(ieee
->dev
);
2504 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2505 notify_wx_assoc_event(ieee
);
2508 static void ieee80211_associate_retry_wq(struct work_struct
*work
)
2510 struct delayed_work
*dwork
= container_of(work
, struct delayed_work
, work
);
2511 struct ieee80211_device
*ieee
= container_of(dwork
, struct ieee80211_device
, associate_retry_wq
);
2512 unsigned long flags
;
2514 down(&ieee
->wx_sem
);
2515 if(!ieee
->proto_started
)
2518 if(ieee
->state
!= IEEE80211_ASSOCIATING_RETRY
)
2521 /* until we do not set the state to IEEE80211_NOLINK
2522 * there are no possibility to have someone else trying
2523 * to start an association procedure (we get here with
2524 * ieee->state = IEEE80211_ASSOCIATING).
2525 * When we set the state to IEEE80211_NOLINK it is possible
2526 * that the RX path run an attempt to associate, but
2527 * both ieee80211_softmac_check_all_nets and the
2528 * RX path works with ieee->lock held so there are no
2529 * problems. If we are still disassociated then start a scan.
2530 * the lock here is necessary to ensure no one try to start
2531 * an association procedure when we have just checked the
2532 * state and we are going to start the scan.
2534 ieee
->state
= IEEE80211_NOLINK
;
2536 ieee80211_softmac_check_all_nets(ieee
);
2538 spin_lock_irqsave(&ieee
->lock
, flags
);
2540 if(ieee
->state
== IEEE80211_NOLINK
)
2541 ieee80211_start_scan(ieee
);
2543 spin_unlock_irqrestore(&ieee
->lock
, flags
);
2549 struct sk_buff
*ieee80211_get_beacon_(struct ieee80211_device
*ieee
)
2551 u8 broadcast_addr
[] = {0xff,0xff,0xff,0xff,0xff,0xff};
2553 struct sk_buff
*skb
;
2554 struct ieee80211_probe_response
*b
;
2556 skb
= ieee80211_probe_resp(ieee
, broadcast_addr
);
2561 b
= (struct ieee80211_probe_response
*) skb
->data
;
2562 b
->header
.frame_ctl
= cpu_to_le16(IEEE80211_STYPE_BEACON
);
2568 struct sk_buff
*ieee80211_get_beacon(struct ieee80211_device
*ieee
)
2570 struct sk_buff
*skb
;
2571 struct ieee80211_probe_response
*b
;
2573 skb
= ieee80211_get_beacon_(ieee
);
2577 b
= (struct ieee80211_probe_response
*) skb
->data
;
2578 b
->header
.seq_ctl
= cpu_to_le16(ieee
->seq_ctrl
[0] << 4);
2580 if (ieee
->seq_ctrl
[0] == 0xFFF)
2581 ieee
->seq_ctrl
[0] = 0;
2583 ieee
->seq_ctrl
[0]++;
2588 void ieee80211_softmac_stop_protocol(struct ieee80211_device
*ieee
)
2590 ieee
->sync_scan_hurryup
= 1;
2591 down(&ieee
->wx_sem
);
2592 ieee80211_stop_protocol(ieee
);
2597 void ieee80211_stop_protocol(struct ieee80211_device
*ieee
)
2599 if (!ieee
->proto_started
)
2602 ieee
->proto_started
= 0;
2604 ieee80211_stop_send_beacons(ieee
);
2605 del_timer_sync(&ieee
->associate_timer
);
2606 cancel_delayed_work(&ieee
->associate_retry_wq
);
2607 cancel_delayed_work(&ieee
->start_ibss_wq
);
2608 ieee80211_stop_scan(ieee
);
2610 ieee80211_disassociate(ieee
);
2611 RemoveAllTS(ieee
); //added as we disconnect from the previous BSS, Remove all TS
2614 void ieee80211_softmac_start_protocol(struct ieee80211_device
*ieee
)
2616 ieee
->sync_scan_hurryup
= 0;
2617 down(&ieee
->wx_sem
);
2618 ieee80211_start_protocol(ieee
);
2622 void ieee80211_start_protocol(struct ieee80211_device
*ieee
)
2626 if (ieee
->proto_started
)
2629 ieee
->proto_started
= 1;
2631 if (ieee
->current_network
.channel
== 0){
2634 if (ch
> MAX_CHANNEL_NUMBER
)
2635 return; /* no channel found */
2636 }while(!GET_DOT11D_INFO(ieee
)->channel_map
[ch
]);
2637 ieee
->current_network
.channel
= ch
;
2640 if (ieee
->current_network
.beacon_interval
== 0)
2641 ieee
->current_network
.beacon_interval
= 100;
2642 // printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);
2643 // ieee->set_chan(ieee->dev,ieee->current_network.channel);
2645 for(i
= 0; i
< 17; i
++) {
2646 ieee
->last_rxseq_num
[i
] = -1;
2647 ieee
->last_rxfrag_num
[i
] = -1;
2648 ieee
->last_packet_time
[i
] = 0;
2651 ieee
->init_wmmparam_flag
= 0;//reinitialize AC_xx_PARAM registers.
2654 /* if the user set the MAC of the ad-hoc cell and then
2655 * switch to managed mode, shall we make sure that association
2656 * attempts does not fail just because the user provide the essid
2657 * and the nic is still checking for the AP MAC ??
2659 if (ieee
->iw_mode
== IW_MODE_INFRA
)
2660 ieee80211_start_bss(ieee
);
2662 else if (ieee
->iw_mode
== IW_MODE_ADHOC
)
2663 ieee80211_start_ibss(ieee
);
2665 else if (ieee
->iw_mode
== IW_MODE_MASTER
)
2666 ieee80211_start_master_bss(ieee
);
2668 else if(ieee
->iw_mode
== IW_MODE_MONITOR
)
2669 ieee80211_start_monitor_mode(ieee
);
2673 #define DRV_NAME "Ieee80211"
2674 void ieee80211_softmac_init(struct ieee80211_device
*ieee
)
2677 memset(&ieee
->current_network
, 0, sizeof(struct ieee80211_network
));
2679 ieee
->state
= IEEE80211_NOLINK
;
2680 ieee
->sync_scan_hurryup
= 0;
2681 for(i
= 0; i
< 5; i
++) {
2682 ieee
->seq_ctrl
[i
] = 0;
2684 ieee
->pDot11dInfo
= kzalloc(sizeof(RT_DOT11D_INFO
), GFP_ATOMIC
);
2685 if (!ieee
->pDot11dInfo
)
2686 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "can't alloc memory for DOT11D\n");
2687 //added for AP roaming
2688 ieee
->LinkDetectInfo
.SlotNum
= 2;
2689 ieee
->LinkDetectInfo
.NumRecvBcnInPeriod
=0;
2690 ieee
->LinkDetectInfo
.NumRecvDataInPeriod
=0;
2693 ieee
->queue_stop
= 0;
2695 ieee
->softmac_features
= 0; //so IEEE2100-like driver are happy
2698 ieee
->proto_started
= 0;
2699 ieee
->basic_rate
= IEEE80211_DEFAULT_BASIC_RATE
;
2701 ieee
->ps
= IEEE80211_PS_DISABLED
;
2702 ieee
->sta_sleep
= 0;
2703 ieee
->Regdot11HTOperationalRateSet
[0]= 0xff;//support MCS 0~7
2704 ieee
->Regdot11HTOperationalRateSet
[1]= 0xff;//support MCS 8~15
2705 ieee
->Regdot11HTOperationalRateSet
[4]= 0x01;
2707 ieee
->actscanning
= false;
2708 ieee
->beinretry
= false;
2709 ieee
->is_set_key
= false;
2710 init_mgmt_queue(ieee
);
2712 ieee
->sta_edca_param
[0] = 0x0000A403;
2713 ieee
->sta_edca_param
[1] = 0x0000A427;
2714 ieee
->sta_edca_param
[2] = 0x005E4342;
2715 ieee
->sta_edca_param
[3] = 0x002F3262;
2716 ieee
->aggregation
= true;
2717 ieee
->enable_rx_imm_BA
= 1;
2718 ieee
->tx_pending
.txb
= NULL
;
2720 init_timer(&ieee
->associate_timer
);
2721 ieee
->associate_timer
.data
= (unsigned long)ieee
;
2722 ieee
->associate_timer
.function
= ieee80211_associate_abort_cb
;
2724 init_timer(&ieee
->beacon_timer
);
2725 ieee
->beacon_timer
.data
= (unsigned long) ieee
;
2726 ieee
->beacon_timer
.function
= ieee80211_send_beacon_cb
;
2728 ieee
->wq
= create_workqueue(DRV_NAME
);
2730 INIT_DELAYED_WORK(&ieee
->start_ibss_wq
,ieee80211_start_ibss_wq
);
2731 INIT_WORK(&ieee
->associate_complete_wq
, ieee80211_associate_complete_wq
);
2732 INIT_WORK(&ieee
->associate_procedure_wq
, ieee80211_associate_procedure_wq
);
2733 INIT_DELAYED_WORK(&ieee
->softmac_scan_wq
,ieee80211_softmac_scan_wq
);
2734 INIT_DELAYED_WORK(&ieee
->associate_retry_wq
, ieee80211_associate_retry_wq
);
2735 INIT_WORK(&ieee
->wx_sync_scan_wq
,ieee80211_wx_sync_scan_wq
);
2738 sema_init(&ieee
->wx_sem
, 1);
2739 sema_init(&ieee
->scan_sem
, 1);
2741 spin_lock_init(&ieee
->mgmt_tx_lock
);
2742 spin_lock_init(&ieee
->beacon_lock
);
2744 tasklet_init(&ieee
->ps_task
,
2745 (void(*)(unsigned long)) ieee80211_sta_ps
,
2746 (unsigned long)ieee
);
2750 void ieee80211_softmac_free(struct ieee80211_device
*ieee
)
2752 down(&ieee
->wx_sem
);
2753 kfree(ieee
->pDot11dInfo
);
2754 ieee
->pDot11dInfo
= NULL
;
2755 del_timer_sync(&ieee
->associate_timer
);
2757 cancel_delayed_work(&ieee
->associate_retry_wq
);
2758 destroy_workqueue(ieee
->wq
);
2763 /********************************************************
2764 * Start of WPA code. *
2765 * this is stolen from the ipw2200 driver *
2766 ********************************************************/
2769 static int ieee80211_wpa_enable(struct ieee80211_device
*ieee
, int value
)
2771 /* This is called when wpa_supplicant loads and closes the driver
2773 printk("%s WPA\n",value
? "enabling" : "disabling");
2774 ieee
->wpa_enabled
= value
;
2779 static void ieee80211_wpa_assoc_frame(struct ieee80211_device
*ieee
,
2780 char *wpa_ie
, int wpa_ie_len
)
2782 /* make sure WPA is enabled */
2783 ieee80211_wpa_enable(ieee
, 1);
2785 ieee80211_disassociate(ieee
);
2789 static int ieee80211_wpa_mlme(struct ieee80211_device
*ieee
, int command
, int reason
)
2795 case IEEE_MLME_STA_DEAUTH
:
2799 case IEEE_MLME_STA_DISASSOC
:
2800 ieee80211_disassociate(ieee
);
2804 printk("Unknown MLME request: %d\n", command
);
2812 static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device
*ieee
,
2813 struct ieee_param
*param
, int plen
)
2817 if (param
->u
.wpa_ie
.len
> MAX_WPA_IE_LEN
||
2818 (param
->u
.wpa_ie
.len
&& param
->u
.wpa_ie
.data
== NULL
))
2821 if (param
->u
.wpa_ie
.len
) {
2822 buf
= kmemdup(param
->u
.wpa_ie
.data
, param
->u
.wpa_ie
.len
,
2827 kfree(ieee
->wpa_ie
);
2829 ieee
->wpa_ie_len
= param
->u
.wpa_ie
.len
;
2831 kfree(ieee
->wpa_ie
);
2832 ieee
->wpa_ie
= NULL
;
2833 ieee
->wpa_ie_len
= 0;
2836 ieee80211_wpa_assoc_frame(ieee
, ieee
->wpa_ie
, ieee
->wpa_ie_len
);
2840 #define AUTH_ALG_OPEN_SYSTEM 0x1
2841 #define AUTH_ALG_SHARED_KEY 0x2
2843 static int ieee80211_wpa_set_auth_algs(struct ieee80211_device
*ieee
, int value
)
2846 struct ieee80211_security sec
= {
2847 .flags
= SEC_AUTH_MODE
,
2851 if (value
& AUTH_ALG_SHARED_KEY
) {
2852 sec
.auth_mode
= WLAN_AUTH_SHARED_KEY
;
2854 ieee
->auth_mode
= 1;
2855 } else if (value
& AUTH_ALG_OPEN_SYSTEM
){
2856 sec
.auth_mode
= WLAN_AUTH_OPEN
;
2858 ieee
->auth_mode
= 0;
2860 else if (value
& IW_AUTH_ALG_LEAP
){
2861 sec
.auth_mode
= WLAN_AUTH_LEAP
;
2863 ieee
->auth_mode
= 2;
2867 if (ieee
->set_security
)
2868 ieee
->set_security(ieee
->dev
, &sec
);
2870 // ret = -EOPNOTSUPP;
2875 static int ieee80211_wpa_set_param(struct ieee80211_device
*ieee
, u8 name
, u32 value
)
2878 unsigned long flags
;
2881 case IEEE_PARAM_WPA_ENABLED
:
2882 ret
= ieee80211_wpa_enable(ieee
, value
);
2885 case IEEE_PARAM_TKIP_COUNTERMEASURES
:
2886 ieee
->tkip_countermeasures
=value
;
2889 case IEEE_PARAM_DROP_UNENCRYPTED
: {
2892 * wpa_supplicant calls set_wpa_enabled when the driver
2893 * is loaded and unloaded, regardless of if WPA is being
2894 * used. No other calls are made which can be used to
2895 * determine if encryption will be used or not prior to
2896 * association being expected. If encryption is not being
2897 * used, drop_unencrypted is set to false, else true -- we
2898 * can use this to determine if the CAP_PRIVACY_ON bit should
2901 struct ieee80211_security sec
= {
2902 .flags
= SEC_ENABLED
,
2905 ieee
->drop_unencrypted
= value
;
2906 /* We only change SEC_LEVEL for open mode. Others
2907 * are set by ipw_wpa_set_encryption.
2910 sec
.flags
|= SEC_LEVEL
;
2911 sec
.level
= SEC_LEVEL_0
;
2914 sec
.flags
|= SEC_LEVEL
;
2915 sec
.level
= SEC_LEVEL_1
;
2917 if (ieee
->set_security
)
2918 ieee
->set_security(ieee
->dev
, &sec
);
2922 case IEEE_PARAM_PRIVACY_INVOKED
:
2923 ieee
->privacy_invoked
=value
;
2926 case IEEE_PARAM_AUTH_ALGS
:
2927 ret
= ieee80211_wpa_set_auth_algs(ieee
, value
);
2930 case IEEE_PARAM_IEEE_802_1X
:
2931 ieee
->ieee802_1x
=value
;
2933 case IEEE_PARAM_WPAX_SELECT
:
2934 // added for WPA2 mixed mode
2935 spin_lock_irqsave(&ieee
->wpax_suitlist_lock
,flags
);
2936 ieee
->wpax_type_set
= 1;
2937 ieee
->wpax_type_notify
= value
;
2938 spin_unlock_irqrestore(&ieee
->wpax_suitlist_lock
,flags
);
2942 printk("Unknown WPA param: %d\n",name
);
2949 /* implementation borrowed from hostap driver */
2951 static int ieee80211_wpa_set_encryption(struct ieee80211_device
*ieee
,
2952 struct ieee_param
*param
, int param_len
)
2956 struct ieee80211_crypto_ops
*ops
;
2957 struct ieee80211_crypt_data
**crypt
;
2959 struct ieee80211_security sec
= {
2963 param
->u
.crypt
.err
= 0;
2964 param
->u
.crypt
.alg
[IEEE_CRYPT_ALG_NAME_LEN
- 1] = '\0';
2967 (int) ((char *) param
->u
.crypt
.key
- (char *) param
) +
2968 param
->u
.crypt
.key_len
) {
2969 printk("Len mismatch %d, %d\n", param_len
,
2970 param
->u
.crypt
.key_len
);
2973 if (is_broadcast_ether_addr(param
->sta_addr
)) {
2974 if (param
->u
.crypt
.idx
>= WEP_KEYS
)
2976 crypt
= &ieee
->crypt
[param
->u
.crypt
.idx
];
2981 if (strcmp(param
->u
.crypt
.alg
, "none") == 0) {
2986 sec
.level
= SEC_LEVEL_0
;
2987 sec
.flags
|= SEC_ENABLED
| SEC_LEVEL
;
2988 ieee80211_crypt_delayed_deinit(ieee
, crypt
);
2995 sec
.flags
|= SEC_ENABLED
;
2997 /* IPW HW cannot build TKIP MIC, host decryption still needed. */
2998 if (!(ieee
->host_encrypt
|| ieee
->host_decrypt
) &&
2999 strcmp(param
->u
.crypt
.alg
, "TKIP"))
3000 goto skip_host_crypt
;
3002 ops
= ieee80211_get_crypto_ops(param
->u
.crypt
.alg
);
3003 if (ops
== NULL
&& strcmp(param
->u
.crypt
.alg
, "WEP") == 0) {
3004 request_module("ieee80211_crypt_wep");
3005 ops
= ieee80211_get_crypto_ops(param
->u
.crypt
.alg
);
3006 //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
3007 } else if (ops
== NULL
&& strcmp(param
->u
.crypt
.alg
, "TKIP") == 0) {
3008 request_module("ieee80211_crypt_tkip");
3009 ops
= ieee80211_get_crypto_ops(param
->u
.crypt
.alg
);
3010 } else if (ops
== NULL
&& strcmp(param
->u
.crypt
.alg
, "CCMP") == 0) {
3011 request_module("ieee80211_crypt_ccmp");
3012 ops
= ieee80211_get_crypto_ops(param
->u
.crypt
.alg
);
3015 printk("unknown crypto alg '%s'\n", param
->u
.crypt
.alg
);
3016 param
->u
.crypt
.err
= IEEE_CRYPT_ERR_UNKNOWN_ALG
;
3021 if (*crypt
== NULL
|| (*crypt
)->ops
!= ops
) {
3022 struct ieee80211_crypt_data
*new_crypt
;
3024 ieee80211_crypt_delayed_deinit(ieee
, crypt
);
3026 new_crypt
= kmalloc(sizeof(*new_crypt
), GFP_KERNEL
);
3027 if (new_crypt
== NULL
) {
3031 memset(new_crypt
, 0, sizeof(struct ieee80211_crypt_data
));
3032 new_crypt
->ops
= ops
;
3033 if (new_crypt
->ops
&& try_module_get(new_crypt
->ops
->owner
))
3035 new_crypt
->ops
->init(param
->u
.crypt
.idx
);
3037 if (new_crypt
->priv
== NULL
) {
3039 param
->u
.crypt
.err
= IEEE_CRYPT_ERR_CRYPT_INIT_FAILED
;
3047 if (param
->u
.crypt
.key_len
> 0 && (*crypt
)->ops
->set_key
&&
3048 (*crypt
)->ops
->set_key(param
->u
.crypt
.key
,
3049 param
->u
.crypt
.key_len
, param
->u
.crypt
.seq
,
3050 (*crypt
)->priv
) < 0) {
3051 printk("key setting failed\n");
3052 param
->u
.crypt
.err
= IEEE_CRYPT_ERR_KEY_SET_FAILED
;
3058 if (param
->u
.crypt
.set_tx
) {
3059 ieee
->tx_keyidx
= param
->u
.crypt
.idx
;
3060 sec
.active_key
= param
->u
.crypt
.idx
;
3061 sec
.flags
|= SEC_ACTIVE_KEY
;
3063 sec
.flags
&= ~SEC_ACTIVE_KEY
;
3065 if (param
->u
.crypt
.alg
!= NULL
) {
3066 memcpy(sec
.keys
[param
->u
.crypt
.idx
],
3068 param
->u
.crypt
.key_len
);
3069 sec
.key_sizes
[param
->u
.crypt
.idx
] = param
->u
.crypt
.key_len
;
3070 sec
.flags
|= (1 << param
->u
.crypt
.idx
);
3072 if (strcmp(param
->u
.crypt
.alg
, "WEP") == 0) {
3073 sec
.flags
|= SEC_LEVEL
;
3074 sec
.level
= SEC_LEVEL_1
;
3075 } else if (strcmp(param
->u
.crypt
.alg
, "TKIP") == 0) {
3076 sec
.flags
|= SEC_LEVEL
;
3077 sec
.level
= SEC_LEVEL_2
;
3078 } else if (strcmp(param
->u
.crypt
.alg
, "CCMP") == 0) {
3079 sec
.flags
|= SEC_LEVEL
;
3080 sec
.level
= SEC_LEVEL_3
;
3084 if (ieee
->set_security
)
3085 ieee
->set_security(ieee
->dev
, &sec
);
3087 /* Do not reset port if card is in Managed mode since resetting will
3088 * generate new IEEE 802.11 authentication which may end up in looping
3089 * with IEEE 802.1X. If your hardware requires a reset after WEP
3090 * configuration (for example... Prism2), implement the reset_port in
3091 * the callbacks structures used to initialize the 802.11 stack. */
3092 if (ieee
->reset_on_keychange
&&
3093 ieee
->iw_mode
!= IW_MODE_INFRA
&&
3095 ieee
->reset_port(ieee
->dev
)) {
3096 printk("reset_port failed\n");
3097 param
->u
.crypt
.err
= IEEE_CRYPT_ERR_CARD_CONF_FAILED
;
3104 inline struct sk_buff
*ieee80211_disassociate_skb(
3105 struct ieee80211_network
*beacon
,
3106 struct ieee80211_device
*ieee
,
3109 struct sk_buff
*skb
;
3110 struct ieee80211_disassoc
*disass
;
3112 skb
= dev_alloc_skb(sizeof(struct ieee80211_disassoc
));
3116 disass
= (struct ieee80211_disassoc
*) skb_put(skb
,sizeof(struct ieee80211_disassoc
));
3117 disass
->header
.frame_ctl
= cpu_to_le16(IEEE80211_STYPE_DISASSOC
);
3118 disass
->header
.duration_id
= 0;
3120 memcpy(disass
->header
.addr1
, beacon
->bssid
, ETH_ALEN
);
3121 memcpy(disass
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
3122 memcpy(disass
->header
.addr3
, beacon
->bssid
, ETH_ALEN
);
3124 disass
->reason
= asRsn
;
3131 struct ieee80211_device
*ieee
,
3136 struct ieee80211_network
*beacon
= &ieee
->current_network
;
3137 struct sk_buff
*skb
;
3138 skb
= ieee80211_disassociate_skb(beacon
,ieee
,asRsn
);
3140 softmac_mgmt_xmit(skb
, ieee
);
3141 //dev_kfree_skb_any(skb);//edit by thomas
3145 int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device
*ieee
, struct iw_point
*p
)
3147 struct ieee_param
*param
;
3150 down(&ieee
->wx_sem
);
3151 //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
3153 if (p
->length
< sizeof(struct ieee_param
) || !p
->pointer
){
3158 param
= memdup_user(p
->pointer
, p
->length
);
3159 if (IS_ERR(param
)) {
3160 ret
= PTR_ERR(param
);
3164 switch (param
->cmd
) {
3166 case IEEE_CMD_SET_WPA_PARAM
:
3167 ret
= ieee80211_wpa_set_param(ieee
, param
->u
.wpa_param
.name
,
3168 param
->u
.wpa_param
.value
);
3171 case IEEE_CMD_SET_WPA_IE
:
3172 ret
= ieee80211_wpa_set_wpa_ie(ieee
, param
, p
->length
);
3175 case IEEE_CMD_SET_ENCRYPTION
:
3176 ret
= ieee80211_wpa_set_encryption(ieee
, param
, p
->length
);
3180 ret
= ieee80211_wpa_mlme(ieee
, param
->u
.mlme
.command
,
3181 param
->u
.mlme
.reason_code
);
3185 printk("Unknown WPA supplicant request: %d\n",param
->cmd
);
3190 if (ret
== 0 && copy_to_user(p
->pointer
, param
, p
->length
))
3200 void notify_wx_assoc_event(struct ieee80211_device
*ieee
)
3202 union iwreq_data wrqu
;
3203 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
3204 if (ieee
->state
== IEEE80211_LINKED
)
3205 memcpy(wrqu
.ap_addr
.sa_data
, ieee
->current_network
.bssid
, ETH_ALEN
);
3207 memset(wrqu
.ap_addr
.sa_data
, 0, ETH_ALEN
);
3208 wireless_send_event(ieee
->dev
, SIOCGIWAP
, &wrqu
, NULL
);
3211 EXPORT_SYMBOL(ieee80211_get_beacon
);
3212 EXPORT_SYMBOL(ieee80211_wake_queue
);
3213 EXPORT_SYMBOL(ieee80211_stop_queue
);
3214 EXPORT_SYMBOL(ieee80211_reset_queue
);
3215 EXPORT_SYMBOL(ieee80211_softmac_stop_protocol
);
3216 EXPORT_SYMBOL(ieee80211_softmac_start_protocol
);
3217 EXPORT_SYMBOL(ieee80211_is_shortslot
);
3218 EXPORT_SYMBOL(ieee80211_is_54g
);
3219 EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl
);
3220 EXPORT_SYMBOL(ieee80211_ps_tx_ack
);
3221 EXPORT_SYMBOL(ieee80211_softmac_xmit
);
3222 EXPORT_SYMBOL(ieee80211_stop_send_beacons
);
3223 EXPORT_SYMBOL(notify_wx_assoc_event
);
3224 EXPORT_SYMBOL(SendDisassociation
);
3225 EXPORT_SYMBOL(ieee80211_disassociate
);
3226 EXPORT_SYMBOL(ieee80211_start_send_beacons
);
3227 EXPORT_SYMBOL(ieee80211_stop_scan
);
3228 EXPORT_SYMBOL(ieee80211_send_probe_requests
);
3229 EXPORT_SYMBOL(ieee80211_softmac_scan_syncro
);
3230 EXPORT_SYMBOL(ieee80211_start_scan_syncro
);
3231 //EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame);