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;
132 void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
135 *tag++ = MFIE_TYPE_GENERIC; //0
146 printk(KERN_ALERT "This is enable turbo mode IE process\n");
150 void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
153 nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
156 * if the queue is full but we have newer frames then
157 * just overwrites the oldest.
159 * if (nh == ieee->mgmt_queue_tail)
162 ieee->mgmt_queue_head = nh;
163 ieee->mgmt_queue_ring[nh] = skb;
168 struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
172 if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
175 ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
177 ieee->mgmt_queue_tail =
178 (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
183 void init_mgmt_queue(struct ieee80211_device *ieee)
185 ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
188 u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee)
190 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
193 // 2008/01/25 MH For broadcom, MGNT frame set as OFDM 6M.
194 if(pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M)
197 rate = ieee->basic_rate & 0x7f;
200 // 2005.01.26, by rcnjko.
201 if(ieee->mode == IEEE_A||
202 ieee->mode== IEEE_N_5G||
203 (ieee->mode== IEEE_N_24G&&!pHTInfo->bCurSuppCCK))
210 // Data rate of ProbeReq is already decided. Annie, 2005-03-31
211 if( pMgntInfo->bScanInProgress || (pMgntInfo->bDualModeScanStep!=0) )
213 if(pMgntInfo->dot11CurrentWirelessMode==WIRELESS_MODE_A)
223 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
225 inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
228 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
229 struct ieee80211_hdr_3addr *header=
230 (struct ieee80211_hdr_3addr *) skb->data;
232 cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8);
233 spin_lock_irqsave(&ieee->lock, flags);
235 /* called with 2nd param 0, no mgmt lock required */
236 ieee80211_sta_wakeup(ieee,0);
238 tcb_desc->queue_index = MGNT_QUEUE;
239 tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
240 tcb_desc->RATRIndex = 7;
241 tcb_desc->bTxDisableRateFallBack = 1;
242 tcb_desc->bTxUseDriverAssingedRate = 1;
245 if(ieee->queue_stop){
246 enqueue_mgmt(ieee,skb);
248 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
250 if (ieee->seq_ctrl[0] == 0xFFF)
251 ieee->seq_ctrl[0] = 0;
255 /* avoid watchdog triggers */
256 ieee->dev->trans_start = jiffies;
257 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
258 //dev_kfree_skb_any(skb);//edit by thomas
261 spin_unlock_irqrestore(&ieee->lock, flags);
263 spin_unlock_irqrestore(&ieee->lock, flags);
264 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
266 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
268 if (ieee->seq_ctrl[0] == 0xFFF)
269 ieee->seq_ctrl[0] = 0;
273 /* check wether the managed packet queued greater than 5 */
274 if(!ieee->check_nic_enough_desc(ieee->dev,tcb_desc->queue_index)||\
275 (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)||\
276 (ieee->queue_stop) ) {
277 /* insert the skb packet to the management queue */
278 /* as for the completion function, it does not need
279 * to check it any more.
281 printk("%s():insert to waitqueue!\n",__FUNCTION__);
282 skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb);
284 //printk("TX packet!\n");
285 ieee->softmac_hard_start_xmit(skb,ieee->dev);
286 //dev_kfree_skb_any(skb);//edit by thomas
288 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
292 inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
295 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
296 struct ieee80211_hdr_3addr *header =
297 (struct ieee80211_hdr_3addr *) skb->data;
302 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
304 if (ieee->seq_ctrl[0] == 0xFFF)
305 ieee->seq_ctrl[0] = 0;
309 /* avoid watchdog triggers */
310 ieee->dev->trans_start = jiffies;
311 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
315 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
317 if (ieee->seq_ctrl[0] == 0xFFF)
318 ieee->seq_ctrl[0] = 0;
322 ieee->softmac_hard_start_xmit(skb,ieee->dev);
325 //dev_kfree_skb_any(skb);//edit by thomas
328 inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
330 unsigned int len,rate_len;
333 struct ieee80211_probe_request *req;
335 len = ieee->current_network.ssid_len;
337 rate_len = ieee80211_MFIE_rate_len(ieee);
339 skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
340 2 + len + rate_len + ieee->tx_headroom);
344 skb_reserve(skb, ieee->tx_headroom);
346 req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
347 req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
348 req->header.duration_id = 0; //FIXME: is this OK ?
350 memset(req->header.addr1, 0xff, ETH_ALEN);
351 memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
352 memset(req->header.addr3, 0xff, ETH_ALEN);
354 tag = (u8 *) skb_put(skb,len+2+rate_len);
356 *tag++ = MFIE_TYPE_SSID;
358 memcpy(tag, ieee->current_network.ssid, len);
361 ieee80211_MFIE_Brate(ieee,&tag);
362 ieee80211_MFIE_Grate(ieee,&tag);
366 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
367 void ieee80211_send_beacon(struct ieee80211_device *ieee)
372 //unsigned long flags;
373 skb = ieee80211_get_beacon_(ieee);
376 softmac_mgmt_xmit(skb, ieee);
377 ieee->softmac_stats.tx_beacons++;
378 //dev_kfree_skb_any(skb);//edit by thomas
380 // ieee->beacon_timer.expires = jiffies +
381 // (MSECS( ieee->current_network.beacon_interval -5));
383 //spin_lock_irqsave(&ieee->beacon_lock,flags);
384 if(ieee->beacon_txing && ieee->ieee_up){
385 // if(!timer_pending(&ieee->beacon_timer))
386 // add_timer(&ieee->beacon_timer);
387 mod_timer(&ieee->beacon_timer,jiffies+(MSECS(ieee->current_network.beacon_interval-5)));
389 //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
393 void ieee80211_send_beacon_cb(unsigned long _ieee)
395 struct ieee80211_device *ieee =
396 (struct ieee80211_device *) _ieee;
399 spin_lock_irqsave(&ieee->beacon_lock, flags);
400 ieee80211_send_beacon(ieee);
401 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
405 void ieee80211_send_probe(struct ieee80211_device *ieee)
409 skb = ieee80211_probe_req(ieee);
411 softmac_mgmt_xmit(skb, ieee);
412 ieee->softmac_stats.tx_probe_rq++;
413 //dev_kfree_skb_any(skb);//edit by thomas
417 void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
419 if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){
420 ieee80211_send_probe(ieee);
421 ieee80211_send_probe(ieee);
425 /* this performs syncro scan blocking the caller until all channels
426 * in the allowed channel map has been checked.
428 void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
431 u8 channel_map[MAX_CHANNEL_NUMBER+1];
432 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
433 down(&ieee->scan_sem);
440 if (ch > MAX_CHANNEL_NUMBER)
441 goto out; /* scan completed */
442 }while(!channel_map[ch]);
444 /* this function can be called in two situations
445 * 1- We have switched to ad-hoc mode and we are
446 * performing a complete syncro scan before conclude
447 * there are no interesting cell and to create a
448 * new one. In this case the link state is
449 * IEEE80211_NOLINK until we found an interesting cell.
450 * If so the ieee8021_new_net, called by the RX path
451 * will set the state to IEEE80211_LINKED, so we stop
453 * 2- We are linked and the root uses run iwlist scan.
454 * So we switch to IEEE80211_LINKED_SCANNING to remember
455 * that we are still logically linked (not interested in
456 * new network events, despite for updating the net list,
457 * but we are temporarly 'unlinked' as the driver shall
458 * not filter RX frames and the channel is changing.
459 * So the only situation in witch are interested is to check
460 * if the state become LINKED because of the #1 situation
463 if (ieee->state == IEEE80211_LINKED)
465 ieee->set_chan(ieee->dev, ch);
466 if(channel_map[ch] == 1)
467 ieee80211_send_probe_requests(ieee);
469 /* this prevent excessive time wait when we
470 * need to wait for a syncro scan to end..
472 if(ieee->state < IEEE80211_LINKED)
475 if (ieee->sync_scan_hurryup)
479 msleep_interruptible_rsl(IEEE80211_SOFTMAC_SCAN_TIME);
483 if(ieee->state < IEEE80211_LINKED){
484 ieee->actscanning = false;
488 ieee->sync_scan_hurryup = 0;
489 if(IS_DOT11D_ENABLE(ieee))
490 DOT11D_ScanComplete(ieee);
496 void ieee80211_softmac_scan_wq(struct work_struct *work)
498 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
499 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
500 static short watchdog = 0;
501 u8 channel_map[MAX_CHANNEL_NUMBER+1];
502 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
505 down(&ieee->scan_sem);
507 ieee->current_network.channel =
508 (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
509 if (watchdog++ > MAX_CHANNEL_NUMBER)
511 //if current channel is not in channel map, set to default channel.
512 if (!channel_map[ieee->current_network.channel]) {
513 ieee->current_network.channel = 6;
514 goto out; /* no good chans */
517 }while(!channel_map[ieee->current_network.channel]);
518 if (ieee->scanning == 0 )
520 ieee->set_chan(ieee->dev, ieee->current_network.channel);
521 if(channel_map[ieee->current_network.channel] == 1)
522 ieee80211_send_probe_requests(ieee);
525 queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
530 if(IS_DOT11D_ENABLE(ieee))
531 DOT11D_ScanComplete(ieee);
532 ieee->actscanning = false;
540 void ieee80211_beacons_start(struct ieee80211_device *ieee)
543 spin_lock_irqsave(&ieee->beacon_lock,flags);
545 ieee->beacon_txing = 1;
546 ieee80211_send_beacon(ieee);
548 spin_unlock_irqrestore(&ieee->beacon_lock,flags);
551 void ieee80211_beacons_stop(struct ieee80211_device *ieee)
555 spin_lock_irqsave(&ieee->beacon_lock,flags);
557 ieee->beacon_txing = 0;
558 del_timer_sync(&ieee->beacon_timer);
560 spin_unlock_irqrestore(&ieee->beacon_lock,flags);
565 void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
567 if(ieee->stop_send_beacons)
568 ieee->stop_send_beacons(ieee->dev);
569 if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
570 ieee80211_beacons_stop(ieee);
574 void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
576 if(ieee->start_send_beacons)
577 ieee->start_send_beacons(ieee->dev,ieee->basic_rate);
578 if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
579 ieee80211_beacons_start(ieee);
583 void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
585 // unsigned long flags;
587 //ieee->sync_scan_hurryup = 1;
589 down(&ieee->scan_sem);
590 // spin_lock_irqsave(&ieee->lock, flags);
592 if (ieee->scanning == 1){
595 cancel_delayed_work(&ieee->softmac_scan_wq);
598 // spin_unlock_irqrestore(&ieee->lock, flags);
602 void ieee80211_stop_scan(struct ieee80211_device *ieee)
604 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
605 ieee80211_softmac_stop_scan(ieee);
607 ieee->stop_scan(ieee->dev);
610 /* called with ieee->lock held */
611 void ieee80211_start_scan(struct ieee80211_device *ieee)
613 if(IS_DOT11D_ENABLE(ieee) )
615 if(IS_COUNTRY_IE_VALID(ieee))
617 RESET_CIE_WATCHDOG(ieee);
620 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
621 if (ieee->scanning == 0){
623 queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0);
626 ieee->start_scan(ieee->dev);
630 /* called with wx_sem held */
631 void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
633 if(IS_DOT11D_ENABLE(ieee) )
635 if(IS_COUNTRY_IE_VALID(ieee))
637 RESET_CIE_WATCHDOG(ieee);
640 ieee->sync_scan_hurryup = 0;
641 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
642 ieee80211_softmac_scan_syncro(ieee);
644 ieee->scan_syncro(ieee->dev);
648 inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
649 struct ieee80211_device *ieee, int challengelen)
652 struct ieee80211_authentication *auth;
653 int len = sizeof(struct ieee80211_authentication) + challengelen + ieee->tx_headroom;
656 skb = dev_alloc_skb(len);
657 if (!skb) return NULL;
659 skb_reserve(skb, ieee->tx_headroom);
660 auth = (struct ieee80211_authentication *)
661 skb_put(skb, sizeof(struct ieee80211_authentication));
663 auth->header.frame_ctl = IEEE80211_STYPE_AUTH;
664 if (challengelen) auth->header.frame_ctl |= IEEE80211_FCTL_WEP;
666 auth->header.duration_id = 0x013a; //FIXME
668 memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
669 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
670 memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
672 //auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
673 if(ieee->auth_mode == 0)
674 auth->algorithm = WLAN_AUTH_OPEN;
675 else if(ieee->auth_mode == 1)
676 auth->algorithm = WLAN_AUTH_SHARED_KEY;
677 else if(ieee->auth_mode == 2)
678 auth->algorithm = WLAN_AUTH_OPEN;//0x80;
679 printk("=================>%s():auth->algorithm is %d\n",__FUNCTION__,auth->algorithm);
680 auth->transaction = cpu_to_le16(ieee->associate_seq);
681 ieee->associate_seq++;
683 auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
690 static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
694 struct ieee80211_probe_response *beacon_buf;
695 struct sk_buff *skb = NULL;
697 int atim_len,erp_len;
698 struct ieee80211_crypt_data* crypt;
700 char *ssid = ieee->current_network.ssid;
701 int ssid_len = ieee->current_network.ssid_len;
702 int rate_len = ieee->current_network.rates_len+2;
703 int rate_ex_len = ieee->current_network.rates_ex_len;
704 int wpa_ie_len = ieee->wpa_ie_len;
705 u8 erpinfo_content = 0;
710 u8 tmp_ht_info_len=0;
711 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
712 u8* tmp_generic_ie_buf=NULL;
713 u8 tmp_generic_ie_len=0;
715 if(rate_ex_len > 0) rate_ex_len+=2;
717 if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
722 if(ieee80211_is_54g(ieee->current_network))
728 crypt = ieee->crypt[ieee->tx_keyidx];
731 encrypt = ieee->host_encrypt && crypt && crypt->ops &&
732 ((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len));
734 tmp_ht_cap_buf =(u8*) &(ieee->pHTInfo->SelfHTCap);
735 tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
736 tmp_ht_info_buf =(u8*) &(ieee->pHTInfo->SelfHTInfo);
737 tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo);
738 HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len,encrypt);
739 HTConstructInfoElement(ieee,tmp_ht_info_buf,&tmp_ht_info_len, encrypt);
742 if(pHTInfo->bRegRT2RTAggregation)
744 tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
745 tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer);
746 HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len);
748 // 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);
749 beacon_size = sizeof(struct ieee80211_probe_response)+2+
759 // +tmp_generic_ie_len
762 skb = dev_alloc_skb(beacon_size);
765 skb_reserve(skb, ieee->tx_headroom);
766 beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, (beacon_size - ieee->tx_headroom));
767 memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
768 memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
769 memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
771 beacon_buf->header.duration_id = 0; //FIXME
772 beacon_buf->beacon_interval =
773 cpu_to_le16(ieee->current_network.beacon_interval);
774 beacon_buf->capability =
775 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
776 beacon_buf->capability |=
777 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE); //add short preamble here
779 if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
780 cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
782 crypt = ieee->crypt[ieee->tx_keyidx];
784 beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
787 beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
788 beacon_buf->info_element[0].id = MFIE_TYPE_SSID;
789 beacon_buf->info_element[0].len = ssid_len;
791 tag = (u8*) beacon_buf->info_element[0].data;
793 memcpy(tag, ssid, ssid_len);
797 *(tag++) = MFIE_TYPE_RATES;
798 *(tag++) = rate_len-2;
799 memcpy(tag,ieee->current_network.rates,rate_len-2);
802 *(tag++) = MFIE_TYPE_DS_SET;
804 *(tag++) = ieee->current_network.channel;
808 *(tag++) = MFIE_TYPE_IBSS_SET;
810 //*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window);
811 val16 = cpu_to_le16(ieee->current_network.atim_window);
812 memcpy((u8 *)tag, (u8 *)&val16, 2);
817 *(tag++) = MFIE_TYPE_ERP;
819 *(tag++) = erpinfo_content;
822 *(tag++) = MFIE_TYPE_RATES_EX;
823 *(tag++) = rate_ex_len-2;
824 memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
830 if (ieee->iw_mode == IW_MODE_ADHOC)
831 {//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
832 memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
834 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
838 //skb->dev = ieee->dev;
843 struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
848 struct ieee80211_crypt_data* crypt;
849 struct ieee80211_assoc_response_frame *assoc;
852 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
853 int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len + ieee->tx_headroom;
855 skb = dev_alloc_skb(len);
860 skb_reserve(skb, ieee->tx_headroom);
862 assoc = (struct ieee80211_assoc_response_frame *)
863 skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
865 assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
866 memcpy(assoc->header.addr1, dest,ETH_ALEN);
867 memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
868 memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
869 assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
870 WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
874 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
876 if (ieee->host_encrypt)
877 crypt = ieee->crypt[ieee->tx_keyidx];
880 encrypt = ( crypt && crypt->ops);
883 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
886 assoc->aid = cpu_to_le16(ieee->assoc_id);
887 if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
888 else ieee->assoc_id++;
890 tag = (u8*) skb_put(skb, rate_len);
892 ieee80211_MFIE_Brate(ieee, &tag);
893 ieee80211_MFIE_Grate(ieee, &tag);
898 struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest)
901 struct ieee80211_authentication *auth;
902 int len = ieee->tx_headroom + sizeof(struct ieee80211_authentication)+1;
904 skb = dev_alloc_skb(len);
909 skb->len = sizeof(struct ieee80211_authentication);
911 auth = (struct ieee80211_authentication *)skb->data;
913 auth->status = cpu_to_le16(status);
914 auth->transaction = cpu_to_le16(2);
915 auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
917 memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
918 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
919 memcpy(auth->header.addr1, dest, ETH_ALEN);
920 auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
926 struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
929 struct ieee80211_hdr_3addr* hdr;
931 skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
936 hdr = (struct ieee80211_hdr_3addr*)skb_put(skb,sizeof(struct ieee80211_hdr_3addr));
938 memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
939 memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
940 memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
942 hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
943 IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
944 (pwr ? IEEE80211_FCTL_PM:0));
952 void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest)
954 struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
957 softmac_mgmt_xmit(buf, ieee);
961 void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest)
963 struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
966 softmac_mgmt_xmit(buf, ieee);
970 void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
974 struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
976 softmac_mgmt_xmit(buf, ieee);
980 inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
983 //unsigned long flags;
985 struct ieee80211_assoc_request_frame *hdr;
987 //short info_addr = 0;
989 //u16 suite_count = 0;
990 //u8 suit_select = 0;
991 //unsigned int wpa_len = beacon->wpa_ie_len;
993 u8* ht_cap_buf = NULL;
995 u8* realtek_ie_buf=NULL;
997 int wpa_ie_len= ieee->wpa_ie_len;
998 unsigned int ckip_ie_len=0;
999 unsigned int ccxrm_ie_len=0;
1000 unsigned int cxvernum_ie_len=0;
1001 struct ieee80211_crypt_data* crypt;
1004 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
1005 unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
1007 unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
1012 crypt = ieee->crypt[ieee->tx_keyidx];
1013 encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len));
1015 //Include High Throuput capability && Realtek proprietary
1016 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1018 ht_cap_buf = (u8*)&(ieee->pHTInfo->SelfHTCap);
1019 ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
1020 HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt);
1021 if(ieee->pHTInfo->bCurrentRT2RTAggregation)
1023 realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
1024 realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer);
1025 HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len);
1029 if(ieee->qos_support){
1030 wmm_info_len = beacon->qos_data.supported?9:0;
1034 if(beacon->bCkipSupported)
1038 if(beacon->bCcxRmEnable)
1042 if( beacon->BssCcxVerNumber >= 2 )
1044 cxvernum_ie_len = 5+2;
1047 len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1048 + beacon->ssid_len//essid tagged val
1049 + rate_len//rates tagged val
1058 + ieee->tx_headroom;
1060 len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1061 + beacon->ssid_len//essid tagged val
1062 + rate_len//rates tagged val
1070 + ieee->tx_headroom;
1073 skb = dev_alloc_skb(len);
1078 skb_reserve(skb, ieee->tx_headroom);
1080 hdr = (struct ieee80211_assoc_request_frame *)
1081 skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)+2);
1084 hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
1085 hdr->header.duration_id= 37; //FIXME
1086 memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
1087 memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1088 memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
1090 memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John
1092 hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
1093 if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
1094 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1096 if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1097 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); //add short_preamble here
1099 if(ieee->short_slot)
1100 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
1101 if (wmm_info_len) //QOS
1102 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS);
1104 hdr->listen_interval = 0xa; //FIXME
1106 hdr->info_element[0].id = MFIE_TYPE_SSID;
1108 hdr->info_element[0].len = beacon->ssid_len;
1109 tag = skb_put(skb, beacon->ssid_len);
1110 memcpy(tag, beacon->ssid, beacon->ssid_len);
1112 tag = skb_put(skb, rate_len);
1114 ieee80211_MFIE_Brate(ieee, &tag);
1115 ieee80211_MFIE_Grate(ieee, &tag);
1116 // For CCX 1 S13, CKIP. Added by Annie, 2006-08-14.
1117 if( beacon->bCkipSupported )
1119 static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client"
1120 u8 CcxAironetBuf[30];
1121 OCTET_STRING osCcxAironetIE;
1123 memset(CcxAironetBuf, 0,30);
1124 osCcxAironetIE.Octet = CcxAironetBuf;
1125 osCcxAironetIE.Length = sizeof(CcxAironetBuf);
1127 // Ref. CCX test plan v3.61, 3.2.3.1 step 13.
1128 // We want to make the device type as "4500-client". 060926, by CCW.
1130 memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui));
1132 // CCX1 spec V1.13, A01.1 CKIP Negotiation (page23):
1133 // "The CKIP negotiation is started with the associate request from the client to the access point,
1134 // containing an Aironet element with both the MIC and KP bits set."
1135 osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |= (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ;
1136 tag = skb_put(skb, ckip_ie_len);
1137 *tag++ = MFIE_TYPE_AIRONET;
1138 *tag++ = osCcxAironetIE.Length;
1139 memcpy(tag,osCcxAironetIE.Octet,osCcxAironetIE.Length);
1140 tag += osCcxAironetIE.Length;
1143 if(beacon->bCcxRmEnable)
1145 static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
1146 OCTET_STRING osCcxRmCap;
1148 osCcxRmCap.Octet = CcxRmCapBuf;
1149 osCcxRmCap.Length = sizeof(CcxRmCapBuf);
1150 tag = skb_put(skb,ccxrm_ie_len);
1151 *tag++ = MFIE_TYPE_GENERIC;
1152 *tag++ = osCcxRmCap.Length;
1153 memcpy(tag,osCcxRmCap.Octet,osCcxRmCap.Length);
1154 tag += osCcxRmCap.Length;
1157 if( beacon->BssCcxVerNumber >= 2 )
1159 u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
1160 OCTET_STRING osCcxVerNum;
1161 CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
1162 osCcxVerNum.Octet = CcxVerNumBuf;
1163 osCcxVerNum.Length = sizeof(CcxVerNumBuf);
1164 tag = skb_put(skb,cxvernum_ie_len);
1165 *tag++ = MFIE_TYPE_GENERIC;
1166 *tag++ = osCcxVerNum.Length;
1167 memcpy(tag,osCcxVerNum.Octet,osCcxVerNum.Length);
1168 tag += osCcxVerNum.Length;
1171 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
1172 if(ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC)
1174 tag = skb_put(skb, ht_cap_len);
1175 *tag++ = MFIE_TYPE_HT_CAP;
1176 *tag++ = ht_cap_len - 2;
1177 memcpy(tag, ht_cap_buf,ht_cap_len -2);
1178 tag += ht_cap_len -2;
1183 //choose what wpa_supplicant gives to associate.
1184 tag = skb_put(skb, wpa_ie_len);
1186 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
1189 tag = skb_put(skb,wmm_info_len);
1191 ieee80211_WMM_Info(ieee, &tag);
1194 tag = skb_put(skb,turbo_info_len);
1195 if(turbo_info_len) {
1196 ieee80211_TURBO_Info(ieee, &tag);
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_GENERIC;
1205 *tag++ = ht_cap_len - 2;
1206 memcpy(tag, ht_cap_buf,ht_cap_len - 2);
1207 tag += ht_cap_len -2;
1210 if(ieee->pHTInfo->bCurrentRT2RTAggregation){
1211 tag = skb_put(skb, realtek_ie_len);
1212 *tag++ = MFIE_TYPE_GENERIC;
1213 *tag++ = realtek_ie_len - 2;
1214 memcpy(tag, realtek_ie_buf,realtek_ie_len -2 );
1217 // printk("<=====%s(), %p, %p\n", __FUNCTION__, ieee->dev, ieee->dev->dev_addr);
1218 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
1222 void ieee80211_associate_abort(struct ieee80211_device *ieee)
1225 unsigned long flags;
1226 spin_lock_irqsave(&ieee->lock, flags);
1228 ieee->associate_seq++;
1230 /* don't scan, and avoid to have the RX path possibily
1231 * try again to associate. Even do not react to AUTH or
1232 * ASSOC response. Just wait for the retry wq to be scheduled.
1233 * Here we will check if there are good nets to associate
1234 * with, so we retry or just get back to NO_LINK and scanning
1236 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
1237 IEEE80211_DEBUG_MGMT("Authentication failed\n");
1238 ieee->softmac_stats.no_auth_rs++;
1240 IEEE80211_DEBUG_MGMT("Association failed\n");
1241 ieee->softmac_stats.no_ass_rs++;
1244 ieee->state = IEEE80211_ASSOCIATING_RETRY;
1246 queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \
1247 IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
1249 spin_unlock_irqrestore(&ieee->lock, flags);
1252 void ieee80211_associate_abort_cb(unsigned long dev)
1254 ieee80211_associate_abort((struct ieee80211_device *) dev);
1258 void ieee80211_associate_step1(struct ieee80211_device *ieee)
1260 struct ieee80211_network *beacon = &ieee->current_network;
1261 struct sk_buff *skb;
1263 IEEE80211_DEBUG_MGMT("Stopping scan\n");
1265 ieee->softmac_stats.tx_auth_rq++;
1266 skb=ieee80211_authentication_req(beacon, ieee, 0);
1269 ieee80211_associate_abort(ieee);
1271 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
1272 IEEE80211_DEBUG_MGMT("Sending authentication request\n");
1273 //printk(KERN_WARNING "Sending authentication request\n");
1274 softmac_mgmt_xmit(skb, ieee);
1275 //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
1276 if(!timer_pending(&ieee->associate_timer)){
1277 ieee->associate_timer.expires = jiffies + (HZ / 2);
1278 add_timer(&ieee->associate_timer);
1280 //dev_kfree_skb_any(skb);//edit by thomas
1284 void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
1287 struct sk_buff *skb;
1288 struct ieee80211_network *beacon = &ieee->current_network;
1289 // int hlen = sizeof(struct ieee80211_authentication);
1291 ieee->associate_seq++;
1292 ieee->softmac_stats.tx_auth_rq++;
1294 skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
1296 ieee80211_associate_abort(ieee);
1298 c = skb_put(skb, chlen+2);
1299 *(c++) = MFIE_TYPE_CHALLENGE;
1301 memcpy(c, challenge, chlen);
1303 IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
1305 ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr ));
1307 softmac_mgmt_xmit(skb, ieee);
1308 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1309 //dev_kfree_skb_any(skb);//edit by thomas
1314 void ieee80211_associate_step2(struct ieee80211_device *ieee)
1316 struct sk_buff* skb;
1317 struct ieee80211_network *beacon = &ieee->current_network;
1319 del_timer_sync(&ieee->associate_timer);
1321 IEEE80211_DEBUG_MGMT("Sending association request\n");
1323 ieee->softmac_stats.tx_ass_rq++;
1324 skb=ieee80211_association_req(beacon, ieee);
1326 ieee80211_associate_abort(ieee);
1328 softmac_mgmt_xmit(skb, ieee);
1329 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1330 //dev_kfree_skb_any(skb);//edit by thomas
1333 void ieee80211_associate_complete_wq(struct work_struct *work)
1335 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
1336 printk(KERN_INFO "Associated successfully\n");
1337 if(ieee80211_is_54g(ieee->current_network) &&
1338 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1341 printk(KERN_INFO"Using G rates:%d\n", ieee->rate);
1344 printk(KERN_INFO"Using B rates:%d\n", ieee->rate);
1346 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1348 printk("Successfully associated, ht enabled\n");
1353 printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
1354 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1355 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1357 ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500);
1358 // To prevent the immediately calling watch_dog after association.
1359 if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
1361 ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
1362 ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
1364 ieee->link_change(ieee->dev);
1365 if(ieee->is_silent_reset == 0){
1366 printk("============>normal associate\n");
1367 notify_wx_assoc_event(ieee);
1369 else if(ieee->is_silent_reset == 1)
1371 printk("==================>silent reset associate\n");
1372 ieee->is_silent_reset = 0;
1375 if (ieee->data_hard_resume)
1376 ieee->data_hard_resume(ieee->dev);
1377 netif_carrier_on(ieee->dev);
1380 void ieee80211_associate_complete(struct ieee80211_device *ieee)
1383 // struct net_device* dev = ieee->dev;
1384 del_timer_sync(&ieee->associate_timer);
1386 ieee->state = IEEE80211_LINKED;
1387 //ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet);
1388 queue_work(ieee->wq, &ieee->associate_complete_wq);
1391 void ieee80211_associate_procedure_wq(struct work_struct *work)
1393 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
1394 ieee->sync_scan_hurryup = 1;
1395 down(&ieee->wx_sem);
1397 if (ieee->data_hard_stop)
1398 ieee->data_hard_stop(ieee->dev);
1400 ieee80211_stop_scan(ieee);
1401 printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);
1402 //ieee->set_chan(ieee->dev, ieee->current_network.channel);
1403 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1405 ieee->associate_seq = 1;
1406 ieee80211_associate_step1(ieee);
1411 inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
1413 u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
1414 int tmp_ssid_len = 0;
1416 short apset,ssidset,ssidbroad,apmatch,ssidmatch;
1418 /* we are interested in new new only if we are not associated
1419 * and we are not associating / authenticating
1421 if (ieee->state != IEEE80211_NOLINK)
1424 if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
1427 if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
1431 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){
1432 /* if the user specified the AP MAC, we need also the essid
1433 * This could be obtained by beacons or, if the network does not
1434 * broadcast it, it can be put manually.
1436 apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
1437 ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
1438 ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0');
1439 apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
1440 ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\
1441 (!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
1444 if ( /* if the user set the AP check if match.
1445 * if the network does not broadcast essid we check the user supplyed ANY essid
1446 * if the network does broadcast and the user does not set essid it is OK
1447 * if the network does broadcast and the user did set essid chech if essid match
1449 ( apset && apmatch &&
1450 ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
1451 /* if the ap is not set, check that the user set the bssid
1452 * and the network does bradcast and that those two bssid matches
1454 (!apset && ssidset && ssidbroad && ssidmatch)
1456 /* if the essid is hidden replace it with the
1457 * essid provided by the user.
1460 strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
1461 tmp_ssid_len = ieee->current_network.ssid_len;
1463 memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
1466 strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
1467 ieee->current_network.ssid_len = tmp_ssid_len;
1469 printk(KERN_INFO"Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d\n",ieee->current_network.ssid,ieee->current_network.channel, ieee->current_network.qos_data.supported, ieee->pHTInfo->bEnableHT, ieee->current_network.bssht.bdSupportHT);
1471 //ieee->pHTInfo->IOTAction = 0;
1472 HTResetIOTSetting(ieee->pHTInfo);
1473 if (ieee->iw_mode == IW_MODE_INFRA){
1474 /* Join the network for the first time */
1475 ieee->AsocRetryCount = 0;
1476 //for HT by amy 080514
1477 if((ieee->current_network.qos_data.supported == 1) &&
1478 // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT))
1479 ieee->current_network.bssht.bdSupportHT)
1480 /*WB, 2008.09.09:bCurrentHTSupport and bEnableHT two flags are going to put together to check whether we are in HT now, so needn't to check bEnableHT flags here. That's is to say we will set to HT support whenever joined AP has the ability to support HT. And whether we are in HT or not, please check bCurrentHTSupport&&bEnableHT now please.*/
1482 // ieee->pHTInfo->bCurrentHTSupport = true;
1483 HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network));
1487 ieee->pHTInfo->bCurrentHTSupport = false;
1490 ieee->state = IEEE80211_ASSOCIATING;
1491 queue_work(ieee->wq, &ieee->associate_procedure_wq);
1493 if(ieee80211_is_54g(ieee->current_network) &&
1494 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1496 ieee->SetWirelessMode(ieee->dev, IEEE_G);
1497 printk(KERN_INFO"Using G rates\n");
1500 ieee->SetWirelessMode(ieee->dev, IEEE_B);
1501 printk(KERN_INFO"Using B rates\n");
1503 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1504 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1505 ieee->state = IEEE80211_LINKED;
1513 void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
1515 unsigned long flags;
1516 struct ieee80211_network *target;
1518 spin_lock_irqsave(&ieee->lock, flags);
1520 list_for_each_entry(target, &ieee->network_list, list) {
1522 /* if the state become different that NOLINK means
1523 * we had found what we are searching for
1526 if (ieee->state != IEEE80211_NOLINK)
1529 if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
1530 ieee80211_softmac_new_net(ieee, target);
1533 spin_unlock_irqrestore(&ieee->lock, flags);
1538 static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen)
1540 struct ieee80211_authentication *a;
1542 if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
1543 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
1547 a = (struct ieee80211_authentication*) skb->data;
1548 if(skb->len > (sizeof(struct ieee80211_authentication) +3)){
1549 t = skb->data + sizeof(struct ieee80211_authentication);
1551 if(*(t++) == MFIE_TYPE_CHALLENGE){
1553 *challenge = kmemdup(t, *chlen, GFP_ATOMIC);
1559 return cpu_to_le16(a->status);
1564 int auth_rq_parse(struct sk_buff *skb,u8* dest)
1566 struct ieee80211_authentication *a;
1568 if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
1569 IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
1572 a = (struct ieee80211_authentication*) skb->data;
1574 memcpy(dest,a->header.addr2, ETH_ALEN);
1576 if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
1577 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1579 return WLAN_STATUS_SUCCESS;
1582 static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
1589 struct ieee80211_hdr_3addr *header =
1590 (struct ieee80211_hdr_3addr *) skb->data;
1592 if (skb->len < sizeof (struct ieee80211_hdr_3addr ))
1593 return -1; /* corrupted */
1595 memcpy(src,header->addr2, ETH_ALEN);
1597 skbend = (u8*)skb->data + skb->len;
1599 tag = skb->data + sizeof (struct ieee80211_hdr_3addr );
1601 while (tag+1 < skbend){
1607 tag++; /* point to the len field */
1608 tag = tag + *(tag); /* point to the last data byte of the tag */
1609 tag++; /* point to the next tag */
1612 //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
1613 if (ssidlen == 0) return 1;
1615 if (!ssid) return 1; /* ssid not found in tagged param */
1616 return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
1620 int assoc_rq_parse(struct sk_buff *skb,u8* dest)
1622 struct ieee80211_assoc_request_frame *a;
1624 if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
1625 sizeof(struct ieee80211_info_element))) {
1627 IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
1631 a = (struct ieee80211_assoc_request_frame*) skb->data;
1633 memcpy(dest,a->header.addr2,ETH_ALEN);
1638 static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid)
1640 struct ieee80211_assoc_response_frame *response_head;
1643 if (skb->len < sizeof(struct ieee80211_assoc_response_frame)){
1644 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
1648 response_head = (struct ieee80211_assoc_response_frame*) skb->data;
1649 *aid = le16_to_cpu(response_head->aid) & 0x3fff;
1651 status_code = le16_to_cpu(response_head->status);
1652 if((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \
1653 status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&&
1654 ((ieee->mode == IEEE_G) &&
1655 (ieee->current_network.mode == IEEE_N_24G) &&
1656 (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) {
1657 ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
1659 ieee->AsocRetryCount = 0;
1662 return le16_to_cpu(response_head->status);
1666 ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1670 //IEEE80211DMESG("Rx probe");
1671 ieee->softmac_stats.rx_probe_rq++;
1672 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1673 if (probe_rq_parse(ieee, skb, dest)){
1674 //IEEE80211DMESG("Was for me!");
1675 ieee->softmac_stats.tx_probe_rs++;
1676 ieee80211_resp_to_probe(ieee, dest);
1681 ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1685 //IEEE80211DMESG("Rx probe");
1686 ieee->softmac_stats.rx_auth_rq++;
1688 status = auth_rq_parse(skb, dest);
1690 ieee80211_resp_to_auth(ieee, status, dest);
1692 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1697 ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1701 //unsigned long flags;
1703 ieee->softmac_stats.rx_ass_rq++;
1704 if (assoc_rq_parse(skb,dest) != -1){
1705 ieee80211_resp_to_assoc_rq(ieee, dest);
1708 printk(KERN_INFO"New client associated: %pM\n", dest);
1714 void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
1717 struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
1720 softmac_ps_mgmt_xmit(buf, ieee);
1725 short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
1727 int timeout = ieee->ps_timeout;
1729 /*if(ieee->ps == IEEE80211_PS_DISABLED ||
1730 ieee->iw_mode != IW_MODE_INFRA ||
1731 ieee->state != IEEE80211_LINKED)
1735 dtim = ieee->current_network.dtim_data;
1737 if(!(dtim & IEEE80211_DTIM_VALID))
1739 timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
1740 //printk("VALID\n");
1741 ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
1743 if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
1746 if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
1749 if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
1752 if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
1753 (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
1757 *time_l = ieee->current_network.last_dtim_sta_time[0]
1758 + (ieee->current_network.beacon_interval
1759 * ieee->current_network.dtim_period) * 1000;
1763 *time_h = ieee->current_network.last_dtim_sta_time[1];
1764 if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
1773 inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
1779 unsigned long flags,flags2;
1781 spin_lock_irqsave(&ieee->lock, flags);
1783 if((ieee->ps == IEEE80211_PS_DISABLED ||
1784 ieee->iw_mode != IW_MODE_INFRA ||
1785 ieee->state != IEEE80211_LINKED)){
1787 // #warning CHECK_LOCK_HERE
1788 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1790 ieee80211_sta_wakeup(ieee, 1);
1792 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1795 sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
1796 /* 2 wake, 1 sleep, 0 do nothing */
1802 if(ieee->sta_sleep == 1)
1803 ieee->enter_sleep_state(ieee->dev,th,tl);
1805 else if(ieee->sta_sleep == 0){
1806 // printk("send null 1\n");
1807 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1809 if(ieee->ps_is_queue_empty(ieee->dev)){
1812 ieee->sta_sleep = 2;
1814 ieee->ps_request_tx_ack(ieee->dev);
1816 ieee80211_sta_ps_send_null_frame(ieee,1);
1821 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1826 }else if(sleep == 2){
1827 //#warning CHECK_LOCK_HERE
1828 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1830 ieee80211_sta_wakeup(ieee,1);
1832 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1836 spin_unlock_irqrestore(&ieee->lock, flags);
1840 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
1842 if(ieee->sta_sleep == 0){
1844 printk("Warning: driver is probably failing to report TX ps error\n");
1845 ieee->ps_request_tx_ack(ieee->dev);
1846 ieee80211_sta_ps_send_null_frame(ieee, 0);
1852 if(ieee->sta_sleep == 1)
1853 ieee->sta_wake_up(ieee->dev);
1855 ieee->sta_sleep = 0;
1858 ieee->ps_request_tx_ack(ieee->dev);
1859 ieee80211_sta_ps_send_null_frame(ieee, 0);
1863 void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
1865 unsigned long flags,flags2;
1867 spin_lock_irqsave(&ieee->lock, flags);
1869 if(ieee->sta_sleep == 2){
1870 /* Null frame with PS bit set */
1872 ieee->sta_sleep = 1;
1873 ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
1875 /* if the card report not success we can't be sure the AP
1876 * has not RXed so we can't assume the AP believe us awake
1879 /* 21112005 - tx again null without PS bit if lost */
1882 if((ieee->sta_sleep == 0) && !success){
1883 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1884 ieee80211_sta_ps_send_null_frame(ieee, 0);
1885 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1888 spin_unlock_irqrestore(&ieee->lock, flags);
1890 void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb)
1892 struct ieee80211_hdr* header = (struct ieee80211_hdr*)skb->data;
1893 u8* act = ieee80211_get_payload(header);
1895 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
1898 IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
1906 if (*act == ACT_ADDBAREQ)
1907 ieee80211_rx_ADDBAReq(ieee, skb);
1908 else if (*act == ACT_ADDBARSP)
1909 ieee80211_rx_ADDBARsp(ieee, skb);
1910 else if (*act == ACT_DELBA)
1911 ieee80211_rx_DELBA(ieee, skb);
1914 // if (net_ratelimit())
1915 // IEEE80211_DEBUG(IEEE80211_DL_BA, "unknown action frame(%d)\n", tmp);
1922 ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
1923 struct ieee80211_rx_stats *rx_stats, u16 type,
1926 struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
1931 struct ieee80211_assoc_response_frame *assoc_resp;
1932 // struct ieee80211_info_element *info_element;
1933 bool bSupportNmode = true, bHalfSupportNmode = false; //default support N mode, disable halfNmode
1935 if(!ieee->proto_started)
1938 if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
1939 ieee->iw_mode == IW_MODE_INFRA &&
1940 ieee->state == IEEE80211_LINKED))
1942 tasklet_schedule(&ieee->ps_task);
1944 if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
1945 WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
1946 ieee->last_rx_ps_time = jiffies;
1948 switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
1950 case IEEE80211_STYPE_ASSOC_RESP:
1951 case IEEE80211_STYPE_REASSOC_RESP:
1953 IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
1954 WLAN_FC_GET_STYPE(header->frame_ctl));
1955 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
1956 ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
1957 ieee->iw_mode == IW_MODE_INFRA){
1958 struct ieee80211_network network_resp;
1959 struct ieee80211_network *network = &network_resp;
1961 if (0 == (errcode=assoc_parse(ieee,skb, &aid))){
1962 ieee->state=IEEE80211_LINKED;
1963 ieee->assoc_id = aid;
1964 ieee->softmac_stats.rx_ass_ok++;
1965 /* station support qos */
1966 /* Let the register setting defaultly with Legacy station */
1967 if(ieee->qos_support) {
1968 assoc_resp = (struct ieee80211_assoc_response_frame*)skb->data;
1969 memset(network, 0, sizeof(*network));
1970 if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\
1971 rx_stats->len - sizeof(*assoc_resp),\
1976 { //filling the PeerHTCap. //maybe not necessary as we can get its info from current_network.
1977 memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
1978 memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
1980 if (ieee->handle_assoc_response != NULL)
1981 ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame*)header, network);
1983 ieee80211_associate_complete(ieee);
1985 /* aid could not been allocated */
1986 ieee->softmac_stats.rx_ass_err++;
1988 "Association response status code 0x%x\n",
1990 IEEE80211_DEBUG_MGMT(
1991 "Association response status code 0x%x\n",
1993 if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
1994 queue_work(ieee->wq, &ieee->associate_procedure_wq);
1996 ieee80211_associate_abort(ieee);
2002 case IEEE80211_STYPE_ASSOC_REQ:
2003 case IEEE80211_STYPE_REASSOC_REQ:
2005 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2006 ieee->iw_mode == IW_MODE_MASTER)
2008 ieee80211_rx_assoc_rq(ieee, skb);
2011 case IEEE80211_STYPE_AUTH:
2013 if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){
2014 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
2015 ieee->iw_mode == IW_MODE_INFRA){
2017 IEEE80211_DEBUG_MGMT("Received authentication response");
2019 if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){
2020 if(ieee->open_wep || !challenge){
2021 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
2022 ieee->softmac_stats.rx_auth_rs_ok++;
2023 if(!(ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE))
2025 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
2027 // WEP or TKIP encryption
2028 if(IsHTHalfNmodeAPs(ieee))
2030 bSupportNmode = true;
2031 bHalfSupportNmode = true;
2035 bSupportNmode = false;
2036 bHalfSupportNmode = false;
2038 printk("==========>to link with AP using SEC(%d, %d)", bSupportNmode, bHalfSupportNmode);
2041 /* Dummy wirless mode setting to avoid encryption issue */
2044 ieee->SetWirelessMode(ieee->dev, \
2045 ieee->current_network.mode);
2049 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2052 if (ieee->current_network.mode == IEEE_N_24G && bHalfSupportNmode == true)
2054 printk("===============>entern half N mode\n");
2055 ieee->bHalfWirelessN24GMode = true;
2058 ieee->bHalfWirelessN24GMode = false;
2060 ieee80211_associate_step2(ieee);
2062 ieee80211_auth_challenge(ieee, challenge, chlen);
2065 ieee->softmac_stats.rx_auth_rs_err++;
2066 IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode);
2067 ieee80211_associate_abort(ieee);
2070 }else if (ieee->iw_mode == IW_MODE_MASTER){
2071 ieee80211_rx_auth_rq(ieee, skb);
2076 case IEEE80211_STYPE_PROBE_REQ:
2078 if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
2079 ((ieee->iw_mode == IW_MODE_ADHOC ||
2080 ieee->iw_mode == IW_MODE_MASTER) &&
2081 ieee->state == IEEE80211_LINKED)){
2082 ieee80211_rx_probe_rq(ieee, skb);
2086 case IEEE80211_STYPE_DISASSOC:
2087 case IEEE80211_STYPE_DEAUTH:
2088 /* FIXME for now repeat all the association procedure
2089 * both for disassociation and deauthentication
2091 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2092 ieee->state == IEEE80211_LINKED &&
2093 ieee->iw_mode == IW_MODE_INFRA){
2095 ieee->state = IEEE80211_ASSOCIATING;
2096 ieee->softmac_stats.reassoc++;
2098 notify_wx_assoc_event(ieee);
2099 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2100 RemovePeerTS(ieee, header->addr2);
2101 queue_work(ieee->wq, &ieee->associate_procedure_wq);
2104 case IEEE80211_STYPE_MANAGE_ACT:
2105 ieee80211_process_action(ieee,skb);
2112 //dev_kfree_skb_any(skb);
2116 /* following are for a simpler TX queue management.
2117 * Instead of using netif_[stop/wake]_queue the driver
2118 * will uses these two function (plus a reset one), that
2119 * will internally uses the kernel netif_* and takes
2120 * care of the ieee802.11 fragmentation.
2121 * So the driver receives a fragment per time and might
2122 * call the stop function when it want without take care
2123 * to have enought room to TX an entire packet.
2124 * This might be useful if each fragment need it's own
2125 * descriptor, thus just keep a total free memory > than
2126 * the max fragmentation treshold is not enought.. If the
2127 * ieee802.11 stack passed a TXB struct then you needed
2128 * to keep N free descriptors where
2129 * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
2130 * In this way you need just one and the 802.11 stack
2131 * will take care of buffering fragments and pass them to
2132 * to the driver later, when it wakes the queue.
2134 void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
2137 unsigned int queue_index = txb->queue_index;
2138 unsigned long flags;
2140 cb_desc *tcb_desc = NULL;
2142 spin_lock_irqsave(&ieee->lock,flags);
2144 /* called with 2nd parm 0, no tx mgmt lock required */
2145 ieee80211_sta_wakeup(ieee,0);
2147 /* update the tx status */
2148 ieee->stats.tx_bytes += txb->payload_size;
2149 ieee->stats.tx_packets++;
2150 tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
2151 if(tcb_desc->bMulticast) {
2152 ieee->stats.multicast++;
2154 /* if xmit available, just xmit it immediately, else just insert it to the wait queue */
2155 for(i = 0; i < txb->nr_frags; i++) {
2156 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2157 if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) ||
2159 if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
2161 (!ieee->check_nic_enough_desc(ieee->dev,queue_index))||\
2162 (ieee->queue_stop)) {
2163 /* insert the skb packet to the wait queue */
2164 /* as for the completion function, it does not need
2165 * to check it any more.
2167 //printk("error:no descriptor left@queue_index %d\n", queue_index);
2168 //ieee80211_stop_queue(ieee);
2169 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2170 skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]);
2172 skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
2175 ieee->softmac_data_hard_start_xmit(
2177 ieee->dev,ieee->rate);
2178 //ieee->stats.tx_packets++;
2179 //ieee->stats.tx_bytes += txb->fragments[i]->len;
2180 //ieee->dev->trans_start = jiffies;
2183 ieee80211_txb_free(txb);
2186 spin_unlock_irqrestore(&ieee->lock,flags);
2190 /* called with ieee->lock acquired */
2191 void ieee80211_resume_tx(struct ieee80211_device *ieee)
2194 for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
2196 if (ieee->queue_stop){
2197 ieee->tx_pending.frag = i;
2201 ieee->softmac_data_hard_start_xmit(
2202 ieee->tx_pending.txb->fragments[i],
2203 ieee->dev,ieee->rate);
2204 //(i+1)<ieee->tx_pending.txb->nr_frags);
2205 ieee->stats.tx_packets++;
2206 ieee->dev->trans_start = jiffies;
2211 ieee80211_txb_free(ieee->tx_pending.txb);
2212 ieee->tx_pending.txb = NULL;
2216 void ieee80211_reset_queue(struct ieee80211_device *ieee)
2218 unsigned long flags;
2220 spin_lock_irqsave(&ieee->lock,flags);
2221 init_mgmt_queue(ieee);
2222 if (ieee->tx_pending.txb){
2223 ieee80211_txb_free(ieee->tx_pending.txb);
2224 ieee->tx_pending.txb = NULL;
2226 ieee->queue_stop = 0;
2227 spin_unlock_irqrestore(&ieee->lock,flags);
2231 void ieee80211_wake_queue(struct ieee80211_device *ieee)
2234 unsigned long flags;
2235 struct sk_buff *skb;
2236 struct ieee80211_hdr_3addr *header;
2238 spin_lock_irqsave(&ieee->lock,flags);
2239 if (! ieee->queue_stop) goto exit;
2241 ieee->queue_stop = 0;
2243 if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){
2244 while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
2246 header = (struct ieee80211_hdr_3addr *) skb->data;
2248 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2250 if (ieee->seq_ctrl[0] == 0xFFF)
2251 ieee->seq_ctrl[0] = 0;
2253 ieee->seq_ctrl[0]++;
2255 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
2256 //dev_kfree_skb_any(skb);//edit by thomas
2259 if (!ieee->queue_stop && ieee->tx_pending.txb)
2260 ieee80211_resume_tx(ieee);
2262 if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){
2263 ieee->softmac_stats.swtxawake++;
2264 netif_wake_queue(ieee->dev);
2268 spin_unlock_irqrestore(&ieee->lock,flags);
2272 void ieee80211_stop_queue(struct ieee80211_device *ieee)
2274 //unsigned long flags;
2275 //spin_lock_irqsave(&ieee->lock,flags);
2277 if (! netif_queue_stopped(ieee->dev)){
2278 netif_stop_queue(ieee->dev);
2279 ieee->softmac_stats.swtxstop++;
2281 ieee->queue_stop = 1;
2282 //spin_unlock_irqrestore(&ieee->lock,flags);
2287 inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
2290 get_random_bytes(ieee->current_network.bssid, ETH_ALEN);
2292 /* an IBSS cell address must have the two less significant
2293 * bits of the first byte = 2
2295 ieee->current_network.bssid[0] &= ~0x01;
2296 ieee->current_network.bssid[0] |= 0x02;
2299 /* called in user context only */
2300 void ieee80211_start_master_bss(struct ieee80211_device *ieee)
2304 if (ieee->current_network.ssid_len == 0){
2305 strncpy(ieee->current_network.ssid,
2306 IEEE80211_DEFAULT_TX_ESSID,
2309 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2313 memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
2315 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2316 ieee->state = IEEE80211_LINKED;
2317 ieee->link_change(ieee->dev);
2318 notify_wx_assoc_event(ieee);
2320 if (ieee->data_hard_resume)
2321 ieee->data_hard_resume(ieee->dev);
2323 netif_carrier_on(ieee->dev);
2326 void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
2330 if (ieee->data_hard_resume)
2331 ieee->data_hard_resume(ieee->dev);
2333 netif_carrier_on(ieee->dev);
2336 void ieee80211_start_ibss_wq(struct work_struct *work)
2339 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2340 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
2341 /* iwconfig mode ad-hoc will schedule this and return
2342 * on the other hand this will block further iwconfig SET
2343 * operations because of the wx_sem hold.
2344 * Anyway some most set operations set a flag to speed-up
2345 * (abort) this wq (when syncro scanning) before sleeping
2348 if(!ieee->proto_started){
2349 printk("==========oh driver down return\n");
2352 down(&ieee->wx_sem);
2354 if (ieee->current_network.ssid_len == 0){
2355 strcpy(ieee->current_network.ssid,IEEE80211_DEFAULT_TX_ESSID);
2356 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2360 /* check if we have this cell in our network list */
2361 ieee80211_softmac_check_all_nets(ieee);
2364 // if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK))
2365 if (ieee->state == IEEE80211_NOLINK)
2366 ieee->current_network.channel = 6;
2367 /* if not then the state is not linked. Maybe the user swithced to
2368 * ad-hoc mode just after being in monitor mode, or just after
2369 * being very few time in managed mode (so the card have had no
2370 * time to scan all the chans..) or we have just run up the iface
2371 * after setting ad-hoc mode. So we have to give another try..
2372 * Here, in ibss mode, should be safe to do this without extra care
2373 * (in bss mode we had to make sure no-one tryed to associate when
2374 * we had just checked the ieee->state and we was going to start the
2375 * scan) beacause in ibss mode the ieee80211_new_net function, when
2376 * finds a good net, just set the ieee->state to IEEE80211_LINKED,
2377 * so, at worst, we waste a bit of time to initiate an unneeded syncro
2378 * scan, that will stop at the first round because it sees the state
2381 if (ieee->state == IEEE80211_NOLINK)
2382 ieee80211_start_scan_syncro(ieee);
2384 /* the network definitively is not here.. create a new cell */
2385 if (ieee->state == IEEE80211_NOLINK){
2386 printk("creating new IBSS cell\n");
2388 ieee80211_randomize_cell(ieee);
2390 if(ieee->modulation & IEEE80211_CCK_MODULATION){
2392 ieee->current_network.rates_len = 4;
2394 ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
2395 ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
2396 ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
2397 ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
2400 ieee->current_network.rates_len = 0;
2402 if(ieee->modulation & IEEE80211_OFDM_MODULATION){
2403 ieee->current_network.rates_ex_len = 8;
2405 ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
2406 ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
2407 ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
2408 ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
2409 ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
2410 ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
2411 ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
2412 ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
2416 ieee->current_network.rates_ex_len = 0;
2420 // By default, WMM function will be disabled in IBSS mode
2421 ieee->current_network.QoS_Enable = 0;
2422 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2423 ieee->current_network.atim_window = 0;
2424 ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
2425 if(ieee->short_slot)
2426 ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
2430 ieee->state = IEEE80211_LINKED;
2432 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2433 ieee->link_change(ieee->dev);
2435 notify_wx_assoc_event(ieee);
2437 ieee80211_start_send_beacons(ieee);
2439 if (ieee->data_hard_resume)
2440 ieee->data_hard_resume(ieee->dev);
2441 netif_carrier_on(ieee->dev);
2446 inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
2448 queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150);
2451 /* this is called only in user context, with wx_sem held */
2452 void ieee80211_start_bss(struct ieee80211_device *ieee)
2454 unsigned long flags;
2456 // Ref: 802.11d 11.1.3.3
2457 // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
2459 if(IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
2461 if(! ieee->bGlobalDomain)
2466 /* check if we have already found the net we
2467 * are interested in (if any).
2468 * if not (we are disassociated and we are not
2469 * in associating / authenticating phase) start the background scanning.
2471 ieee80211_softmac_check_all_nets(ieee);
2473 /* ensure no-one start an associating process (thus setting
2474 * the ieee->state to ieee80211_ASSOCIATING) while we
2475 * have just cheked it and we are going to enable scan.
2476 * The ieee80211_new_net function is always called with
2477 * lock held (from both ieee80211_softmac_check_all_nets and
2478 * the rx path), so we cannot be in the middle of such function
2480 spin_lock_irqsave(&ieee->lock, flags);
2482 if (ieee->state == IEEE80211_NOLINK){
2483 ieee->actscanning = true;
2484 ieee80211_start_scan(ieee);
2486 spin_unlock_irqrestore(&ieee->lock, flags);
2489 /* called only in userspace context */
2490 void ieee80211_disassociate(struct ieee80211_device *ieee)
2494 netif_carrier_off(ieee->dev);
2495 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
2496 ieee80211_reset_queue(ieee);
2498 if (ieee->data_hard_stop)
2499 ieee->data_hard_stop(ieee->dev);
2500 if(IS_DOT11D_ENABLE(ieee))
2502 ieee->state = IEEE80211_NOLINK;
2503 ieee->is_set_key = false;
2504 ieee->link_change(ieee->dev);
2505 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2506 notify_wx_assoc_event(ieee);
2509 void ieee80211_associate_retry_wq(struct work_struct *work)
2511 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2512 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
2513 unsigned long flags;
2515 down(&ieee->wx_sem);
2516 if(!ieee->proto_started)
2519 if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
2522 /* until we do not set the state to IEEE80211_NOLINK
2523 * there are no possibility to have someone else trying
2524 * to start an association procdure (we get here with
2525 * ieee->state = IEEE80211_ASSOCIATING).
2526 * When we set the state to IEEE80211_NOLINK it is possible
2527 * that the RX path run an attempt to associate, but
2528 * both ieee80211_softmac_check_all_nets and the
2529 * RX path works with ieee->lock held so there are no
2530 * problems. If we are still disassociated then start a scan.
2531 * the lock here is necessary to ensure no one try to start
2532 * an association procedure when we have just checked the
2533 * state and we are going to start the scan.
2535 ieee->state = IEEE80211_NOLINK;
2537 ieee80211_softmac_check_all_nets(ieee);
2539 spin_lock_irqsave(&ieee->lock, flags);
2541 if(ieee->state == IEEE80211_NOLINK)
2542 ieee80211_start_scan(ieee);
2544 spin_unlock_irqrestore(&ieee->lock, flags);
2550 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
2552 u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
2554 struct sk_buff *skb;
2555 struct ieee80211_probe_response *b;
2557 skb = ieee80211_probe_resp(ieee, broadcast_addr);
2562 b = (struct ieee80211_probe_response *) skb->data;
2563 b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
2569 struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
2571 struct sk_buff *skb;
2572 struct ieee80211_probe_response *b;
2574 skb = ieee80211_get_beacon_(ieee);
2578 b = (struct ieee80211_probe_response *) skb->data;
2579 b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2581 if (ieee->seq_ctrl[0] == 0xFFF)
2582 ieee->seq_ctrl[0] = 0;
2584 ieee->seq_ctrl[0]++;
2589 void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
2591 ieee->sync_scan_hurryup = 1;
2592 down(&ieee->wx_sem);
2593 ieee80211_stop_protocol(ieee);
2598 void ieee80211_stop_protocol(struct ieee80211_device *ieee)
2600 if (!ieee->proto_started)
2603 ieee->proto_started = 0;
2605 ieee80211_stop_send_beacons(ieee);
2606 del_timer_sync(&ieee->associate_timer);
2607 cancel_delayed_work(&ieee->associate_retry_wq);
2608 cancel_delayed_work(&ieee->start_ibss_wq);
2609 ieee80211_stop_scan(ieee);
2611 ieee80211_disassociate(ieee);
2612 RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
2615 void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
2617 ieee->sync_scan_hurryup = 0;
2618 down(&ieee->wx_sem);
2619 ieee80211_start_protocol(ieee);
2623 void ieee80211_start_protocol(struct ieee80211_device *ieee)
2627 if (ieee->proto_started)
2630 ieee->proto_started = 1;
2632 if (ieee->current_network.channel == 0){
2635 if (ch > MAX_CHANNEL_NUMBER)
2636 return; /* no channel found */
2637 }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
2638 ieee->current_network.channel = ch;
2641 if (ieee->current_network.beacon_interval == 0)
2642 ieee->current_network.beacon_interval = 100;
2643 // printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);
2644 // ieee->set_chan(ieee->dev,ieee->current_network.channel);
2646 for(i = 0; i < 17; i++) {
2647 ieee->last_rxseq_num[i] = -1;
2648 ieee->last_rxfrag_num[i] = -1;
2649 ieee->last_packet_time[i] = 0;
2652 ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
2655 /* if the user set the MAC of the ad-hoc cell and then
2656 * switch to managed mode, shall we make sure that association
2657 * attempts does not fail just because the user provide the essid
2658 * and the nic is still checking for the AP MAC ??
2660 if (ieee->iw_mode == IW_MODE_INFRA)
2661 ieee80211_start_bss(ieee);
2663 else if (ieee->iw_mode == IW_MODE_ADHOC)
2664 ieee80211_start_ibss(ieee);
2666 else if (ieee->iw_mode == IW_MODE_MASTER)
2667 ieee80211_start_master_bss(ieee);
2669 else if(ieee->iw_mode == IW_MODE_MONITOR)
2670 ieee80211_start_monitor_mode(ieee);
2674 #define DRV_NAME "Ieee80211"
2675 void ieee80211_softmac_init(struct ieee80211_device *ieee)
2678 memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
2680 ieee->state = IEEE80211_NOLINK;
2681 ieee->sync_scan_hurryup = 0;
2682 for(i = 0; i < 5; i++) {
2683 ieee->seq_ctrl[i] = 0;
2685 ieee->pDot11dInfo = kzalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
2686 if (!ieee->pDot11dInfo)
2687 IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
2688 //added for AP roaming
2689 ieee->LinkDetectInfo.SlotNum = 2;
2690 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
2691 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
2694 ieee->queue_stop = 0;
2696 ieee->softmac_features = 0; //so IEEE2100-like driver are happy
2699 ieee->proto_started = 0;
2700 ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
2702 ieee->ps = IEEE80211_PS_DISABLED;
2703 ieee->sta_sleep = 0;
2704 ieee->Regdot11HTOperationalRateSet[0]= 0xff;//support MCS 0~7
2705 ieee->Regdot11HTOperationalRateSet[1]= 0xff;//support MCS 8~15
2706 ieee->Regdot11HTOperationalRateSet[4]= 0x01;
2708 ieee->actscanning = false;
2709 ieee->beinretry = false;
2710 ieee->is_set_key = false;
2711 init_mgmt_queue(ieee);
2713 ieee->sta_edca_param[0] = 0x0000A403;
2714 ieee->sta_edca_param[1] = 0x0000A427;
2715 ieee->sta_edca_param[2] = 0x005E4342;
2716 ieee->sta_edca_param[3] = 0x002F3262;
2717 ieee->aggregation = true;
2718 ieee->enable_rx_imm_BA = 1;
2719 ieee->tx_pending.txb = NULL;
2721 init_timer(&ieee->associate_timer);
2722 ieee->associate_timer.data = (unsigned long)ieee;
2723 ieee->associate_timer.function = ieee80211_associate_abort_cb;
2725 init_timer(&ieee->beacon_timer);
2726 ieee->beacon_timer.data = (unsigned long) ieee;
2727 ieee->beacon_timer.function = ieee80211_send_beacon_cb;
2729 #ifdef PF_SYNCTHREAD
2730 ieee->wq = create_workqueue(DRV_NAME,0);
2732 ieee->wq = create_workqueue(DRV_NAME);
2735 INIT_DELAYED_WORK(&ieee->start_ibss_wq,ieee80211_start_ibss_wq);
2736 INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
2737 INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
2738 INIT_DELAYED_WORK(&ieee->softmac_scan_wq,ieee80211_softmac_scan_wq);
2739 INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
2740 INIT_WORK(&ieee->wx_sync_scan_wq,ieee80211_wx_sync_scan_wq);
2743 sema_init(&ieee->wx_sem, 1);
2744 sema_init(&ieee->scan_sem, 1);
2746 spin_lock_init(&ieee->mgmt_tx_lock);
2747 spin_lock_init(&ieee->beacon_lock);
2749 tasklet_init(&ieee->ps_task,
2750 (void(*)(unsigned long)) ieee80211_sta_ps,
2751 (unsigned long)ieee);
2755 void ieee80211_softmac_free(struct ieee80211_device *ieee)
2757 down(&ieee->wx_sem);
2758 kfree(ieee->pDot11dInfo);
2759 ieee->pDot11dInfo = NULL;
2760 del_timer_sync(&ieee->associate_timer);
2762 cancel_delayed_work(&ieee->associate_retry_wq);
2763 destroy_workqueue(ieee->wq);
2768 /********************************************************
2769 * Start of WPA code. *
2770 * this is stolen from the ipw2200 driver *
2771 ********************************************************/
2774 static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
2776 /* This is called when wpa_supplicant loads and closes the driver
2778 printk("%s WPA\n",value ? "enabling" : "disabling");
2779 ieee->wpa_enabled = value;
2784 void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len)
2786 /* make sure WPA is enabled */
2787 ieee80211_wpa_enable(ieee, 1);
2789 ieee80211_disassociate(ieee);
2793 static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
2799 case IEEE_MLME_STA_DEAUTH:
2803 case IEEE_MLME_STA_DISASSOC:
2804 ieee80211_disassociate(ieee);
2808 printk("Unknown MLME request: %d\n", command);
2816 static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
2817 struct ieee_param *param, int plen)
2821 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
2822 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
2825 if (param->u.wpa_ie.len) {
2826 buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len,
2831 kfree(ieee->wpa_ie);
2833 ieee->wpa_ie_len = param->u.wpa_ie.len;
2835 kfree(ieee->wpa_ie);
2836 ieee->wpa_ie = NULL;
2837 ieee->wpa_ie_len = 0;
2840 ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
2844 #define AUTH_ALG_OPEN_SYSTEM 0x1
2845 #define AUTH_ALG_SHARED_KEY 0x2
2847 static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
2850 struct ieee80211_security sec = {
2851 .flags = SEC_AUTH_MODE,
2855 if (value & AUTH_ALG_SHARED_KEY) {
2856 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
2858 ieee->auth_mode = 1;
2859 } else if (value & AUTH_ALG_OPEN_SYSTEM){
2860 sec.auth_mode = WLAN_AUTH_OPEN;
2862 ieee->auth_mode = 0;
2864 else if (value & IW_AUTH_ALG_LEAP){
2865 sec.auth_mode = WLAN_AUTH_LEAP;
2867 ieee->auth_mode = 2;
2871 if (ieee->set_security)
2872 ieee->set_security(ieee->dev, &sec);
2874 // ret = -EOPNOTSUPP;
2879 static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
2882 unsigned long flags;
2885 case IEEE_PARAM_WPA_ENABLED:
2886 ret = ieee80211_wpa_enable(ieee, value);
2889 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2890 ieee->tkip_countermeasures=value;
2893 case IEEE_PARAM_DROP_UNENCRYPTED: {
2896 * wpa_supplicant calls set_wpa_enabled when the driver
2897 * is loaded and unloaded, regardless of if WPA is being
2898 * used. No other calls are made which can be used to
2899 * determine if encryption will be used or not prior to
2900 * association being expected. If encryption is not being
2901 * used, drop_unencrypted is set to false, else true -- we
2902 * can use this to determine if the CAP_PRIVACY_ON bit should
2905 struct ieee80211_security sec = {
2906 .flags = SEC_ENABLED,
2909 ieee->drop_unencrypted = value;
2910 /* We only change SEC_LEVEL for open mode. Others
2911 * are set by ipw_wpa_set_encryption.
2914 sec.flags |= SEC_LEVEL;
2915 sec.level = SEC_LEVEL_0;
2918 sec.flags |= SEC_LEVEL;
2919 sec.level = SEC_LEVEL_1;
2921 if (ieee->set_security)
2922 ieee->set_security(ieee->dev, &sec);
2926 case IEEE_PARAM_PRIVACY_INVOKED:
2927 ieee->privacy_invoked=value;
2930 case IEEE_PARAM_AUTH_ALGS:
2931 ret = ieee80211_wpa_set_auth_algs(ieee, value);
2934 case IEEE_PARAM_IEEE_802_1X:
2935 ieee->ieee802_1x=value;
2937 case IEEE_PARAM_WPAX_SELECT:
2938 // added for WPA2 mixed mode
2939 spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
2940 ieee->wpax_type_set = 1;
2941 ieee->wpax_type_notify = value;
2942 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
2946 printk("Unknown WPA param: %d\n",name);
2953 /* implementation borrowed from hostap driver */
2955 static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
2956 struct ieee_param *param, int param_len)
2960 struct ieee80211_crypto_ops *ops;
2961 struct ieee80211_crypt_data **crypt;
2963 struct ieee80211_security sec = {
2967 param->u.crypt.err = 0;
2968 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
2971 (int) ((char *) param->u.crypt.key - (char *) param) +
2972 param->u.crypt.key_len) {
2973 printk("Len mismatch %d, %d\n", param_len,
2974 param->u.crypt.key_len);
2977 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
2978 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
2979 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
2980 if (param->u.crypt.idx >= WEP_KEYS)
2982 crypt = &ieee->crypt[param->u.crypt.idx];
2987 if (strcmp(param->u.crypt.alg, "none") == 0) {
2992 sec.level = SEC_LEVEL_0;
2993 sec.flags |= SEC_ENABLED | SEC_LEVEL;
2994 ieee80211_crypt_delayed_deinit(ieee, crypt);
3001 sec.flags |= SEC_ENABLED;
3003 /* IPW HW cannot build TKIP MIC, host decryption still needed. */
3004 if (!(ieee->host_encrypt || ieee->host_decrypt) &&
3005 strcmp(param->u.crypt.alg, "TKIP"))
3006 goto skip_host_crypt;
3008 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3009 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
3010 request_module("ieee80211_crypt_wep");
3011 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3012 //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
3013 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
3014 request_module("ieee80211_crypt_tkip");
3015 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3016 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
3017 request_module("ieee80211_crypt_ccmp");
3018 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3021 printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
3022 param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
3027 if (*crypt == NULL || (*crypt)->ops != ops) {
3028 struct ieee80211_crypt_data *new_crypt;
3030 ieee80211_crypt_delayed_deinit(ieee, crypt);
3032 new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL);
3033 if (new_crypt == NULL) {
3037 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
3038 new_crypt->ops = ops;
3039 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
3041 new_crypt->ops->init(param->u.crypt.idx);
3043 if (new_crypt->priv == NULL) {
3045 param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
3053 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
3054 (*crypt)->ops->set_key(param->u.crypt.key,
3055 param->u.crypt.key_len, param->u.crypt.seq,
3056 (*crypt)->priv) < 0) {
3057 printk("key setting failed\n");
3058 param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
3064 if (param->u.crypt.set_tx) {
3065 ieee->tx_keyidx = param->u.crypt.idx;
3066 sec.active_key = param->u.crypt.idx;
3067 sec.flags |= SEC_ACTIVE_KEY;
3069 sec.flags &= ~SEC_ACTIVE_KEY;
3071 if (param->u.crypt.alg != NULL) {
3072 memcpy(sec.keys[param->u.crypt.idx],
3074 param->u.crypt.key_len);
3075 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
3076 sec.flags |= (1 << param->u.crypt.idx);
3078 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3079 sec.flags |= SEC_LEVEL;
3080 sec.level = SEC_LEVEL_1;
3081 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3082 sec.flags |= SEC_LEVEL;
3083 sec.level = SEC_LEVEL_2;
3084 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3085 sec.flags |= SEC_LEVEL;
3086 sec.level = SEC_LEVEL_3;
3090 if (ieee->set_security)
3091 ieee->set_security(ieee->dev, &sec);
3093 /* Do not reset port if card is in Managed mode since resetting will
3094 * generate new IEEE 802.11 authentication which may end up in looping
3095 * with IEEE 802.1X. If your hardware requires a reset after WEP
3096 * configuration (for example... Prism2), implement the reset_port in
3097 * the callbacks structures used to initialize the 802.11 stack. */
3098 if (ieee->reset_on_keychange &&
3099 ieee->iw_mode != IW_MODE_INFRA &&
3101 ieee->reset_port(ieee->dev)) {
3102 printk("reset_port failed\n");
3103 param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
3110 inline struct sk_buff *ieee80211_disassociate_skb(
3111 struct ieee80211_network *beacon,
3112 struct ieee80211_device *ieee,
3115 struct sk_buff *skb;
3116 struct ieee80211_disassoc *disass;
3118 skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc));
3122 disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc));
3123 disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
3124 disass->header.duration_id = 0;
3126 memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
3127 memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
3128 memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
3130 disass->reason = asRsn;
3137 struct ieee80211_device *ieee,
3142 struct ieee80211_network *beacon = &ieee->current_network;
3143 struct sk_buff *skb;
3144 skb = ieee80211_disassociate_skb(beacon,ieee,asRsn);
3146 softmac_mgmt_xmit(skb, ieee);
3147 //dev_kfree_skb_any(skb);//edit by thomas
3151 int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
3153 struct ieee_param *param;
3156 down(&ieee->wx_sem);
3157 //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
3159 if (p->length < sizeof(struct ieee_param) || !p->pointer){
3164 param = kmalloc(p->length, GFP_KERNEL);
3169 if (copy_from_user(param, p->pointer, p->length)) {
3175 switch (param->cmd) {
3177 case IEEE_CMD_SET_WPA_PARAM:
3178 ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
3179 param->u.wpa_param.value);
3182 case IEEE_CMD_SET_WPA_IE:
3183 ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
3186 case IEEE_CMD_SET_ENCRYPTION:
3187 ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
3191 ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
3192 param->u.mlme.reason_code);
3196 printk("Unknown WPA supplicant request: %d\n",param->cmd);
3201 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
3211 void notify_wx_assoc_event(struct ieee80211_device *ieee)
3213 union iwreq_data wrqu;
3214 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3215 if (ieee->state == IEEE80211_LINKED)
3216 memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
3218 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
3219 wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
3222 EXPORT_SYMBOL(ieee80211_get_beacon);
3223 EXPORT_SYMBOL(ieee80211_wake_queue);
3224 EXPORT_SYMBOL(ieee80211_stop_queue);
3225 EXPORT_SYMBOL(ieee80211_reset_queue);
3226 EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
3227 EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
3228 EXPORT_SYMBOL(ieee80211_is_shortslot);
3229 EXPORT_SYMBOL(ieee80211_is_54g);
3230 EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
3231 EXPORT_SYMBOL(ieee80211_ps_tx_ack);
3232 EXPORT_SYMBOL(ieee80211_softmac_xmit);
3233 EXPORT_SYMBOL(ieee80211_stop_send_beacons);
3234 EXPORT_SYMBOL(notify_wx_assoc_event);
3235 EXPORT_SYMBOL(SendDisassociation);
3236 EXPORT_SYMBOL(ieee80211_disassociate);
3237 EXPORT_SYMBOL(ieee80211_start_send_beacons);
3238 EXPORT_SYMBOL(ieee80211_stop_scan);
3239 EXPORT_SYMBOL(ieee80211_send_probe_requests);
3240 EXPORT_SYMBOL(ieee80211_softmac_scan_syncro);
3241 EXPORT_SYMBOL(ieee80211_start_scan_syncro);
3242 //EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame);