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/version.h>
22 #include <asm/uaccess.h>
27 u8 rsn_authen_cipher_suite[16][4] = {
28 {0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved
29 {0x00,0x0F,0xAC,0x01}, //WEP-40 //RSNA default
30 {0x00,0x0F,0xAC,0x02}, //TKIP //NONE //{used just as default}
31 {0x00,0x0F,0xAC,0x03}, //WRAP-historical
32 {0x00,0x0F,0xAC,0x04}, //CCMP
33 {0x00,0x0F,0xAC,0x05}, //WEP-104
36 short ieee80211_is_54g(struct ieee80211_network net)
38 return ((net.rates_ex_len > 0) || (net.rates_len > 4));
41 short ieee80211_is_shortslot(struct ieee80211_network net)
43 return (net.capability & WLAN_CAPABILITY_SHORT_SLOT);
46 /* returns the total length needed for pleacing the RATE MFIE
47 * tag and the EXTENDED RATE MFIE tag if needed.
48 * It encludes two bytes per tag for the tag itself and its len
50 unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
52 unsigned int rate_len = 0;
54 if (ieee->modulation & IEEE80211_CCK_MODULATION)
55 rate_len = IEEE80211_CCK_RATE_LEN + 2;
57 if (ieee->modulation & IEEE80211_OFDM_MODULATION)
59 rate_len += IEEE80211_OFDM_RATE_LEN + 2;
64 /* pleace the MFIE rate, tag to the memory (double) poined.
65 * Then it updates the pointer so that
66 * it points after the new MFIE tag added.
68 void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
72 if (ieee->modulation & IEEE80211_CCK_MODULATION){
73 *tag++ = MFIE_TYPE_RATES;
75 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
76 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
77 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
78 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
81 /* We may add an option for custom rates that specific HW might support */
85 void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
89 if (ieee->modulation & IEEE80211_OFDM_MODULATION){
91 *tag++ = MFIE_TYPE_RATES_EX;
93 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
94 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
95 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
96 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
97 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
98 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
99 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
100 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
104 /* We may add an option for custom rates that specific HW might support */
109 void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) {
112 *tag++ = MFIE_TYPE_GENERIC; //0
121 if(ieee->current_network.wmm_info & 0x80) {
122 *tag++ = 0x0f|MAX_SP_Len;
133 void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
136 *tag++ = MFIE_TYPE_GENERIC; //0
147 printk(KERN_ALERT "This is enable turbo mode IE process\n");
151 void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
154 nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
157 * if the queue is full but we have newer frames then
158 * just overwrites the oldest.
160 * if (nh == ieee->mgmt_queue_tail)
163 ieee->mgmt_queue_head = nh;
164 ieee->mgmt_queue_ring[nh] = skb;
169 struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
173 if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
176 ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
178 ieee->mgmt_queue_tail =
179 (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
184 void init_mgmt_queue(struct ieee80211_device *ieee)
186 ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
189 u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee)
191 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
194 // 2008/01/25 MH For broadcom, MGNT frame set as OFDM 6M.
195 if(pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M)
198 rate = ieee->basic_rate & 0x7f;
201 // 2005.01.26, by rcnjko.
202 if(ieee->mode == IEEE_A||
203 ieee->mode== IEEE_N_5G||
204 (ieee->mode== IEEE_N_24G&&!pHTInfo->bCurSuppCCK))
211 // Data rate of ProbeReq is already decided. Annie, 2005-03-31
212 if( pMgntInfo->bScanInProgress || (pMgntInfo->bDualModeScanStep!=0) )
214 if(pMgntInfo->dot11CurrentWirelessMode==WIRELESS_MODE_A)
224 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
226 inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
229 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
230 struct ieee80211_hdr_3addr *header=
231 (struct ieee80211_hdr_3addr *) skb->data;
233 cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8);
234 spin_lock_irqsave(&ieee->lock, flags);
236 /* called with 2nd param 0, no mgmt lock required */
237 ieee80211_sta_wakeup(ieee,0);
239 tcb_desc->queue_index = MGNT_QUEUE;
240 tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
241 tcb_desc->RATRIndex = 7;
242 tcb_desc->bTxDisableRateFallBack = 1;
243 tcb_desc->bTxUseDriverAssingedRate = 1;
246 if(ieee->queue_stop){
247 enqueue_mgmt(ieee,skb);
249 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
251 if (ieee->seq_ctrl[0] == 0xFFF)
252 ieee->seq_ctrl[0] = 0;
256 /* avoid watchdog triggers */
257 ieee->dev->trans_start = jiffies;
258 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
259 //dev_kfree_skb_any(skb);//edit by thomas
262 spin_unlock_irqrestore(&ieee->lock, flags);
264 spin_unlock_irqrestore(&ieee->lock, flags);
265 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
267 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
269 if (ieee->seq_ctrl[0] == 0xFFF)
270 ieee->seq_ctrl[0] = 0;
274 /* check wether the managed packet queued greater than 5 */
275 if(!ieee->check_nic_enough_desc(ieee->dev,tcb_desc->queue_index)||\
276 (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)||\
277 (ieee->queue_stop) ) {
278 /* insert the skb packet to the management queue */
279 /* as for the completion function, it does not need
280 * to check it any more.
282 printk("%s():insert to waitqueue!\n",__FUNCTION__);
283 skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb);
285 //printk("TX packet!\n");
286 ieee->softmac_hard_start_xmit(skb,ieee->dev);
287 //dev_kfree_skb_any(skb);//edit by thomas
289 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
293 inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
296 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
297 struct ieee80211_hdr_3addr *header =
298 (struct ieee80211_hdr_3addr *) skb->data;
303 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
305 if (ieee->seq_ctrl[0] == 0xFFF)
306 ieee->seq_ctrl[0] = 0;
310 /* avoid watchdog triggers */
311 ieee->dev->trans_start = jiffies;
312 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
316 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
318 if (ieee->seq_ctrl[0] == 0xFFF)
319 ieee->seq_ctrl[0] = 0;
323 ieee->softmac_hard_start_xmit(skb,ieee->dev);
326 //dev_kfree_skb_any(skb);//edit by thomas
329 inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
331 unsigned int len,rate_len;
334 struct ieee80211_probe_request *req;
336 len = ieee->current_network.ssid_len;
338 rate_len = ieee80211_MFIE_rate_len(ieee);
340 skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
341 2 + len + rate_len + ieee->tx_headroom);
345 skb_reserve(skb, ieee->tx_headroom);
347 req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
348 req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
349 req->header.duration_id = 0; //FIXME: is this OK ?
351 memset(req->header.addr1, 0xff, ETH_ALEN);
352 memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
353 memset(req->header.addr3, 0xff, ETH_ALEN);
355 tag = (u8 *) skb_put(skb,len+2+rate_len);
357 *tag++ = MFIE_TYPE_SSID;
359 memcpy(tag, ieee->current_network.ssid, len);
362 ieee80211_MFIE_Brate(ieee,&tag);
363 ieee80211_MFIE_Grate(ieee,&tag);
367 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
368 void ieee80211_send_beacon(struct ieee80211_device *ieee)
373 //unsigned long flags;
374 skb = ieee80211_get_beacon_(ieee);
377 softmac_mgmt_xmit(skb, ieee);
378 ieee->softmac_stats.tx_beacons++;
379 //dev_kfree_skb_any(skb);//edit by thomas
381 // ieee->beacon_timer.expires = jiffies +
382 // (MSECS( ieee->current_network.beacon_interval -5));
384 //spin_lock_irqsave(&ieee->beacon_lock,flags);
385 if(ieee->beacon_txing && ieee->ieee_up){
386 // if(!timer_pending(&ieee->beacon_timer))
387 // add_timer(&ieee->beacon_timer);
388 mod_timer(&ieee->beacon_timer,jiffies+(MSECS(ieee->current_network.beacon_interval-5)));
390 //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
394 void ieee80211_send_beacon_cb(unsigned long _ieee)
396 struct ieee80211_device *ieee =
397 (struct ieee80211_device *) _ieee;
400 spin_lock_irqsave(&ieee->beacon_lock, flags);
401 ieee80211_send_beacon(ieee);
402 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
406 void ieee80211_send_probe(struct ieee80211_device *ieee)
410 skb = ieee80211_probe_req(ieee);
412 softmac_mgmt_xmit(skb, ieee);
413 ieee->softmac_stats.tx_probe_rq++;
414 //dev_kfree_skb_any(skb);//edit by thomas
418 void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
420 if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){
421 ieee80211_send_probe(ieee);
422 ieee80211_send_probe(ieee);
426 /* this performs syncro scan blocking the caller until all channels
427 * in the allowed channel map has been checked.
429 void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
433 u8 channel_map[MAX_CHANNEL_NUMBER+1];
434 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
436 down(&ieee->scan_sem);
443 if (ch > MAX_CHANNEL_NUMBER)
444 goto out; /* scan completed */
446 }while(!channel_map[ch]);
448 }while(!ieee->channel_map[ch]);
451 /* this fuction can be called in two situations
452 * 1- We have switched to ad-hoc mode and we are
453 * performing a complete syncro scan before conclude
454 * there are no interesting cell and to create a
455 * new one. In this case the link state is
456 * IEEE80211_NOLINK until we found an interesting cell.
457 * If so the ieee8021_new_net, called by the RX path
458 * will set the state to IEEE80211_LINKED, so we stop
460 * 2- We are linked and the root uses run iwlist scan.
461 * So we switch to IEEE80211_LINKED_SCANNING to remember
462 * that we are still logically linked (not interested in
463 * new network events, despite for updating the net list,
464 * but we are temporarly 'unlinked' as the driver shall
465 * not filter RX frames and the channel is changing.
466 * So the only situation in witch are interested is to check
467 * if the state become LINKED because of the #1 situation
470 if (ieee->state == IEEE80211_LINKED)
472 ieee->set_chan(ieee->dev, ch);
474 if(channel_map[ch] == 1)
476 ieee80211_send_probe_requests(ieee);
478 /* this prevent excessive time wait when we
479 * need to wait for a syncro scan to end..
481 if(ieee->state < IEEE80211_LINKED)
484 if (ieee->sync_scan_hurryup)
488 msleep_interruptible_rsl(IEEE80211_SOFTMAC_SCAN_TIME);
492 if(ieee->state < IEEE80211_LINKED){
493 ieee->actscanning = false;
497 ieee->sync_scan_hurryup = 0;
499 if(IS_DOT11D_ENABLE(ieee))
500 DOT11D_ScanComplete(ieee);
507 void ieee80211_softmac_scan_wq(struct work_struct *work)
509 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
510 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
511 static short watchdog = 0;
513 u8 channel_map[MAX_CHANNEL_NUMBER+1];
514 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
518 down(&ieee->scan_sem);
520 ieee->current_network.channel =
521 (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
522 if (watchdog++ > MAX_CHANNEL_NUMBER)
524 //if current channel is not in channel map, set to default channel.
526 if (!channel_map[ieee->current_network.channel]);
528 if (!ieee->channel_map[ieee->current_network.channel]);
530 ieee->current_network.channel = 6;
531 goto out; /* no good chans */
534 }while(!channel_map[ieee->current_network.channel]);
536 }while(!ieee->channel_map[ieee->current_network.channel]);
538 if (ieee->scanning == 0 )
540 ieee->set_chan(ieee->dev, ieee->current_network.channel);
542 if(channel_map[ieee->current_network.channel] == 1)
544 ieee80211_send_probe_requests(ieee);
547 queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
553 if(IS_DOT11D_ENABLE(ieee))
554 DOT11D_ScanComplete(ieee);
556 ieee->actscanning = false;
564 void ieee80211_beacons_start(struct ieee80211_device *ieee)
567 spin_lock_irqsave(&ieee->beacon_lock,flags);
569 ieee->beacon_txing = 1;
570 ieee80211_send_beacon(ieee);
572 spin_unlock_irqrestore(&ieee->beacon_lock,flags);
575 void ieee80211_beacons_stop(struct ieee80211_device *ieee)
579 spin_lock_irqsave(&ieee->beacon_lock,flags);
581 ieee->beacon_txing = 0;
582 del_timer_sync(&ieee->beacon_timer);
584 spin_unlock_irqrestore(&ieee->beacon_lock,flags);
589 void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
591 if(ieee->stop_send_beacons)
592 ieee->stop_send_beacons(ieee->dev);
593 if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
594 ieee80211_beacons_stop(ieee);
598 void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
600 if(ieee->start_send_beacons)
601 ieee->start_send_beacons(ieee->dev,ieee->basic_rate);
602 if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
603 ieee80211_beacons_start(ieee);
607 void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
609 // unsigned long flags;
611 //ieee->sync_scan_hurryup = 1;
613 down(&ieee->scan_sem);
614 // spin_lock_irqsave(&ieee->lock, flags);
616 if (ieee->scanning == 1){
619 cancel_delayed_work(&ieee->softmac_scan_wq);
622 // spin_unlock_irqrestore(&ieee->lock, flags);
626 void ieee80211_stop_scan(struct ieee80211_device *ieee)
628 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
629 ieee80211_softmac_stop_scan(ieee);
631 ieee->stop_scan(ieee->dev);
634 /* called with ieee->lock held */
635 void ieee80211_start_scan(struct ieee80211_device *ieee)
638 if(IS_DOT11D_ENABLE(ieee) )
640 if(IS_COUNTRY_IE_VALID(ieee))
642 RESET_CIE_WATCHDOG(ieee);
646 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
647 if (ieee->scanning == 0){
649 queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0);
652 ieee->start_scan(ieee->dev);
656 /* called with wx_sem held */
657 void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
660 if(IS_DOT11D_ENABLE(ieee) )
662 if(IS_COUNTRY_IE_VALID(ieee))
664 RESET_CIE_WATCHDOG(ieee);
668 ieee->sync_scan_hurryup = 0;
669 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
670 ieee80211_softmac_scan_syncro(ieee);
672 ieee->scan_syncro(ieee->dev);
676 inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
677 struct ieee80211_device *ieee, int challengelen)
680 struct ieee80211_authentication *auth;
681 int len = sizeof(struct ieee80211_authentication) + challengelen + ieee->tx_headroom;
684 skb = dev_alloc_skb(len);
685 if (!skb) return NULL;
687 skb_reserve(skb, ieee->tx_headroom);
688 auth = (struct ieee80211_authentication *)
689 skb_put(skb, sizeof(struct ieee80211_authentication));
691 auth->header.frame_ctl = IEEE80211_STYPE_AUTH;
692 if (challengelen) auth->header.frame_ctl |= IEEE80211_FCTL_WEP;
694 auth->header.duration_id = 0x013a; //FIXME
696 memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
697 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
698 memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
700 //auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
701 if(ieee->auth_mode == 0)
702 auth->algorithm = WLAN_AUTH_OPEN;
703 else if(ieee->auth_mode == 1)
704 auth->algorithm = WLAN_AUTH_SHARED_KEY;
705 else if(ieee->auth_mode == 2)
706 auth->algorithm = WLAN_AUTH_OPEN;//0x80;
707 printk("=================>%s():auth->algorithm is %d\n",__FUNCTION__,auth->algorithm);
708 auth->transaction = cpu_to_le16(ieee->associate_seq);
709 ieee->associate_seq++;
711 auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
718 static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
722 struct ieee80211_probe_response *beacon_buf;
723 struct sk_buff *skb = NULL;
725 int atim_len,erp_len;
726 struct ieee80211_crypt_data* crypt;
728 char *ssid = ieee->current_network.ssid;
729 int ssid_len = ieee->current_network.ssid_len;
730 int rate_len = ieee->current_network.rates_len+2;
731 int rate_ex_len = ieee->current_network.rates_ex_len;
732 int wpa_ie_len = ieee->wpa_ie_len;
733 u8 erpinfo_content = 0;
738 u8 tmp_ht_info_len=0;
739 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
740 u8* tmp_generic_ie_buf=NULL;
741 u8 tmp_generic_ie_len=0;
743 if(rate_ex_len > 0) rate_ex_len+=2;
745 if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
750 if(ieee80211_is_54g(ieee->current_network))
756 crypt = ieee->crypt[ieee->tx_keyidx];
759 encrypt = ieee->host_encrypt && crypt && crypt->ops &&
760 ((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len));
762 tmp_ht_cap_buf =(u8*) &(ieee->pHTInfo->SelfHTCap);
763 tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
764 tmp_ht_info_buf =(u8*) &(ieee->pHTInfo->SelfHTInfo);
765 tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo);
766 HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len,encrypt);
767 HTConstructInfoElement(ieee,tmp_ht_info_buf,&tmp_ht_info_len, encrypt);
770 if(pHTInfo->bRegRT2RTAggregation)
772 tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
773 tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer);
774 HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len);
776 // 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);
777 beacon_size = sizeof(struct ieee80211_probe_response)+2+
787 // +tmp_generic_ie_len
790 skb = dev_alloc_skb(beacon_size);
793 skb_reserve(skb, ieee->tx_headroom);
794 beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, (beacon_size - ieee->tx_headroom));
795 memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
796 memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
797 memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
799 beacon_buf->header.duration_id = 0; //FIXME
800 beacon_buf->beacon_interval =
801 cpu_to_le16(ieee->current_network.beacon_interval);
802 beacon_buf->capability =
803 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
804 beacon_buf->capability |=
805 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE); //add short preamble here
807 if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
808 cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
810 crypt = ieee->crypt[ieee->tx_keyidx];
812 beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
815 beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
816 beacon_buf->info_element[0].id = MFIE_TYPE_SSID;
817 beacon_buf->info_element[0].len = ssid_len;
819 tag = (u8*) beacon_buf->info_element[0].data;
821 memcpy(tag, ssid, ssid_len);
825 *(tag++) = MFIE_TYPE_RATES;
826 *(tag++) = rate_len-2;
827 memcpy(tag,ieee->current_network.rates,rate_len-2);
830 *(tag++) = MFIE_TYPE_DS_SET;
832 *(tag++) = ieee->current_network.channel;
836 *(tag++) = MFIE_TYPE_IBSS_SET;
838 //*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window);
839 val16 = cpu_to_le16(ieee->current_network.atim_window);
840 memcpy((u8 *)tag, (u8 *)&val16, 2);
845 *(tag++) = MFIE_TYPE_ERP;
847 *(tag++) = erpinfo_content;
850 *(tag++) = MFIE_TYPE_RATES_EX;
851 *(tag++) = rate_ex_len-2;
852 memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
858 if (ieee->iw_mode == IW_MODE_ADHOC)
859 {//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
860 memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
862 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
866 //skb->dev = ieee->dev;
871 struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
876 struct ieee80211_crypt_data* crypt;
877 struct ieee80211_assoc_response_frame *assoc;
880 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
881 int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len + ieee->tx_headroom;
883 skb = dev_alloc_skb(len);
888 skb_reserve(skb, ieee->tx_headroom);
890 assoc = (struct ieee80211_assoc_response_frame *)
891 skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
893 assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
894 memcpy(assoc->header.addr1, dest,ETH_ALEN);
895 memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
896 memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
897 assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
898 WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
902 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
904 if (ieee->host_encrypt)
905 crypt = ieee->crypt[ieee->tx_keyidx];
908 encrypt = ( crypt && crypt->ops);
911 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
914 assoc->aid = cpu_to_le16(ieee->assoc_id);
915 if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
916 else ieee->assoc_id++;
918 tag = (u8*) skb_put(skb, rate_len);
920 ieee80211_MFIE_Brate(ieee, &tag);
921 ieee80211_MFIE_Grate(ieee, &tag);
926 struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest)
929 struct ieee80211_authentication *auth;
930 int len = ieee->tx_headroom + sizeof(struct ieee80211_authentication)+1;
932 skb = dev_alloc_skb(len);
937 skb->len = sizeof(struct ieee80211_authentication);
939 auth = (struct ieee80211_authentication *)skb->data;
941 auth->status = cpu_to_le16(status);
942 auth->transaction = cpu_to_le16(2);
943 auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
945 memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
946 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
947 memcpy(auth->header.addr1, dest, ETH_ALEN);
948 auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
954 struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
957 struct ieee80211_hdr_3addr* hdr;
959 skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
964 hdr = (struct ieee80211_hdr_3addr*)skb_put(skb,sizeof(struct ieee80211_hdr_3addr));
966 memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
967 memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
968 memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
970 hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
971 IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
972 (pwr ? IEEE80211_FCTL_PM:0));
980 void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest)
982 struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
985 softmac_mgmt_xmit(buf, ieee);
989 void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest)
991 struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
994 softmac_mgmt_xmit(buf, ieee);
998 void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
1002 struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
1004 softmac_mgmt_xmit(buf, ieee);
1008 inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
1010 struct sk_buff *skb;
1011 //unsigned long flags;
1013 struct ieee80211_assoc_request_frame *hdr;
1015 //short info_addr = 0;
1017 //u16 suite_count = 0;
1018 //u8 suit_select = 0;
1019 //unsigned int wpa_len = beacon->wpa_ie_len;
1021 u8* ht_cap_buf = NULL;
1023 u8* realtek_ie_buf=NULL;
1024 u8 realtek_ie_len=0;
1025 int wpa_ie_len= ieee->wpa_ie_len;
1026 unsigned int ckip_ie_len=0;
1027 unsigned int ccxrm_ie_len=0;
1028 unsigned int cxvernum_ie_len=0;
1029 struct ieee80211_crypt_data* crypt;
1032 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
1033 unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
1035 unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
1040 crypt = ieee->crypt[ieee->tx_keyidx];
1041 encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len));
1043 //Include High Throuput capability && Realtek proprietary
1044 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1046 ht_cap_buf = (u8*)&(ieee->pHTInfo->SelfHTCap);
1047 ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
1048 HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt);
1049 if(ieee->pHTInfo->bCurrentRT2RTAggregation)
1051 realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
1052 realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer);
1053 HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len);
1057 if(ieee->qos_support){
1058 wmm_info_len = beacon->qos_data.supported?9:0;
1062 if(beacon->bCkipSupported)
1066 if(beacon->bCcxRmEnable)
1070 if( beacon->BssCcxVerNumber >= 2 )
1072 cxvernum_ie_len = 5+2;
1075 len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1076 + beacon->ssid_len//essid tagged val
1077 + rate_len//rates tagged val
1086 + ieee->tx_headroom;
1088 len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1089 + beacon->ssid_len//essid tagged val
1090 + rate_len//rates tagged val
1098 + ieee->tx_headroom;
1101 skb = dev_alloc_skb(len);
1106 skb_reserve(skb, ieee->tx_headroom);
1108 hdr = (struct ieee80211_assoc_request_frame *)
1109 skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)+2);
1112 hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
1113 hdr->header.duration_id= 37; //FIXME
1114 memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
1115 memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1116 memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
1118 memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John
1120 hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
1121 if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
1122 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1124 if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1125 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); //add short_preamble here
1127 if(ieee->short_slot)
1128 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
1129 if (wmm_info_len) //QOS
1130 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS);
1132 hdr->listen_interval = 0xa; //FIXME
1134 hdr->info_element[0].id = MFIE_TYPE_SSID;
1136 hdr->info_element[0].len = beacon->ssid_len;
1137 tag = skb_put(skb, beacon->ssid_len);
1138 memcpy(tag, beacon->ssid, beacon->ssid_len);
1140 tag = skb_put(skb, rate_len);
1142 ieee80211_MFIE_Brate(ieee, &tag);
1143 ieee80211_MFIE_Grate(ieee, &tag);
1144 // For CCX 1 S13, CKIP. Added by Annie, 2006-08-14.
1145 if( beacon->bCkipSupported )
1147 static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client"
1148 u8 CcxAironetBuf[30];
1149 OCTET_STRING osCcxAironetIE;
1151 memset(CcxAironetBuf, 0,30);
1152 osCcxAironetIE.Octet = CcxAironetBuf;
1153 osCcxAironetIE.Length = sizeof(CcxAironetBuf);
1155 // Ref. CCX test plan v3.61, 3.2.3.1 step 13.
1156 // We want to make the device type as "4500-client". 060926, by CCW.
1158 memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui));
1160 // CCX1 spec V1.13, A01.1 CKIP Negotiation (page23):
1161 // "The CKIP negotiation is started with the associate request from the client to the access point,
1162 // containing an Aironet element with both the MIC and KP bits set."
1163 osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |= (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ;
1164 tag = skb_put(skb, ckip_ie_len);
1165 *tag++ = MFIE_TYPE_AIRONET;
1166 *tag++ = osCcxAironetIE.Length;
1167 memcpy(tag,osCcxAironetIE.Octet,osCcxAironetIE.Length);
1168 tag += osCcxAironetIE.Length;
1171 if(beacon->bCcxRmEnable)
1173 static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
1174 OCTET_STRING osCcxRmCap;
1176 osCcxRmCap.Octet = CcxRmCapBuf;
1177 osCcxRmCap.Length = sizeof(CcxRmCapBuf);
1178 tag = skb_put(skb,ccxrm_ie_len);
1179 *tag++ = MFIE_TYPE_GENERIC;
1180 *tag++ = osCcxRmCap.Length;
1181 memcpy(tag,osCcxRmCap.Octet,osCcxRmCap.Length);
1182 tag += osCcxRmCap.Length;
1185 if( beacon->BssCcxVerNumber >= 2 )
1187 u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
1188 OCTET_STRING osCcxVerNum;
1189 CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
1190 osCcxVerNum.Octet = CcxVerNumBuf;
1191 osCcxVerNum.Length = sizeof(CcxVerNumBuf);
1192 tag = skb_put(skb,cxvernum_ie_len);
1193 *tag++ = MFIE_TYPE_GENERIC;
1194 *tag++ = osCcxVerNum.Length;
1195 memcpy(tag,osCcxVerNum.Octet,osCcxVerNum.Length);
1196 tag += osCcxVerNum.Length;
1199 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
1200 if(ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC)
1202 tag = skb_put(skb, ht_cap_len);
1203 *tag++ = MFIE_TYPE_HT_CAP;
1204 *tag++ = ht_cap_len - 2;
1205 memcpy(tag, ht_cap_buf,ht_cap_len -2);
1206 tag += ht_cap_len -2;
1211 //choose what wpa_supplicant gives to associate.
1212 tag = skb_put(skb, wpa_ie_len);
1214 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
1217 tag = skb_put(skb,wmm_info_len);
1219 ieee80211_WMM_Info(ieee, &tag);
1222 tag = skb_put(skb,turbo_info_len);
1223 if(turbo_info_len) {
1224 ieee80211_TURBO_Info(ieee, &tag);
1228 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
1229 if(ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC)
1231 tag = skb_put(skb, ht_cap_len);
1232 *tag++ = MFIE_TYPE_GENERIC;
1233 *tag++ = ht_cap_len - 2;
1234 memcpy(tag, ht_cap_buf,ht_cap_len - 2);
1235 tag += ht_cap_len -2;
1238 if(ieee->pHTInfo->bCurrentRT2RTAggregation){
1239 tag = skb_put(skb, realtek_ie_len);
1240 *tag++ = MFIE_TYPE_GENERIC;
1241 *tag++ = realtek_ie_len - 2;
1242 memcpy(tag, realtek_ie_buf,realtek_ie_len -2 );
1245 // printk("<=====%s(), %p, %p\n", __FUNCTION__, ieee->dev, ieee->dev->dev_addr);
1246 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
1250 void ieee80211_associate_abort(struct ieee80211_device *ieee)
1253 unsigned long flags;
1254 spin_lock_irqsave(&ieee->lock, flags);
1256 ieee->associate_seq++;
1258 /* don't scan, and avoid to have the RX path possibily
1259 * try again to associate. Even do not react to AUTH or
1260 * ASSOC response. Just wait for the retry wq to be scheduled.
1261 * Here we will check if there are good nets to associate
1262 * with, so we retry or just get back to NO_LINK and scanning
1264 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
1265 IEEE80211_DEBUG_MGMT("Authentication failed\n");
1266 ieee->softmac_stats.no_auth_rs++;
1268 IEEE80211_DEBUG_MGMT("Association failed\n");
1269 ieee->softmac_stats.no_ass_rs++;
1272 ieee->state = IEEE80211_ASSOCIATING_RETRY;
1274 queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \
1275 IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
1277 spin_unlock_irqrestore(&ieee->lock, flags);
1280 void ieee80211_associate_abort_cb(unsigned long dev)
1282 ieee80211_associate_abort((struct ieee80211_device *) dev);
1286 void ieee80211_associate_step1(struct ieee80211_device *ieee)
1288 struct ieee80211_network *beacon = &ieee->current_network;
1289 struct sk_buff *skb;
1291 IEEE80211_DEBUG_MGMT("Stopping scan\n");
1293 ieee->softmac_stats.tx_auth_rq++;
1294 skb=ieee80211_authentication_req(beacon, ieee, 0);
1297 ieee80211_associate_abort(ieee);
1299 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
1300 IEEE80211_DEBUG_MGMT("Sending authentication request\n");
1301 //printk(KERN_WARNING "Sending authentication request\n");
1302 softmac_mgmt_xmit(skb, ieee);
1303 //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
1304 if(!timer_pending(&ieee->associate_timer)){
1305 ieee->associate_timer.expires = jiffies + (HZ / 2);
1306 add_timer(&ieee->associate_timer);
1308 //dev_kfree_skb_any(skb);//edit by thomas
1312 void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
1315 struct sk_buff *skb;
1316 struct ieee80211_network *beacon = &ieee->current_network;
1317 // int hlen = sizeof(struct ieee80211_authentication);
1319 ieee->associate_seq++;
1320 ieee->softmac_stats.tx_auth_rq++;
1322 skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
1324 ieee80211_associate_abort(ieee);
1326 c = skb_put(skb, chlen+2);
1327 *(c++) = MFIE_TYPE_CHALLENGE;
1329 memcpy(c, challenge, chlen);
1331 IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
1333 ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr ));
1335 softmac_mgmt_xmit(skb, ieee);
1336 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1337 //dev_kfree_skb_any(skb);//edit by thomas
1342 void ieee80211_associate_step2(struct ieee80211_device *ieee)
1344 struct sk_buff* skb;
1345 struct ieee80211_network *beacon = &ieee->current_network;
1347 del_timer_sync(&ieee->associate_timer);
1349 IEEE80211_DEBUG_MGMT("Sending association request\n");
1351 ieee->softmac_stats.tx_ass_rq++;
1352 skb=ieee80211_association_req(beacon, ieee);
1354 ieee80211_associate_abort(ieee);
1356 softmac_mgmt_xmit(skb, ieee);
1357 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1358 //dev_kfree_skb_any(skb);//edit by thomas
1361 void ieee80211_associate_complete_wq(struct work_struct *work)
1363 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
1364 printk(KERN_INFO "Associated successfully\n");
1365 if(ieee80211_is_54g(ieee->current_network) &&
1366 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1369 printk(KERN_INFO"Using G rates:%d\n", ieee->rate);
1372 printk(KERN_INFO"Using B rates:%d\n", ieee->rate);
1374 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1376 printk("Successfully associated, ht enabled\n");
1381 printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
1382 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1383 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1385 ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500);
1386 // To prevent the immediately calling watch_dog after association.
1387 if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
1389 ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
1390 ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
1392 ieee->link_change(ieee->dev);
1393 if(ieee->is_silent_reset == 0){
1394 printk("============>normal associate\n");
1395 notify_wx_assoc_event(ieee);
1397 else if(ieee->is_silent_reset == 1)
1399 printk("==================>silent reset associate\n");
1400 ieee->is_silent_reset = 0;
1403 if (ieee->data_hard_resume)
1404 ieee->data_hard_resume(ieee->dev);
1405 netif_carrier_on(ieee->dev);
1408 void ieee80211_associate_complete(struct ieee80211_device *ieee)
1411 // struct net_device* dev = ieee->dev;
1412 del_timer_sync(&ieee->associate_timer);
1414 ieee->state = IEEE80211_LINKED;
1415 //ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet);
1416 queue_work(ieee->wq, &ieee->associate_complete_wq);
1419 void ieee80211_associate_procedure_wq(struct work_struct *work)
1421 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
1422 ieee->sync_scan_hurryup = 1;
1423 down(&ieee->wx_sem);
1425 if (ieee->data_hard_stop)
1426 ieee->data_hard_stop(ieee->dev);
1428 ieee80211_stop_scan(ieee);
1429 printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);
1430 //ieee->set_chan(ieee->dev, ieee->current_network.channel);
1431 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1433 ieee->associate_seq = 1;
1434 ieee80211_associate_step1(ieee);
1439 inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
1441 u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
1442 int tmp_ssid_len = 0;
1444 short apset,ssidset,ssidbroad,apmatch,ssidmatch;
1446 /* we are interested in new new only if we are not associated
1447 * and we are not associating / authenticating
1449 if (ieee->state != IEEE80211_NOLINK)
1452 if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
1455 if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
1459 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){
1460 /* if the user specified the AP MAC, we need also the essid
1461 * This could be obtained by beacons or, if the network does not
1462 * broadcast it, it can be put manually.
1464 apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
1465 ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
1466 ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0');
1467 apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
1468 ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\
1469 (!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
1472 if ( /* if the user set the AP check if match.
1473 * if the network does not broadcast essid we check the user supplyed ANY essid
1474 * if the network does broadcast and the user does not set essid it is OK
1475 * if the network does broadcast and the user did set essid chech if essid match
1477 ( apset && apmatch &&
1478 ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
1479 /* if the ap is not set, check that the user set the bssid
1480 * and the network does bradcast and that those two bssid matches
1482 (!apset && ssidset && ssidbroad && ssidmatch)
1484 /* if the essid is hidden replace it with the
1485 * essid provided by the user.
1488 strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
1489 tmp_ssid_len = ieee->current_network.ssid_len;
1491 memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
1494 strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
1495 ieee->current_network.ssid_len = tmp_ssid_len;
1497 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);
1499 //ieee->pHTInfo->IOTAction = 0;
1500 HTResetIOTSetting(ieee->pHTInfo);
1501 if (ieee->iw_mode == IW_MODE_INFRA){
1502 /* Join the network for the first time */
1503 ieee->AsocRetryCount = 0;
1504 //for HT by amy 080514
1505 if((ieee->current_network.qos_data.supported == 1) &&
1506 // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT))
1507 ieee->current_network.bssht.bdSupportHT)
1508 /*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.*/
1510 // ieee->pHTInfo->bCurrentHTSupport = true;
1511 HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network));
1515 ieee->pHTInfo->bCurrentHTSupport = false;
1518 ieee->state = IEEE80211_ASSOCIATING;
1519 queue_work(ieee->wq, &ieee->associate_procedure_wq);
1521 if(ieee80211_is_54g(ieee->current_network) &&
1522 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1524 ieee->SetWirelessMode(ieee->dev, IEEE_G);
1525 printk(KERN_INFO"Using G rates\n");
1528 ieee->SetWirelessMode(ieee->dev, IEEE_B);
1529 printk(KERN_INFO"Using B rates\n");
1531 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1532 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1533 ieee->state = IEEE80211_LINKED;
1541 void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
1543 unsigned long flags;
1544 struct ieee80211_network *target;
1546 spin_lock_irqsave(&ieee->lock, flags);
1548 list_for_each_entry(target, &ieee->network_list, list) {
1550 /* if the state become different that NOLINK means
1551 * we had found what we are searching for
1554 if (ieee->state != IEEE80211_NOLINK)
1557 if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
1558 ieee80211_softmac_new_net(ieee, target);
1561 spin_unlock_irqrestore(&ieee->lock, flags);
1566 static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen)
1568 struct ieee80211_authentication *a;
1570 if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
1571 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
1575 a = (struct ieee80211_authentication*) skb->data;
1576 if(skb->len > (sizeof(struct ieee80211_authentication) +3)){
1577 t = skb->data + sizeof(struct ieee80211_authentication);
1579 if(*(t++) == MFIE_TYPE_CHALLENGE){
1581 *challenge = (u8*)kmalloc(*chlen, GFP_ATOMIC);
1582 memcpy(*challenge, t, *chlen);
1586 return cpu_to_le16(a->status);
1591 int auth_rq_parse(struct sk_buff *skb,u8* dest)
1593 struct ieee80211_authentication *a;
1595 if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
1596 IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
1599 a = (struct ieee80211_authentication*) skb->data;
1601 memcpy(dest,a->header.addr2, ETH_ALEN);
1603 if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
1604 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1606 return WLAN_STATUS_SUCCESS;
1609 static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
1616 struct ieee80211_hdr_3addr *header =
1617 (struct ieee80211_hdr_3addr *) skb->data;
1619 if (skb->len < sizeof (struct ieee80211_hdr_3addr ))
1620 return -1; /* corrupted */
1622 memcpy(src,header->addr2, ETH_ALEN);
1624 skbend = (u8*)skb->data + skb->len;
1626 tag = skb->data + sizeof (struct ieee80211_hdr_3addr );
1628 while (tag+1 < skbend){
1634 tag++; /* point to the len field */
1635 tag = tag + *(tag); /* point to the last data byte of the tag */
1636 tag++; /* point to the next tag */
1639 //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
1640 if (ssidlen == 0) return 1;
1642 if (!ssid) return 1; /* ssid not found in tagged param */
1643 return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
1647 int assoc_rq_parse(struct sk_buff *skb,u8* dest)
1649 struct ieee80211_assoc_request_frame *a;
1651 if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
1652 sizeof(struct ieee80211_info_element))) {
1654 IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
1658 a = (struct ieee80211_assoc_request_frame*) skb->data;
1660 memcpy(dest,a->header.addr2,ETH_ALEN);
1665 static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid)
1667 struct ieee80211_assoc_response_frame *response_head;
1670 if (skb->len < sizeof(struct ieee80211_assoc_response_frame)){
1671 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
1675 response_head = (struct ieee80211_assoc_response_frame*) skb->data;
1676 *aid = le16_to_cpu(response_head->aid) & 0x3fff;
1678 status_code = le16_to_cpu(response_head->status);
1679 if((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \
1680 status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&&
1681 ((ieee->mode == IEEE_G) &&
1682 (ieee->current_network.mode == IEEE_N_24G) &&
1683 (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) {
1684 ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
1686 ieee->AsocRetryCount = 0;
1689 return le16_to_cpu(response_head->status);
1693 ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1697 //IEEE80211DMESG("Rx probe");
1698 ieee->softmac_stats.rx_probe_rq++;
1699 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1700 if (probe_rq_parse(ieee, skb, dest)){
1701 //IEEE80211DMESG("Was for me!");
1702 ieee->softmac_stats.tx_probe_rs++;
1703 ieee80211_resp_to_probe(ieee, dest);
1708 ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1712 //IEEE80211DMESG("Rx probe");
1713 ieee->softmac_stats.rx_auth_rq++;
1715 if ((status = auth_rq_parse(skb, dest))!= -1){
1716 ieee80211_resp_to_auth(ieee, status, dest);
1718 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1723 ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1727 //unsigned long flags;
1729 ieee->softmac_stats.rx_ass_rq++;
1730 if (assoc_rq_parse(skb,dest) != -1){
1731 ieee80211_resp_to_assoc_rq(ieee, dest);
1734 printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest));
1740 void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
1743 struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
1746 softmac_ps_mgmt_xmit(buf, ieee);
1751 short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
1753 int timeout = ieee->ps_timeout;
1755 /*if(ieee->ps == IEEE80211_PS_DISABLED ||
1756 ieee->iw_mode != IW_MODE_INFRA ||
1757 ieee->state != IEEE80211_LINKED)
1761 dtim = ieee->current_network.dtim_data;
1763 if(!(dtim & IEEE80211_DTIM_VALID))
1765 timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
1766 //printk("VALID\n");
1767 ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
1769 if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
1772 if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
1775 if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
1778 if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
1779 (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
1783 *time_l = ieee->current_network.last_dtim_sta_time[0]
1784 + (ieee->current_network.beacon_interval
1785 * ieee->current_network.dtim_period) * 1000;
1789 *time_h = ieee->current_network.last_dtim_sta_time[1];
1790 if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
1799 inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
1805 unsigned long flags,flags2;
1807 spin_lock_irqsave(&ieee->lock, flags);
1809 if((ieee->ps == IEEE80211_PS_DISABLED ||
1810 ieee->iw_mode != IW_MODE_INFRA ||
1811 ieee->state != IEEE80211_LINKED)){
1813 // #warning CHECK_LOCK_HERE
1814 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1816 ieee80211_sta_wakeup(ieee, 1);
1818 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1821 sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
1822 /* 2 wake, 1 sleep, 0 do nothing */
1828 if(ieee->sta_sleep == 1)
1829 ieee->enter_sleep_state(ieee->dev,th,tl);
1831 else if(ieee->sta_sleep == 0){
1832 // printk("send null 1\n");
1833 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1835 if(ieee->ps_is_queue_empty(ieee->dev)){
1838 ieee->sta_sleep = 2;
1840 ieee->ps_request_tx_ack(ieee->dev);
1842 ieee80211_sta_ps_send_null_frame(ieee,1);
1847 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1852 }else if(sleep == 2){
1853 //#warning CHECK_LOCK_HERE
1854 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1856 ieee80211_sta_wakeup(ieee,1);
1858 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1862 spin_unlock_irqrestore(&ieee->lock, flags);
1866 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
1868 if(ieee->sta_sleep == 0){
1870 printk("Warning: driver is probably failing to report TX ps error\n");
1871 ieee->ps_request_tx_ack(ieee->dev);
1872 ieee80211_sta_ps_send_null_frame(ieee, 0);
1878 if(ieee->sta_sleep == 1)
1879 ieee->sta_wake_up(ieee->dev);
1881 ieee->sta_sleep = 0;
1884 ieee->ps_request_tx_ack(ieee->dev);
1885 ieee80211_sta_ps_send_null_frame(ieee, 0);
1889 void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
1891 unsigned long flags,flags2;
1893 spin_lock_irqsave(&ieee->lock, flags);
1895 if(ieee->sta_sleep == 2){
1896 /* Null frame with PS bit set */
1898 ieee->sta_sleep = 1;
1899 ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
1901 /* if the card report not success we can't be sure the AP
1902 * has not RXed so we can't assume the AP believe us awake
1905 /* 21112005 - tx again null without PS bit if lost */
1908 if((ieee->sta_sleep == 0) && !success){
1909 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1910 ieee80211_sta_ps_send_null_frame(ieee, 0);
1911 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1914 spin_unlock_irqrestore(&ieee->lock, flags);
1916 void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb)
1918 struct ieee80211_hdr* header = (struct ieee80211_hdr*)skb->data;
1919 u8* act = ieee80211_get_payload(header);
1921 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
1924 IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
1932 if (*act == ACT_ADDBAREQ)
1933 ieee80211_rx_ADDBAReq(ieee, skb);
1934 else if (*act == ACT_ADDBARSP)
1935 ieee80211_rx_ADDBARsp(ieee, skb);
1936 else if (*act == ACT_DELBA)
1937 ieee80211_rx_DELBA(ieee, skb);
1940 // if (net_ratelimit())
1941 // IEEE80211_DEBUG(IEEE80211_DL_BA, "unknown action frame(%d)\n", tmp);
1948 ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
1949 struct ieee80211_rx_stats *rx_stats, u16 type,
1952 struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
1957 struct ieee80211_assoc_response_frame *assoc_resp;
1958 // struct ieee80211_info_element *info_element;
1959 bool bSupportNmode = true, bHalfSupportNmode = false; //default support N mode, disable halfNmode
1961 if(!ieee->proto_started)
1964 if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
1965 ieee->iw_mode == IW_MODE_INFRA &&
1966 ieee->state == IEEE80211_LINKED))
1968 tasklet_schedule(&ieee->ps_task);
1970 if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
1971 WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
1972 ieee->last_rx_ps_time = jiffies;
1974 switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
1976 case IEEE80211_STYPE_ASSOC_RESP:
1977 case IEEE80211_STYPE_REASSOC_RESP:
1979 IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
1980 WLAN_FC_GET_STYPE(header->frame_ctl));
1981 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
1982 ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
1983 ieee->iw_mode == IW_MODE_INFRA){
1984 struct ieee80211_network network_resp;
1985 struct ieee80211_network *network = &network_resp;
1987 if (0 == (errcode=assoc_parse(ieee,skb, &aid))){
1988 ieee->state=IEEE80211_LINKED;
1989 ieee->assoc_id = aid;
1990 ieee->softmac_stats.rx_ass_ok++;
1991 /* station support qos */
1992 /* Let the register setting defaultly with Legacy station */
1993 if(ieee->qos_support) {
1994 assoc_resp = (struct ieee80211_assoc_response_frame*)skb->data;
1995 memset(network, 0, sizeof(*network));
1996 if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\
1997 rx_stats->len - sizeof(*assoc_resp),\
2002 { //filling the PeerHTCap. //maybe not neccesary as we can get its info from current_network.
2003 memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
2004 memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
2006 if (ieee->handle_assoc_response != NULL)
2007 ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame*)header, network);
2009 ieee80211_associate_complete(ieee);
2011 /* aid could not been allocated */
2012 ieee->softmac_stats.rx_ass_err++;
2014 "Association response status code 0x%x\n",
2016 IEEE80211_DEBUG_MGMT(
2017 "Association response status code 0x%x\n",
2019 if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
2020 queue_work(ieee->wq, &ieee->associate_procedure_wq);
2022 ieee80211_associate_abort(ieee);
2028 case IEEE80211_STYPE_ASSOC_REQ:
2029 case IEEE80211_STYPE_REASSOC_REQ:
2031 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2032 ieee->iw_mode == IW_MODE_MASTER)
2034 ieee80211_rx_assoc_rq(ieee, skb);
2037 case IEEE80211_STYPE_AUTH:
2039 if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){
2040 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
2041 ieee->iw_mode == IW_MODE_INFRA){
2043 IEEE80211_DEBUG_MGMT("Received authentication response");
2045 if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){
2046 if(ieee->open_wep || !challenge){
2047 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
2048 ieee->softmac_stats.rx_auth_rs_ok++;
2049 if(!(ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE))
2051 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
2053 // WEP or TKIP encryption
2054 if(IsHTHalfNmodeAPs(ieee))
2056 bSupportNmode = true;
2057 bHalfSupportNmode = true;
2061 bSupportNmode = false;
2062 bHalfSupportNmode = false;
2064 printk("==========>to link with AP using SEC(%d, %d)", bSupportNmode, bHalfSupportNmode);
2067 /* Dummy wirless mode setting to avoid encryption issue */
2070 ieee->SetWirelessMode(ieee->dev, \
2071 ieee->current_network.mode);
2075 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2078 if (ieee->current_network.mode == IEEE_N_24G && bHalfSupportNmode == true)
2080 printk("===============>entern half N mode\n");
2081 ieee->bHalfWirelessN24GMode = true;
2084 ieee->bHalfWirelessN24GMode = false;
2086 ieee80211_associate_step2(ieee);
2088 ieee80211_auth_challenge(ieee, challenge, chlen);
2091 ieee->softmac_stats.rx_auth_rs_err++;
2092 IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode);
2093 ieee80211_associate_abort(ieee);
2096 }else if (ieee->iw_mode == IW_MODE_MASTER){
2097 ieee80211_rx_auth_rq(ieee, skb);
2102 case IEEE80211_STYPE_PROBE_REQ:
2104 if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
2105 ((ieee->iw_mode == IW_MODE_ADHOC ||
2106 ieee->iw_mode == IW_MODE_MASTER) &&
2107 ieee->state == IEEE80211_LINKED)){
2108 ieee80211_rx_probe_rq(ieee, skb);
2112 case IEEE80211_STYPE_DISASSOC:
2113 case IEEE80211_STYPE_DEAUTH:
2114 /* FIXME for now repeat all the association procedure
2115 * both for disassociation and deauthentication
2117 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2118 ieee->state == IEEE80211_LINKED &&
2119 ieee->iw_mode == IW_MODE_INFRA){
2121 ieee->state = IEEE80211_ASSOCIATING;
2122 ieee->softmac_stats.reassoc++;
2124 notify_wx_assoc_event(ieee);
2125 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2126 RemovePeerTS(ieee, header->addr2);
2127 queue_work(ieee->wq, &ieee->associate_procedure_wq);
2130 case IEEE80211_STYPE_MANAGE_ACT:
2131 ieee80211_process_action(ieee,skb);
2138 //dev_kfree_skb_any(skb);
2142 /* following are for a simplier TX queue management.
2143 * Instead of using netif_[stop/wake]_queue the driver
2144 * will uses these two function (plus a reset one), that
2145 * will internally uses the kernel netif_* and takes
2146 * care of the ieee802.11 fragmentation.
2147 * So the driver receives a fragment per time and might
2148 * call the stop function when it want without take care
2149 * to have enought room to TX an entire packet.
2150 * This might be useful if each fragment need it's own
2151 * descriptor, thus just keep a total free memory > than
2152 * the max fragmentation treshold is not enought.. If the
2153 * ieee802.11 stack passed a TXB struct then you needed
2154 * to keep N free descriptors where
2155 * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
2156 * In this way you need just one and the 802.11 stack
2157 * will take care of buffering fragments and pass them to
2158 * to the driver later, when it wakes the queue.
2160 void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
2163 unsigned int queue_index = txb->queue_index;
2164 unsigned long flags;
2166 cb_desc *tcb_desc = NULL;
2168 spin_lock_irqsave(&ieee->lock,flags);
2170 /* called with 2nd parm 0, no tx mgmt lock required */
2171 ieee80211_sta_wakeup(ieee,0);
2173 /* update the tx status */
2174 ieee->stats.tx_bytes += txb->payload_size;
2175 ieee->stats.tx_packets++;
2176 tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
2177 if(tcb_desc->bMulticast) {
2178 ieee->stats.multicast++;
2180 /* if xmit available, just xmit it immediately, else just insert it to the wait queue */
2181 for(i = 0; i < txb->nr_frags; i++) {
2182 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2183 if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) ||
2185 if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
2187 (!ieee->check_nic_enough_desc(ieee->dev,queue_index))||\
2188 (ieee->queue_stop)) {
2189 /* insert the skb packet to the wait queue */
2190 /* as for the completion function, it does not need
2191 * to check it any more.
2193 //printk("error:no descriptor left@queue_index %d\n", queue_index);
2194 //ieee80211_stop_queue(ieee);
2195 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2196 skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]);
2198 skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
2201 ieee->softmac_data_hard_start_xmit(
2203 ieee->dev,ieee->rate);
2204 //ieee->stats.tx_packets++;
2205 //ieee->stats.tx_bytes += txb->fragments[i]->len;
2206 //ieee->dev->trans_start = jiffies;
2209 ieee80211_txb_free(txb);
2212 spin_unlock_irqrestore(&ieee->lock,flags);
2216 /* called with ieee->lock acquired */
2217 void ieee80211_resume_tx(struct ieee80211_device *ieee)
2220 for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
2222 if (ieee->queue_stop){
2223 ieee->tx_pending.frag = i;
2227 ieee->softmac_data_hard_start_xmit(
2228 ieee->tx_pending.txb->fragments[i],
2229 ieee->dev,ieee->rate);
2230 //(i+1)<ieee->tx_pending.txb->nr_frags);
2231 ieee->stats.tx_packets++;
2232 ieee->dev->trans_start = jiffies;
2237 ieee80211_txb_free(ieee->tx_pending.txb);
2238 ieee->tx_pending.txb = NULL;
2242 void ieee80211_reset_queue(struct ieee80211_device *ieee)
2244 unsigned long flags;
2246 spin_lock_irqsave(&ieee->lock,flags);
2247 init_mgmt_queue(ieee);
2248 if (ieee->tx_pending.txb){
2249 ieee80211_txb_free(ieee->tx_pending.txb);
2250 ieee->tx_pending.txb = NULL;
2252 ieee->queue_stop = 0;
2253 spin_unlock_irqrestore(&ieee->lock,flags);
2257 void ieee80211_wake_queue(struct ieee80211_device *ieee)
2260 unsigned long flags;
2261 struct sk_buff *skb;
2262 struct ieee80211_hdr_3addr *header;
2264 spin_lock_irqsave(&ieee->lock,flags);
2265 if (! ieee->queue_stop) goto exit;
2267 ieee->queue_stop = 0;
2269 if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){
2270 while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
2272 header = (struct ieee80211_hdr_3addr *) skb->data;
2274 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2276 if (ieee->seq_ctrl[0] == 0xFFF)
2277 ieee->seq_ctrl[0] = 0;
2279 ieee->seq_ctrl[0]++;
2281 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
2282 //dev_kfree_skb_any(skb);//edit by thomas
2285 if (!ieee->queue_stop && ieee->tx_pending.txb)
2286 ieee80211_resume_tx(ieee);
2288 if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){
2289 ieee->softmac_stats.swtxawake++;
2290 netif_wake_queue(ieee->dev);
2294 spin_unlock_irqrestore(&ieee->lock,flags);
2298 void ieee80211_stop_queue(struct ieee80211_device *ieee)
2300 //unsigned long flags;
2301 //spin_lock_irqsave(&ieee->lock,flags);
2303 if (! netif_queue_stopped(ieee->dev)){
2304 netif_stop_queue(ieee->dev);
2305 ieee->softmac_stats.swtxstop++;
2307 ieee->queue_stop = 1;
2308 //spin_unlock_irqrestore(&ieee->lock,flags);
2313 inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
2316 get_random_bytes(ieee->current_network.bssid, ETH_ALEN);
2318 /* an IBSS cell address must have the two less significant
2319 * bits of the first byte = 2
2321 ieee->current_network.bssid[0] &= ~0x01;
2322 ieee->current_network.bssid[0] |= 0x02;
2325 /* called in user context only */
2326 void ieee80211_start_master_bss(struct ieee80211_device *ieee)
2330 if (ieee->current_network.ssid_len == 0){
2331 strncpy(ieee->current_network.ssid,
2332 IEEE80211_DEFAULT_TX_ESSID,
2335 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2339 memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
2341 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2342 ieee->state = IEEE80211_LINKED;
2343 ieee->link_change(ieee->dev);
2344 notify_wx_assoc_event(ieee);
2346 if (ieee->data_hard_resume)
2347 ieee->data_hard_resume(ieee->dev);
2349 netif_carrier_on(ieee->dev);
2352 void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
2356 if (ieee->data_hard_resume)
2357 ieee->data_hard_resume(ieee->dev);
2359 netif_carrier_on(ieee->dev);
2362 void ieee80211_start_ibss_wq(struct work_struct *work)
2365 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2366 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
2367 /* iwconfig mode ad-hoc will schedule this and return
2368 * on the other hand this will block further iwconfig SET
2369 * operations because of the wx_sem hold.
2370 * Anyway some most set operations set a flag to speed-up
2371 * (abort) this wq (when syncro scanning) before sleeping
2374 if(!ieee->proto_started){
2375 printk("==========oh driver down return\n");
2378 down(&ieee->wx_sem);
2380 if (ieee->current_network.ssid_len == 0){
2381 strcpy(ieee->current_network.ssid,IEEE80211_DEFAULT_TX_ESSID);
2382 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2386 /* check if we have this cell in our network list */
2387 ieee80211_softmac_check_all_nets(ieee);
2390 #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.
2391 // if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK))
2392 if (ieee->state == IEEE80211_NOLINK)
2393 ieee->current_network.channel = 6;
2395 /* if not then the state is not linked. Maybe the user swithced to
2396 * ad-hoc mode just after being in monitor mode, or just after
2397 * being very few time in managed mode (so the card have had no
2398 * time to scan all the chans..) or we have just run up the iface
2399 * after setting ad-hoc mode. So we have to give another try..
2400 * Here, in ibss mode, should be safe to do this without extra care
2401 * (in bss mode we had to make sure no-one tryed to associate when
2402 * we had just checked the ieee->state and we was going to start the
2403 * scan) beacause in ibss mode the ieee80211_new_net function, when
2404 * finds a good net, just set the ieee->state to IEEE80211_LINKED,
2405 * so, at worst, we waste a bit of time to initiate an unneeded syncro
2406 * scan, that will stop at the first round because it sees the state
2409 if (ieee->state == IEEE80211_NOLINK)
2410 ieee80211_start_scan_syncro(ieee);
2412 /* the network definitively is not here.. create a new cell */
2413 if (ieee->state == IEEE80211_NOLINK){
2414 printk("creating new IBSS cell\n");
2416 ieee80211_randomize_cell(ieee);
2418 if(ieee->modulation & IEEE80211_CCK_MODULATION){
2420 ieee->current_network.rates_len = 4;
2422 ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
2423 ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
2424 ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
2425 ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
2428 ieee->current_network.rates_len = 0;
2430 if(ieee->modulation & IEEE80211_OFDM_MODULATION){
2431 ieee->current_network.rates_ex_len = 8;
2433 ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
2434 ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
2435 ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
2436 ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
2437 ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
2438 ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
2439 ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
2440 ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
2444 ieee->current_network.rates_ex_len = 0;
2448 // By default, WMM function will be disabled in IBSS mode
2449 ieee->current_network.QoS_Enable = 0;
2450 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2451 ieee->current_network.atim_window = 0;
2452 ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
2453 if(ieee->short_slot)
2454 ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
2458 ieee->state = IEEE80211_LINKED;
2460 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2461 ieee->link_change(ieee->dev);
2463 notify_wx_assoc_event(ieee);
2465 ieee80211_start_send_beacons(ieee);
2467 if (ieee->data_hard_resume)
2468 ieee->data_hard_resume(ieee->dev);
2469 netif_carrier_on(ieee->dev);
2474 inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
2476 queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150);
2479 /* this is called only in user context, with wx_sem held */
2480 void ieee80211_start_bss(struct ieee80211_device *ieee)
2482 unsigned long flags;
2483 #ifdef ENABLE_DOT11D
2485 // Ref: 802.11d 11.1.3.3
2486 // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
2488 if(IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
2490 if(! ieee->bGlobalDomain)
2496 /* check if we have already found the net we
2497 * are interested in (if any).
2498 * if not (we are disassociated and we are not
2499 * in associating / authenticating phase) start the background scanning.
2501 ieee80211_softmac_check_all_nets(ieee);
2503 /* ensure no-one start an associating process (thus setting
2504 * the ieee->state to ieee80211_ASSOCIATING) while we
2505 * have just cheked it and we are going to enable scan.
2506 * The ieee80211_new_net function is always called with
2507 * lock held (from both ieee80211_softmac_check_all_nets and
2508 * the rx path), so we cannot be in the middle of such function
2510 spin_lock_irqsave(&ieee->lock, flags);
2512 if (ieee->state == IEEE80211_NOLINK){
2513 ieee->actscanning = true;
2514 ieee80211_start_scan(ieee);
2516 spin_unlock_irqrestore(&ieee->lock, flags);
2519 /* called only in userspace context */
2520 void ieee80211_disassociate(struct ieee80211_device *ieee)
2524 netif_carrier_off(ieee->dev);
2525 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
2526 ieee80211_reset_queue(ieee);
2528 if (ieee->data_hard_stop)
2529 ieee->data_hard_stop(ieee->dev);
2530 #ifdef ENABLE_DOT11D
2531 if(IS_DOT11D_ENABLE(ieee))
2534 ieee->state = IEEE80211_NOLINK;
2535 ieee->is_set_key = false;
2536 ieee->link_change(ieee->dev);
2537 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2538 notify_wx_assoc_event(ieee);
2541 void ieee80211_associate_retry_wq(struct work_struct *work)
2543 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2544 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
2545 unsigned long flags;
2547 down(&ieee->wx_sem);
2548 if(!ieee->proto_started)
2551 if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
2554 /* until we do not set the state to IEEE80211_NOLINK
2555 * there are no possibility to have someone else trying
2556 * to start an association procdure (we get here with
2557 * ieee->state = IEEE80211_ASSOCIATING).
2558 * When we set the state to IEEE80211_NOLINK it is possible
2559 * that the RX path run an attempt to associate, but
2560 * both ieee80211_softmac_check_all_nets and the
2561 * RX path works with ieee->lock held so there are no
2562 * problems. If we are still disassociated then start a scan.
2563 * the lock here is necessary to ensure no one try to start
2564 * an association procedure when we have just checked the
2565 * state and we are going to start the scan.
2567 ieee->state = IEEE80211_NOLINK;
2569 ieee80211_softmac_check_all_nets(ieee);
2571 spin_lock_irqsave(&ieee->lock, flags);
2573 if(ieee->state == IEEE80211_NOLINK)
2574 ieee80211_start_scan(ieee);
2576 spin_unlock_irqrestore(&ieee->lock, flags);
2582 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
2584 u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
2586 struct sk_buff *skb;
2587 struct ieee80211_probe_response *b;
2589 skb = ieee80211_probe_resp(ieee, broadcast_addr);
2594 b = (struct ieee80211_probe_response *) skb->data;
2595 b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
2601 struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
2603 struct sk_buff *skb;
2604 struct ieee80211_probe_response *b;
2606 skb = ieee80211_get_beacon_(ieee);
2610 b = (struct ieee80211_probe_response *) skb->data;
2611 b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2613 if (ieee->seq_ctrl[0] == 0xFFF)
2614 ieee->seq_ctrl[0] = 0;
2616 ieee->seq_ctrl[0]++;
2621 void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
2623 ieee->sync_scan_hurryup = 1;
2624 down(&ieee->wx_sem);
2625 ieee80211_stop_protocol(ieee);
2630 void ieee80211_stop_protocol(struct ieee80211_device *ieee)
2632 if (!ieee->proto_started)
2635 ieee->proto_started = 0;
2637 ieee80211_stop_send_beacons(ieee);
2638 del_timer_sync(&ieee->associate_timer);
2639 cancel_delayed_work(&ieee->associate_retry_wq);
2640 cancel_delayed_work(&ieee->start_ibss_wq);
2641 ieee80211_stop_scan(ieee);
2643 ieee80211_disassociate(ieee);
2644 RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
2647 void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
2649 ieee->sync_scan_hurryup = 0;
2650 down(&ieee->wx_sem);
2651 ieee80211_start_protocol(ieee);
2655 void ieee80211_start_protocol(struct ieee80211_device *ieee)
2659 if (ieee->proto_started)
2662 ieee->proto_started = 1;
2664 if (ieee->current_network.channel == 0){
2667 if (ch > MAX_CHANNEL_NUMBER)
2668 return; /* no channel found */
2669 #ifdef ENABLE_DOT11D
2670 }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
2672 }while(!ieee->channel_map[ch]);
2674 ieee->current_network.channel = ch;
2677 if (ieee->current_network.beacon_interval == 0)
2678 ieee->current_network.beacon_interval = 100;
2679 // printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);
2680 // ieee->set_chan(ieee->dev,ieee->current_network.channel);
2682 for(i = 0; i < 17; i++) {
2683 ieee->last_rxseq_num[i] = -1;
2684 ieee->last_rxfrag_num[i] = -1;
2685 ieee->last_packet_time[i] = 0;
2688 ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
2691 /* if the user set the MAC of the ad-hoc cell and then
2692 * switch to managed mode, shall we make sure that association
2693 * attempts does not fail just because the user provide the essid
2694 * and the nic is still checking for the AP MAC ??
2696 if (ieee->iw_mode == IW_MODE_INFRA)
2697 ieee80211_start_bss(ieee);
2699 else if (ieee->iw_mode == IW_MODE_ADHOC)
2700 ieee80211_start_ibss(ieee);
2702 else if (ieee->iw_mode == IW_MODE_MASTER)
2703 ieee80211_start_master_bss(ieee);
2705 else if(ieee->iw_mode == IW_MODE_MONITOR)
2706 ieee80211_start_monitor_mode(ieee);
2710 #define DRV_NAME "Ieee80211"
2711 void ieee80211_softmac_init(struct ieee80211_device *ieee)
2714 memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
2716 ieee->state = IEEE80211_NOLINK;
2717 ieee->sync_scan_hurryup = 0;
2718 for(i = 0; i < 5; i++) {
2719 ieee->seq_ctrl[i] = 0;
2721 #ifdef ENABLE_DOT11D
2722 ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
2723 if (!ieee->pDot11dInfo)
2724 IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
2725 memset(ieee->pDot11dInfo, 0, sizeof(RT_DOT11D_INFO));
2727 //added for AP roaming
2728 ieee->LinkDetectInfo.SlotNum = 2;
2729 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
2730 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
2733 ieee->queue_stop = 0;
2735 ieee->softmac_features = 0; //so IEEE2100-like driver are happy
2738 ieee->proto_started = 0;
2739 ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
2741 ieee->ps = IEEE80211_PS_DISABLED;
2742 ieee->sta_sleep = 0;
2743 ieee->Regdot11HTOperationalRateSet[0]= 0xff;//support MCS 0~7
2744 ieee->Regdot11HTOperationalRateSet[1]= 0xff;//support MCS 8~15
2745 ieee->Regdot11HTOperationalRateSet[4]= 0x01;
2747 ieee->actscanning = false;
2748 ieee->beinretry = false;
2749 ieee->is_set_key = false;
2750 init_mgmt_queue(ieee);
2752 ieee->sta_edca_param[0] = 0x0000A403;
2753 ieee->sta_edca_param[1] = 0x0000A427;
2754 ieee->sta_edca_param[2] = 0x005E4342;
2755 ieee->sta_edca_param[3] = 0x002F3262;
2756 ieee->aggregation = true;
2757 ieee->enable_rx_imm_BA = 1;
2758 ieee->tx_pending.txb = NULL;
2760 init_timer(&ieee->associate_timer);
2761 ieee->associate_timer.data = (unsigned long)ieee;
2762 ieee->associate_timer.function = ieee80211_associate_abort_cb;
2764 init_timer(&ieee->beacon_timer);
2765 ieee->beacon_timer.data = (unsigned long) ieee;
2766 ieee->beacon_timer.function = ieee80211_send_beacon_cb;
2768 #ifdef PF_SYNCTHREAD
2769 ieee->wq = create_workqueue(DRV_NAME,0);
2771 ieee->wq = create_workqueue(DRV_NAME);
2774 INIT_DELAYED_WORK(&ieee->start_ibss_wq,ieee80211_start_ibss_wq);
2775 INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
2776 INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
2777 INIT_DELAYED_WORK(&ieee->softmac_scan_wq,ieee80211_softmac_scan_wq);
2778 INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
2779 INIT_WORK(&ieee->wx_sync_scan_wq,ieee80211_wx_sync_scan_wq);
2782 sema_init(&ieee->wx_sem, 1);
2783 sema_init(&ieee->scan_sem, 1);
2785 spin_lock_init(&ieee->mgmt_tx_lock);
2786 spin_lock_init(&ieee->beacon_lock);
2788 tasklet_init(&ieee->ps_task,
2789 (void(*)(unsigned long)) ieee80211_sta_ps,
2790 (unsigned long)ieee);
2794 void ieee80211_softmac_free(struct ieee80211_device *ieee)
2796 down(&ieee->wx_sem);
2797 #ifdef ENABLE_DOT11D
2798 if(NULL != ieee->pDot11dInfo)
2800 kfree(ieee->pDot11dInfo);
2801 ieee->pDot11dInfo = NULL;
2804 del_timer_sync(&ieee->associate_timer);
2806 cancel_delayed_work(&ieee->associate_retry_wq);
2807 destroy_workqueue(ieee->wq);
2812 /********************************************************
2813 * Start of WPA code. *
2814 * this is stolen from the ipw2200 driver *
2815 ********************************************************/
2818 static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
2820 /* This is called when wpa_supplicant loads and closes the driver
2822 printk("%s WPA\n",value ? "enabling" : "disabling");
2823 ieee->wpa_enabled = value;
2828 void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len)
2830 /* make sure WPA is enabled */
2831 ieee80211_wpa_enable(ieee, 1);
2833 ieee80211_disassociate(ieee);
2837 static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
2843 case IEEE_MLME_STA_DEAUTH:
2847 case IEEE_MLME_STA_DISASSOC:
2848 ieee80211_disassociate(ieee);
2852 printk("Unknown MLME request: %d\n", command);
2860 static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
2861 struct ieee_param *param, int plen)
2865 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
2866 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
2869 if (param->u.wpa_ie.len) {
2870 buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
2874 memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
2875 kfree(ieee->wpa_ie);
2877 ieee->wpa_ie_len = param->u.wpa_ie.len;
2879 kfree(ieee->wpa_ie);
2880 ieee->wpa_ie = NULL;
2881 ieee->wpa_ie_len = 0;
2884 ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
2888 #define AUTH_ALG_OPEN_SYSTEM 0x1
2889 #define AUTH_ALG_SHARED_KEY 0x2
2891 static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
2894 struct ieee80211_security sec = {
2895 .flags = SEC_AUTH_MODE,
2899 if (value & AUTH_ALG_SHARED_KEY) {
2900 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
2902 ieee->auth_mode = 1;
2903 } else if (value & AUTH_ALG_OPEN_SYSTEM){
2904 sec.auth_mode = WLAN_AUTH_OPEN;
2906 ieee->auth_mode = 0;
2908 else if (value & IW_AUTH_ALG_LEAP){
2909 sec.auth_mode = WLAN_AUTH_LEAP;
2911 ieee->auth_mode = 2;
2915 if (ieee->set_security)
2916 ieee->set_security(ieee->dev, &sec);
2918 // ret = -EOPNOTSUPP;
2923 static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
2926 unsigned long flags;
2929 case IEEE_PARAM_WPA_ENABLED:
2930 ret = ieee80211_wpa_enable(ieee, value);
2933 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2934 ieee->tkip_countermeasures=value;
2937 case IEEE_PARAM_DROP_UNENCRYPTED: {
2940 * wpa_supplicant calls set_wpa_enabled when the driver
2941 * is loaded and unloaded, regardless of if WPA is being
2942 * used. No other calls are made which can be used to
2943 * determine if encryption will be used or not prior to
2944 * association being expected. If encryption is not being
2945 * used, drop_unencrypted is set to false, else true -- we
2946 * can use this to determine if the CAP_PRIVACY_ON bit should
2949 struct ieee80211_security sec = {
2950 .flags = SEC_ENABLED,
2953 ieee->drop_unencrypted = value;
2954 /* We only change SEC_LEVEL for open mode. Others
2955 * are set by ipw_wpa_set_encryption.
2958 sec.flags |= SEC_LEVEL;
2959 sec.level = SEC_LEVEL_0;
2962 sec.flags |= SEC_LEVEL;
2963 sec.level = SEC_LEVEL_1;
2965 if (ieee->set_security)
2966 ieee->set_security(ieee->dev, &sec);
2970 case IEEE_PARAM_PRIVACY_INVOKED:
2971 ieee->privacy_invoked=value;
2974 case IEEE_PARAM_AUTH_ALGS:
2975 ret = ieee80211_wpa_set_auth_algs(ieee, value);
2978 case IEEE_PARAM_IEEE_802_1X:
2979 ieee->ieee802_1x=value;
2981 case IEEE_PARAM_WPAX_SELECT:
2982 // added for WPA2 mixed mode
2983 spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
2984 ieee->wpax_type_set = 1;
2985 ieee->wpax_type_notify = value;
2986 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
2990 printk("Unknown WPA param: %d\n",name);
2997 /* implementation borrowed from hostap driver */
2999 static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
3000 struct ieee_param *param, int param_len)
3004 struct ieee80211_crypto_ops *ops;
3005 struct ieee80211_crypt_data **crypt;
3007 struct ieee80211_security sec = {
3011 param->u.crypt.err = 0;
3012 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
3015 (int) ((char *) param->u.crypt.key - (char *) param) +
3016 param->u.crypt.key_len) {
3017 printk("Len mismatch %d, %d\n", param_len,
3018 param->u.crypt.key_len);
3021 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3022 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3023 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3024 if (param->u.crypt.idx >= WEP_KEYS)
3026 crypt = &ieee->crypt[param->u.crypt.idx];
3031 if (strcmp(param->u.crypt.alg, "none") == 0) {
3036 sec.level = SEC_LEVEL_0;
3037 sec.flags |= SEC_ENABLED | SEC_LEVEL;
3038 ieee80211_crypt_delayed_deinit(ieee, crypt);
3045 sec.flags |= SEC_ENABLED;
3047 /* IPW HW cannot build TKIP MIC, host decryption still needed. */
3048 if (!(ieee->host_encrypt || ieee->host_decrypt) &&
3049 strcmp(param->u.crypt.alg, "TKIP"))
3050 goto skip_host_crypt;
3052 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3053 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
3054 request_module("ieee80211_crypt_wep");
3055 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3056 //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
3057 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
3058 request_module("ieee80211_crypt_tkip");
3059 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3060 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
3061 request_module("ieee80211_crypt_ccmp");
3062 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3065 printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
3066 param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
3071 if (*crypt == NULL || (*crypt)->ops != ops) {
3072 struct ieee80211_crypt_data *new_crypt;
3074 ieee80211_crypt_delayed_deinit(ieee, crypt);
3076 new_crypt = (struct ieee80211_crypt_data *)
3077 kmalloc(sizeof(*new_crypt), GFP_KERNEL);
3078 if (new_crypt == NULL) {
3082 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
3083 new_crypt->ops = ops;
3084 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
3086 new_crypt->ops->init(param->u.crypt.idx);
3088 if (new_crypt->priv == NULL) {
3090 param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
3098 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
3099 (*crypt)->ops->set_key(param->u.crypt.key,
3100 param->u.crypt.key_len, param->u.crypt.seq,
3101 (*crypt)->priv) < 0) {
3102 printk("key setting failed\n");
3103 param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
3109 if (param->u.crypt.set_tx) {
3110 ieee->tx_keyidx = param->u.crypt.idx;
3111 sec.active_key = param->u.crypt.idx;
3112 sec.flags |= SEC_ACTIVE_KEY;
3114 sec.flags &= ~SEC_ACTIVE_KEY;
3116 if (param->u.crypt.alg != NULL) {
3117 memcpy(sec.keys[param->u.crypt.idx],
3119 param->u.crypt.key_len);
3120 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
3121 sec.flags |= (1 << param->u.crypt.idx);
3123 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3124 sec.flags |= SEC_LEVEL;
3125 sec.level = SEC_LEVEL_1;
3126 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3127 sec.flags |= SEC_LEVEL;
3128 sec.level = SEC_LEVEL_2;
3129 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3130 sec.flags |= SEC_LEVEL;
3131 sec.level = SEC_LEVEL_3;
3135 if (ieee->set_security)
3136 ieee->set_security(ieee->dev, &sec);
3138 /* Do not reset port if card is in Managed mode since resetting will
3139 * generate new IEEE 802.11 authentication which may end up in looping
3140 * with IEEE 802.1X. If your hardware requires a reset after WEP
3141 * configuration (for example... Prism2), implement the reset_port in
3142 * the callbacks structures used to initialize the 802.11 stack. */
3143 if (ieee->reset_on_keychange &&
3144 ieee->iw_mode != IW_MODE_INFRA &&
3146 ieee->reset_port(ieee->dev)) {
3147 printk("reset_port failed\n");
3148 param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
3155 inline struct sk_buff *ieee80211_disassociate_skb(
3156 struct ieee80211_network *beacon,
3157 struct ieee80211_device *ieee,
3160 struct sk_buff *skb;
3161 struct ieee80211_disassoc *disass;
3163 skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc));
3167 disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc));
3168 disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
3169 disass->header.duration_id = 0;
3171 memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
3172 memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
3173 memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
3175 disass->reason = asRsn;
3182 struct ieee80211_device *ieee,
3187 struct ieee80211_network *beacon = &ieee->current_network;
3188 struct sk_buff *skb;
3189 skb = ieee80211_disassociate_skb(beacon,ieee,asRsn);
3191 softmac_mgmt_xmit(skb, ieee);
3192 //dev_kfree_skb_any(skb);//edit by thomas
3196 int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
3198 struct ieee_param *param;
3201 down(&ieee->wx_sem);
3202 //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
3204 if (p->length < sizeof(struct ieee_param) || !p->pointer){
3209 param = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
3214 if (copy_from_user(param, p->pointer, p->length)) {
3220 switch (param->cmd) {
3222 case IEEE_CMD_SET_WPA_PARAM:
3223 ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
3224 param->u.wpa_param.value);
3227 case IEEE_CMD_SET_WPA_IE:
3228 ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
3231 case IEEE_CMD_SET_ENCRYPTION:
3232 ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
3236 ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
3237 param->u.mlme.reason_code);
3241 printk("Unknown WPA supplicant request: %d\n",param->cmd);
3246 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
3256 void notify_wx_assoc_event(struct ieee80211_device *ieee)
3258 union iwreq_data wrqu;
3259 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3260 if (ieee->state == IEEE80211_LINKED)
3261 memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
3263 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
3264 wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
3267 EXPORT_SYMBOL(ieee80211_get_beacon);
3268 EXPORT_SYMBOL(ieee80211_wake_queue);
3269 EXPORT_SYMBOL(ieee80211_stop_queue);
3270 EXPORT_SYMBOL(ieee80211_reset_queue);
3271 EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
3272 EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
3273 EXPORT_SYMBOL(ieee80211_is_shortslot);
3274 EXPORT_SYMBOL(ieee80211_is_54g);
3275 EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
3276 EXPORT_SYMBOL(ieee80211_ps_tx_ack);
3277 EXPORT_SYMBOL(ieee80211_softmac_xmit);
3278 EXPORT_SYMBOL(ieee80211_stop_send_beacons);
3279 EXPORT_SYMBOL(notify_wx_assoc_event);
3280 EXPORT_SYMBOL(SendDisassociation);
3281 EXPORT_SYMBOL(ieee80211_disassociate);
3282 EXPORT_SYMBOL(ieee80211_start_send_beacons);
3283 EXPORT_SYMBOL(ieee80211_stop_scan);
3284 EXPORT_SYMBOL(ieee80211_send_probe_requests);
3285 EXPORT_SYMBOL(ieee80211_softmac_scan_syncro);
3286 EXPORT_SYMBOL(ieee80211_start_scan_syncro);
3287 //EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame);