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>
28 u8 rsn_authen_cipher_suite[16][4] = {
29 {0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved
30 {0x00,0x0F,0xAC,0x01}, //WEP-40 //RSNA default
31 {0x00,0x0F,0xAC,0x02}, //TKIP //NONE //{used just as default}
32 {0x00,0x0F,0xAC,0x03}, //WRAP-historical
33 {0x00,0x0F,0xAC,0x04}, //CCMP
34 {0x00,0x0F,0xAC,0x05}, //WEP-104
37 short ieee80211_is_54g(struct ieee80211_network net)
39 return ((net.rates_ex_len > 0) || (net.rates_len > 4));
42 short ieee80211_is_shortslot(struct ieee80211_network net)
44 return (net.capability & WLAN_CAPABILITY_SHORT_SLOT);
47 /* returns the total length needed for pleacing the RATE MFIE
48 * tag and the EXTENDED RATE MFIE tag if needed.
49 * It encludes two bytes per tag for the tag itself and its len
51 unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
53 unsigned int rate_len = 0;
55 if (ieee->modulation & IEEE80211_CCK_MODULATION)
56 rate_len = IEEE80211_CCK_RATE_LEN + 2;
58 if (ieee->modulation & IEEE80211_OFDM_MODULATION)
60 rate_len += IEEE80211_OFDM_RATE_LEN + 2;
65 /* pleace the MFIE rate, tag to the memory (double) poined.
66 * Then it updates the pointer so that
67 * it points after the new MFIE tag added.
69 void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
73 if (ieee->modulation & IEEE80211_CCK_MODULATION){
74 *tag++ = MFIE_TYPE_RATES;
76 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
77 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
78 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
79 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
82 /* We may add an option for custom rates that specific HW might support */
86 void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
90 if (ieee->modulation & IEEE80211_OFDM_MODULATION){
92 *tag++ = MFIE_TYPE_RATES_EX;
94 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
95 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
96 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
97 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
98 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
99 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
100 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
101 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
105 /* We may add an option for custom rates that specific HW might support */
110 void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) {
113 *tag++ = MFIE_TYPE_GENERIC; //0
122 if(ieee->current_network.wmm_info & 0x80) {
123 *tag++ = 0x0f|MAX_SP_Len;
134 void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
137 *tag++ = MFIE_TYPE_GENERIC; //0
148 printk(KERN_ALERT "This is enable turbo mode IE process\n");
152 void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
155 nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
158 * if the queue is full but we have newer frames then
159 * just overwrites the oldest.
161 * if (nh == ieee->mgmt_queue_tail)
164 ieee->mgmt_queue_head = nh;
165 ieee->mgmt_queue_ring[nh] = skb;
170 struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
174 if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
177 ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
179 ieee->mgmt_queue_tail =
180 (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
185 void init_mgmt_queue(struct ieee80211_device *ieee)
187 ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
190 u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee)
192 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
195 // 2008/01/25 MH For broadcom, MGNT frame set as OFDM 6M.
196 if(pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M)
199 rate = ieee->basic_rate & 0x7f;
202 // 2005.01.26, by rcnjko.
203 if(ieee->mode == IEEE_A||
204 ieee->mode== IEEE_N_5G||
205 (ieee->mode== IEEE_N_24G&&!pHTInfo->bCurSuppCCK))
212 // Data rate of ProbeReq is already decided. Annie, 2005-03-31
213 if( pMgntInfo->bScanInProgress || (pMgntInfo->bDualModeScanStep!=0) )
215 if(pMgntInfo->dot11CurrentWirelessMode==WIRELESS_MODE_A)
225 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
227 inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
230 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
231 struct ieee80211_hdr_3addr *header=
232 (struct ieee80211_hdr_3addr *) skb->data;
234 cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8);
235 spin_lock_irqsave(&ieee->lock, flags);
237 /* called with 2nd param 0, no mgmt lock required */
238 ieee80211_sta_wakeup(ieee,0);
240 tcb_desc->queue_index = MGNT_QUEUE;
241 tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
242 tcb_desc->RATRIndex = 7;
243 tcb_desc->bTxDisableRateFallBack = 1;
244 tcb_desc->bTxUseDriverAssingedRate = 1;
247 if(ieee->queue_stop){
248 enqueue_mgmt(ieee,skb);
250 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
252 if (ieee->seq_ctrl[0] == 0xFFF)
253 ieee->seq_ctrl[0] = 0;
257 /* avoid watchdog triggers */
258 ieee->dev->trans_start = jiffies;
259 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
260 //dev_kfree_skb_any(skb);//edit by thomas
263 spin_unlock_irqrestore(&ieee->lock, flags);
265 spin_unlock_irqrestore(&ieee->lock, flags);
266 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
268 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
270 if (ieee->seq_ctrl[0] == 0xFFF)
271 ieee->seq_ctrl[0] = 0;
275 /* check wether the managed packet queued greater than 5 */
276 if(!ieee->check_nic_enough_desc(ieee->dev,tcb_desc->queue_index)||\
277 (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)||\
278 (ieee->queue_stop) ) {
279 /* insert the skb packet to the management queue */
280 /* as for the completion function, it does not need
281 * to check it any more.
283 printk("%s():insert to waitqueue!\n",__FUNCTION__);
284 skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb);
286 //printk("TX packet!\n");
287 ieee->softmac_hard_start_xmit(skb,ieee->dev);
288 //dev_kfree_skb_any(skb);//edit by thomas
290 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
294 inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
297 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
298 struct ieee80211_hdr_3addr *header =
299 (struct ieee80211_hdr_3addr *) skb->data;
304 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
306 if (ieee->seq_ctrl[0] == 0xFFF)
307 ieee->seq_ctrl[0] = 0;
311 /* avoid watchdog triggers */
312 ieee->dev->trans_start = jiffies;
313 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
317 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
319 if (ieee->seq_ctrl[0] == 0xFFF)
320 ieee->seq_ctrl[0] = 0;
324 ieee->softmac_hard_start_xmit(skb,ieee->dev);
327 //dev_kfree_skb_any(skb);//edit by thomas
330 inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
332 unsigned int len,rate_len;
335 struct ieee80211_probe_request *req;
337 len = ieee->current_network.ssid_len;
339 rate_len = ieee80211_MFIE_rate_len(ieee);
341 skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
342 2 + len + rate_len + ieee->tx_headroom);
346 skb_reserve(skb, ieee->tx_headroom);
348 req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
349 req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
350 req->header.duration_id = 0; //FIXME: is this OK ?
352 memset(req->header.addr1, 0xff, ETH_ALEN);
353 memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
354 memset(req->header.addr3, 0xff, ETH_ALEN);
356 tag = (u8 *) skb_put(skb,len+2+rate_len);
358 *tag++ = MFIE_TYPE_SSID;
360 memcpy(tag, ieee->current_network.ssid, len);
363 ieee80211_MFIE_Brate(ieee,&tag);
364 ieee80211_MFIE_Grate(ieee,&tag);
368 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
369 void ieee80211_send_beacon(struct ieee80211_device *ieee)
374 //unsigned long flags;
375 skb = ieee80211_get_beacon_(ieee);
378 softmac_mgmt_xmit(skb, ieee);
379 ieee->softmac_stats.tx_beacons++;
380 //dev_kfree_skb_any(skb);//edit by thomas
382 // ieee->beacon_timer.expires = jiffies +
383 // (MSECS( ieee->current_network.beacon_interval -5));
385 //spin_lock_irqsave(&ieee->beacon_lock,flags);
386 if(ieee->beacon_txing && ieee->ieee_up){
387 // if(!timer_pending(&ieee->beacon_timer))
388 // add_timer(&ieee->beacon_timer);
389 mod_timer(&ieee->beacon_timer,jiffies+(MSECS(ieee->current_network.beacon_interval-5)));
391 //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
395 void ieee80211_send_beacon_cb(unsigned long _ieee)
397 struct ieee80211_device *ieee =
398 (struct ieee80211_device *) _ieee;
401 spin_lock_irqsave(&ieee->beacon_lock, flags);
402 ieee80211_send_beacon(ieee);
403 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
407 void ieee80211_send_probe(struct ieee80211_device *ieee)
411 skb = ieee80211_probe_req(ieee);
413 softmac_mgmt_xmit(skb, ieee);
414 ieee->softmac_stats.tx_probe_rq++;
415 //dev_kfree_skb_any(skb);//edit by thomas
419 void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
421 if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){
422 ieee80211_send_probe(ieee);
423 ieee80211_send_probe(ieee);
427 /* this performs syncro scan blocking the caller until all channels
428 * in the allowed channel map has been checked.
430 void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
434 u8 channel_map[MAX_CHANNEL_NUMBER+1];
435 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
437 down(&ieee->scan_sem);
444 if (ch > MAX_CHANNEL_NUMBER)
445 goto out; /* scan completed */
447 }while(!channel_map[ch]);
449 }while(!ieee->channel_map[ch]);
452 /* this fuction can be called in two situations
453 * 1- We have switched to ad-hoc mode and we are
454 * performing a complete syncro scan before conclude
455 * there are no interesting cell and to create a
456 * new one. In this case the link state is
457 * IEEE80211_NOLINK until we found an interesting cell.
458 * If so the ieee8021_new_net, called by the RX path
459 * will set the state to IEEE80211_LINKED, so we stop
461 * 2- We are linked and the root uses run iwlist scan.
462 * So we switch to IEEE80211_LINKED_SCANNING to remember
463 * that we are still logically linked (not interested in
464 * new network events, despite for updating the net list,
465 * but we are temporarly 'unlinked' as the driver shall
466 * not filter RX frames and the channel is changing.
467 * So the only situation in witch are interested is to check
468 * if the state become LINKED because of the #1 situation
471 if (ieee->state == IEEE80211_LINKED)
473 ieee->set_chan(ieee->dev, ch);
475 if(channel_map[ch] == 1)
477 ieee80211_send_probe_requests(ieee);
479 /* this prevent excessive time wait when we
480 * need to wait for a syncro scan to end..
482 if(ieee->state < IEEE80211_LINKED)
485 if (ieee->sync_scan_hurryup)
489 msleep_interruptible_rsl(IEEE80211_SOFTMAC_SCAN_TIME);
493 if(ieee->state < IEEE80211_LINKED){
494 ieee->actscanning = false;
498 ieee->sync_scan_hurryup = 0;
500 if(IS_DOT11D_ENABLE(ieee))
501 DOT11D_ScanComplete(ieee);
508 void ieee80211_softmac_scan_wq(struct work_struct *work)
510 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
511 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
512 static short watchdog = 0;
514 u8 channel_map[MAX_CHANNEL_NUMBER+1];
515 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
519 down(&ieee->scan_sem);
521 ieee->current_network.channel =
522 (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
523 if (watchdog++ > MAX_CHANNEL_NUMBER)
525 //if current channel is not in channel map, set to default channel.
527 if (!channel_map[ieee->current_network.channel]);
529 if (!ieee->channel_map[ieee->current_network.channel]);
531 ieee->current_network.channel = 6;
532 goto out; /* no good chans */
535 }while(!channel_map[ieee->current_network.channel]);
537 }while(!ieee->channel_map[ieee->current_network.channel]);
539 if (ieee->scanning == 0 )
541 ieee->set_chan(ieee->dev, ieee->current_network.channel);
543 if(channel_map[ieee->current_network.channel] == 1)
545 ieee80211_send_probe_requests(ieee);
548 queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
554 if(IS_DOT11D_ENABLE(ieee))
555 DOT11D_ScanComplete(ieee);
557 ieee->actscanning = false;
565 void ieee80211_beacons_start(struct ieee80211_device *ieee)
568 spin_lock_irqsave(&ieee->beacon_lock,flags);
570 ieee->beacon_txing = 1;
571 ieee80211_send_beacon(ieee);
573 spin_unlock_irqrestore(&ieee->beacon_lock,flags);
576 void ieee80211_beacons_stop(struct ieee80211_device *ieee)
580 spin_lock_irqsave(&ieee->beacon_lock,flags);
582 ieee->beacon_txing = 0;
583 del_timer_sync(&ieee->beacon_timer);
585 spin_unlock_irqrestore(&ieee->beacon_lock,flags);
590 void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
592 if(ieee->stop_send_beacons)
593 ieee->stop_send_beacons(ieee->dev);
594 if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
595 ieee80211_beacons_stop(ieee);
599 void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
601 if(ieee->start_send_beacons)
602 ieee->start_send_beacons(ieee->dev,ieee->basic_rate);
603 if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
604 ieee80211_beacons_start(ieee);
608 void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
610 // unsigned long flags;
612 //ieee->sync_scan_hurryup = 1;
614 down(&ieee->scan_sem);
615 // spin_lock_irqsave(&ieee->lock, flags);
617 if (ieee->scanning == 1){
620 cancel_delayed_work(&ieee->softmac_scan_wq);
623 // spin_unlock_irqrestore(&ieee->lock, flags);
627 void ieee80211_stop_scan(struct ieee80211_device *ieee)
629 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
630 ieee80211_softmac_stop_scan(ieee);
632 ieee->stop_scan(ieee->dev);
635 /* called with ieee->lock held */
636 void ieee80211_start_scan(struct ieee80211_device *ieee)
639 if(IS_DOT11D_ENABLE(ieee) )
641 if(IS_COUNTRY_IE_VALID(ieee))
643 RESET_CIE_WATCHDOG(ieee);
647 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
648 if (ieee->scanning == 0){
650 queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0);
653 ieee->start_scan(ieee->dev);
657 /* called with wx_sem held */
658 void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
661 if(IS_DOT11D_ENABLE(ieee) )
663 if(IS_COUNTRY_IE_VALID(ieee))
665 RESET_CIE_WATCHDOG(ieee);
669 ieee->sync_scan_hurryup = 0;
670 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
671 ieee80211_softmac_scan_syncro(ieee);
673 ieee->scan_syncro(ieee->dev);
677 inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
678 struct ieee80211_device *ieee, int challengelen)
681 struct ieee80211_authentication *auth;
682 int len = sizeof(struct ieee80211_authentication) + challengelen + ieee->tx_headroom;
685 skb = dev_alloc_skb(len);
686 if (!skb) return NULL;
688 skb_reserve(skb, ieee->tx_headroom);
689 auth = (struct ieee80211_authentication *)
690 skb_put(skb, sizeof(struct ieee80211_authentication));
692 auth->header.frame_ctl = IEEE80211_STYPE_AUTH;
693 if (challengelen) auth->header.frame_ctl |= IEEE80211_FCTL_WEP;
695 auth->header.duration_id = 0x013a; //FIXME
697 memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
698 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
699 memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
701 //auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
702 if(ieee->auth_mode == 0)
703 auth->algorithm = WLAN_AUTH_OPEN;
704 else if(ieee->auth_mode == 1)
705 auth->algorithm = WLAN_AUTH_SHARED_KEY;
706 else if(ieee->auth_mode == 2)
707 auth->algorithm = WLAN_AUTH_OPEN;//0x80;
708 printk("=================>%s():auth->algorithm is %d\n",__FUNCTION__,auth->algorithm);
709 auth->transaction = cpu_to_le16(ieee->associate_seq);
710 ieee->associate_seq++;
712 auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
719 static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
723 struct ieee80211_probe_response *beacon_buf;
724 struct sk_buff *skb = NULL;
726 int atim_len,erp_len;
727 struct ieee80211_crypt_data* crypt;
729 char *ssid = ieee->current_network.ssid;
730 int ssid_len = ieee->current_network.ssid_len;
731 int rate_len = ieee->current_network.rates_len+2;
732 int rate_ex_len = ieee->current_network.rates_ex_len;
733 int wpa_ie_len = ieee->wpa_ie_len;
734 u8 erpinfo_content = 0;
739 u8 tmp_ht_info_len=0;
740 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
741 u8* tmp_generic_ie_buf=NULL;
742 u8 tmp_generic_ie_len=0;
744 if(rate_ex_len > 0) rate_ex_len+=2;
746 if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
751 if(ieee80211_is_54g(ieee->current_network))
757 crypt = ieee->crypt[ieee->tx_keyidx];
760 encrypt = ieee->host_encrypt && crypt && crypt->ops &&
761 ((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len));
763 tmp_ht_cap_buf =(u8*) &(ieee->pHTInfo->SelfHTCap);
764 tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
765 tmp_ht_info_buf =(u8*) &(ieee->pHTInfo->SelfHTInfo);
766 tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo);
767 HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len,encrypt);
768 HTConstructInfoElement(ieee,tmp_ht_info_buf,&tmp_ht_info_len, encrypt);
771 if(pHTInfo->bRegRT2RTAggregation)
773 tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
774 tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer);
775 HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len);
777 // 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);
778 beacon_size = sizeof(struct ieee80211_probe_response)+2+
788 // +tmp_generic_ie_len
791 skb = dev_alloc_skb(beacon_size);
794 skb_reserve(skb, ieee->tx_headroom);
795 beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, (beacon_size - ieee->tx_headroom));
796 memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
797 memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
798 memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
800 beacon_buf->header.duration_id = 0; //FIXME
801 beacon_buf->beacon_interval =
802 cpu_to_le16(ieee->current_network.beacon_interval);
803 beacon_buf->capability =
804 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
805 beacon_buf->capability |=
806 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE); //add short preamble here
808 if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
809 cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
811 crypt = ieee->crypt[ieee->tx_keyidx];
813 beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
816 beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
817 beacon_buf->info_element[0].id = MFIE_TYPE_SSID;
818 beacon_buf->info_element[0].len = ssid_len;
820 tag = (u8*) beacon_buf->info_element[0].data;
822 memcpy(tag, ssid, ssid_len);
826 *(tag++) = MFIE_TYPE_RATES;
827 *(tag++) = rate_len-2;
828 memcpy(tag,ieee->current_network.rates,rate_len-2);
831 *(tag++) = MFIE_TYPE_DS_SET;
833 *(tag++) = ieee->current_network.channel;
837 *(tag++) = MFIE_TYPE_IBSS_SET;
839 //*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window);
840 val16 = cpu_to_le16(ieee->current_network.atim_window);
841 memcpy((u8 *)tag, (u8 *)&val16, 2);
846 *(tag++) = MFIE_TYPE_ERP;
848 *(tag++) = erpinfo_content;
851 *(tag++) = MFIE_TYPE_RATES_EX;
852 *(tag++) = rate_ex_len-2;
853 memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
859 if (ieee->iw_mode == IW_MODE_ADHOC)
860 {//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
861 memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
863 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
867 //skb->dev = ieee->dev;
872 struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
877 struct ieee80211_crypt_data* crypt;
878 struct ieee80211_assoc_response_frame *assoc;
881 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
882 int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len + ieee->tx_headroom;
884 skb = dev_alloc_skb(len);
889 skb_reserve(skb, ieee->tx_headroom);
891 assoc = (struct ieee80211_assoc_response_frame *)
892 skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
894 assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
895 memcpy(assoc->header.addr1, dest,ETH_ALEN);
896 memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
897 memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
898 assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
899 WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
903 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
905 if (ieee->host_encrypt)
906 crypt = ieee->crypt[ieee->tx_keyidx];
909 encrypt = ( crypt && crypt->ops);
912 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
915 assoc->aid = cpu_to_le16(ieee->assoc_id);
916 if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
917 else ieee->assoc_id++;
919 tag = (u8*) skb_put(skb, rate_len);
921 ieee80211_MFIE_Brate(ieee, &tag);
922 ieee80211_MFIE_Grate(ieee, &tag);
927 struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest)
930 struct ieee80211_authentication *auth;
931 int len = ieee->tx_headroom + sizeof(struct ieee80211_authentication)+1;
933 skb = dev_alloc_skb(len);
938 skb->len = sizeof(struct ieee80211_authentication);
940 auth = (struct ieee80211_authentication *)skb->data;
942 auth->status = cpu_to_le16(status);
943 auth->transaction = cpu_to_le16(2);
944 auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
946 memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
947 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
948 memcpy(auth->header.addr1, dest, ETH_ALEN);
949 auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
955 struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
958 struct ieee80211_hdr_3addr* hdr;
960 skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
965 hdr = (struct ieee80211_hdr_3addr*)skb_put(skb,sizeof(struct ieee80211_hdr_3addr));
967 memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
968 memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
969 memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
971 hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
972 IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
973 (pwr ? IEEE80211_FCTL_PM:0));
981 void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest)
983 struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
986 softmac_mgmt_xmit(buf, ieee);
990 void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest)
992 struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
995 softmac_mgmt_xmit(buf, ieee);
999 void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
1003 struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
1005 softmac_mgmt_xmit(buf, ieee);
1009 inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
1011 struct sk_buff *skb;
1012 //unsigned long flags;
1014 struct ieee80211_assoc_request_frame *hdr;
1016 //short info_addr = 0;
1018 //u16 suite_count = 0;
1019 //u8 suit_select = 0;
1020 //unsigned int wpa_len = beacon->wpa_ie_len;
1022 u8* ht_cap_buf = NULL;
1024 u8* realtek_ie_buf=NULL;
1025 u8 realtek_ie_len=0;
1026 int wpa_ie_len= ieee->wpa_ie_len;
1027 unsigned int ckip_ie_len=0;
1028 unsigned int ccxrm_ie_len=0;
1029 unsigned int cxvernum_ie_len=0;
1030 struct ieee80211_crypt_data* crypt;
1033 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
1034 unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
1036 unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
1041 crypt = ieee->crypt[ieee->tx_keyidx];
1042 encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len));
1044 //Include High Throuput capability && Realtek proprietary
1045 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1047 ht_cap_buf = (u8*)&(ieee->pHTInfo->SelfHTCap);
1048 ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
1049 HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt);
1050 if(ieee->pHTInfo->bCurrentRT2RTAggregation)
1052 realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
1053 realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer);
1054 HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len);
1058 if(ieee->qos_support){
1059 wmm_info_len = beacon->qos_data.supported?9:0;
1063 if(beacon->bCkipSupported)
1067 if(beacon->bCcxRmEnable)
1071 if( beacon->BssCcxVerNumber >= 2 )
1073 cxvernum_ie_len = 5+2;
1076 len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1077 + beacon->ssid_len//essid tagged val
1078 + rate_len//rates tagged val
1087 + ieee->tx_headroom;
1089 len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1090 + beacon->ssid_len//essid tagged val
1091 + rate_len//rates tagged val
1099 + ieee->tx_headroom;
1102 skb = dev_alloc_skb(len);
1107 skb_reserve(skb, ieee->tx_headroom);
1109 hdr = (struct ieee80211_assoc_request_frame *)
1110 skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)+2);
1113 hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
1114 hdr->header.duration_id= 37; //FIXME
1115 memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
1116 memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1117 memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
1119 memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John
1121 hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
1122 if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
1123 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1125 if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1126 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); //add short_preamble here
1128 if(ieee->short_slot)
1129 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
1130 if (wmm_info_len) //QOS
1131 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS);
1133 hdr->listen_interval = 0xa; //FIXME
1135 hdr->info_element[0].id = MFIE_TYPE_SSID;
1137 hdr->info_element[0].len = beacon->ssid_len;
1138 tag = skb_put(skb, beacon->ssid_len);
1139 memcpy(tag, beacon->ssid, beacon->ssid_len);
1141 tag = skb_put(skb, rate_len);
1143 ieee80211_MFIE_Brate(ieee, &tag);
1144 ieee80211_MFIE_Grate(ieee, &tag);
1145 // For CCX 1 S13, CKIP. Added by Annie, 2006-08-14.
1146 if( beacon->bCkipSupported )
1148 static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client"
1149 u8 CcxAironetBuf[30];
1150 OCTET_STRING osCcxAironetIE;
1152 memset(CcxAironetBuf, 0,30);
1153 osCcxAironetIE.Octet = CcxAironetBuf;
1154 osCcxAironetIE.Length = sizeof(CcxAironetBuf);
1156 // Ref. CCX test plan v3.61, 3.2.3.1 step 13.
1157 // We want to make the device type as "4500-client". 060926, by CCW.
1159 memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui));
1161 // CCX1 spec V1.13, A01.1 CKIP Negotiation (page23):
1162 // "The CKIP negotiation is started with the associate request from the client to the access point,
1163 // containing an Aironet element with both the MIC and KP bits set."
1164 osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |= (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ;
1165 tag = skb_put(skb, ckip_ie_len);
1166 *tag++ = MFIE_TYPE_AIRONET;
1167 *tag++ = osCcxAironetIE.Length;
1168 memcpy(tag,osCcxAironetIE.Octet,osCcxAironetIE.Length);
1169 tag += osCcxAironetIE.Length;
1172 if(beacon->bCcxRmEnable)
1174 static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
1175 OCTET_STRING osCcxRmCap;
1177 osCcxRmCap.Octet = CcxRmCapBuf;
1178 osCcxRmCap.Length = sizeof(CcxRmCapBuf);
1179 tag = skb_put(skb,ccxrm_ie_len);
1180 *tag++ = MFIE_TYPE_GENERIC;
1181 *tag++ = osCcxRmCap.Length;
1182 memcpy(tag,osCcxRmCap.Octet,osCcxRmCap.Length);
1183 tag += osCcxRmCap.Length;
1186 if( beacon->BssCcxVerNumber >= 2 )
1188 u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
1189 OCTET_STRING osCcxVerNum;
1190 CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
1191 osCcxVerNum.Octet = CcxVerNumBuf;
1192 osCcxVerNum.Length = sizeof(CcxVerNumBuf);
1193 tag = skb_put(skb,cxvernum_ie_len);
1194 *tag++ = MFIE_TYPE_GENERIC;
1195 *tag++ = osCcxVerNum.Length;
1196 memcpy(tag,osCcxVerNum.Octet,osCcxVerNum.Length);
1197 tag += osCcxVerNum.Length;
1200 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
1201 if(ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC)
1203 tag = skb_put(skb, ht_cap_len);
1204 *tag++ = MFIE_TYPE_HT_CAP;
1205 *tag++ = ht_cap_len - 2;
1206 memcpy(tag, ht_cap_buf,ht_cap_len -2);
1207 tag += ht_cap_len -2;
1212 //choose what wpa_supplicant gives to associate.
1213 tag = skb_put(skb, wpa_ie_len);
1215 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
1218 tag = skb_put(skb,wmm_info_len);
1220 ieee80211_WMM_Info(ieee, &tag);
1223 tag = skb_put(skb,turbo_info_len);
1224 if(turbo_info_len) {
1225 ieee80211_TURBO_Info(ieee, &tag);
1229 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
1230 if(ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC)
1232 tag = skb_put(skb, ht_cap_len);
1233 *tag++ = MFIE_TYPE_GENERIC;
1234 *tag++ = ht_cap_len - 2;
1235 memcpy(tag, ht_cap_buf,ht_cap_len - 2);
1236 tag += ht_cap_len -2;
1239 if(ieee->pHTInfo->bCurrentRT2RTAggregation){
1240 tag = skb_put(skb, realtek_ie_len);
1241 *tag++ = MFIE_TYPE_GENERIC;
1242 *tag++ = realtek_ie_len - 2;
1243 memcpy(tag, realtek_ie_buf,realtek_ie_len -2 );
1246 // printk("<=====%s(), %p, %p\n", __FUNCTION__, ieee->dev, ieee->dev->dev_addr);
1247 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
1251 void ieee80211_associate_abort(struct ieee80211_device *ieee)
1254 unsigned long flags;
1255 spin_lock_irqsave(&ieee->lock, flags);
1257 ieee->associate_seq++;
1259 /* don't scan, and avoid to have the RX path possibily
1260 * try again to associate. Even do not react to AUTH or
1261 * ASSOC response. Just wait for the retry wq to be scheduled.
1262 * Here we will check if there are good nets to associate
1263 * with, so we retry or just get back to NO_LINK and scanning
1265 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
1266 IEEE80211_DEBUG_MGMT("Authentication failed\n");
1267 ieee->softmac_stats.no_auth_rs++;
1269 IEEE80211_DEBUG_MGMT("Association failed\n");
1270 ieee->softmac_stats.no_ass_rs++;
1273 ieee->state = IEEE80211_ASSOCIATING_RETRY;
1275 queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \
1276 IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
1278 spin_unlock_irqrestore(&ieee->lock, flags);
1281 void ieee80211_associate_abort_cb(unsigned long dev)
1283 ieee80211_associate_abort((struct ieee80211_device *) dev);
1287 void ieee80211_associate_step1(struct ieee80211_device *ieee)
1289 struct ieee80211_network *beacon = &ieee->current_network;
1290 struct sk_buff *skb;
1292 IEEE80211_DEBUG_MGMT("Stopping scan\n");
1294 ieee->softmac_stats.tx_auth_rq++;
1295 skb=ieee80211_authentication_req(beacon, ieee, 0);
1298 ieee80211_associate_abort(ieee);
1300 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
1301 IEEE80211_DEBUG_MGMT("Sending authentication request\n");
1302 //printk(KERN_WARNING "Sending authentication request\n");
1303 softmac_mgmt_xmit(skb, ieee);
1304 //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
1305 if(!timer_pending(&ieee->associate_timer)){
1306 ieee->associate_timer.expires = jiffies + (HZ / 2);
1307 add_timer(&ieee->associate_timer);
1309 //dev_kfree_skb_any(skb);//edit by thomas
1313 void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
1316 struct sk_buff *skb;
1317 struct ieee80211_network *beacon = &ieee->current_network;
1318 // int hlen = sizeof(struct ieee80211_authentication);
1320 ieee->associate_seq++;
1321 ieee->softmac_stats.tx_auth_rq++;
1323 skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
1325 ieee80211_associate_abort(ieee);
1327 c = skb_put(skb, chlen+2);
1328 *(c++) = MFIE_TYPE_CHALLENGE;
1330 memcpy(c, challenge, chlen);
1332 IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
1334 ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr ));
1336 softmac_mgmt_xmit(skb, ieee);
1337 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1338 //dev_kfree_skb_any(skb);//edit by thomas
1343 void ieee80211_associate_step2(struct ieee80211_device *ieee)
1345 struct sk_buff* skb;
1346 struct ieee80211_network *beacon = &ieee->current_network;
1348 del_timer_sync(&ieee->associate_timer);
1350 IEEE80211_DEBUG_MGMT("Sending association request\n");
1352 ieee->softmac_stats.tx_ass_rq++;
1353 skb=ieee80211_association_req(beacon, ieee);
1355 ieee80211_associate_abort(ieee);
1357 softmac_mgmt_xmit(skb, ieee);
1358 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1359 //dev_kfree_skb_any(skb);//edit by thomas
1362 void ieee80211_associate_complete_wq(struct work_struct *work)
1364 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
1365 printk(KERN_INFO "Associated successfully\n");
1366 if(ieee80211_is_54g(ieee->current_network) &&
1367 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1370 printk(KERN_INFO"Using G rates:%d\n", ieee->rate);
1373 printk(KERN_INFO"Using B rates:%d\n", ieee->rate);
1375 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1377 printk("Successfully associated, ht enabled\n");
1382 printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
1383 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1384 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1386 ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500);
1387 // To prevent the immediately calling watch_dog after association.
1388 if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
1390 ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
1391 ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
1393 ieee->link_change(ieee->dev);
1394 if(ieee->is_silent_reset == 0){
1395 printk("============>normal associate\n");
1396 notify_wx_assoc_event(ieee);
1398 else if(ieee->is_silent_reset == 1)
1400 printk("==================>silent reset associate\n");
1401 ieee->is_silent_reset = 0;
1404 if (ieee->data_hard_resume)
1405 ieee->data_hard_resume(ieee->dev);
1406 netif_carrier_on(ieee->dev);
1409 void ieee80211_associate_complete(struct ieee80211_device *ieee)
1412 // struct net_device* dev = ieee->dev;
1413 del_timer_sync(&ieee->associate_timer);
1415 ieee->state = IEEE80211_LINKED;
1416 //ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet);
1417 queue_work(ieee->wq, &ieee->associate_complete_wq);
1420 void ieee80211_associate_procedure_wq(struct work_struct *work)
1422 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
1423 ieee->sync_scan_hurryup = 1;
1424 down(&ieee->wx_sem);
1426 if (ieee->data_hard_stop)
1427 ieee->data_hard_stop(ieee->dev);
1429 ieee80211_stop_scan(ieee);
1430 printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);
1431 //ieee->set_chan(ieee->dev, ieee->current_network.channel);
1432 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1434 ieee->associate_seq = 1;
1435 ieee80211_associate_step1(ieee);
1440 inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
1442 u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
1443 int tmp_ssid_len = 0;
1445 short apset,ssidset,ssidbroad,apmatch,ssidmatch;
1447 /* we are interested in new new only if we are not associated
1448 * and we are not associating / authenticating
1450 if (ieee->state != IEEE80211_NOLINK)
1453 if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
1456 if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
1460 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){
1461 /* if the user specified the AP MAC, we need also the essid
1462 * This could be obtained by beacons or, if the network does not
1463 * broadcast it, it can be put manually.
1465 apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
1466 ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
1467 ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0');
1468 apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
1469 ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\
1470 (!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
1473 if ( /* if the user set the AP check if match.
1474 * if the network does not broadcast essid we check the user supplyed ANY essid
1475 * if the network does broadcast and the user does not set essid it is OK
1476 * if the network does broadcast and the user did set essid chech if essid match
1478 ( apset && apmatch &&
1479 ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
1480 /* if the ap is not set, check that the user set the bssid
1481 * and the network does bradcast and that those two bssid matches
1483 (!apset && ssidset && ssidbroad && ssidmatch)
1485 /* if the essid is hidden replace it with the
1486 * essid provided by the user.
1489 strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
1490 tmp_ssid_len = ieee->current_network.ssid_len;
1492 memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
1495 strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
1496 ieee->current_network.ssid_len = tmp_ssid_len;
1498 printk(KERN_INFO"Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d\n",ieee->current_network.ssid,ieee->current_network.channel, ieee->current_network.qos_data.supported, ieee->pHTInfo->bEnableHT, ieee->current_network.bssht.bdSupportHT);
1500 //ieee->pHTInfo->IOTAction = 0;
1501 HTResetIOTSetting(ieee->pHTInfo);
1502 if (ieee->iw_mode == IW_MODE_INFRA){
1503 /* Join the network for the first time */
1504 ieee->AsocRetryCount = 0;
1505 //for HT by amy 080514
1506 if((ieee->current_network.qos_data.supported == 1) &&
1507 // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT))
1508 ieee->current_network.bssht.bdSupportHT)
1509 /*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.*/
1511 // ieee->pHTInfo->bCurrentHTSupport = true;
1512 HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network));
1516 ieee->pHTInfo->bCurrentHTSupport = false;
1519 ieee->state = IEEE80211_ASSOCIATING;
1520 queue_work(ieee->wq, &ieee->associate_procedure_wq);
1522 if(ieee80211_is_54g(ieee->current_network) &&
1523 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1525 ieee->SetWirelessMode(ieee->dev, IEEE_G);
1526 printk(KERN_INFO"Using G rates\n");
1529 ieee->SetWirelessMode(ieee->dev, IEEE_B);
1530 printk(KERN_INFO"Using B rates\n");
1532 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1533 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1534 ieee->state = IEEE80211_LINKED;
1542 void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
1544 unsigned long flags;
1545 struct ieee80211_network *target;
1547 spin_lock_irqsave(&ieee->lock, flags);
1549 list_for_each_entry(target, &ieee->network_list, list) {
1551 /* if the state become different that NOLINK means
1552 * we had found what we are searching for
1555 if (ieee->state != IEEE80211_NOLINK)
1558 if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
1559 ieee80211_softmac_new_net(ieee, target);
1562 spin_unlock_irqrestore(&ieee->lock, flags);
1567 static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen)
1569 struct ieee80211_authentication *a;
1571 if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
1572 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
1576 a = (struct ieee80211_authentication*) skb->data;
1577 if(skb->len > (sizeof(struct ieee80211_authentication) +3)){
1578 t = skb->data + sizeof(struct ieee80211_authentication);
1580 if(*(t++) == MFIE_TYPE_CHALLENGE){
1582 *challenge = kmalloc(*chlen, GFP_ATOMIC);
1585 memcpy(*challenge, t, *chlen);
1589 return cpu_to_le16(a->status);
1594 int auth_rq_parse(struct sk_buff *skb,u8* dest)
1596 struct ieee80211_authentication *a;
1598 if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
1599 IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
1602 a = (struct ieee80211_authentication*) skb->data;
1604 memcpy(dest,a->header.addr2, ETH_ALEN);
1606 if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
1607 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1609 return WLAN_STATUS_SUCCESS;
1612 static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
1619 struct ieee80211_hdr_3addr *header =
1620 (struct ieee80211_hdr_3addr *) skb->data;
1622 if (skb->len < sizeof (struct ieee80211_hdr_3addr ))
1623 return -1; /* corrupted */
1625 memcpy(src,header->addr2, ETH_ALEN);
1627 skbend = (u8*)skb->data + skb->len;
1629 tag = skb->data + sizeof (struct ieee80211_hdr_3addr );
1631 while (tag+1 < skbend){
1637 tag++; /* point to the len field */
1638 tag = tag + *(tag); /* point to the last data byte of the tag */
1639 tag++; /* point to the next tag */
1642 //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
1643 if (ssidlen == 0) return 1;
1645 if (!ssid) return 1; /* ssid not found in tagged param */
1646 return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
1650 int assoc_rq_parse(struct sk_buff *skb,u8* dest)
1652 struct ieee80211_assoc_request_frame *a;
1654 if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
1655 sizeof(struct ieee80211_info_element))) {
1657 IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
1661 a = (struct ieee80211_assoc_request_frame*) skb->data;
1663 memcpy(dest,a->header.addr2,ETH_ALEN);
1668 static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid)
1670 struct ieee80211_assoc_response_frame *response_head;
1673 if (skb->len < sizeof(struct ieee80211_assoc_response_frame)){
1674 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
1678 response_head = (struct ieee80211_assoc_response_frame*) skb->data;
1679 *aid = le16_to_cpu(response_head->aid) & 0x3fff;
1681 status_code = le16_to_cpu(response_head->status);
1682 if((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \
1683 status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&&
1684 ((ieee->mode == IEEE_G) &&
1685 (ieee->current_network.mode == IEEE_N_24G) &&
1686 (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) {
1687 ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
1689 ieee->AsocRetryCount = 0;
1692 return le16_to_cpu(response_head->status);
1696 ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1700 //IEEE80211DMESG("Rx probe");
1701 ieee->softmac_stats.rx_probe_rq++;
1702 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1703 if (probe_rq_parse(ieee, skb, dest)){
1704 //IEEE80211DMESG("Was for me!");
1705 ieee->softmac_stats.tx_probe_rs++;
1706 ieee80211_resp_to_probe(ieee, dest);
1711 ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1715 //IEEE80211DMESG("Rx probe");
1716 ieee->softmac_stats.rx_auth_rq++;
1718 status = auth_rq_parse(skb, dest);
1720 ieee80211_resp_to_auth(ieee, status, dest);
1722 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1727 ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1731 //unsigned long flags;
1733 ieee->softmac_stats.rx_ass_rq++;
1734 if (assoc_rq_parse(skb,dest) != -1){
1735 ieee80211_resp_to_assoc_rq(ieee, dest);
1738 printk(KERN_INFO"New client associated: %pM\n", dest);
1744 void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
1747 struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
1750 softmac_ps_mgmt_xmit(buf, ieee);
1755 short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
1757 int timeout = ieee->ps_timeout;
1759 /*if(ieee->ps == IEEE80211_PS_DISABLED ||
1760 ieee->iw_mode != IW_MODE_INFRA ||
1761 ieee->state != IEEE80211_LINKED)
1765 dtim = ieee->current_network.dtim_data;
1767 if(!(dtim & IEEE80211_DTIM_VALID))
1769 timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
1770 //printk("VALID\n");
1771 ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
1773 if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
1776 if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
1779 if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
1782 if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
1783 (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
1787 *time_l = ieee->current_network.last_dtim_sta_time[0]
1788 + (ieee->current_network.beacon_interval
1789 * ieee->current_network.dtim_period) * 1000;
1793 *time_h = ieee->current_network.last_dtim_sta_time[1];
1794 if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
1803 inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
1809 unsigned long flags,flags2;
1811 spin_lock_irqsave(&ieee->lock, flags);
1813 if((ieee->ps == IEEE80211_PS_DISABLED ||
1814 ieee->iw_mode != IW_MODE_INFRA ||
1815 ieee->state != IEEE80211_LINKED)){
1817 // #warning CHECK_LOCK_HERE
1818 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1820 ieee80211_sta_wakeup(ieee, 1);
1822 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1825 sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
1826 /* 2 wake, 1 sleep, 0 do nothing */
1832 if(ieee->sta_sleep == 1)
1833 ieee->enter_sleep_state(ieee->dev,th,tl);
1835 else if(ieee->sta_sleep == 0){
1836 // printk("send null 1\n");
1837 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1839 if(ieee->ps_is_queue_empty(ieee->dev)){
1842 ieee->sta_sleep = 2;
1844 ieee->ps_request_tx_ack(ieee->dev);
1846 ieee80211_sta_ps_send_null_frame(ieee,1);
1851 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1856 }else if(sleep == 2){
1857 //#warning CHECK_LOCK_HERE
1858 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1860 ieee80211_sta_wakeup(ieee,1);
1862 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1866 spin_unlock_irqrestore(&ieee->lock, flags);
1870 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
1872 if(ieee->sta_sleep == 0){
1874 printk("Warning: driver is probably failing to report TX ps error\n");
1875 ieee->ps_request_tx_ack(ieee->dev);
1876 ieee80211_sta_ps_send_null_frame(ieee, 0);
1882 if(ieee->sta_sleep == 1)
1883 ieee->sta_wake_up(ieee->dev);
1885 ieee->sta_sleep = 0;
1888 ieee->ps_request_tx_ack(ieee->dev);
1889 ieee80211_sta_ps_send_null_frame(ieee, 0);
1893 void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
1895 unsigned long flags,flags2;
1897 spin_lock_irqsave(&ieee->lock, flags);
1899 if(ieee->sta_sleep == 2){
1900 /* Null frame with PS bit set */
1902 ieee->sta_sleep = 1;
1903 ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
1905 /* if the card report not success we can't be sure the AP
1906 * has not RXed so we can't assume the AP believe us awake
1909 /* 21112005 - tx again null without PS bit if lost */
1912 if((ieee->sta_sleep == 0) && !success){
1913 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1914 ieee80211_sta_ps_send_null_frame(ieee, 0);
1915 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1918 spin_unlock_irqrestore(&ieee->lock, flags);
1920 void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb)
1922 struct ieee80211_hdr* header = (struct ieee80211_hdr*)skb->data;
1923 u8* act = ieee80211_get_payload(header);
1925 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
1928 IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
1936 if (*act == ACT_ADDBAREQ)
1937 ieee80211_rx_ADDBAReq(ieee, skb);
1938 else if (*act == ACT_ADDBARSP)
1939 ieee80211_rx_ADDBARsp(ieee, skb);
1940 else if (*act == ACT_DELBA)
1941 ieee80211_rx_DELBA(ieee, skb);
1944 // if (net_ratelimit())
1945 // IEEE80211_DEBUG(IEEE80211_DL_BA, "unknown action frame(%d)\n", tmp);
1952 ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
1953 struct ieee80211_rx_stats *rx_stats, u16 type,
1956 struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
1961 struct ieee80211_assoc_response_frame *assoc_resp;
1962 // struct ieee80211_info_element *info_element;
1963 bool bSupportNmode = true, bHalfSupportNmode = false; //default support N mode, disable halfNmode
1965 if(!ieee->proto_started)
1968 if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
1969 ieee->iw_mode == IW_MODE_INFRA &&
1970 ieee->state == IEEE80211_LINKED))
1972 tasklet_schedule(&ieee->ps_task);
1974 if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
1975 WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
1976 ieee->last_rx_ps_time = jiffies;
1978 switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
1980 case IEEE80211_STYPE_ASSOC_RESP:
1981 case IEEE80211_STYPE_REASSOC_RESP:
1983 IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
1984 WLAN_FC_GET_STYPE(header->frame_ctl));
1985 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
1986 ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
1987 ieee->iw_mode == IW_MODE_INFRA){
1988 struct ieee80211_network network_resp;
1989 struct ieee80211_network *network = &network_resp;
1991 if (0 == (errcode=assoc_parse(ieee,skb, &aid))){
1992 ieee->state=IEEE80211_LINKED;
1993 ieee->assoc_id = aid;
1994 ieee->softmac_stats.rx_ass_ok++;
1995 /* station support qos */
1996 /* Let the register setting defaultly with Legacy station */
1997 if(ieee->qos_support) {
1998 assoc_resp = (struct ieee80211_assoc_response_frame*)skb->data;
1999 memset(network, 0, sizeof(*network));
2000 if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\
2001 rx_stats->len - sizeof(*assoc_resp),\
2006 { //filling the PeerHTCap. //maybe not neccesary as we can get its info from current_network.
2007 memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
2008 memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
2010 if (ieee->handle_assoc_response != NULL)
2011 ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame*)header, network);
2013 ieee80211_associate_complete(ieee);
2015 /* aid could not been allocated */
2016 ieee->softmac_stats.rx_ass_err++;
2018 "Association response status code 0x%x\n",
2020 IEEE80211_DEBUG_MGMT(
2021 "Association response status code 0x%x\n",
2023 if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
2024 queue_work(ieee->wq, &ieee->associate_procedure_wq);
2026 ieee80211_associate_abort(ieee);
2032 case IEEE80211_STYPE_ASSOC_REQ:
2033 case IEEE80211_STYPE_REASSOC_REQ:
2035 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2036 ieee->iw_mode == IW_MODE_MASTER)
2038 ieee80211_rx_assoc_rq(ieee, skb);
2041 case IEEE80211_STYPE_AUTH:
2043 if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){
2044 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
2045 ieee->iw_mode == IW_MODE_INFRA){
2047 IEEE80211_DEBUG_MGMT("Received authentication response");
2049 if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){
2050 if(ieee->open_wep || !challenge){
2051 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
2052 ieee->softmac_stats.rx_auth_rs_ok++;
2053 if(!(ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE))
2055 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
2057 // WEP or TKIP encryption
2058 if(IsHTHalfNmodeAPs(ieee))
2060 bSupportNmode = true;
2061 bHalfSupportNmode = true;
2065 bSupportNmode = false;
2066 bHalfSupportNmode = false;
2068 printk("==========>to link with AP using SEC(%d, %d)", bSupportNmode, bHalfSupportNmode);
2071 /* Dummy wirless mode setting to avoid encryption issue */
2074 ieee->SetWirelessMode(ieee->dev, \
2075 ieee->current_network.mode);
2079 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2082 if (ieee->current_network.mode == IEEE_N_24G && bHalfSupportNmode == true)
2084 printk("===============>entern half N mode\n");
2085 ieee->bHalfWirelessN24GMode = true;
2088 ieee->bHalfWirelessN24GMode = false;
2090 ieee80211_associate_step2(ieee);
2092 ieee80211_auth_challenge(ieee, challenge, chlen);
2095 ieee->softmac_stats.rx_auth_rs_err++;
2096 IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode);
2097 ieee80211_associate_abort(ieee);
2100 }else if (ieee->iw_mode == IW_MODE_MASTER){
2101 ieee80211_rx_auth_rq(ieee, skb);
2106 case IEEE80211_STYPE_PROBE_REQ:
2108 if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
2109 ((ieee->iw_mode == IW_MODE_ADHOC ||
2110 ieee->iw_mode == IW_MODE_MASTER) &&
2111 ieee->state == IEEE80211_LINKED)){
2112 ieee80211_rx_probe_rq(ieee, skb);
2116 case IEEE80211_STYPE_DISASSOC:
2117 case IEEE80211_STYPE_DEAUTH:
2118 /* FIXME for now repeat all the association procedure
2119 * both for disassociation and deauthentication
2121 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2122 ieee->state == IEEE80211_LINKED &&
2123 ieee->iw_mode == IW_MODE_INFRA){
2125 ieee->state = IEEE80211_ASSOCIATING;
2126 ieee->softmac_stats.reassoc++;
2128 notify_wx_assoc_event(ieee);
2129 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2130 RemovePeerTS(ieee, header->addr2);
2131 queue_work(ieee->wq, &ieee->associate_procedure_wq);
2134 case IEEE80211_STYPE_MANAGE_ACT:
2135 ieee80211_process_action(ieee,skb);
2142 //dev_kfree_skb_any(skb);
2146 /* following are for a simplier TX queue management.
2147 * Instead of using netif_[stop/wake]_queue the driver
2148 * will uses these two function (plus a reset one), that
2149 * will internally uses the kernel netif_* and takes
2150 * care of the ieee802.11 fragmentation.
2151 * So the driver receives a fragment per time and might
2152 * call the stop function when it want without take care
2153 * to have enought room to TX an entire packet.
2154 * This might be useful if each fragment need it's own
2155 * descriptor, thus just keep a total free memory > than
2156 * the max fragmentation treshold is not enought.. If the
2157 * ieee802.11 stack passed a TXB struct then you needed
2158 * to keep N free descriptors where
2159 * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
2160 * In this way you need just one and the 802.11 stack
2161 * will take care of buffering fragments and pass them to
2162 * to the driver later, when it wakes the queue.
2164 void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
2167 unsigned int queue_index = txb->queue_index;
2168 unsigned long flags;
2170 cb_desc *tcb_desc = NULL;
2172 spin_lock_irqsave(&ieee->lock,flags);
2174 /* called with 2nd parm 0, no tx mgmt lock required */
2175 ieee80211_sta_wakeup(ieee,0);
2177 /* update the tx status */
2178 ieee->stats.tx_bytes += txb->payload_size;
2179 ieee->stats.tx_packets++;
2180 tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
2181 if(tcb_desc->bMulticast) {
2182 ieee->stats.multicast++;
2184 /* if xmit available, just xmit it immediately, else just insert it to the wait queue */
2185 for(i = 0; i < txb->nr_frags; i++) {
2186 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2187 if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) ||
2189 if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
2191 (!ieee->check_nic_enough_desc(ieee->dev,queue_index))||\
2192 (ieee->queue_stop)) {
2193 /* insert the skb packet to the wait queue */
2194 /* as for the completion function, it does not need
2195 * to check it any more.
2197 //printk("error:no descriptor left@queue_index %d\n", queue_index);
2198 //ieee80211_stop_queue(ieee);
2199 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2200 skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]);
2202 skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
2205 ieee->softmac_data_hard_start_xmit(
2207 ieee->dev,ieee->rate);
2208 //ieee->stats.tx_packets++;
2209 //ieee->stats.tx_bytes += txb->fragments[i]->len;
2210 //ieee->dev->trans_start = jiffies;
2213 ieee80211_txb_free(txb);
2216 spin_unlock_irqrestore(&ieee->lock,flags);
2220 /* called with ieee->lock acquired */
2221 void ieee80211_resume_tx(struct ieee80211_device *ieee)
2224 for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
2226 if (ieee->queue_stop){
2227 ieee->tx_pending.frag = i;
2231 ieee->softmac_data_hard_start_xmit(
2232 ieee->tx_pending.txb->fragments[i],
2233 ieee->dev,ieee->rate);
2234 //(i+1)<ieee->tx_pending.txb->nr_frags);
2235 ieee->stats.tx_packets++;
2236 ieee->dev->trans_start = jiffies;
2241 ieee80211_txb_free(ieee->tx_pending.txb);
2242 ieee->tx_pending.txb = NULL;
2246 void ieee80211_reset_queue(struct ieee80211_device *ieee)
2248 unsigned long flags;
2250 spin_lock_irqsave(&ieee->lock,flags);
2251 init_mgmt_queue(ieee);
2252 if (ieee->tx_pending.txb){
2253 ieee80211_txb_free(ieee->tx_pending.txb);
2254 ieee->tx_pending.txb = NULL;
2256 ieee->queue_stop = 0;
2257 spin_unlock_irqrestore(&ieee->lock,flags);
2261 void ieee80211_wake_queue(struct ieee80211_device *ieee)
2264 unsigned long flags;
2265 struct sk_buff *skb;
2266 struct ieee80211_hdr_3addr *header;
2268 spin_lock_irqsave(&ieee->lock,flags);
2269 if (! ieee->queue_stop) goto exit;
2271 ieee->queue_stop = 0;
2273 if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){
2274 while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
2276 header = (struct ieee80211_hdr_3addr *) skb->data;
2278 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2280 if (ieee->seq_ctrl[0] == 0xFFF)
2281 ieee->seq_ctrl[0] = 0;
2283 ieee->seq_ctrl[0]++;
2285 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
2286 //dev_kfree_skb_any(skb);//edit by thomas
2289 if (!ieee->queue_stop && ieee->tx_pending.txb)
2290 ieee80211_resume_tx(ieee);
2292 if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){
2293 ieee->softmac_stats.swtxawake++;
2294 netif_wake_queue(ieee->dev);
2298 spin_unlock_irqrestore(&ieee->lock,flags);
2302 void ieee80211_stop_queue(struct ieee80211_device *ieee)
2304 //unsigned long flags;
2305 //spin_lock_irqsave(&ieee->lock,flags);
2307 if (! netif_queue_stopped(ieee->dev)){
2308 netif_stop_queue(ieee->dev);
2309 ieee->softmac_stats.swtxstop++;
2311 ieee->queue_stop = 1;
2312 //spin_unlock_irqrestore(&ieee->lock,flags);
2317 inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
2320 get_random_bytes(ieee->current_network.bssid, ETH_ALEN);
2322 /* an IBSS cell address must have the two less significant
2323 * bits of the first byte = 2
2325 ieee->current_network.bssid[0] &= ~0x01;
2326 ieee->current_network.bssid[0] |= 0x02;
2329 /* called in user context only */
2330 void ieee80211_start_master_bss(struct ieee80211_device *ieee)
2334 if (ieee->current_network.ssid_len == 0){
2335 strncpy(ieee->current_network.ssid,
2336 IEEE80211_DEFAULT_TX_ESSID,
2339 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2343 memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
2345 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2346 ieee->state = IEEE80211_LINKED;
2347 ieee->link_change(ieee->dev);
2348 notify_wx_assoc_event(ieee);
2350 if (ieee->data_hard_resume)
2351 ieee->data_hard_resume(ieee->dev);
2353 netif_carrier_on(ieee->dev);
2356 void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
2360 if (ieee->data_hard_resume)
2361 ieee->data_hard_resume(ieee->dev);
2363 netif_carrier_on(ieee->dev);
2366 void ieee80211_start_ibss_wq(struct work_struct *work)
2369 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2370 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
2371 /* iwconfig mode ad-hoc will schedule this and return
2372 * on the other hand this will block further iwconfig SET
2373 * operations because of the wx_sem hold.
2374 * Anyway some most set operations set a flag to speed-up
2375 * (abort) this wq (when syncro scanning) before sleeping
2378 if(!ieee->proto_started){
2379 printk("==========oh driver down return\n");
2382 down(&ieee->wx_sem);
2384 if (ieee->current_network.ssid_len == 0){
2385 strcpy(ieee->current_network.ssid,IEEE80211_DEFAULT_TX_ESSID);
2386 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2390 /* check if we have this cell in our network list */
2391 ieee80211_softmac_check_all_nets(ieee);
2394 #ifdef ENABLE_DOT11D //if creating an ad-hoc, set its channel to 10 temporarily--this is the requirement for ASUS, not 11D, so disable 11d.
2395 // if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK))
2396 if (ieee->state == IEEE80211_NOLINK)
2397 ieee->current_network.channel = 6;
2399 /* if not then the state is not linked. Maybe the user swithced to
2400 * ad-hoc mode just after being in monitor mode, or just after
2401 * being very few time in managed mode (so the card have had no
2402 * time to scan all the chans..) or we have just run up the iface
2403 * after setting ad-hoc mode. So we have to give another try..
2404 * Here, in ibss mode, should be safe to do this without extra care
2405 * (in bss mode we had to make sure no-one tryed to associate when
2406 * we had just checked the ieee->state and we was going to start the
2407 * scan) beacause in ibss mode the ieee80211_new_net function, when
2408 * finds a good net, just set the ieee->state to IEEE80211_LINKED,
2409 * so, at worst, we waste a bit of time to initiate an unneeded syncro
2410 * scan, that will stop at the first round because it sees the state
2413 if (ieee->state == IEEE80211_NOLINK)
2414 ieee80211_start_scan_syncro(ieee);
2416 /* the network definitively is not here.. create a new cell */
2417 if (ieee->state == IEEE80211_NOLINK){
2418 printk("creating new IBSS cell\n");
2420 ieee80211_randomize_cell(ieee);
2422 if(ieee->modulation & IEEE80211_CCK_MODULATION){
2424 ieee->current_network.rates_len = 4;
2426 ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
2427 ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
2428 ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
2429 ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
2432 ieee->current_network.rates_len = 0;
2434 if(ieee->modulation & IEEE80211_OFDM_MODULATION){
2435 ieee->current_network.rates_ex_len = 8;
2437 ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
2438 ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
2439 ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
2440 ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
2441 ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
2442 ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
2443 ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
2444 ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
2448 ieee->current_network.rates_ex_len = 0;
2452 // By default, WMM function will be disabled in IBSS mode
2453 ieee->current_network.QoS_Enable = 0;
2454 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2455 ieee->current_network.atim_window = 0;
2456 ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
2457 if(ieee->short_slot)
2458 ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
2462 ieee->state = IEEE80211_LINKED;
2464 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2465 ieee->link_change(ieee->dev);
2467 notify_wx_assoc_event(ieee);
2469 ieee80211_start_send_beacons(ieee);
2471 if (ieee->data_hard_resume)
2472 ieee->data_hard_resume(ieee->dev);
2473 netif_carrier_on(ieee->dev);
2478 inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
2480 queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150);
2483 /* this is called only in user context, with wx_sem held */
2484 void ieee80211_start_bss(struct ieee80211_device *ieee)
2486 unsigned long flags;
2487 #ifdef ENABLE_DOT11D
2489 // Ref: 802.11d 11.1.3.3
2490 // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
2492 if(IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
2494 if(! ieee->bGlobalDomain)
2500 /* check if we have already found the net we
2501 * are interested in (if any).
2502 * if not (we are disassociated and we are not
2503 * in associating / authenticating phase) start the background scanning.
2505 ieee80211_softmac_check_all_nets(ieee);
2507 /* ensure no-one start an associating process (thus setting
2508 * the ieee->state to ieee80211_ASSOCIATING) while we
2509 * have just cheked it and we are going to enable scan.
2510 * The ieee80211_new_net function is always called with
2511 * lock held (from both ieee80211_softmac_check_all_nets and
2512 * the rx path), so we cannot be in the middle of such function
2514 spin_lock_irqsave(&ieee->lock, flags);
2516 if (ieee->state == IEEE80211_NOLINK){
2517 ieee->actscanning = true;
2518 ieee80211_start_scan(ieee);
2520 spin_unlock_irqrestore(&ieee->lock, flags);
2523 /* called only in userspace context */
2524 void ieee80211_disassociate(struct ieee80211_device *ieee)
2528 netif_carrier_off(ieee->dev);
2529 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
2530 ieee80211_reset_queue(ieee);
2532 if (ieee->data_hard_stop)
2533 ieee->data_hard_stop(ieee->dev);
2534 #ifdef ENABLE_DOT11D
2535 if(IS_DOT11D_ENABLE(ieee))
2538 ieee->state = IEEE80211_NOLINK;
2539 ieee->is_set_key = false;
2540 ieee->link_change(ieee->dev);
2541 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2542 notify_wx_assoc_event(ieee);
2545 void ieee80211_associate_retry_wq(struct work_struct *work)
2547 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2548 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
2549 unsigned long flags;
2551 down(&ieee->wx_sem);
2552 if(!ieee->proto_started)
2555 if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
2558 /* until we do not set the state to IEEE80211_NOLINK
2559 * there are no possibility to have someone else trying
2560 * to start an association procdure (we get here with
2561 * ieee->state = IEEE80211_ASSOCIATING).
2562 * When we set the state to IEEE80211_NOLINK it is possible
2563 * that the RX path run an attempt to associate, but
2564 * both ieee80211_softmac_check_all_nets and the
2565 * RX path works with ieee->lock held so there are no
2566 * problems. If we are still disassociated then start a scan.
2567 * the lock here is necessary to ensure no one try to start
2568 * an association procedure when we have just checked the
2569 * state and we are going to start the scan.
2571 ieee->state = IEEE80211_NOLINK;
2573 ieee80211_softmac_check_all_nets(ieee);
2575 spin_lock_irqsave(&ieee->lock, flags);
2577 if(ieee->state == IEEE80211_NOLINK)
2578 ieee80211_start_scan(ieee);
2580 spin_unlock_irqrestore(&ieee->lock, flags);
2586 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
2588 u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
2590 struct sk_buff *skb;
2591 struct ieee80211_probe_response *b;
2593 skb = ieee80211_probe_resp(ieee, broadcast_addr);
2598 b = (struct ieee80211_probe_response *) skb->data;
2599 b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
2605 struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
2607 struct sk_buff *skb;
2608 struct ieee80211_probe_response *b;
2610 skb = ieee80211_get_beacon_(ieee);
2614 b = (struct ieee80211_probe_response *) skb->data;
2615 b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2617 if (ieee->seq_ctrl[0] == 0xFFF)
2618 ieee->seq_ctrl[0] = 0;
2620 ieee->seq_ctrl[0]++;
2625 void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
2627 ieee->sync_scan_hurryup = 1;
2628 down(&ieee->wx_sem);
2629 ieee80211_stop_protocol(ieee);
2634 void ieee80211_stop_protocol(struct ieee80211_device *ieee)
2636 if (!ieee->proto_started)
2639 ieee->proto_started = 0;
2641 ieee80211_stop_send_beacons(ieee);
2642 del_timer_sync(&ieee->associate_timer);
2643 cancel_delayed_work(&ieee->associate_retry_wq);
2644 cancel_delayed_work(&ieee->start_ibss_wq);
2645 ieee80211_stop_scan(ieee);
2647 ieee80211_disassociate(ieee);
2648 RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
2651 void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
2653 ieee->sync_scan_hurryup = 0;
2654 down(&ieee->wx_sem);
2655 ieee80211_start_protocol(ieee);
2659 void ieee80211_start_protocol(struct ieee80211_device *ieee)
2663 if (ieee->proto_started)
2666 ieee->proto_started = 1;
2668 if (ieee->current_network.channel == 0){
2671 if (ch > MAX_CHANNEL_NUMBER)
2672 return; /* no channel found */
2673 #ifdef ENABLE_DOT11D
2674 }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
2676 }while(!ieee->channel_map[ch]);
2678 ieee->current_network.channel = ch;
2681 if (ieee->current_network.beacon_interval == 0)
2682 ieee->current_network.beacon_interval = 100;
2683 // printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);
2684 // ieee->set_chan(ieee->dev,ieee->current_network.channel);
2686 for(i = 0; i < 17; i++) {
2687 ieee->last_rxseq_num[i] = -1;
2688 ieee->last_rxfrag_num[i] = -1;
2689 ieee->last_packet_time[i] = 0;
2692 ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
2695 /* if the user set the MAC of the ad-hoc cell and then
2696 * switch to managed mode, shall we make sure that association
2697 * attempts does not fail just because the user provide the essid
2698 * and the nic is still checking for the AP MAC ??
2700 if (ieee->iw_mode == IW_MODE_INFRA)
2701 ieee80211_start_bss(ieee);
2703 else if (ieee->iw_mode == IW_MODE_ADHOC)
2704 ieee80211_start_ibss(ieee);
2706 else if (ieee->iw_mode == IW_MODE_MASTER)
2707 ieee80211_start_master_bss(ieee);
2709 else if(ieee->iw_mode == IW_MODE_MONITOR)
2710 ieee80211_start_monitor_mode(ieee);
2714 #define DRV_NAME "Ieee80211"
2715 void ieee80211_softmac_init(struct ieee80211_device *ieee)
2718 memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
2720 ieee->state = IEEE80211_NOLINK;
2721 ieee->sync_scan_hurryup = 0;
2722 for(i = 0; i < 5; i++) {
2723 ieee->seq_ctrl[i] = 0;
2725 #ifdef ENABLE_DOT11D
2726 ieee->pDot11dInfo = kzalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
2727 if (!ieee->pDot11dInfo)
2728 IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
2730 //added for AP roaming
2731 ieee->LinkDetectInfo.SlotNum = 2;
2732 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
2733 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
2736 ieee->queue_stop = 0;
2738 ieee->softmac_features = 0; //so IEEE2100-like driver are happy
2741 ieee->proto_started = 0;
2742 ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
2744 ieee->ps = IEEE80211_PS_DISABLED;
2745 ieee->sta_sleep = 0;
2746 ieee->Regdot11HTOperationalRateSet[0]= 0xff;//support MCS 0~7
2747 ieee->Regdot11HTOperationalRateSet[1]= 0xff;//support MCS 8~15
2748 ieee->Regdot11HTOperationalRateSet[4]= 0x01;
2750 ieee->actscanning = false;
2751 ieee->beinretry = false;
2752 ieee->is_set_key = false;
2753 init_mgmt_queue(ieee);
2755 ieee->sta_edca_param[0] = 0x0000A403;
2756 ieee->sta_edca_param[1] = 0x0000A427;
2757 ieee->sta_edca_param[2] = 0x005E4342;
2758 ieee->sta_edca_param[3] = 0x002F3262;
2759 ieee->aggregation = true;
2760 ieee->enable_rx_imm_BA = 1;
2761 ieee->tx_pending.txb = NULL;
2763 init_timer(&ieee->associate_timer);
2764 ieee->associate_timer.data = (unsigned long)ieee;
2765 ieee->associate_timer.function = ieee80211_associate_abort_cb;
2767 init_timer(&ieee->beacon_timer);
2768 ieee->beacon_timer.data = (unsigned long) ieee;
2769 ieee->beacon_timer.function = ieee80211_send_beacon_cb;
2771 #ifdef PF_SYNCTHREAD
2772 ieee->wq = create_workqueue(DRV_NAME,0);
2774 ieee->wq = create_workqueue(DRV_NAME);
2777 INIT_DELAYED_WORK(&ieee->start_ibss_wq,ieee80211_start_ibss_wq);
2778 INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
2779 INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
2780 INIT_DELAYED_WORK(&ieee->softmac_scan_wq,ieee80211_softmac_scan_wq);
2781 INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
2782 INIT_WORK(&ieee->wx_sync_scan_wq,ieee80211_wx_sync_scan_wq);
2785 sema_init(&ieee->wx_sem, 1);
2786 sema_init(&ieee->scan_sem, 1);
2788 spin_lock_init(&ieee->mgmt_tx_lock);
2789 spin_lock_init(&ieee->beacon_lock);
2791 tasklet_init(&ieee->ps_task,
2792 (void(*)(unsigned long)) ieee80211_sta_ps,
2793 (unsigned long)ieee);
2797 void ieee80211_softmac_free(struct ieee80211_device *ieee)
2799 down(&ieee->wx_sem);
2800 #ifdef ENABLE_DOT11D
2801 if(NULL != ieee->pDot11dInfo)
2803 kfree(ieee->pDot11dInfo);
2804 ieee->pDot11dInfo = NULL;
2807 del_timer_sync(&ieee->associate_timer);
2809 cancel_delayed_work(&ieee->associate_retry_wq);
2810 destroy_workqueue(ieee->wq);
2815 /********************************************************
2816 * Start of WPA code. *
2817 * this is stolen from the ipw2200 driver *
2818 ********************************************************/
2821 static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
2823 /* This is called when wpa_supplicant loads and closes the driver
2825 printk("%s WPA\n",value ? "enabling" : "disabling");
2826 ieee->wpa_enabled = value;
2831 void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len)
2833 /* make sure WPA is enabled */
2834 ieee80211_wpa_enable(ieee, 1);
2836 ieee80211_disassociate(ieee);
2840 static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
2846 case IEEE_MLME_STA_DEAUTH:
2850 case IEEE_MLME_STA_DISASSOC:
2851 ieee80211_disassociate(ieee);
2855 printk("Unknown MLME request: %d\n", command);
2863 static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
2864 struct ieee_param *param, int plen)
2868 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
2869 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
2872 if (param->u.wpa_ie.len) {
2873 buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
2877 memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
2878 kfree(ieee->wpa_ie);
2880 ieee->wpa_ie_len = param->u.wpa_ie.len;
2882 kfree(ieee->wpa_ie);
2883 ieee->wpa_ie = NULL;
2884 ieee->wpa_ie_len = 0;
2887 ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
2891 #define AUTH_ALG_OPEN_SYSTEM 0x1
2892 #define AUTH_ALG_SHARED_KEY 0x2
2894 static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
2897 struct ieee80211_security sec = {
2898 .flags = SEC_AUTH_MODE,
2902 if (value & AUTH_ALG_SHARED_KEY) {
2903 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
2905 ieee->auth_mode = 1;
2906 } else if (value & AUTH_ALG_OPEN_SYSTEM){
2907 sec.auth_mode = WLAN_AUTH_OPEN;
2909 ieee->auth_mode = 0;
2911 else if (value & IW_AUTH_ALG_LEAP){
2912 sec.auth_mode = WLAN_AUTH_LEAP;
2914 ieee->auth_mode = 2;
2918 if (ieee->set_security)
2919 ieee->set_security(ieee->dev, &sec);
2921 // ret = -EOPNOTSUPP;
2926 static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
2929 unsigned long flags;
2932 case IEEE_PARAM_WPA_ENABLED:
2933 ret = ieee80211_wpa_enable(ieee, value);
2936 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2937 ieee->tkip_countermeasures=value;
2940 case IEEE_PARAM_DROP_UNENCRYPTED: {
2943 * wpa_supplicant calls set_wpa_enabled when the driver
2944 * is loaded and unloaded, regardless of if WPA is being
2945 * used. No other calls are made which can be used to
2946 * determine if encryption will be used or not prior to
2947 * association being expected. If encryption is not being
2948 * used, drop_unencrypted is set to false, else true -- we
2949 * can use this to determine if the CAP_PRIVACY_ON bit should
2952 struct ieee80211_security sec = {
2953 .flags = SEC_ENABLED,
2956 ieee->drop_unencrypted = value;
2957 /* We only change SEC_LEVEL for open mode. Others
2958 * are set by ipw_wpa_set_encryption.
2961 sec.flags |= SEC_LEVEL;
2962 sec.level = SEC_LEVEL_0;
2965 sec.flags |= SEC_LEVEL;
2966 sec.level = SEC_LEVEL_1;
2968 if (ieee->set_security)
2969 ieee->set_security(ieee->dev, &sec);
2973 case IEEE_PARAM_PRIVACY_INVOKED:
2974 ieee->privacy_invoked=value;
2977 case IEEE_PARAM_AUTH_ALGS:
2978 ret = ieee80211_wpa_set_auth_algs(ieee, value);
2981 case IEEE_PARAM_IEEE_802_1X:
2982 ieee->ieee802_1x=value;
2984 case IEEE_PARAM_WPAX_SELECT:
2985 // added for WPA2 mixed mode
2986 spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
2987 ieee->wpax_type_set = 1;
2988 ieee->wpax_type_notify = value;
2989 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
2993 printk("Unknown WPA param: %d\n",name);
3000 /* implementation borrowed from hostap driver */
3002 static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
3003 struct ieee_param *param, int param_len)
3007 struct ieee80211_crypto_ops *ops;
3008 struct ieee80211_crypt_data **crypt;
3010 struct ieee80211_security sec = {
3014 param->u.crypt.err = 0;
3015 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
3018 (int) ((char *) param->u.crypt.key - (char *) param) +
3019 param->u.crypt.key_len) {
3020 printk("Len mismatch %d, %d\n", param_len,
3021 param->u.crypt.key_len);
3024 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3025 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3026 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3027 if (param->u.crypt.idx >= WEP_KEYS)
3029 crypt = &ieee->crypt[param->u.crypt.idx];
3034 if (strcmp(param->u.crypt.alg, "none") == 0) {
3039 sec.level = SEC_LEVEL_0;
3040 sec.flags |= SEC_ENABLED | SEC_LEVEL;
3041 ieee80211_crypt_delayed_deinit(ieee, crypt);
3048 sec.flags |= SEC_ENABLED;
3050 /* IPW HW cannot build TKIP MIC, host decryption still needed. */
3051 if (!(ieee->host_encrypt || ieee->host_decrypt) &&
3052 strcmp(param->u.crypt.alg, "TKIP"))
3053 goto skip_host_crypt;
3055 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3056 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
3057 request_module("ieee80211_crypt_wep");
3058 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3059 //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
3060 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
3061 request_module("ieee80211_crypt_tkip");
3062 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3063 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
3064 request_module("ieee80211_crypt_ccmp");
3065 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3068 printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
3069 param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
3074 if (*crypt == NULL || (*crypt)->ops != ops) {
3075 struct ieee80211_crypt_data *new_crypt;
3077 ieee80211_crypt_delayed_deinit(ieee, crypt);
3079 new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL);
3080 if (new_crypt == NULL) {
3084 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
3085 new_crypt->ops = ops;
3086 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
3088 new_crypt->ops->init(param->u.crypt.idx);
3090 if (new_crypt->priv == NULL) {
3092 param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
3100 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
3101 (*crypt)->ops->set_key(param->u.crypt.key,
3102 param->u.crypt.key_len, param->u.crypt.seq,
3103 (*crypt)->priv) < 0) {
3104 printk("key setting failed\n");
3105 param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
3111 if (param->u.crypt.set_tx) {
3112 ieee->tx_keyidx = param->u.crypt.idx;
3113 sec.active_key = param->u.crypt.idx;
3114 sec.flags |= SEC_ACTIVE_KEY;
3116 sec.flags &= ~SEC_ACTIVE_KEY;
3118 if (param->u.crypt.alg != NULL) {
3119 memcpy(sec.keys[param->u.crypt.idx],
3121 param->u.crypt.key_len);
3122 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
3123 sec.flags |= (1 << param->u.crypt.idx);
3125 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3126 sec.flags |= SEC_LEVEL;
3127 sec.level = SEC_LEVEL_1;
3128 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3129 sec.flags |= SEC_LEVEL;
3130 sec.level = SEC_LEVEL_2;
3131 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3132 sec.flags |= SEC_LEVEL;
3133 sec.level = SEC_LEVEL_3;
3137 if (ieee->set_security)
3138 ieee->set_security(ieee->dev, &sec);
3140 /* Do not reset port if card is in Managed mode since resetting will
3141 * generate new IEEE 802.11 authentication which may end up in looping
3142 * with IEEE 802.1X. If your hardware requires a reset after WEP
3143 * configuration (for example... Prism2), implement the reset_port in
3144 * the callbacks structures used to initialize the 802.11 stack. */
3145 if (ieee->reset_on_keychange &&
3146 ieee->iw_mode != IW_MODE_INFRA &&
3148 ieee->reset_port(ieee->dev)) {
3149 printk("reset_port failed\n");
3150 param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
3157 inline struct sk_buff *ieee80211_disassociate_skb(
3158 struct ieee80211_network *beacon,
3159 struct ieee80211_device *ieee,
3162 struct sk_buff *skb;
3163 struct ieee80211_disassoc *disass;
3165 skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc));
3169 disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc));
3170 disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
3171 disass->header.duration_id = 0;
3173 memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
3174 memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
3175 memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
3177 disass->reason = asRsn;
3184 struct ieee80211_device *ieee,
3189 struct ieee80211_network *beacon = &ieee->current_network;
3190 struct sk_buff *skb;
3191 skb = ieee80211_disassociate_skb(beacon,ieee,asRsn);
3193 softmac_mgmt_xmit(skb, ieee);
3194 //dev_kfree_skb_any(skb);//edit by thomas
3198 int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
3200 struct ieee_param *param;
3203 down(&ieee->wx_sem);
3204 //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
3206 if (p->length < sizeof(struct ieee_param) || !p->pointer){
3211 param = kmalloc(p->length, GFP_KERNEL);
3216 if (copy_from_user(param, p->pointer, p->length)) {
3222 switch (param->cmd) {
3224 case IEEE_CMD_SET_WPA_PARAM:
3225 ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
3226 param->u.wpa_param.value);
3229 case IEEE_CMD_SET_WPA_IE:
3230 ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
3233 case IEEE_CMD_SET_ENCRYPTION:
3234 ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
3238 ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
3239 param->u.mlme.reason_code);
3243 printk("Unknown WPA supplicant request: %d\n",param->cmd);
3248 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
3258 void notify_wx_assoc_event(struct ieee80211_device *ieee)
3260 union iwreq_data wrqu;
3261 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3262 if (ieee->state == IEEE80211_LINKED)
3263 memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
3265 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
3266 wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
3269 EXPORT_SYMBOL(ieee80211_get_beacon);
3270 EXPORT_SYMBOL(ieee80211_wake_queue);
3271 EXPORT_SYMBOL(ieee80211_stop_queue);
3272 EXPORT_SYMBOL(ieee80211_reset_queue);
3273 EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
3274 EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
3275 EXPORT_SYMBOL(ieee80211_is_shortslot);
3276 EXPORT_SYMBOL(ieee80211_is_54g);
3277 EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
3278 EXPORT_SYMBOL(ieee80211_ps_tx_ack);
3279 EXPORT_SYMBOL(ieee80211_softmac_xmit);
3280 EXPORT_SYMBOL(ieee80211_stop_send_beacons);
3281 EXPORT_SYMBOL(notify_wx_assoc_event);
3282 EXPORT_SYMBOL(SendDisassociation);
3283 EXPORT_SYMBOL(ieee80211_disassociate);
3284 EXPORT_SYMBOL(ieee80211_start_send_beacons);
3285 EXPORT_SYMBOL(ieee80211_stop_scan);
3286 EXPORT_SYMBOL(ieee80211_send_probe_requests);
3287 EXPORT_SYMBOL(ieee80211_softmac_scan_syncro);
3288 EXPORT_SYMBOL(ieee80211_start_scan_syncro);
3289 //EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame);