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/slab.h>
22 #include <linux/version.h>
23 #include <asm/uaccess.h>
26 u8 rsn_authen_cipher_suite[16][4] = {
27 {0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved
28 {0x00,0x0F,0xAC,0x01}, //WEP-40 //RSNA default
29 {0x00,0x0F,0xAC,0x02}, //TKIP //NONE //{used just as default}
30 {0x00,0x0F,0xAC,0x03}, //WRAP-historical
31 {0x00,0x0F,0xAC,0x04}, //CCMP
32 {0x00,0x0F,0xAC,0x05}, //WEP-104
35 short ieee80211_is_54g(struct ieee80211_network net)
37 return ((net.rates_ex_len > 0) || (net.rates_len > 4));
40 short ieee80211_is_shortslot(struct ieee80211_network net)
42 return (net.capability & WLAN_CAPABILITY_SHORT_SLOT);
45 /* returns the total length needed for pleacing the RATE MFIE
46 * tag and the EXTENDED RATE MFIE tag if needed.
47 * It encludes two bytes per tag for the tag itself and its len
49 unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
51 unsigned int rate_len = 0;
53 if (ieee->modulation & IEEE80211_CCK_MODULATION)
54 rate_len = IEEE80211_CCK_RATE_LEN + 2;
56 if (ieee->modulation & IEEE80211_OFDM_MODULATION)
58 rate_len += IEEE80211_OFDM_RATE_LEN + 2;
63 /* pleace the MFIE rate, tag to the memory (double) poined.
64 * Then it updates the pointer so that
65 * it points after the new MFIE tag added.
67 void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
71 if (ieee->modulation & IEEE80211_CCK_MODULATION){
72 *tag++ = MFIE_TYPE_RATES;
74 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
75 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
76 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
77 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
80 /* We may add an option for custom rates that specific HW might support */
84 void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
88 if (ieee->modulation & IEEE80211_OFDM_MODULATION){
90 *tag++ = MFIE_TYPE_RATES_EX;
92 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
93 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
94 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
95 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
96 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
97 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
98 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
99 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
103 /* We may add an option for custom rates that specific HW might support */
108 void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) {
111 *tag++ = MFIE_TYPE_GENERIC; //0
120 if(ieee->current_network.wmm_info & 0x80) {
121 *tag++ = 0x0f|MAX_SP_Len;
131 void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
134 *tag++ = MFIE_TYPE_GENERIC; //0
145 printk(KERN_ALERT "This is enable turbo mode IE process\n");
148 void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
151 nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
154 * if the queue is full but we have newer frames then
155 * just overwrites the oldest.
157 * if (nh == ieee->mgmt_queue_tail)
160 ieee->mgmt_queue_head = nh;
161 ieee->mgmt_queue_ring[nh] = skb;
166 struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
170 if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
173 ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
175 ieee->mgmt_queue_tail =
176 (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
181 void init_mgmt_queue(struct ieee80211_device *ieee)
183 ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
186 u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee)
188 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
191 // 2008/01/25 MH For broadcom, MGNT frame set as OFDM 6M.
192 if(pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M)
195 rate = ieee->basic_rate & 0x7f;
198 // 2005.01.26, by rcnjko.
199 if(ieee->mode == IEEE_A||
200 ieee->mode== IEEE_N_5G||
201 (ieee->mode== IEEE_N_24G&&!pHTInfo->bCurSuppCCK))
208 // Data rate of ProbeReq is already decided. Annie, 2005-03-31
209 if( pMgntInfo->bScanInProgress || (pMgntInfo->bDualModeScanStep!=0) )
211 if(pMgntInfo->dot11CurrentWirelessMode==WIRELESS_MODE_A)
221 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
223 inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
226 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
227 struct ieee80211_hdr_3addr *header=
228 (struct ieee80211_hdr_3addr *) skb->data;
230 cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8);
231 spin_lock_irqsave(&ieee->lock, flags);
233 /* called with 2nd param 0, no mgmt lock required */
234 ieee80211_sta_wakeup(ieee,0);
236 tcb_desc->queue_index = MGNT_QUEUE;
237 tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
238 tcb_desc->RATRIndex = 7;
239 tcb_desc->bTxDisableRateFallBack = 1;
240 tcb_desc->bTxUseDriverAssingedRate = 1;
243 if(ieee->queue_stop){
244 enqueue_mgmt(ieee,skb);
246 header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
248 if (ieee->seq_ctrl[0] == 0xFFF)
249 ieee->seq_ctrl[0] = 0;
253 /* avoid watchdog triggers */
254 // ieee->dev->trans_start = jiffies;
255 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
256 //dev_kfree_skb_any(skb);//edit by thomas
259 spin_unlock_irqrestore(&ieee->lock, flags);
261 spin_unlock_irqrestore(&ieee->lock, flags);
262 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
264 header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
266 if (ieee->seq_ctrl[0] == 0xFFF)
267 ieee->seq_ctrl[0] = 0;
271 /* check wether the managed packet queued greater than 5 */
272 if(!ieee->check_nic_enough_desc(ieee->dev,tcb_desc->queue_index)||\
273 (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)||\
274 (ieee->queue_stop) ) {
275 /* insert the skb packet to the management queue */
276 /* as for the completion function, it does not need
277 * to check it any more.
279 printk("%s():insert to waitqueue!\n",__FUNCTION__);
280 skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb);
282 //printk("TX packet!\n");
283 ieee->softmac_hard_start_xmit(skb,ieee->dev);
284 //dev_kfree_skb_any(skb);//edit by thomas
286 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
290 inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
293 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
294 struct ieee80211_hdr_3addr *header =
295 (struct ieee80211_hdr_3addr *) skb->data;
296 cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8);
298 tcb_desc->queue_index = MGNT_QUEUE;
299 tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
300 tcb_desc->RATRIndex = 7;
301 tcb_desc->bTxDisableRateFallBack = 1;
302 tcb_desc->bTxUseDriverAssingedRate = 1;
303 //printk("=============>%s()\n", __FUNCTION__);
306 header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
308 if (ieee->seq_ctrl[0] == 0xFFF)
309 ieee->seq_ctrl[0] = 0;
313 /* avoid watchdog triggers */
314 // ieee->dev->trans_start = jiffies;
315 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
319 header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
321 if (ieee->seq_ctrl[0] == 0xFFF)
322 ieee->seq_ctrl[0] = 0;
326 ieee->softmac_hard_start_xmit(skb,ieee->dev);
329 //dev_kfree_skb_any(skb);//edit by thomas
332 inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
334 unsigned int len,rate_len;
337 struct ieee80211_probe_request *req;
339 len = ieee->current_network.ssid_len;
341 rate_len = ieee80211_MFIE_rate_len(ieee);
343 skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
344 2 + len + rate_len + ieee->tx_headroom);
348 skb_reserve(skb, ieee->tx_headroom);
350 req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
351 req->header.frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
352 req->header.duration_id = 0; //FIXME: is this OK ?
354 memset(req->header.addr1, 0xff, ETH_ALEN);
355 memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
356 memset(req->header.addr3, 0xff, ETH_ALEN);
358 tag = (u8 *) skb_put(skb,len+2+rate_len);
360 *tag++ = MFIE_TYPE_SSID;
362 memcpy(tag, ieee->current_network.ssid, len);
365 ieee80211_MFIE_Brate(ieee,&tag);
366 ieee80211_MFIE_Grate(ieee,&tag);
370 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
371 void ieee80211_send_beacon(struct ieee80211_device *ieee)
376 //unsigned long flags;
377 skb = ieee80211_get_beacon_(ieee);
380 softmac_mgmt_xmit(skb, ieee);
381 ieee->softmac_stats.tx_beacons++;
382 //dev_kfree_skb_any(skb);//edit by thomas
384 // ieee->beacon_timer.expires = jiffies +
385 // (MSECS( ieee->current_network.beacon_interval -5));
387 //spin_lock_irqsave(&ieee->beacon_lock,flags);
388 if(ieee->beacon_txing && ieee->ieee_up){
389 // if(!timer_pending(&ieee->beacon_timer))
390 // add_timer(&ieee->beacon_timer);
391 mod_timer(&ieee->beacon_timer,jiffies+(MSECS(ieee->current_network.beacon_interval-5)));
393 //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
397 void ieee80211_send_beacon_cb(unsigned long _ieee)
399 struct ieee80211_device *ieee =
400 (struct ieee80211_device *) _ieee;
403 spin_lock_irqsave(&ieee->beacon_lock, flags);
404 ieee80211_send_beacon(ieee);
405 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
409 void ieee80211_send_probe(struct ieee80211_device *ieee)
413 skb = ieee80211_probe_req(ieee);
415 softmac_mgmt_xmit(skb, ieee);
416 ieee->softmac_stats.tx_probe_rq++;
417 //dev_kfree_skb_any(skb);//edit by thomas
421 void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
423 if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){
424 ieee80211_send_probe(ieee);
425 ieee80211_send_probe(ieee);
429 /* this performs syncro scan blocking the caller until all channels
430 * in the allowed channel map has been checked.
432 void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
435 u8 channel_map[MAX_CHANNEL_NUMBER+1];
436 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
437 ieee->be_scan_inprogress = true;
438 down(&ieee->scan_sem);
445 if (ch > MAX_CHANNEL_NUMBER)
446 goto out; /* scan completed */
447 }while(!channel_map[ch]);
449 /* this fuction can be called in two situations
450 * 1- We have switched to ad-hoc mode and we are
451 * performing a complete syncro scan before conclude
452 * there are no interesting cell and to create a
453 * new one. In this case the link state is
454 * IEEE80211_NOLINK until we found an interesting cell.
455 * If so the ieee8021_new_net, called by the RX path
456 * will set the state to IEEE80211_LINKED, so we stop
458 * 2- We are linked and the root uses run iwlist scan.
459 * So we switch to IEEE80211_LINKED_SCANNING to remember
460 * that we are still logically linked (not interested in
461 * new network events, despite for updating the net list,
462 * but we are temporarly 'unlinked' as the driver shall
463 * not filter RX frames and the channel is changing.
464 * So the only situation in witch are interested is to check
465 * if the state become LINKED because of the #1 situation
468 if (ieee->state == IEEE80211_LINKED)
470 ieee->set_chan(ieee->dev, ch);
471 if(channel_map[ch] == 1)
472 ieee80211_send_probe_requests(ieee);
474 /* this prevent excessive time wait when we
475 * need to wait for a syncro scan to end..
477 if(ieee->state < IEEE80211_LINKED)
480 if (ieee->sync_scan_hurryup)
484 msleep_interruptible_rsl(IEEE80211_SOFTMAC_SCAN_TIME);
488 if(ieee->state < IEEE80211_LINKED){
489 ieee->actscanning = false;
491 ieee->be_scan_inprogress = false;
494 ieee->sync_scan_hurryup = 0;
495 if(IS_DOT11D_ENABLE(ieee))
496 DOT11D_ScanComplete(ieee);
498 ieee->be_scan_inprogress = false;
502 void ieee80211_softmac_scan_wq(struct work_struct *work)
504 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
505 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
506 u8 last_channel = ieee->current_network.channel; //recored init channel inorder not change current channel when comming out the scan unexpectedly. WB.
507 u8 channel_map[MAX_CHANNEL_NUMBER+1];
508 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
511 down(&ieee->scan_sem);
513 ieee->current_network.channel =
514 (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
515 if (ieee->scan_watch_dog++ > MAX_CHANNEL_NUMBER)
517 //if current channel is not in channel map, set to default channel.
518 if (!channel_map[ieee->current_network.channel]);
519 ieee->current_network.channel = 6;
520 goto out; /* no good chans */
522 }while(!channel_map[ieee->current_network.channel]);
523 if (ieee->scanning == 0 )
525 ieee->set_chan(ieee->dev, ieee->current_network.channel);
526 if(channel_map[ieee->current_network.channel] == 1)
527 ieee80211_send_probe_requests(ieee);
529 queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
534 if(IS_DOT11D_ENABLE(ieee))
535 DOT11D_ScanComplete(ieee);
536 ieee->current_network.channel = last_channel;
537 ieee->actscanning = false;
538 ieee->scan_watch_dog = 0;
543 void ieee80211_beacons_start(struct ieee80211_device *ieee)
546 spin_lock_irqsave(&ieee->beacon_lock,flags);
548 ieee->beacon_txing = 1;
549 ieee80211_send_beacon(ieee);
551 spin_unlock_irqrestore(&ieee->beacon_lock,flags);
554 void ieee80211_beacons_stop(struct ieee80211_device *ieee)
558 spin_lock_irqsave(&ieee->beacon_lock,flags);
560 ieee->beacon_txing = 0;
561 del_timer_sync(&ieee->beacon_timer);
563 spin_unlock_irqrestore(&ieee->beacon_lock,flags);
568 void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
570 if(ieee->stop_send_beacons)
571 ieee->stop_send_beacons(ieee->dev);
572 if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
573 ieee80211_beacons_stop(ieee);
577 void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
579 if(ieee->start_send_beacons)
580 ieee->start_send_beacons(ieee->dev);
581 if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
582 ieee80211_beacons_start(ieee);
586 void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
588 // unsigned long flags;
590 //ieee->sync_scan_hurryup = 1;
592 down(&ieee->scan_sem);
593 // spin_lock_irqsave(&ieee->lock, flags);
594 ieee->scan_watch_dog = 0;
595 if (ieee->scanning == 1){
598 cancel_delayed_work(&ieee->softmac_scan_wq);
601 // spin_unlock_irqrestore(&ieee->lock, flags);
605 void ieee80211_stop_scan(struct ieee80211_device *ieee)
607 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
608 ieee80211_softmac_stop_scan(ieee);
610 ieee->stop_scan(ieee->dev);
613 /* called with ieee->lock held */
614 void ieee80211_rtl_start_scan(struct ieee80211_device *ieee)
616 if(IS_DOT11D_ENABLE(ieee) )
618 if(IS_COUNTRY_IE_VALID(ieee))
620 RESET_CIE_WATCHDOG(ieee);
623 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
624 if (ieee->scanning == 0){
626 queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0);
629 ieee->start_scan(ieee->dev);
633 /* called with wx_sem held */
634 void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
636 if(IS_DOT11D_ENABLE(ieee) )
638 if(IS_COUNTRY_IE_VALID(ieee))
640 RESET_CIE_WATCHDOG(ieee);
643 ieee->sync_scan_hurryup = 0;
644 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
645 ieee80211_softmac_scan_syncro(ieee);
647 ieee->scan_syncro(ieee->dev);
651 inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
652 struct ieee80211_device *ieee, int challengelen)
655 struct ieee80211_authentication *auth;
656 int len = sizeof(struct ieee80211_authentication) + challengelen + ieee->tx_headroom;
659 skb = dev_alloc_skb(len);
660 if (!skb) return NULL;
662 skb_reserve(skb, ieee->tx_headroom);
663 auth = (struct ieee80211_authentication *)
664 skb_put(skb, sizeof(struct ieee80211_authentication));
666 auth->header.frame_control = IEEE80211_STYPE_AUTH;
667 if (challengelen) auth->header.frame_control |= IEEE80211_FCTL_WEP;
669 auth->header.duration_id = 0x013a; //FIXME
671 memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
672 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
673 memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
675 //auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
676 if(ieee->auth_mode == 0)
677 auth->algorithm = WLAN_AUTH_OPEN;
678 else if(ieee->auth_mode == 1)
679 auth->algorithm = WLAN_AUTH_SHARED_KEY;
680 else if(ieee->auth_mode == 2)
681 auth->algorithm = WLAN_AUTH_OPEN;//0x80;
682 printk("=================>%s():auth->algorithm is %d\n",__FUNCTION__,auth->algorithm);
683 auth->transaction = cpu_to_le16(ieee->associate_seq);
684 ieee->associate_seq++;
686 auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
693 static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
697 struct ieee80211_probe_response *beacon_buf;
698 struct sk_buff *skb = NULL;
700 int atim_len,erp_len;
701 struct ieee80211_crypt_data* crypt;
703 char *ssid = ieee->current_network.ssid;
704 int ssid_len = ieee->current_network.ssid_len;
705 int rate_len = ieee->current_network.rates_len+2;
706 int rate_ex_len = ieee->current_network.rates_ex_len;
707 int wpa_ie_len = ieee->wpa_ie_len;
708 u8 erpinfo_content = 0;
713 u8 tmp_ht_info_len=0;
714 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
715 u8* tmp_generic_ie_buf=NULL;
716 u8 tmp_generic_ie_len=0;
718 if(rate_ex_len > 0) rate_ex_len+=2;
720 if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
726 if(ieee80211_is_54g(ieee->current_network))
731 if((ieee->current_network.mode == IEEE_G)
732 ||( ieee->current_network.mode == IEEE_N_24G && ieee->pHTInfo->bCurSuppCCK)) {
735 if(ieee->current_network.buseprotection)
736 erpinfo_content |= ERP_UseProtection;
743 crypt = ieee->crypt[ieee->tx_keyidx];
746 encrypt = ieee->host_encrypt && crypt && crypt->ops &&
747 ((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len));
750 tmp_ht_cap_buf =(u8*) &(ieee->pHTInfo->SelfHTCap);
751 tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
752 tmp_ht_info_buf =(u8*) &(ieee->pHTInfo->SelfHTInfo);
753 tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo);
754 HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len,encrypt);
755 HTConstructInfoElement(ieee,tmp_ht_info_buf,&tmp_ht_info_len, encrypt);
758 if(pHTInfo->bRegRT2RTAggregation)
760 tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
761 tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer);
762 HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len);
764 // 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);
766 beacon_size = sizeof(struct ieee80211_probe_response)+2+
776 // +tmp_generic_ie_len
779 skb = dev_alloc_skb(beacon_size);
782 skb_reserve(skb, ieee->tx_headroom);
783 beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, (beacon_size - ieee->tx_headroom));
784 memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
785 memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
786 memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
788 beacon_buf->header.duration_id = 0; //FIXME
789 beacon_buf->beacon_interval =
790 cpu_to_le16(ieee->current_network.beacon_interval);
791 beacon_buf->capability =
792 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
793 beacon_buf->capability |=
794 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE); //add short preamble here
796 if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
797 cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
799 crypt = ieee->crypt[ieee->tx_keyidx];
802 beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
805 beacon_buf->header.frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
806 beacon_buf->info_element[0].id = MFIE_TYPE_SSID;
807 beacon_buf->info_element[0].len = ssid_len;
809 tag = (u8*) beacon_buf->info_element[0].data;
811 memcpy(tag, ssid, ssid_len);
815 *(tag++) = MFIE_TYPE_RATES;
816 *(tag++) = rate_len-2;
817 memcpy(tag,ieee->current_network.rates,rate_len-2);
820 *(tag++) = MFIE_TYPE_DS_SET;
822 *(tag++) = ieee->current_network.channel;
826 *(tag++) = MFIE_TYPE_IBSS_SET;
828 //*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window);
829 val16 = cpu_to_le16(ieee->current_network.atim_window);
830 memcpy((u8 *)tag, (u8 *)&val16, 2);
835 *(tag++) = MFIE_TYPE_ERP;
837 *(tag++) = erpinfo_content;
841 *(tag++) = MFIE_TYPE_RATES_EX;
842 *(tag++) = rate_ex_len-2;
843 memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
849 if (ieee->iw_mode == IW_MODE_ADHOC)
850 {//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
851 memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
853 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
857 //skb->dev = ieee->dev;
862 struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
867 struct ieee80211_crypt_data* crypt;
868 struct ieee80211_assoc_response_frame *assoc;
871 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
872 int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len + ieee->tx_headroom;
874 skb = dev_alloc_skb(len);
879 skb_reserve(skb, ieee->tx_headroom);
881 assoc = (struct ieee80211_assoc_response_frame *)
882 skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
884 assoc->header.frame_control = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
885 memcpy(assoc->header.addr1, dest,ETH_ALEN);
886 memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
887 memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
888 assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
889 WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
893 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
895 if (ieee->host_encrypt)
896 crypt = ieee->crypt[ieee->tx_keyidx];
899 encrypt = ( crypt && crypt->ops);
902 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
905 assoc->aid = cpu_to_le16(ieee->assoc_id);
906 if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
907 else ieee->assoc_id++;
909 tag = (u8*) skb_put(skb, rate_len);
911 ieee80211_MFIE_Brate(ieee, &tag);
912 ieee80211_MFIE_Grate(ieee, &tag);
917 struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest)
920 struct ieee80211_authentication *auth;
921 int len = ieee->tx_headroom + sizeof(struct ieee80211_authentication)+1;
923 skb = dev_alloc_skb(len);
928 skb->len = sizeof(struct ieee80211_authentication);
930 auth = (struct ieee80211_authentication *)skb->data;
932 auth->status = cpu_to_le16(status);
933 auth->transaction = cpu_to_le16(2);
934 auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
936 memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
937 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
938 memcpy(auth->header.addr1, dest, ETH_ALEN);
939 auth->header.frame_control = cpu_to_le16(IEEE80211_STYPE_AUTH);
945 struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
948 struct ieee80211_hdr_3addr* hdr;
950 skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
955 hdr = (struct ieee80211_hdr_3addr*)skb_put(skb,sizeof(struct ieee80211_hdr_3addr));
957 memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
958 memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
959 memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
961 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
962 IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
963 (pwr ? IEEE80211_FCTL_PM:0));
971 void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest)
973 struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
976 softmac_mgmt_xmit(buf, ieee);
980 void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest)
982 struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
985 softmac_mgmt_xmit(buf, ieee);
989 void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
993 struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
995 softmac_mgmt_xmit(buf, ieee);
999 inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
1001 struct sk_buff *skb;
1002 //unsigned long flags;
1004 struct ieee80211_assoc_request_frame *hdr;
1006 //short info_addr = 0;
1008 //u16 suite_count = 0;
1009 //u8 suit_select = 0;
1010 //unsigned int wpa_len = beacon->wpa_ie_len;
1012 u8* ht_cap_buf = NULL;
1014 u8* realtek_ie_buf=NULL;
1015 u8 realtek_ie_len=0;
1016 int wpa_ie_len= ieee->wpa_ie_len;
1017 unsigned int ckip_ie_len=0;
1018 unsigned int ccxrm_ie_len=0;
1019 unsigned int cxvernum_ie_len=0;
1020 struct ieee80211_crypt_data* crypt;
1023 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
1024 unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
1025 unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
1029 crypt = ieee->crypt[ieee->tx_keyidx];
1030 encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len));
1032 //Include High Throuput capability && Realtek proprietary
1033 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1035 ht_cap_buf = (u8*)&(ieee->pHTInfo->SelfHTCap);
1036 ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
1037 HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt);
1038 if(ieee->pHTInfo->bCurrentRT2RTAggregation)
1040 realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
1041 realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer);
1042 HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len);
1046 if(ieee->qos_support){
1047 wmm_info_len = beacon->qos_data.supported?9:0;
1051 if(beacon->bCkipSupported)
1055 if(beacon->bCcxRmEnable)
1059 if( beacon->BssCcxVerNumber >= 2 )
1061 cxvernum_ie_len = 5+2;
1063 len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1064 + beacon->ssid_len//essid tagged val
1065 + rate_len//rates tagged val
1074 + ieee->tx_headroom;
1076 skb = dev_alloc_skb(len);
1081 skb_reserve(skb, ieee->tx_headroom);
1083 hdr = (struct ieee80211_assoc_request_frame *)
1084 skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)+2);
1087 hdr->header.frame_control = IEEE80211_STYPE_ASSOC_REQ;
1088 hdr->header.duration_id= 37; //FIXME
1089 memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
1090 memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1091 memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
1093 memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John
1095 hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
1096 if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
1097 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1099 if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1100 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); //add short_preamble here
1102 if(ieee->short_slot)
1103 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
1104 if (wmm_info_len) //QOS
1105 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS);
1107 hdr->listen_interval = 0xa; //FIXME
1109 hdr->info_element[0].id = MFIE_TYPE_SSID;
1111 hdr->info_element[0].len = beacon->ssid_len;
1112 tag = skb_put(skb, beacon->ssid_len);
1113 memcpy(tag, beacon->ssid, beacon->ssid_len);
1115 tag = skb_put(skb, rate_len);
1117 ieee80211_MFIE_Brate(ieee, &tag);
1118 ieee80211_MFIE_Grate(ieee, &tag);
1119 // For CCX 1 S13, CKIP. Added by Annie, 2006-08-14.
1120 if( beacon->bCkipSupported )
1122 static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client"
1123 u8 CcxAironetBuf[30];
1124 OCTET_STRING osCcxAironetIE;
1126 memset(CcxAironetBuf, 0,30);
1127 osCcxAironetIE.Octet = CcxAironetBuf;
1128 osCcxAironetIE.Length = sizeof(CcxAironetBuf);
1130 // Ref. CCX test plan v3.61, 3.2.3.1 step 13.
1131 // We want to make the device type as "4500-client". 060926, by CCW.
1133 memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui));
1135 // CCX1 spec V1.13, A01.1 CKIP Negotiation (page23):
1136 // "The CKIP negotiation is started with the associate request from the client to the access point,
1137 // containing an Aironet element with both the MIC and KP bits set."
1138 osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |= (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ;
1139 tag = skb_put(skb, ckip_ie_len);
1140 *tag++ = MFIE_TYPE_AIRONET;
1141 *tag++ = osCcxAironetIE.Length;
1142 memcpy(tag,osCcxAironetIE.Octet,osCcxAironetIE.Length);
1143 tag += osCcxAironetIE.Length;
1146 if(beacon->bCcxRmEnable)
1148 static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
1149 OCTET_STRING osCcxRmCap;
1151 osCcxRmCap.Octet = CcxRmCapBuf;
1152 osCcxRmCap.Length = sizeof(CcxRmCapBuf);
1153 tag = skb_put(skb,ccxrm_ie_len);
1154 *tag++ = MFIE_TYPE_GENERIC;
1155 *tag++ = osCcxRmCap.Length;
1156 memcpy(tag,osCcxRmCap.Octet,osCcxRmCap.Length);
1157 tag += osCcxRmCap.Length;
1160 if( beacon->BssCcxVerNumber >= 2 )
1162 u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
1163 OCTET_STRING osCcxVerNum;
1164 CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
1165 osCcxVerNum.Octet = CcxVerNumBuf;
1166 osCcxVerNum.Length = sizeof(CcxVerNumBuf);
1167 tag = skb_put(skb,cxvernum_ie_len);
1168 *tag++ = MFIE_TYPE_GENERIC;
1169 *tag++ = osCcxVerNum.Length;
1170 memcpy(tag,osCcxVerNum.Octet,osCcxVerNum.Length);
1171 tag += osCcxVerNum.Length;
1174 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
1175 if(ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC)
1177 tag = skb_put(skb, ht_cap_len);
1178 *tag++ = MFIE_TYPE_HT_CAP;
1179 *tag++ = ht_cap_len - 2;
1180 memcpy(tag, ht_cap_buf,ht_cap_len -2);
1181 tag += ht_cap_len -2;
1186 //choose what wpa_supplicant gives to associate.
1187 tag = skb_put(skb, wpa_ie_len);
1189 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
1192 tag = skb_put(skb,wmm_info_len);
1194 ieee80211_WMM_Info(ieee, &tag);
1196 tag = skb_put(skb,turbo_info_len);
1197 if(turbo_info_len) {
1198 ieee80211_TURBO_Info(ieee, &tag);
1201 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
1202 if(ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC)
1204 tag = skb_put(skb, ht_cap_len);
1205 *tag++ = MFIE_TYPE_GENERIC;
1206 *tag++ = ht_cap_len - 2;
1207 memcpy(tag, ht_cap_buf,ht_cap_len - 2);
1208 tag += ht_cap_len -2;
1211 if(ieee->pHTInfo->bCurrentRT2RTAggregation){
1212 tag = skb_put(skb, realtek_ie_len);
1213 *tag++ = MFIE_TYPE_GENERIC;
1214 *tag++ = realtek_ie_len - 2;
1215 memcpy(tag, realtek_ie_buf,realtek_ie_len -2 );
1218 // printk("<=====%s(), %p, %p\n", __FUNCTION__, ieee->dev, ieee->dev->dev_addr);
1219 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
1223 void ieee80211_associate_abort(struct ieee80211_device *ieee)
1226 unsigned long flags;
1227 spin_lock_irqsave(&ieee->lock, flags);
1229 ieee->associate_seq++;
1231 /* don't scan, and avoid to have the RX path possibily
1232 * try again to associate. Even do not react to AUTH or
1233 * ASSOC response. Just wait for the retry wq to be scheduled.
1234 * Here we will check if there are good nets to associate
1235 * with, so we retry or just get back to NO_LINK and scanning
1237 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
1238 IEEE80211_DEBUG_MGMT("Authentication failed\n");
1239 ieee->softmac_stats.no_auth_rs++;
1241 IEEE80211_DEBUG_MGMT("Association failed\n");
1242 ieee->softmac_stats.no_ass_rs++;
1245 ieee->state = IEEE80211_ASSOCIATING_RETRY;
1247 queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \
1248 IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
1250 spin_unlock_irqrestore(&ieee->lock, flags);
1253 void ieee80211_associate_abort_cb(unsigned long dev)
1255 ieee80211_associate_abort((struct ieee80211_device *) dev);
1259 void ieee80211_associate_step1(struct ieee80211_device *ieee)
1261 struct ieee80211_network *beacon = &ieee->current_network;
1262 struct sk_buff *skb;
1264 IEEE80211_DEBUG_MGMT("Stopping scan\n");
1266 ieee->softmac_stats.tx_auth_rq++;
1267 skb=ieee80211_authentication_req(beacon, ieee, 0);
1270 ieee80211_associate_abort(ieee);
1272 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
1273 IEEE80211_DEBUG_MGMT("Sending authentication request\n");
1274 //printk(KERN_WARNING "Sending authentication request\n");
1275 softmac_mgmt_xmit(skb, ieee);
1276 //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
1277 if(!timer_pending(&ieee->associate_timer)){
1278 ieee->associate_timer.expires = jiffies + (HZ / 2);
1279 add_timer(&ieee->associate_timer);
1281 //dev_kfree_skb_any(skb);//edit by thomas
1285 void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
1288 struct sk_buff *skb;
1289 struct ieee80211_network *beacon = &ieee->current_network;
1290 // int hlen = sizeof(struct ieee80211_authentication);
1292 ieee->associate_seq++;
1293 ieee->softmac_stats.tx_auth_rq++;
1295 skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
1297 ieee80211_associate_abort(ieee);
1299 c = skb_put(skb, chlen+2);
1300 *(c++) = MFIE_TYPE_CHALLENGE;
1302 memcpy(c, challenge, chlen);
1304 IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
1306 ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr ));
1308 softmac_mgmt_xmit(skb, ieee);
1309 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1310 //dev_kfree_skb_any(skb);//edit by thomas
1315 void ieee80211_associate_step2(struct ieee80211_device *ieee)
1317 struct sk_buff* skb;
1318 struct ieee80211_network *beacon = &ieee->current_network;
1320 del_timer_sync(&ieee->associate_timer);
1322 IEEE80211_DEBUG_MGMT("Sending association request\n");
1324 ieee->softmac_stats.tx_ass_rq++;
1325 skb=ieee80211_association_req(beacon, ieee);
1327 ieee80211_associate_abort(ieee);
1329 softmac_mgmt_xmit(skb, ieee);
1330 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1331 //dev_kfree_skb_any(skb);//edit by thomas
1335 void ieee80211_associate_complete_wq(struct work_struct *work)
1337 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
1339 printk(KERN_INFO "Associated successfully\n");
1340 ieee->is_roaming = false;
1341 if(ieee80211_is_54g(ieee->current_network) &&
1342 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1345 printk(KERN_INFO"Using G rates:%d\n", ieee->rate);
1348 printk(KERN_INFO"Using B rates:%d\n", ieee->rate);
1350 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1352 printk("Successfully associated, ht enabled\n");
1357 printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
1358 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1359 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1361 ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500);
1362 // To prevent the immediately calling watch_dog after association.
1363 if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
1365 ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
1366 ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
1368 ieee->link_change(ieee->dev);
1369 if(ieee->is_silent_reset == 0){
1370 printk("============>normal associate\n");
1371 notify_wx_assoc_event(ieee);
1373 else if(ieee->is_silent_reset == 1)
1375 printk("==================>silent reset associate\n");
1376 ieee->is_silent_reset = 0;
1379 if (ieee->data_hard_resume)
1380 ieee->data_hard_resume(ieee->dev);
1381 netif_carrier_on(ieee->dev);
1384 void ieee80211_associate_complete(struct ieee80211_device *ieee)
1387 // struct net_device* dev = ieee->dev;
1388 del_timer_sync(&ieee->associate_timer);
1390 ieee->state = IEEE80211_LINKED;
1391 //ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet);
1392 queue_work(ieee->wq, &ieee->associate_complete_wq);
1395 void ieee80211_associate_procedure_wq(struct work_struct *work)
1397 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
1399 ieee->sync_scan_hurryup = 1;
1400 down(&ieee->wx_sem);
1402 if (ieee->data_hard_stop)
1403 ieee->data_hard_stop(ieee->dev);
1405 ieee80211_stop_scan(ieee);
1406 printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);
1407 //ieee->set_chan(ieee->dev, ieee->current_network.channel);
1408 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1410 ieee->associate_seq = 1;
1411 ieee80211_associate_step1(ieee);
1416 inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
1418 u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
1419 int tmp_ssid_len = 0;
1421 short apset,ssidset,ssidbroad,apmatch,ssidmatch;
1423 /* we are interested in new new only if we are not associated
1424 * and we are not associating / authenticating
1426 if (ieee->state != IEEE80211_NOLINK)
1429 if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
1432 if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
1436 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){
1437 /* if the user specified the AP MAC, we need also the essid
1438 * This could be obtained by beacons or, if the network does not
1439 * broadcast it, it can be put manually.
1441 apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
1442 ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
1443 ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0');
1444 apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
1445 ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\
1446 (!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
1449 if ( /* if the user set the AP check if match.
1450 * if the network does not broadcast essid we check the user supplyed ANY essid
1451 * if the network does broadcast and the user does not set essid it is OK
1452 * if the network does broadcast and the user did set essid chech if essid match
1454 ( apset && apmatch &&
1455 ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
1456 /* if the ap is not set, check that the user set the bssid
1457 * and the network does bradcast and that those two bssid matches
1459 (!apset && ssidset && ssidbroad && ssidmatch)
1461 /* if the essid is hidden replace it with the
1462 * essid provided by the user.
1465 strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
1466 tmp_ssid_len = ieee->current_network.ssid_len;
1468 memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
1471 strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
1472 ieee->current_network.ssid_len = tmp_ssid_len;
1474 printk(KERN_INFO"Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d, mode:%x\n",ieee->current_network.ssid,ieee->current_network.channel, ieee->current_network.qos_data.supported, ieee->pHTInfo->bEnableHT, ieee->current_network.bssht.bdSupportHT, ieee->current_network.mode);
1476 //ieee->pHTInfo->IOTAction = 0;
1477 HTResetIOTSetting(ieee->pHTInfo);
1478 if (ieee->iw_mode == IW_MODE_INFRA){
1479 /* Join the network for the first time */
1480 ieee->AsocRetryCount = 0;
1481 //for HT by amy 080514
1482 if((ieee->current_network.qos_data.supported == 1) &&
1483 // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT))
1484 ieee->current_network.bssht.bdSupportHT)
1485 /*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.*/
1487 // ieee->pHTInfo->bCurrentHTSupport = true;
1488 HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network));
1492 ieee->pHTInfo->bCurrentHTSupport = false;
1495 ieee->state = IEEE80211_ASSOCIATING;
1496 if(ieee->LedControlHandler != NULL)
1497 ieee->LedControlHandler(ieee->dev, LED_CTL_START_TO_LINK);
1498 queue_work(ieee->wq, &ieee->associate_procedure_wq);
1500 if(ieee80211_is_54g(ieee->current_network) &&
1501 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1503 ieee->SetWirelessMode(ieee->dev, IEEE_G);
1504 printk(KERN_INFO"Using G rates\n");
1507 ieee->SetWirelessMode(ieee->dev, IEEE_B);
1508 printk(KERN_INFO"Using B rates\n");
1510 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1511 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1512 ieee->state = IEEE80211_LINKED;
1520 void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
1522 unsigned long flags;
1523 struct ieee80211_network *target;
1525 spin_lock_irqsave(&ieee->lock, flags);
1527 list_for_each_entry(target, &ieee->network_list, list) {
1529 /* if the state become different that NOLINK means
1530 * we had found what we are searching for
1533 if (ieee->state != IEEE80211_NOLINK)
1536 if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
1537 ieee80211_softmac_new_net(ieee, target);
1540 spin_unlock_irqrestore(&ieee->lock, flags);
1545 static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen)
1547 struct ieee80211_authentication *a;
1549 if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
1550 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
1554 a = (struct ieee80211_authentication*) skb->data;
1555 if(skb->len > (sizeof(struct ieee80211_authentication) +3)){
1556 t = skb->data + sizeof(struct ieee80211_authentication);
1558 if(*(t++) == MFIE_TYPE_CHALLENGE){
1560 *challenge = kmalloc(*chlen, GFP_ATOMIC);
1561 memcpy(*challenge, t, *chlen);
1565 return cpu_to_le16(a->status);
1570 int auth_rq_parse(struct sk_buff *skb,u8* dest)
1572 struct ieee80211_authentication *a;
1574 if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
1575 IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
1578 a = (struct ieee80211_authentication*) skb->data;
1580 memcpy(dest,a->header.addr2, ETH_ALEN);
1582 if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
1583 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1585 return WLAN_STATUS_SUCCESS;
1588 static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
1595 struct ieee80211_hdr_3addr *header =
1596 (struct ieee80211_hdr_3addr *) skb->data;
1598 if (skb->len < sizeof (struct ieee80211_hdr_3addr ))
1599 return -1; /* corrupted */
1601 memcpy(src,header->addr2, ETH_ALEN);
1603 skbend = (u8*)skb->data + skb->len;
1605 tag = skb->data + sizeof (struct ieee80211_hdr_3addr );
1607 while (tag+1 < skbend){
1613 tag++; /* point to the len field */
1614 tag = tag + *(tag); /* point to the last data byte of the tag */
1615 tag++; /* point to the next tag */
1618 //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
1619 if (ssidlen == 0) return 1;
1621 if (!ssid) return 1; /* ssid not found in tagged param */
1622 return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
1626 int assoc_rq_parse(struct sk_buff *skb,u8* dest)
1628 struct ieee80211_assoc_request_frame *a;
1630 if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
1631 sizeof(struct ieee80211_info_element))) {
1633 IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
1637 a = (struct ieee80211_assoc_request_frame*) skb->data;
1639 memcpy(dest,a->header.addr2,ETH_ALEN);
1644 static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid)
1646 struct ieee80211_assoc_response_frame *response_head;
1649 if (skb->len < sizeof(struct ieee80211_assoc_response_frame)){
1650 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
1654 response_head = (struct ieee80211_assoc_response_frame*) skb->data;
1655 *aid = le16_to_cpu(response_head->aid) & 0x3fff;
1657 status_code = le16_to_cpu(response_head->status);
1658 if((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \
1659 status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&&
1660 ((ieee->mode == IEEE_G) &&
1661 (ieee->current_network.mode == IEEE_N_24G) &&
1662 (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) {
1663 ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
1665 ieee->AsocRetryCount = 0;
1668 return le16_to_cpu(response_head->status);
1672 ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1676 //IEEE80211DMESG("Rx probe");
1677 ieee->softmac_stats.rx_probe_rq++;
1678 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1679 if (probe_rq_parse(ieee, skb, dest)){
1680 //IEEE80211DMESG("Was for me!");
1681 ieee->softmac_stats.tx_probe_rs++;
1682 ieee80211_resp_to_probe(ieee, dest);
1687 ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1691 //IEEE80211DMESG("Rx probe");
1692 ieee->softmac_stats.rx_auth_rq++;
1694 status = auth_rq_parse(skb, dest);
1696 ieee80211_resp_to_auth(ieee, status, dest);
1698 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1703 ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1707 //unsigned long flags;
1709 ieee->softmac_stats.rx_ass_rq++;
1710 if (assoc_rq_parse(skb,dest) != -1){
1711 ieee80211_resp_to_assoc_rq(ieee, dest);
1714 printk(KERN_INFO"New client associated: %pM\n", dest);
1720 void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
1723 struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
1726 softmac_ps_mgmt_xmit(buf, ieee);
1731 short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
1733 int timeout = ieee->ps_timeout;
1735 /*if(ieee->ps == IEEE80211_PS_DISABLED ||
1736 ieee->iw_mode != IW_MODE_INFRA ||
1737 ieee->state != IEEE80211_LINKED)
1741 dtim = ieee->current_network.dtim_data;
1743 if(!(dtim & IEEE80211_DTIM_VALID))
1745 timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
1746 //printk("VALID\n");
1747 ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
1749 if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
1752 if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
1755 if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
1758 if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
1759 (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
1763 *time_l = ieee->current_network.last_dtim_sta_time[0]
1764 + (ieee->current_network.beacon_interval);
1765 // * ieee->current_network.dtim_period) * 1000;
1769 *time_h = ieee->current_network.last_dtim_sta_time[1];
1770 if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
1779 inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
1785 unsigned long flags,flags2;
1787 spin_lock_irqsave(&ieee->lock, flags);
1789 if((ieee->ps == IEEE80211_PS_DISABLED ||
1790 ieee->iw_mode != IW_MODE_INFRA ||
1791 ieee->state != IEEE80211_LINKED)){
1793 // #warning CHECK_LOCK_HERE
1794 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1796 ieee80211_sta_wakeup(ieee, 1);
1798 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1801 sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
1802 /* 2 wake, 1 sleep, 0 do nothing */
1808 if(ieee->sta_sleep == 1)
1809 ieee->enter_sleep_state(ieee->dev,th,tl);
1811 else if(ieee->sta_sleep == 0){
1812 // printk("send null 1\n");
1813 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1815 if(ieee->ps_is_queue_empty(ieee->dev)){
1818 ieee->sta_sleep = 2;
1820 ieee->ack_tx_to_ieee = 1;
1822 ieee80211_sta_ps_send_null_frame(ieee,1);
1827 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1832 }else if(sleep == 2){
1833 //#warning CHECK_LOCK_HERE
1834 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1836 ieee80211_sta_wakeup(ieee,1);
1838 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1842 spin_unlock_irqrestore(&ieee->lock, flags);
1846 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
1848 if(ieee->sta_sleep == 0){
1850 printk("Warning: driver is probably failing to report TX ps error\n");
1851 ieee->ack_tx_to_ieee = 1;
1852 ieee80211_sta_ps_send_null_frame(ieee, 0);
1858 if(ieee->sta_sleep == 1)
1859 ieee->sta_wake_up(ieee->dev);
1861 ieee->sta_sleep = 0;
1864 ieee->ack_tx_to_ieee = 1;
1865 ieee80211_sta_ps_send_null_frame(ieee, 0);
1869 void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
1871 unsigned long flags,flags2;
1873 spin_lock_irqsave(&ieee->lock, flags);
1875 if(ieee->sta_sleep == 2){
1876 /* Null frame with PS bit set */
1878 ieee->sta_sleep = 1;
1879 ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
1881 /* if the card report not success we can't be sure the AP
1882 * has not RXed so we can't assume the AP believe us awake
1885 /* 21112005 - tx again null without PS bit if lost */
1888 if((ieee->sta_sleep == 0) && !success){
1889 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1890 ieee80211_sta_ps_send_null_frame(ieee, 0);
1891 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1894 spin_unlock_irqrestore(&ieee->lock, flags);
1896 void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb)
1898 struct rtl_ieee80211_hdr *header =
1899 (struct rtl_ieee80211_hdr *)skb->data;
1900 u8* act = ieee80211_get_payload(header);
1902 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
1905 IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
1913 if (*act == ACT_ADDBAREQ)
1914 ieee80211_rx_ADDBAReq(ieee, skb);
1915 else if (*act == ACT_ADDBARSP)
1916 ieee80211_rx_ADDBARsp(ieee, skb);
1917 else if (*act == ACT_DELBA)
1918 ieee80211_rx_DELBA(ieee, skb);
1921 // if (net_ratelimit())
1922 // IEEE80211_DEBUG(IEEE80211_DL_BA, "unknown action frame(%d)\n", tmp);
1929 ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
1930 struct ieee80211_rx_stats *rx_stats, u16 type,
1933 struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
1938 struct ieee80211_assoc_response_frame *assoc_resp;
1939 // struct ieee80211_info_element *info_element;
1940 bool bSupportNmode = true, bHalfSupportNmode = false; //default support N mode, disable halfNmode
1942 if(!ieee->proto_started)
1945 switch (WLAN_FC_GET_STYPE(header->frame_control)) {
1947 case IEEE80211_STYPE_ASSOC_RESP:
1948 case IEEE80211_STYPE_REASSOC_RESP:
1950 IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
1951 WLAN_FC_GET_STYPE(header->frame_control));
1952 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
1953 ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
1954 ieee->iw_mode == IW_MODE_INFRA){
1955 struct ieee80211_network network_resp;
1956 struct ieee80211_network *network = &network_resp;
1958 if (0 == (errcode=assoc_parse(ieee,skb, &aid))){
1959 ieee->state=IEEE80211_LINKED;
1960 ieee->assoc_id = aid;
1961 ieee->softmac_stats.rx_ass_ok++;
1962 /* station support qos */
1963 /* Let the register setting defaultly with Legacy station */
1964 if(ieee->qos_support) {
1965 assoc_resp = (struct ieee80211_assoc_response_frame*)skb->data;
1966 memset(network, 0, sizeof(*network));
1967 if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\
1968 rx_stats->len - sizeof(*assoc_resp),\
1973 { //filling the PeerHTCap. //maybe not neccesary as we can get its info from current_network.
1974 memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
1975 memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
1977 if (ieee->handle_assoc_response != NULL)
1978 ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame*)header, network);
1980 ieee80211_associate_complete(ieee);
1982 /* aid could not been allocated */
1983 ieee->softmac_stats.rx_ass_err++;
1985 "Association response status code 0x%x\n",
1987 IEEE80211_DEBUG_MGMT(
1988 "Association response status code 0x%x\n",
1990 if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
1991 queue_work(ieee->wq, &ieee->associate_procedure_wq);
1993 ieee80211_associate_abort(ieee);
1999 case IEEE80211_STYPE_ASSOC_REQ:
2000 case IEEE80211_STYPE_REASSOC_REQ:
2002 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2003 ieee->iw_mode == IW_MODE_MASTER)
2005 ieee80211_rx_assoc_rq(ieee, skb);
2008 case IEEE80211_STYPE_AUTH:
2010 if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){
2011 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
2012 ieee->iw_mode == IW_MODE_INFRA){
2014 IEEE80211_DEBUG_MGMT("Received authentication response");
2016 if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){
2017 if(ieee->open_wep || !challenge){
2018 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
2019 ieee->softmac_stats.rx_auth_rs_ok++;
2020 if(!(ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE))
2022 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
2024 // WEP or TKIP encryption
2025 if(IsHTHalfNmodeAPs(ieee))
2027 bSupportNmode = true;
2028 bHalfSupportNmode = true;
2032 bSupportNmode = false;
2033 bHalfSupportNmode = false;
2035 printk("==========>to link with AP using SEC(%d, %d)", bSupportNmode, bHalfSupportNmode);
2038 /* Dummy wirless mode setting to avoid encryption issue */
2041 ieee->SetWirelessMode(ieee->dev, \
2042 ieee->current_network.mode);
2046 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2049 if (ieee->current_network.mode == IEEE_N_24G && bHalfSupportNmode == true)
2051 printk("===============>entern half N mode\n");
2052 ieee->bHalfWirelessN24GMode = true;
2055 ieee->bHalfWirelessN24GMode = false;
2057 ieee80211_associate_step2(ieee);
2059 ieee80211_rtl_auth_challenge(ieee, challenge, chlen);
2062 ieee->softmac_stats.rx_auth_rs_err++;
2063 IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode);
2065 printk("Authentication respose status code 0x%x",errcode);
2066 ieee80211_associate_abort(ieee);
2069 }else if (ieee->iw_mode == IW_MODE_MASTER){
2070 ieee80211_rx_auth_rq(ieee, skb);
2075 case IEEE80211_STYPE_PROBE_REQ:
2077 if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
2078 ((ieee->iw_mode == IW_MODE_ADHOC ||
2079 ieee->iw_mode == IW_MODE_MASTER) &&
2080 ieee->state == IEEE80211_LINKED)){
2081 ieee80211_rx_probe_rq(ieee, skb);
2085 case IEEE80211_STYPE_DISASSOC:
2086 case IEEE80211_STYPE_DEAUTH:
2087 /* FIXME for now repeat all the association procedure
2088 * both for disassociation and deauthentication
2090 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2091 ieee->state == IEEE80211_LINKED &&
2092 ieee->iw_mode == IW_MODE_INFRA){
2093 printk("==========>received disassoc/deauth(%x) frame, reason code:%x\n",WLAN_FC_GET_STYPE(header->frame_control), ((struct ieee80211_disassoc*)skb->data)->reason);
2094 ieee->state = IEEE80211_ASSOCIATING;
2095 ieee->softmac_stats.reassoc++;
2096 ieee->is_roaming = true;
2097 ieee80211_disassociate(ieee);
2098 // notify_wx_assoc_event(ieee);
2099 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2100 RemovePeerTS(ieee, header->addr2);
2101 if(ieee->LedControlHandler != NULL)
2102 ieee->LedControlHandler(ieee->dev, LED_CTL_START_TO_LINK); //added by amy for LED 090318
2103 queue_work(ieee->wq, &ieee->associate_procedure_wq);
2106 case IEEE80211_STYPE_MANAGE_ACT:
2107 ieee80211_process_action(ieee,skb);
2114 //dev_kfree_skb_any(skb);
2118 /* following are for a simplier TX queue management.
2119 * Instead of using netif_[stop/wake]_queue the driver
2120 * will uses these two function (plus a reset one), that
2121 * will internally uses the kernel netif_* and takes
2122 * care of the ieee802.11 fragmentation.
2123 * So the driver receives a fragment per time and might
2124 * call the stop function when it want without take care
2125 * to have enough room to TX an entire packet.
2126 * This might be useful if each fragment need it's own
2127 * descriptor, thus just keep a total free memory > than
2128 * the max fragmentation threshold is not enough.. If the
2129 * ieee802.11 stack passed a TXB struct then you needed
2130 * to keep N free descriptors where
2131 * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
2132 * In this way you need just one and the 802.11 stack
2133 * will take care of buffering fragments and pass them to
2134 * to the driver later, when it wakes the queue.
2136 void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
2139 unsigned int queue_index = txb->queue_index;
2140 unsigned long flags;
2142 cb_desc *tcb_desc = NULL;
2144 spin_lock_irqsave(&ieee->lock,flags);
2146 /* called with 2nd parm 0, no tx mgmt lock required */
2147 ieee80211_sta_wakeup(ieee,0);
2149 /* update the tx status */
2150 ieee->stats.tx_bytes += txb->payload_size;
2151 ieee->stats.tx_packets++;
2152 tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
2153 if(tcb_desc->bMulticast) {
2154 ieee->stats.multicast++;
2157 /* if xmit available, just xmit it immediately, else just insert it to the wait queue */
2158 for(i = 0; i < txb->nr_frags; i++) {
2159 if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
2160 (!ieee->check_nic_enough_desc(ieee->dev,queue_index))||\
2161 (ieee->queue_stop)) {
2162 /* insert the skb packet to the wait queue */
2163 /* as for the completion function, it does not need
2164 * to check it any more.
2166 //printk("error:no descriptor left@queue_index %d, %d, %d\n", queue_index, skb_queue_len(&ieee->skb_waitQ[queue_index]), ieee->check_nic_enough_desc(ieee->dev,queue_index));
2167 //ieee80211_rtl_stop_queue(ieee);
2168 skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
2170 ieee->softmac_data_hard_start_xmit(
2172 ieee->dev,ieee->rate);
2173 //ieee->stats.tx_packets++;
2174 //ieee->stats.tx_bytes += txb->fragments[i]->len;
2175 //ieee->dev->trans_start = jiffies;
2179 ieee80211_txb_free(txb);
2182 spin_unlock_irqrestore(&ieee->lock,flags);
2186 /* called with ieee->lock acquired */
2187 void ieee80211_resume_tx(struct ieee80211_device *ieee)
2190 for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
2192 if (ieee->queue_stop){
2193 ieee->tx_pending.frag = i;
2197 ieee->softmac_data_hard_start_xmit(
2198 ieee->tx_pending.txb->fragments[i],
2199 ieee->dev,ieee->rate);
2200 //(i+1)<ieee->tx_pending.txb->nr_frags);
2201 ieee->stats.tx_packets++;
2202 // ieee->dev->trans_start = jiffies;
2207 ieee80211_txb_free(ieee->tx_pending.txb);
2208 ieee->tx_pending.txb = NULL;
2212 void ieee80211_reset_queue(struct ieee80211_device *ieee)
2214 unsigned long flags;
2216 spin_lock_irqsave(&ieee->lock,flags);
2217 init_mgmt_queue(ieee);
2218 if (ieee->tx_pending.txb){
2219 ieee80211_txb_free(ieee->tx_pending.txb);
2220 ieee->tx_pending.txb = NULL;
2222 ieee->queue_stop = 0;
2223 spin_unlock_irqrestore(&ieee->lock,flags);
2227 void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee)
2230 unsigned long flags;
2231 struct sk_buff *skb;
2232 struct ieee80211_hdr_3addr *header;
2234 spin_lock_irqsave(&ieee->lock,flags);
2235 if (! ieee->queue_stop) goto exit;
2237 ieee->queue_stop = 0;
2239 if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){
2240 while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
2242 header = (struct ieee80211_hdr_3addr *) skb->data;
2244 header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2246 if (ieee->seq_ctrl[0] == 0xFFF)
2247 ieee->seq_ctrl[0] = 0;
2249 ieee->seq_ctrl[0]++;
2251 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
2252 //dev_kfree_skb_any(skb);//edit by thomas
2255 if (!ieee->queue_stop && ieee->tx_pending.txb)
2256 ieee80211_resume_tx(ieee);
2258 if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){
2259 ieee->softmac_stats.swtxawake++;
2260 netif_wake_queue(ieee->dev);
2264 spin_unlock_irqrestore(&ieee->lock,flags);
2268 void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee)
2270 //unsigned long flags;
2271 //spin_lock_irqsave(&ieee->lock,flags);
2273 if (! netif_queue_stopped(ieee->dev)){
2274 netif_stop_queue(ieee->dev);
2275 ieee->softmac_stats.swtxstop++;
2277 ieee->queue_stop = 1;
2278 //spin_unlock_irqrestore(&ieee->lock,flags);
2283 inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
2286 get_random_bytes(ieee->current_network.bssid, ETH_ALEN);
2288 /* an IBSS cell address must have the two less significant
2289 * bits of the first byte = 2
2291 ieee->current_network.bssid[0] &= ~0x01;
2292 ieee->current_network.bssid[0] |= 0x02;
2295 /* called in user context only */
2296 void ieee80211_start_master_bss(struct ieee80211_device *ieee)
2300 if (ieee->current_network.ssid_len == 0){
2301 strncpy(ieee->current_network.ssid,
2302 IEEE80211_DEFAULT_TX_ESSID,
2305 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2309 memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
2311 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2312 ieee->state = IEEE80211_LINKED;
2313 ieee->link_change(ieee->dev);
2314 notify_wx_assoc_event(ieee);
2316 if (ieee->data_hard_resume)
2317 ieee->data_hard_resume(ieee->dev);
2319 netif_carrier_on(ieee->dev);
2322 void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
2326 if (ieee->data_hard_resume)
2327 ieee->data_hard_resume(ieee->dev);
2329 netif_carrier_on(ieee->dev);
2333 void ieee80211_start_ibss_wq(struct work_struct *work)
2336 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2337 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
2338 /* iwconfig mode ad-hoc will schedule this and return
2339 * on the other hand this will block further iwconfig SET
2340 * operations because of the wx_sem hold.
2341 * Anyway some most set operations set a flag to speed-up
2342 * (abort) this wq (when syncro scanning) before sleeping
2345 if(!ieee->proto_started){
2346 printk("==========oh driver down return\n");
2349 down(&ieee->wx_sem);
2350 //FIXME:set back to 20M whenever HT for ibss is not ready. Otherwise,after being connected to 40M AP, it will still stay in 40M when set to ibss mode. WB 2009.02.04
2351 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
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);
2433 if(ieee->LedControlHandler != NULL)
2434 ieee->LedControlHandler(ieee->dev,LED_CTL_LINK);
2435 notify_wx_assoc_event(ieee);
2437 ieee80211_start_send_beacons(ieee);
2439 if (ieee->data_hard_resume)
2440 ieee->data_hard_resume(ieee->dev);
2441 netif_carrier_on(ieee->dev);
2446 inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
2448 queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150);
2451 /* this is called only in user context, with wx_sem held */
2452 void ieee80211_start_bss(struct ieee80211_device *ieee)
2454 unsigned long flags;
2456 // Ref: 802.11d 11.1.3.3
2457 // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
2459 if(IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
2461 if(! ieee->bGlobalDomain)
2466 /* check if we have already found the net we
2467 * are interested in (if any).
2468 * if not (we are disassociated and we are not
2469 * in associating / authenticating phase) start the background scanning.
2471 ieee80211_softmac_check_all_nets(ieee);
2473 /* ensure no-one start an associating process (thus setting
2474 * the ieee->state to ieee80211_ASSOCIATING) while we
2475 * have just cheked it and we are going to enable scan.
2476 * The ieee80211_new_net function is always called with
2477 * lock held (from both ieee80211_softmac_check_all_nets and
2478 * the rx path), so we cannot be in the middle of such function
2480 spin_lock_irqsave(&ieee->lock, flags);
2482 if (ieee->state == IEEE80211_NOLINK){
2483 ieee->actscanning = true;
2484 ieee80211_rtl_start_scan(ieee);
2486 spin_unlock_irqrestore(&ieee->lock, flags);
2489 void ieee80211_link_change_wq(struct work_struct *work)
2491 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2492 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, link_change_wq);
2494 ieee->link_change(ieee->dev);
2496 /* called only in userspace context */
2497 void ieee80211_disassociate(struct ieee80211_device *ieee)
2501 netif_carrier_off(ieee->dev);
2502 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
2503 ieee80211_reset_queue(ieee);
2505 if (ieee->data_hard_stop)
2506 ieee->data_hard_stop(ieee->dev);
2507 if(IS_DOT11D_ENABLE(ieee))
2509 ieee->state = IEEE80211_NOLINK;
2510 ieee->is_set_key = false;
2512 //LZM for usb dev crash.
2513 //ieee->link_change(ieee->dev);
2514 queue_delayed_work(ieee->wq, &ieee->link_change_wq, 0);
2516 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2517 notify_wx_assoc_event(ieee);
2521 void ieee80211_associate_retry_wq(struct work_struct *work)
2523 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2524 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
2525 unsigned long flags;
2527 down(&ieee->wx_sem);
2528 if(!ieee->proto_started)
2531 if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
2534 /* until we do not set the state to IEEE80211_NOLINK
2535 * there are no possibility to have someone else trying
2536 * to start an association procdure (we get here with
2537 * ieee->state = IEEE80211_ASSOCIATING).
2538 * When we set the state to IEEE80211_NOLINK it is possible
2539 * that the RX path run an attempt to associate, but
2540 * both ieee80211_softmac_check_all_nets and the
2541 * RX path works with ieee->lock held so there are no
2542 * problems. If we are still disassociated then start a scan.
2543 * the lock here is necessary to ensure no one try to start
2544 * an association procedure when we have just checked the
2545 * state and we are going to start the scan.
2547 ieee->beinretry = true;
2548 ieee->state = IEEE80211_NOLINK;
2550 ieee80211_softmac_check_all_nets(ieee);
2552 spin_lock_irqsave(&ieee->lock, flags);
2554 if(ieee->state == IEEE80211_NOLINK)
2556 ieee->actscanning = true;
2557 ieee80211_rtl_start_scan(ieee);
2559 spin_unlock_irqrestore(&ieee->lock, flags);
2561 ieee->beinretry = false;
2566 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
2568 u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
2570 struct sk_buff *skb;
2571 struct ieee80211_probe_response *b;
2573 skb = ieee80211_probe_resp(ieee, broadcast_addr);
2578 b = (struct ieee80211_probe_response *) skb->data;
2579 b->header.frame_control = cpu_to_le16(IEEE80211_STYPE_BEACON);
2585 struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
2587 struct sk_buff *skb;
2588 struct ieee80211_probe_response *b;
2590 skb = ieee80211_get_beacon_(ieee);
2594 b = (struct ieee80211_probe_response *) skb->data;
2595 b->header.seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2597 if (ieee->seq_ctrl[0] == 0xFFF)
2598 ieee->seq_ctrl[0] = 0;
2600 ieee->seq_ctrl[0]++;
2605 void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
2607 ieee->sync_scan_hurryup = 1;
2608 down(&ieee->wx_sem);
2609 ieee80211_stop_protocol(ieee);
2614 void ieee80211_stop_protocol(struct ieee80211_device *ieee)
2616 if (!ieee->proto_started)
2619 ieee->proto_started = 0;
2621 ieee80211_stop_send_beacons(ieee);
2622 del_timer_sync(&ieee->associate_timer);
2623 cancel_delayed_work(&ieee->associate_retry_wq);
2624 cancel_delayed_work(&ieee->start_ibss_wq);
2625 cancel_delayed_work(&ieee->link_change_wq);
2626 ieee80211_stop_scan(ieee);
2628 ieee80211_disassociate(ieee);
2629 RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
2632 void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
2634 ieee->sync_scan_hurryup = 0;
2635 down(&ieee->wx_sem);
2636 ieee80211_start_protocol(ieee);
2640 void ieee80211_start_protocol(struct ieee80211_device *ieee)
2644 if (ieee->proto_started)
2647 ieee->proto_started = 1;
2649 if (ieee->current_network.channel == 0){
2652 if (ch > MAX_CHANNEL_NUMBER)
2653 return; /* no channel found */
2654 }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
2655 ieee->current_network.channel = ch;
2658 if (ieee->current_network.beacon_interval == 0)
2659 ieee->current_network.beacon_interval = 100;
2660 // printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);
2661 // ieee->set_chan(ieee->dev,ieee->current_network.channel);
2663 for(i = 0; i < 17; i++) {
2664 ieee->last_rxseq_num[i] = -1;
2665 ieee->last_rxfrag_num[i] = -1;
2666 ieee->last_packet_time[i] = 0;
2669 ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
2672 /* if the user set the MAC of the ad-hoc cell and then
2673 * switch to managed mode, shall we make sure that association
2674 * attempts does not fail just because the user provide the essid
2675 * and the nic is still checking for the AP MAC ??
2677 if (ieee->iw_mode == IW_MODE_INFRA)
2678 ieee80211_start_bss(ieee);
2680 else if (ieee->iw_mode == IW_MODE_ADHOC)
2681 ieee80211_start_ibss(ieee);
2683 else if (ieee->iw_mode == IW_MODE_MASTER)
2684 ieee80211_start_master_bss(ieee);
2686 else if(ieee->iw_mode == IW_MODE_MONITOR)
2687 ieee80211_start_monitor_mode(ieee);
2691 #define DRV_NAME "Ieee80211"
2692 void ieee80211_softmac_init(struct ieee80211_device *ieee)
2695 memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
2697 ieee->state = IEEE80211_NOLINK;
2698 ieee->sync_scan_hurryup = 0;
2699 for(i = 0; i < 5; i++) {
2700 ieee->seq_ctrl[i] = 0;
2702 ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
2703 if (!ieee->pDot11dInfo)
2704 IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
2705 memset(ieee->pDot11dInfo, 0, sizeof(RT_DOT11D_INFO));
2706 //added for AP roaming
2707 ieee->LinkDetectInfo.SlotNum = 2;
2708 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
2709 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
2712 ieee->queue_stop = 0;
2714 ieee->softmac_features = 0; //so IEEE2100-like driver are happy
2717 ieee->proto_started = 0;
2718 ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
2720 ieee->ps = IEEE80211_PS_DISABLED;
2721 ieee->sta_sleep = 0;
2722 ieee->Regdot11HTOperationalRateSet[0]= 0xff;//support MCS 0~7
2723 ieee->Regdot11HTOperationalRateSet[1]= 0xff;//support MCS 8~15
2724 ieee->Regdot11HTOperationalRateSet[4]= 0x01;
2726 ieee->actscanning = false;
2727 ieee->beinretry = false;
2728 ieee->is_set_key = false;
2729 init_mgmt_queue(ieee);
2731 ieee->sta_edca_param[0] = 0x0000A403;
2732 ieee->sta_edca_param[1] = 0x0000A427;
2733 ieee->sta_edca_param[2] = 0x005E4342;
2734 ieee->sta_edca_param[3] = 0x002F3262;
2735 ieee->aggregation = true;
2736 ieee->enable_rx_imm_BA = 1;
2737 ieee->tx_pending.txb = NULL;
2739 init_timer(&ieee->associate_timer);
2740 ieee->associate_timer.data = (unsigned long)ieee;
2741 ieee->associate_timer.function = ieee80211_associate_abort_cb;
2743 init_timer(&ieee->beacon_timer);
2744 ieee->beacon_timer.data = (unsigned long) ieee;
2745 ieee->beacon_timer.function = ieee80211_send_beacon_cb;
2747 #ifdef PF_SYNCTHREAD
2748 ieee->wq = create_workqueue(DRV_NAME,0);
2750 ieee->wq = create_workqueue(DRV_NAME);
2753 INIT_DELAYED_WORK(&ieee->link_change_wq,ieee80211_link_change_wq);
2754 INIT_DELAYED_WORK(&ieee->start_ibss_wq,ieee80211_start_ibss_wq);
2755 INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
2756 INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
2757 INIT_DELAYED_WORK(&ieee->softmac_scan_wq,ieee80211_softmac_scan_wq);
2758 INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
2759 INIT_WORK(&ieee->wx_sync_scan_wq,ieee80211_wx_sync_scan_wq);
2761 sema_init(&ieee->wx_sem, 1);
2762 sema_init(&ieee->scan_sem, 1);
2764 spin_lock_init(&ieee->mgmt_tx_lock);
2765 spin_lock_init(&ieee->beacon_lock);
2767 tasklet_init(&ieee->ps_task,
2768 (void(*)(unsigned long)) ieee80211_sta_ps,
2769 (unsigned long)ieee);
2773 void ieee80211_softmac_free(struct ieee80211_device *ieee)
2775 down(&ieee->wx_sem);
2776 if(NULL != ieee->pDot11dInfo)
2778 kfree(ieee->pDot11dInfo);
2779 ieee->pDot11dInfo = NULL;
2781 del_timer_sync(&ieee->associate_timer);
2783 cancel_delayed_work(&ieee->associate_retry_wq);
2784 destroy_workqueue(ieee->wq);
2789 /********************************************************
2790 * Start of WPA code. *
2791 * this is stolen from the ipw2200 driver *
2792 ********************************************************/
2795 static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
2797 /* This is called when wpa_supplicant loads and closes the driver
2799 printk("%s WPA\n",value ? "enabling" : "disabling");
2800 ieee->wpa_enabled = value;
2801 memset(ieee->ap_mac_addr, 0, 6); //reset ap_mac_addr everytime it starts wpa.
2806 void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len)
2808 /* make sure WPA is enabled */
2809 ieee80211_wpa_enable(ieee, 1);
2811 ieee80211_disassociate(ieee);
2815 static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
2821 case IEEE_MLME_STA_DEAUTH:
2825 case IEEE_MLME_STA_DISASSOC:
2826 ieee80211_disassociate(ieee);
2830 printk("Unknown MLME request: %d\n", command);
2838 static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
2839 struct ieee_param *param, int plen)
2843 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
2844 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
2847 if (param->u.wpa_ie.len) {
2848 buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
2852 memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
2853 kfree(ieee->wpa_ie);
2855 ieee->wpa_ie_len = param->u.wpa_ie.len;
2857 kfree(ieee->wpa_ie);
2858 ieee->wpa_ie = NULL;
2859 ieee->wpa_ie_len = 0;
2862 ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
2866 #define AUTH_ALG_OPEN_SYSTEM 0x1
2867 #define AUTH_ALG_SHARED_KEY 0x2
2868 #define AUTH_ALG_LEAP 0x4
2869 static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
2872 struct ieee80211_security sec = {
2873 .flags = SEC_AUTH_MODE,
2877 if (value & AUTH_ALG_SHARED_KEY) {
2878 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
2880 ieee->auth_mode = 1;
2881 } else if (value & AUTH_ALG_OPEN_SYSTEM){
2882 sec.auth_mode = WLAN_AUTH_OPEN;
2884 ieee->auth_mode = 0;
2886 else if (value & AUTH_ALG_LEAP){
2887 sec.auth_mode = RTL_WLAN_AUTH_LEAP;
2889 ieee->auth_mode = 2;
2893 if (ieee->set_security)
2894 ieee->set_security(ieee->dev, &sec);
2896 // ret = -EOPNOTSUPP;
2901 static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
2904 unsigned long flags;
2907 case IEEE_PARAM_WPA_ENABLED:
2908 ret = ieee80211_wpa_enable(ieee, value);
2911 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2912 ieee->tkip_countermeasures=value;
2915 case IEEE_PARAM_DROP_UNENCRYPTED: {
2918 * wpa_supplicant calls set_wpa_enabled when the driver
2919 * is loaded and unloaded, regardless of if WPA is being
2920 * used. No other calls are made which can be used to
2921 * determine if encryption will be used or not prior to
2922 * association being expected. If encryption is not being
2923 * used, drop_unencrypted is set to false, else true -- we
2924 * can use this to determine if the CAP_PRIVACY_ON bit should
2927 struct ieee80211_security sec = {
2928 .flags = SEC_ENABLED,
2931 ieee->drop_unencrypted = value;
2932 /* We only change SEC_LEVEL for open mode. Others
2933 * are set by ipw_wpa_set_encryption.
2936 sec.flags |= SEC_LEVEL;
2937 sec.level = SEC_LEVEL_0;
2940 sec.flags |= SEC_LEVEL;
2941 sec.level = SEC_LEVEL_1;
2943 if (ieee->set_security)
2944 ieee->set_security(ieee->dev, &sec);
2948 case IEEE_PARAM_PRIVACY_INVOKED:
2949 ieee->privacy_invoked=value;
2952 case IEEE_PARAM_AUTH_ALGS:
2953 ret = ieee80211_wpa_set_auth_algs(ieee, value);
2956 case IEEE_PARAM_IEEE_802_1X:
2957 ieee->ieee802_1x=value;
2959 case IEEE_PARAM_WPAX_SELECT:
2960 // added for WPA2 mixed mode
2961 spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
2962 ieee->wpax_type_set = 1;
2963 ieee->wpax_type_notify = value;
2964 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
2968 printk("Unknown WPA param: %d\n",name);
2975 /* implementation borrowed from hostap driver */
2977 static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
2978 struct ieee_param *param, int param_len)
2982 struct ieee80211_crypto_ops *ops;
2983 struct ieee80211_crypt_data **crypt;
2985 struct ieee80211_security sec = {
2989 param->u.crypt.err = 0;
2990 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
2993 (int) ((char *) param->u.crypt.key - (char *) param) +
2994 param->u.crypt.key_len) {
2995 printk("Len mismatch %d, %d\n", param_len,
2996 param->u.crypt.key_len);
2999 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3000 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3001 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3002 if (param->u.crypt.idx >= WEP_KEYS)
3004 crypt = &ieee->crypt[param->u.crypt.idx];
3009 if (strcmp(param->u.crypt.alg, "none") == 0) {
3014 sec.level = SEC_LEVEL_0;
3015 sec.flags |= SEC_ENABLED | SEC_LEVEL;
3016 ieee80211_crypt_delayed_deinit(ieee, crypt);
3023 sec.flags |= SEC_ENABLED;
3025 /* IPW HW cannot build TKIP MIC, host decryption still needed. */
3026 if (!(ieee->host_encrypt || ieee->host_decrypt) &&
3027 strcmp(param->u.crypt.alg, "TKIP"))
3028 goto skip_host_crypt;
3030 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3031 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0)
3032 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3033 /* set WEP40 first, it will be modified according to WEP104 or
3034 * WEP40 at other place */
3035 else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0)
3036 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3037 else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0)
3038 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3040 printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
3041 param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
3046 if (*crypt == NULL || (*crypt)->ops != ops) {
3047 struct ieee80211_crypt_data *new_crypt;
3049 ieee80211_crypt_delayed_deinit(ieee, crypt);
3051 new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL);
3052 if (new_crypt == NULL) {
3056 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
3057 new_crypt->ops = ops;
3061 new_crypt->ops->init(param->u.crypt.idx);
3063 if (new_crypt->priv == NULL) {
3065 param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
3073 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
3074 (*crypt)->ops->set_key(param->u.crypt.key,
3075 param->u.crypt.key_len, param->u.crypt.seq,
3076 (*crypt)->priv) < 0) {
3077 printk("key setting failed\n");
3078 param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
3084 if (param->u.crypt.set_tx) {
3085 ieee->tx_keyidx = param->u.crypt.idx;
3086 sec.active_key = param->u.crypt.idx;
3087 sec.flags |= SEC_ACTIVE_KEY;
3089 sec.flags &= ~SEC_ACTIVE_KEY;
3091 if (param->u.crypt.alg != NULL) {
3092 memcpy(sec.keys[param->u.crypt.idx],
3094 param->u.crypt.key_len);
3095 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
3096 sec.flags |= (1 << param->u.crypt.idx);
3098 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3099 sec.flags |= SEC_LEVEL;
3100 sec.level = SEC_LEVEL_1;
3101 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3102 sec.flags |= SEC_LEVEL;
3103 sec.level = SEC_LEVEL_2;
3104 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3105 sec.flags |= SEC_LEVEL;
3106 sec.level = SEC_LEVEL_3;
3110 if (ieee->set_security)
3111 ieee->set_security(ieee->dev, &sec);
3113 /* Do not reset port if card is in Managed mode since resetting will
3114 * generate new IEEE 802.11 authentication which may end up in looping
3115 * with IEEE 802.1X. If your hardware requires a reset after WEP
3116 * configuration (for example... Prism2), implement the reset_port in
3117 * the callbacks structures used to initialize the 802.11 stack. */
3118 if (ieee->reset_on_keychange &&
3119 ieee->iw_mode != IW_MODE_INFRA &&
3121 ieee->reset_port(ieee->dev)) {
3122 printk("reset_port failed\n");
3123 param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
3130 inline struct sk_buff *ieee80211_disassociate_skb(
3131 struct ieee80211_network *beacon,
3132 struct ieee80211_device *ieee,
3135 struct sk_buff *skb;
3136 struct ieee80211_disassoc *disass;
3138 skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc));
3142 disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc));
3143 disass->header.frame_control = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
3144 disass->header.duration_id = 0;
3146 memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
3147 memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
3148 memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
3150 disass->reason = asRsn;
3157 struct ieee80211_device *ieee,
3162 struct ieee80211_network *beacon = &ieee->current_network;
3163 struct sk_buff *skb;
3164 skb = ieee80211_disassociate_skb(beacon,ieee,asRsn);
3166 softmac_mgmt_xmit(skb, ieee);
3167 //dev_kfree_skb_any(skb);//edit by thomas
3171 int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
3173 struct ieee_param *param;
3176 down(&ieee->wx_sem);
3177 //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
3179 if (p->length < sizeof(struct ieee_param) || !p->pointer){
3184 param = kmalloc(p->length, GFP_KERNEL);
3189 if (copy_from_user(param, p->pointer, p->length)) {
3195 switch (param->cmd) {
3197 case IEEE_CMD_SET_WPA_PARAM:
3198 ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
3199 param->u.wpa_param.value);
3202 case IEEE_CMD_SET_WPA_IE:
3203 ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
3206 case IEEE_CMD_SET_ENCRYPTION:
3207 ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
3211 ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
3212 param->u.mlme.reason_code);
3216 printk("Unknown WPA supplicant request: %d\n",param->cmd);
3221 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
3231 void notify_wx_assoc_event(struct ieee80211_device *ieee)
3233 union iwreq_data wrqu;
3234 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3235 if (ieee->state == IEEE80211_LINKED)
3236 memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
3238 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
3239 wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);