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 = (u8*)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 if ((status = auth_rq_parse(skb, dest))!= -1){
1695 ieee80211_resp_to_auth(ieee, status, dest);
1697 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1702 ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1706 //unsigned long flags;
1708 ieee->softmac_stats.rx_ass_rq++;
1709 if (assoc_rq_parse(skb,dest) != -1){
1710 ieee80211_resp_to_assoc_rq(ieee, dest);
1713 printk(KERN_INFO"New client associated: %pM\n", dest);
1719 void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
1722 struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
1725 softmac_ps_mgmt_xmit(buf, ieee);
1730 short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
1732 int timeout = ieee->ps_timeout;
1734 /*if(ieee->ps == IEEE80211_PS_DISABLED ||
1735 ieee->iw_mode != IW_MODE_INFRA ||
1736 ieee->state != IEEE80211_LINKED)
1740 dtim = ieee->current_network.dtim_data;
1742 if(!(dtim & IEEE80211_DTIM_VALID))
1744 timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
1745 //printk("VALID\n");
1746 ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
1748 if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
1751 if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
1754 if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
1757 if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
1758 (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
1762 *time_l = ieee->current_network.last_dtim_sta_time[0]
1763 + (ieee->current_network.beacon_interval);
1764 // * ieee->current_network.dtim_period) * 1000;
1768 *time_h = ieee->current_network.last_dtim_sta_time[1];
1769 if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
1778 inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
1784 unsigned long flags,flags2;
1786 spin_lock_irqsave(&ieee->lock, flags);
1788 if((ieee->ps == IEEE80211_PS_DISABLED ||
1789 ieee->iw_mode != IW_MODE_INFRA ||
1790 ieee->state != IEEE80211_LINKED)){
1792 // #warning CHECK_LOCK_HERE
1793 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1795 ieee80211_sta_wakeup(ieee, 1);
1797 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1800 sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
1801 /* 2 wake, 1 sleep, 0 do nothing */
1807 if(ieee->sta_sleep == 1)
1808 ieee->enter_sleep_state(ieee->dev,th,tl);
1810 else if(ieee->sta_sleep == 0){
1811 // printk("send null 1\n");
1812 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1814 if(ieee->ps_is_queue_empty(ieee->dev)){
1817 ieee->sta_sleep = 2;
1819 ieee->ack_tx_to_ieee = 1;
1821 ieee80211_sta_ps_send_null_frame(ieee,1);
1826 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1831 }else if(sleep == 2){
1832 //#warning CHECK_LOCK_HERE
1833 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1835 ieee80211_sta_wakeup(ieee,1);
1837 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1841 spin_unlock_irqrestore(&ieee->lock, flags);
1845 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
1847 if(ieee->sta_sleep == 0){
1849 printk("Warning: driver is probably failing to report TX ps error\n");
1850 ieee->ack_tx_to_ieee = 1;
1851 ieee80211_sta_ps_send_null_frame(ieee, 0);
1857 if(ieee->sta_sleep == 1)
1858 ieee->sta_wake_up(ieee->dev);
1860 ieee->sta_sleep = 0;
1863 ieee->ack_tx_to_ieee = 1;
1864 ieee80211_sta_ps_send_null_frame(ieee, 0);
1868 void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
1870 unsigned long flags,flags2;
1872 spin_lock_irqsave(&ieee->lock, flags);
1874 if(ieee->sta_sleep == 2){
1875 /* Null frame with PS bit set */
1877 ieee->sta_sleep = 1;
1878 ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
1880 /* if the card report not success we can't be sure the AP
1881 * has not RXed so we can't assume the AP believe us awake
1884 /* 21112005 - tx again null without PS bit if lost */
1887 if((ieee->sta_sleep == 0) && !success){
1888 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1889 ieee80211_sta_ps_send_null_frame(ieee, 0);
1890 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1893 spin_unlock_irqrestore(&ieee->lock, flags);
1895 void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb)
1897 struct rtl_ieee80211_hdr *header =
1898 (struct rtl_ieee80211_hdr *)skb->data;
1899 u8* act = ieee80211_get_payload(header);
1901 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
1904 IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
1912 if (*act == ACT_ADDBAREQ)
1913 ieee80211_rx_ADDBAReq(ieee, skb);
1914 else if (*act == ACT_ADDBARSP)
1915 ieee80211_rx_ADDBARsp(ieee, skb);
1916 else if (*act == ACT_DELBA)
1917 ieee80211_rx_DELBA(ieee, skb);
1920 // if (net_ratelimit())
1921 // IEEE80211_DEBUG(IEEE80211_DL_BA, "unknown action frame(%d)\n", tmp);
1928 ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
1929 struct ieee80211_rx_stats *rx_stats, u16 type,
1932 struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
1937 struct ieee80211_assoc_response_frame *assoc_resp;
1938 // struct ieee80211_info_element *info_element;
1939 bool bSupportNmode = true, bHalfSupportNmode = false; //default support N mode, disable halfNmode
1941 if(!ieee->proto_started)
1944 switch (WLAN_FC_GET_STYPE(header->frame_control)) {
1946 case IEEE80211_STYPE_ASSOC_RESP:
1947 case IEEE80211_STYPE_REASSOC_RESP:
1949 IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
1950 WLAN_FC_GET_STYPE(header->frame_control));
1951 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
1952 ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
1953 ieee->iw_mode == IW_MODE_INFRA){
1954 struct ieee80211_network network_resp;
1955 struct ieee80211_network *network = &network_resp;
1957 if (0 == (errcode=assoc_parse(ieee,skb, &aid))){
1958 ieee->state=IEEE80211_LINKED;
1959 ieee->assoc_id = aid;
1960 ieee->softmac_stats.rx_ass_ok++;
1961 /* station support qos */
1962 /* Let the register setting defaultly with Legacy station */
1963 if(ieee->qos_support) {
1964 assoc_resp = (struct ieee80211_assoc_response_frame*)skb->data;
1965 memset(network, 0, sizeof(*network));
1966 if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\
1967 rx_stats->len - sizeof(*assoc_resp),\
1972 { //filling the PeerHTCap. //maybe not neccesary as we can get its info from current_network.
1973 memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
1974 memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
1976 if (ieee->handle_assoc_response != NULL)
1977 ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame*)header, network);
1979 ieee80211_associate_complete(ieee);
1981 /* aid could not been allocated */
1982 ieee->softmac_stats.rx_ass_err++;
1984 "Association response status code 0x%x\n",
1986 IEEE80211_DEBUG_MGMT(
1987 "Association response status code 0x%x\n",
1989 if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
1990 queue_work(ieee->wq, &ieee->associate_procedure_wq);
1992 ieee80211_associate_abort(ieee);
1998 case IEEE80211_STYPE_ASSOC_REQ:
1999 case IEEE80211_STYPE_REASSOC_REQ:
2001 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2002 ieee->iw_mode == IW_MODE_MASTER)
2004 ieee80211_rx_assoc_rq(ieee, skb);
2007 case IEEE80211_STYPE_AUTH:
2009 if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){
2010 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
2011 ieee->iw_mode == IW_MODE_INFRA){
2013 IEEE80211_DEBUG_MGMT("Received authentication response");
2015 if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){
2016 if(ieee->open_wep || !challenge){
2017 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
2018 ieee->softmac_stats.rx_auth_rs_ok++;
2019 if(!(ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE))
2021 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
2023 // WEP or TKIP encryption
2024 if(IsHTHalfNmodeAPs(ieee))
2026 bSupportNmode = true;
2027 bHalfSupportNmode = true;
2031 bSupportNmode = false;
2032 bHalfSupportNmode = false;
2034 printk("==========>to link with AP using SEC(%d, %d)", bSupportNmode, bHalfSupportNmode);
2037 /* Dummy wirless mode setting to avoid encryption issue */
2040 ieee->SetWirelessMode(ieee->dev, \
2041 ieee->current_network.mode);
2045 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2048 if (ieee->current_network.mode == IEEE_N_24G && bHalfSupportNmode == true)
2050 printk("===============>entern half N mode\n");
2051 ieee->bHalfWirelessN24GMode = true;
2054 ieee->bHalfWirelessN24GMode = false;
2056 ieee80211_associate_step2(ieee);
2058 ieee80211_rtl_auth_challenge(ieee, challenge, chlen);
2061 ieee->softmac_stats.rx_auth_rs_err++;
2062 IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode);
2064 printk("Authentication respose status code 0x%x",errcode);
2065 ieee80211_associate_abort(ieee);
2068 }else if (ieee->iw_mode == IW_MODE_MASTER){
2069 ieee80211_rx_auth_rq(ieee, skb);
2074 case IEEE80211_STYPE_PROBE_REQ:
2076 if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
2077 ((ieee->iw_mode == IW_MODE_ADHOC ||
2078 ieee->iw_mode == IW_MODE_MASTER) &&
2079 ieee->state == IEEE80211_LINKED)){
2080 ieee80211_rx_probe_rq(ieee, skb);
2084 case IEEE80211_STYPE_DISASSOC:
2085 case IEEE80211_STYPE_DEAUTH:
2086 /* FIXME for now repeat all the association procedure
2087 * both for disassociation and deauthentication
2089 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2090 ieee->state == IEEE80211_LINKED &&
2091 ieee->iw_mode == IW_MODE_INFRA){
2092 printk("==========>received disassoc/deauth(%x) frame, reason code:%x\n",WLAN_FC_GET_STYPE(header->frame_control), ((struct ieee80211_disassoc*)skb->data)->reason);
2093 ieee->state = IEEE80211_ASSOCIATING;
2094 ieee->softmac_stats.reassoc++;
2095 ieee->is_roaming = true;
2096 ieee80211_disassociate(ieee);
2097 // notify_wx_assoc_event(ieee);
2098 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2099 RemovePeerTS(ieee, header->addr2);
2100 if(ieee->LedControlHandler != NULL)
2101 ieee->LedControlHandler(ieee->dev, LED_CTL_START_TO_LINK); //added by amy for LED 090318
2102 queue_work(ieee->wq, &ieee->associate_procedure_wq);
2105 case IEEE80211_STYPE_MANAGE_ACT:
2106 ieee80211_process_action(ieee,skb);
2113 //dev_kfree_skb_any(skb);
2117 /* following are for a simplier TX queue management.
2118 * Instead of using netif_[stop/wake]_queue the driver
2119 * will uses these two function (plus a reset one), that
2120 * will internally uses the kernel netif_* and takes
2121 * care of the ieee802.11 fragmentation.
2122 * So the driver receives a fragment per time and might
2123 * call the stop function when it want without take care
2124 * to have enough room to TX an entire packet.
2125 * This might be useful if each fragment need it's own
2126 * descriptor, thus just keep a total free memory > than
2127 * the max fragmentation threshold is not enough.. If the
2128 * ieee802.11 stack passed a TXB struct then you needed
2129 * to keep N free descriptors where
2130 * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
2131 * In this way you need just one and the 802.11 stack
2132 * will take care of buffering fragments and pass them to
2133 * to the driver later, when it wakes the queue.
2135 void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
2138 unsigned int queue_index = txb->queue_index;
2139 unsigned long flags;
2141 cb_desc *tcb_desc = NULL;
2143 spin_lock_irqsave(&ieee->lock,flags);
2145 /* called with 2nd parm 0, no tx mgmt lock required */
2146 ieee80211_sta_wakeup(ieee,0);
2148 /* update the tx status */
2149 ieee->stats.tx_bytes += txb->payload_size;
2150 ieee->stats.tx_packets++;
2151 tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
2152 if(tcb_desc->bMulticast) {
2153 ieee->stats.multicast++;
2156 /* if xmit available, just xmit it immediately, else just insert it to the wait queue */
2157 for(i = 0; i < txb->nr_frags; i++) {
2158 if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
2159 (!ieee->check_nic_enough_desc(ieee->dev,queue_index))||\
2160 (ieee->queue_stop)) {
2161 /* insert the skb packet to the wait queue */
2162 /* as for the completion function, it does not need
2163 * to check it any more.
2165 //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));
2166 //ieee80211_rtl_stop_queue(ieee);
2167 skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
2169 ieee->softmac_data_hard_start_xmit(
2171 ieee->dev,ieee->rate);
2172 //ieee->stats.tx_packets++;
2173 //ieee->stats.tx_bytes += txb->fragments[i]->len;
2174 //ieee->dev->trans_start = jiffies;
2178 ieee80211_txb_free(txb);
2181 spin_unlock_irqrestore(&ieee->lock,flags);
2185 /* called with ieee->lock acquired */
2186 void ieee80211_resume_tx(struct ieee80211_device *ieee)
2189 for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
2191 if (ieee->queue_stop){
2192 ieee->tx_pending.frag = i;
2196 ieee->softmac_data_hard_start_xmit(
2197 ieee->tx_pending.txb->fragments[i],
2198 ieee->dev,ieee->rate);
2199 //(i+1)<ieee->tx_pending.txb->nr_frags);
2200 ieee->stats.tx_packets++;
2201 // ieee->dev->trans_start = jiffies;
2206 ieee80211_txb_free(ieee->tx_pending.txb);
2207 ieee->tx_pending.txb = NULL;
2211 void ieee80211_reset_queue(struct ieee80211_device *ieee)
2213 unsigned long flags;
2215 spin_lock_irqsave(&ieee->lock,flags);
2216 init_mgmt_queue(ieee);
2217 if (ieee->tx_pending.txb){
2218 ieee80211_txb_free(ieee->tx_pending.txb);
2219 ieee->tx_pending.txb = NULL;
2221 ieee->queue_stop = 0;
2222 spin_unlock_irqrestore(&ieee->lock,flags);
2226 void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee)
2229 unsigned long flags;
2230 struct sk_buff *skb;
2231 struct ieee80211_hdr_3addr *header;
2233 spin_lock_irqsave(&ieee->lock,flags);
2234 if (! ieee->queue_stop) goto exit;
2236 ieee->queue_stop = 0;
2238 if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){
2239 while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
2241 header = (struct ieee80211_hdr_3addr *) skb->data;
2243 header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2245 if (ieee->seq_ctrl[0] == 0xFFF)
2246 ieee->seq_ctrl[0] = 0;
2248 ieee->seq_ctrl[0]++;
2250 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
2251 //dev_kfree_skb_any(skb);//edit by thomas
2254 if (!ieee->queue_stop && ieee->tx_pending.txb)
2255 ieee80211_resume_tx(ieee);
2257 if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){
2258 ieee->softmac_stats.swtxawake++;
2259 netif_wake_queue(ieee->dev);
2263 spin_unlock_irqrestore(&ieee->lock,flags);
2267 void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee)
2269 //unsigned long flags;
2270 //spin_lock_irqsave(&ieee->lock,flags);
2272 if (! netif_queue_stopped(ieee->dev)){
2273 netif_stop_queue(ieee->dev);
2274 ieee->softmac_stats.swtxstop++;
2276 ieee->queue_stop = 1;
2277 //spin_unlock_irqrestore(&ieee->lock,flags);
2282 inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
2285 get_random_bytes(ieee->current_network.bssid, ETH_ALEN);
2287 /* an IBSS cell address must have the two less significant
2288 * bits of the first byte = 2
2290 ieee->current_network.bssid[0] &= ~0x01;
2291 ieee->current_network.bssid[0] |= 0x02;
2294 /* called in user context only */
2295 void ieee80211_start_master_bss(struct ieee80211_device *ieee)
2299 if (ieee->current_network.ssid_len == 0){
2300 strncpy(ieee->current_network.ssid,
2301 IEEE80211_DEFAULT_TX_ESSID,
2304 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2308 memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
2310 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2311 ieee->state = IEEE80211_LINKED;
2312 ieee->link_change(ieee->dev);
2313 notify_wx_assoc_event(ieee);
2315 if (ieee->data_hard_resume)
2316 ieee->data_hard_resume(ieee->dev);
2318 netif_carrier_on(ieee->dev);
2321 void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
2325 if (ieee->data_hard_resume)
2326 ieee->data_hard_resume(ieee->dev);
2328 netif_carrier_on(ieee->dev);
2332 void ieee80211_start_ibss_wq(struct work_struct *work)
2335 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2336 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
2337 /* iwconfig mode ad-hoc will schedule this and return
2338 * on the other hand this will block further iwconfig SET
2339 * operations because of the wx_sem hold.
2340 * Anyway some most set operations set a flag to speed-up
2341 * (abort) this wq (when syncro scanning) before sleeping
2344 if(!ieee->proto_started){
2345 printk("==========oh driver down return\n");
2348 down(&ieee->wx_sem);
2349 //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
2350 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2352 if (ieee->current_network.ssid_len == 0){
2353 strcpy(ieee->current_network.ssid,IEEE80211_DEFAULT_TX_ESSID);
2354 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2358 /* check if we have this cell in our network list */
2359 ieee80211_softmac_check_all_nets(ieee);
2362 // if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK))
2363 if (ieee->state == IEEE80211_NOLINK)
2364 ieee->current_network.channel = 6;
2365 /* if not then the state is not linked. Maybe the user swithced to
2366 * ad-hoc mode just after being in monitor mode, or just after
2367 * being very few time in managed mode (so the card have had no
2368 * time to scan all the chans..) or we have just run up the iface
2369 * after setting ad-hoc mode. So we have to give another try..
2370 * Here, in ibss mode, should be safe to do this without extra care
2371 * (in bss mode we had to make sure no-one tryed to associate when
2372 * we had just checked the ieee->state and we was going to start the
2373 * scan) beacause in ibss mode the ieee80211_new_net function, when
2374 * finds a good net, just set the ieee->state to IEEE80211_LINKED,
2375 * so, at worst, we waste a bit of time to initiate an unneeded syncro
2376 * scan, that will stop at the first round because it sees the state
2379 if (ieee->state == IEEE80211_NOLINK)
2380 ieee80211_start_scan_syncro(ieee);
2382 /* the network definitively is not here.. create a new cell */
2383 if (ieee->state == IEEE80211_NOLINK){
2384 printk("creating new IBSS cell\n");
2386 ieee80211_randomize_cell(ieee);
2388 if(ieee->modulation & IEEE80211_CCK_MODULATION){
2390 ieee->current_network.rates_len = 4;
2392 ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
2393 ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
2394 ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
2395 ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
2398 ieee->current_network.rates_len = 0;
2400 if(ieee->modulation & IEEE80211_OFDM_MODULATION){
2401 ieee->current_network.rates_ex_len = 8;
2403 ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
2404 ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
2405 ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
2406 ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
2407 ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
2408 ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
2409 ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
2410 ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
2414 ieee->current_network.rates_ex_len = 0;
2418 // By default, WMM function will be disabled in IBSS mode
2419 ieee->current_network.QoS_Enable = 0;
2420 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2421 ieee->current_network.atim_window = 0;
2422 ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
2423 if(ieee->short_slot)
2424 ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
2428 ieee->state = IEEE80211_LINKED;
2430 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2431 ieee->link_change(ieee->dev);
2432 if(ieee->LedControlHandler != NULL)
2433 ieee->LedControlHandler(ieee->dev,LED_CTL_LINK);
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_rtl_start_scan(ieee);
2485 spin_unlock_irqrestore(&ieee->lock, flags);
2488 void ieee80211_link_change_wq(struct work_struct *work)
2490 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2491 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, link_change_wq);
2493 ieee->link_change(ieee->dev);
2495 /* called only in userspace context */
2496 void ieee80211_disassociate(struct ieee80211_device *ieee)
2500 netif_carrier_off(ieee->dev);
2501 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
2502 ieee80211_reset_queue(ieee);
2504 if (ieee->data_hard_stop)
2505 ieee->data_hard_stop(ieee->dev);
2506 if(IS_DOT11D_ENABLE(ieee))
2508 ieee->state = IEEE80211_NOLINK;
2509 ieee->is_set_key = false;
2511 //LZM for usb dev crash.
2512 //ieee->link_change(ieee->dev);
2513 queue_delayed_work(ieee->wq, &ieee->link_change_wq, 0);
2515 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2516 notify_wx_assoc_event(ieee);
2520 void ieee80211_associate_retry_wq(struct work_struct *work)
2522 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2523 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
2524 unsigned long flags;
2526 down(&ieee->wx_sem);
2527 if(!ieee->proto_started)
2530 if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
2533 /* until we do not set the state to IEEE80211_NOLINK
2534 * there are no possibility to have someone else trying
2535 * to start an association procdure (we get here with
2536 * ieee->state = IEEE80211_ASSOCIATING).
2537 * When we set the state to IEEE80211_NOLINK it is possible
2538 * that the RX path run an attempt to associate, but
2539 * both ieee80211_softmac_check_all_nets and the
2540 * RX path works with ieee->lock held so there are no
2541 * problems. If we are still disassociated then start a scan.
2542 * the lock here is necessary to ensure no one try to start
2543 * an association procedure when we have just checked the
2544 * state and we are going to start the scan.
2546 ieee->beinretry = true;
2547 ieee->state = IEEE80211_NOLINK;
2549 ieee80211_softmac_check_all_nets(ieee);
2551 spin_lock_irqsave(&ieee->lock, flags);
2553 if(ieee->state == IEEE80211_NOLINK)
2555 ieee->actscanning = true;
2556 ieee80211_rtl_start_scan(ieee);
2558 spin_unlock_irqrestore(&ieee->lock, flags);
2560 ieee->beinretry = false;
2565 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
2567 u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
2569 struct sk_buff *skb;
2570 struct ieee80211_probe_response *b;
2572 skb = ieee80211_probe_resp(ieee, broadcast_addr);
2577 b = (struct ieee80211_probe_response *) skb->data;
2578 b->header.frame_control = cpu_to_le16(IEEE80211_STYPE_BEACON);
2584 struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
2586 struct sk_buff *skb;
2587 struct ieee80211_probe_response *b;
2589 skb = ieee80211_get_beacon_(ieee);
2593 b = (struct ieee80211_probe_response *) skb->data;
2594 b->header.seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2596 if (ieee->seq_ctrl[0] == 0xFFF)
2597 ieee->seq_ctrl[0] = 0;
2599 ieee->seq_ctrl[0]++;
2604 void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
2606 ieee->sync_scan_hurryup = 1;
2607 down(&ieee->wx_sem);
2608 ieee80211_stop_protocol(ieee);
2613 void ieee80211_stop_protocol(struct ieee80211_device *ieee)
2615 if (!ieee->proto_started)
2618 ieee->proto_started = 0;
2620 ieee80211_stop_send_beacons(ieee);
2621 del_timer_sync(&ieee->associate_timer);
2622 cancel_delayed_work(&ieee->associate_retry_wq);
2623 cancel_delayed_work(&ieee->start_ibss_wq);
2624 cancel_delayed_work(&ieee->link_change_wq);
2625 ieee80211_stop_scan(ieee);
2627 ieee80211_disassociate(ieee);
2628 RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
2631 void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
2633 ieee->sync_scan_hurryup = 0;
2634 down(&ieee->wx_sem);
2635 ieee80211_start_protocol(ieee);
2639 void ieee80211_start_protocol(struct ieee80211_device *ieee)
2643 if (ieee->proto_started)
2646 ieee->proto_started = 1;
2648 if (ieee->current_network.channel == 0){
2651 if (ch > MAX_CHANNEL_NUMBER)
2652 return; /* no channel found */
2653 }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
2654 ieee->current_network.channel = ch;
2657 if (ieee->current_network.beacon_interval == 0)
2658 ieee->current_network.beacon_interval = 100;
2659 // printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);
2660 // ieee->set_chan(ieee->dev,ieee->current_network.channel);
2662 for(i = 0; i < 17; i++) {
2663 ieee->last_rxseq_num[i] = -1;
2664 ieee->last_rxfrag_num[i] = -1;
2665 ieee->last_packet_time[i] = 0;
2668 ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
2671 /* if the user set the MAC of the ad-hoc cell and then
2672 * switch to managed mode, shall we make sure that association
2673 * attempts does not fail just because the user provide the essid
2674 * and the nic is still checking for the AP MAC ??
2676 if (ieee->iw_mode == IW_MODE_INFRA)
2677 ieee80211_start_bss(ieee);
2679 else if (ieee->iw_mode == IW_MODE_ADHOC)
2680 ieee80211_start_ibss(ieee);
2682 else if (ieee->iw_mode == IW_MODE_MASTER)
2683 ieee80211_start_master_bss(ieee);
2685 else if(ieee->iw_mode == IW_MODE_MONITOR)
2686 ieee80211_start_monitor_mode(ieee);
2690 #define DRV_NAME "Ieee80211"
2691 void ieee80211_softmac_init(struct ieee80211_device *ieee)
2694 memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
2696 ieee->state = IEEE80211_NOLINK;
2697 ieee->sync_scan_hurryup = 0;
2698 for(i = 0; i < 5; i++) {
2699 ieee->seq_ctrl[i] = 0;
2701 ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
2702 if (!ieee->pDot11dInfo)
2703 IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
2704 memset(ieee->pDot11dInfo, 0, sizeof(RT_DOT11D_INFO));
2705 //added for AP roaming
2706 ieee->LinkDetectInfo.SlotNum = 2;
2707 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
2708 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
2711 ieee->queue_stop = 0;
2713 ieee->softmac_features = 0; //so IEEE2100-like driver are happy
2716 ieee->proto_started = 0;
2717 ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
2719 ieee->ps = IEEE80211_PS_DISABLED;
2720 ieee->sta_sleep = 0;
2721 ieee->Regdot11HTOperationalRateSet[0]= 0xff;//support MCS 0~7
2722 ieee->Regdot11HTOperationalRateSet[1]= 0xff;//support MCS 8~15
2723 ieee->Regdot11HTOperationalRateSet[4]= 0x01;
2725 ieee->actscanning = false;
2726 ieee->beinretry = false;
2727 ieee->is_set_key = false;
2728 init_mgmt_queue(ieee);
2730 ieee->sta_edca_param[0] = 0x0000A403;
2731 ieee->sta_edca_param[1] = 0x0000A427;
2732 ieee->sta_edca_param[2] = 0x005E4342;
2733 ieee->sta_edca_param[3] = 0x002F3262;
2734 ieee->aggregation = true;
2735 ieee->enable_rx_imm_BA = 1;
2736 ieee->tx_pending.txb = NULL;
2738 init_timer(&ieee->associate_timer);
2739 ieee->associate_timer.data = (unsigned long)ieee;
2740 ieee->associate_timer.function = ieee80211_associate_abort_cb;
2742 init_timer(&ieee->beacon_timer);
2743 ieee->beacon_timer.data = (unsigned long) ieee;
2744 ieee->beacon_timer.function = ieee80211_send_beacon_cb;
2746 #ifdef PF_SYNCTHREAD
2747 ieee->wq = create_workqueue(DRV_NAME,0);
2749 ieee->wq = create_workqueue(DRV_NAME);
2752 INIT_DELAYED_WORK(&ieee->link_change_wq,ieee80211_link_change_wq);
2753 INIT_DELAYED_WORK(&ieee->start_ibss_wq,ieee80211_start_ibss_wq);
2754 INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
2755 INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
2756 INIT_DELAYED_WORK(&ieee->softmac_scan_wq,ieee80211_softmac_scan_wq);
2757 INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
2758 INIT_WORK(&ieee->wx_sync_scan_wq,ieee80211_wx_sync_scan_wq);
2760 sema_init(&ieee->wx_sem, 1);
2761 sema_init(&ieee->scan_sem, 1);
2763 spin_lock_init(&ieee->mgmt_tx_lock);
2764 spin_lock_init(&ieee->beacon_lock);
2766 tasklet_init(&ieee->ps_task,
2767 (void(*)(unsigned long)) ieee80211_sta_ps,
2768 (unsigned long)ieee);
2772 void ieee80211_softmac_free(struct ieee80211_device *ieee)
2774 down(&ieee->wx_sem);
2775 if(NULL != ieee->pDot11dInfo)
2777 kfree(ieee->pDot11dInfo);
2778 ieee->pDot11dInfo = NULL;
2780 del_timer_sync(&ieee->associate_timer);
2782 cancel_delayed_work(&ieee->associate_retry_wq);
2783 destroy_workqueue(ieee->wq);
2788 /********************************************************
2789 * Start of WPA code. *
2790 * this is stolen from the ipw2200 driver *
2791 ********************************************************/
2794 static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
2796 /* This is called when wpa_supplicant loads and closes the driver
2798 printk("%s WPA\n",value ? "enabling" : "disabling");
2799 ieee->wpa_enabled = value;
2800 memset(ieee->ap_mac_addr, 0, 6); //reset ap_mac_addr everytime it starts wpa.
2805 void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len)
2807 /* make sure WPA is enabled */
2808 ieee80211_wpa_enable(ieee, 1);
2810 ieee80211_disassociate(ieee);
2814 static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
2820 case IEEE_MLME_STA_DEAUTH:
2824 case IEEE_MLME_STA_DISASSOC:
2825 ieee80211_disassociate(ieee);
2829 printk("Unknown MLME request: %d\n", command);
2837 static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
2838 struct ieee_param *param, int plen)
2842 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
2843 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
2846 if (param->u.wpa_ie.len) {
2847 buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
2851 memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
2852 kfree(ieee->wpa_ie);
2854 ieee->wpa_ie_len = param->u.wpa_ie.len;
2856 kfree(ieee->wpa_ie);
2857 ieee->wpa_ie = NULL;
2858 ieee->wpa_ie_len = 0;
2861 ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
2865 #define AUTH_ALG_OPEN_SYSTEM 0x1
2866 #define AUTH_ALG_SHARED_KEY 0x2
2867 #define AUTH_ALG_LEAP 0x4
2868 static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
2871 struct ieee80211_security sec = {
2872 .flags = SEC_AUTH_MODE,
2876 if (value & AUTH_ALG_SHARED_KEY) {
2877 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
2879 ieee->auth_mode = 1;
2880 } else if (value & AUTH_ALG_OPEN_SYSTEM){
2881 sec.auth_mode = WLAN_AUTH_OPEN;
2883 ieee->auth_mode = 0;
2885 else if (value & AUTH_ALG_LEAP){
2886 sec.auth_mode = RTL_WLAN_AUTH_LEAP;
2888 ieee->auth_mode = 2;
2892 if (ieee->set_security)
2893 ieee->set_security(ieee->dev, &sec);
2895 // ret = -EOPNOTSUPP;
2900 static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
2903 unsigned long flags;
2906 case IEEE_PARAM_WPA_ENABLED:
2907 ret = ieee80211_wpa_enable(ieee, value);
2910 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2911 ieee->tkip_countermeasures=value;
2914 case IEEE_PARAM_DROP_UNENCRYPTED: {
2917 * wpa_supplicant calls set_wpa_enabled when the driver
2918 * is loaded and unloaded, regardless of if WPA is being
2919 * used. No other calls are made which can be used to
2920 * determine if encryption will be used or not prior to
2921 * association being expected. If encryption is not being
2922 * used, drop_unencrypted is set to false, else true -- we
2923 * can use this to determine if the CAP_PRIVACY_ON bit should
2926 struct ieee80211_security sec = {
2927 .flags = SEC_ENABLED,
2930 ieee->drop_unencrypted = value;
2931 /* We only change SEC_LEVEL for open mode. Others
2932 * are set by ipw_wpa_set_encryption.
2935 sec.flags |= SEC_LEVEL;
2936 sec.level = SEC_LEVEL_0;
2939 sec.flags |= SEC_LEVEL;
2940 sec.level = SEC_LEVEL_1;
2942 if (ieee->set_security)
2943 ieee->set_security(ieee->dev, &sec);
2947 case IEEE_PARAM_PRIVACY_INVOKED:
2948 ieee->privacy_invoked=value;
2951 case IEEE_PARAM_AUTH_ALGS:
2952 ret = ieee80211_wpa_set_auth_algs(ieee, value);
2955 case IEEE_PARAM_IEEE_802_1X:
2956 ieee->ieee802_1x=value;
2958 case IEEE_PARAM_WPAX_SELECT:
2959 // added for WPA2 mixed mode
2960 spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
2961 ieee->wpax_type_set = 1;
2962 ieee->wpax_type_notify = value;
2963 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
2967 printk("Unknown WPA param: %d\n",name);
2974 /* implementation borrowed from hostap driver */
2976 static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
2977 struct ieee_param *param, int param_len)
2981 struct ieee80211_crypto_ops *ops;
2982 struct ieee80211_crypt_data **crypt;
2984 struct ieee80211_security sec = {
2988 param->u.crypt.err = 0;
2989 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
2992 (int) ((char *) param->u.crypt.key - (char *) param) +
2993 param->u.crypt.key_len) {
2994 printk("Len mismatch %d, %d\n", param_len,
2995 param->u.crypt.key_len);
2998 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
2999 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3000 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3001 if (param->u.crypt.idx >= WEP_KEYS)
3003 crypt = &ieee->crypt[param->u.crypt.idx];
3008 if (strcmp(param->u.crypt.alg, "none") == 0) {
3013 sec.level = SEC_LEVEL_0;
3014 sec.flags |= SEC_ENABLED | SEC_LEVEL;
3015 ieee80211_crypt_delayed_deinit(ieee, crypt);
3022 sec.flags |= SEC_ENABLED;
3024 /* IPW HW cannot build TKIP MIC, host decryption still needed. */
3025 if (!(ieee->host_encrypt || ieee->host_decrypt) &&
3026 strcmp(param->u.crypt.alg, "TKIP"))
3027 goto skip_host_crypt;
3029 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3030 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0)
3031 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3032 /* set WEP40 first, it will be modified according to WEP104 or
3033 * WEP40 at other place */
3034 else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0)
3035 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3036 else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0)
3037 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3039 printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
3040 param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
3045 if (*crypt == NULL || (*crypt)->ops != ops) {
3046 struct ieee80211_crypt_data *new_crypt;
3048 ieee80211_crypt_delayed_deinit(ieee, crypt);
3050 new_crypt = (struct ieee80211_crypt_data *)
3051 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 = (struct ieee_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);