1 /* IEEE 802.11 SoftMAC layer
2 * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
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 <asm/uaccess.h>
23 #include <linux/etherdevice.h>
27 short ieee80211_is_54g(const struct ieee80211_network *net)
29 return (net->rates_ex_len > 0) || (net->rates_len > 4);
31 EXPORT_SYMBOL(ieee80211_is_54g);
33 short ieee80211_is_shortslot(const struct ieee80211_network *net)
35 return net->capability & WLAN_CAPABILITY_SHORT_SLOT;
37 EXPORT_SYMBOL(ieee80211_is_shortslot);
39 /* returns the total length needed for pleacing the RATE MFIE
40 * tag and the EXTENDED RATE MFIE tag if needed.
41 * It encludes two bytes per tag for the tag itself and its len
43 static unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
45 unsigned int rate_len = 0;
47 if (ieee->modulation & IEEE80211_CCK_MODULATION)
48 rate_len = IEEE80211_CCK_RATE_LEN + 2;
50 if (ieee->modulation & IEEE80211_OFDM_MODULATION)
52 rate_len += IEEE80211_OFDM_RATE_LEN + 2;
57 /* pleace the MFIE rate, tag to the memory (double) poined.
58 * Then it updates the pointer so that
59 * it points after the new MFIE tag added.
61 static void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
65 if (ieee->modulation & IEEE80211_CCK_MODULATION){
66 *tag++ = MFIE_TYPE_RATES;
68 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
69 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
70 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
71 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
74 /* We may add an option for custom rates that specific HW might support */
78 static void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
82 if (ieee->modulation & IEEE80211_OFDM_MODULATION){
84 *tag++ = MFIE_TYPE_RATES_EX;
86 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
87 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
88 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
89 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
90 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
91 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
92 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
93 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
97 /* We may add an option for custom rates that specific HW might support */
102 static void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p)
106 *tag++ = MFIE_TYPE_GENERIC; //0
115 if(ieee->current_network.wmm_info & 0x80) {
116 *tag++ = 0x0f|MAX_SP_Len;
127 static void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p)
131 *tag++ = MFIE_TYPE_GENERIC; //0
142 printk(KERN_ALERT "This is enable turbo mode IE process\n");
146 static void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
149 nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
152 * if the queue is full but we have newer frames then
153 * just overwrites the oldest.
155 * if (nh == ieee->mgmt_queue_tail)
158 ieee->mgmt_queue_head = nh;
159 ieee->mgmt_queue_ring[nh] = skb;
164 static struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
168 if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
171 ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
173 ieee->mgmt_queue_tail =
174 (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
179 static void init_mgmt_queue(struct ieee80211_device *ieee)
181 ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
184 static u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee)
186 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
189 // 2008/01/25 MH For broadcom, MGNT frame set as OFDM 6M.
190 if(pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M)
193 rate = ieee->basic_rate & 0x7f;
196 // 2005.01.26, by rcnjko.
197 if(ieee->mode == IEEE_A||
198 ieee->mode== IEEE_N_5G||
199 (ieee->mode== IEEE_N_24G&&!pHTInfo->bCurSuppCCK))
206 // Data rate of ProbeReq is already decided. Annie, 2005-03-31
207 if( pMgntInfo->bScanInProgress || (pMgntInfo->bDualModeScanStep!=0) )
209 if(pMgntInfo->dot11CurrentWirelessMode==WIRELESS_MODE_A)
219 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
221 inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
224 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
225 struct ieee80211_hdr_3addr *header=
226 (struct ieee80211_hdr_3addr *) skb->data;
228 cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8);
229 spin_lock_irqsave(&ieee->lock, flags);
231 /* called with 2nd param 0, no mgmt lock required */
232 ieee80211_sta_wakeup(ieee, 0);
234 tcb_desc->queue_index = MGNT_QUEUE;
235 tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
236 tcb_desc->RATRIndex = 7;
237 tcb_desc->bTxDisableRateFallBack = 1;
238 tcb_desc->bTxUseDriverAssingedRate = 1;
241 if(ieee->queue_stop){
242 enqueue_mgmt(ieee, skb);
244 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
246 if (ieee->seq_ctrl[0] == 0xFFF)
247 ieee->seq_ctrl[0] = 0;
251 /* avoid watchdog triggers */
252 ieee->dev->trans_start = jiffies;
253 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
254 //dev_kfree_skb_any(skb);//edit by thomas
257 spin_unlock_irqrestore(&ieee->lock, flags);
259 spin_unlock_irqrestore(&ieee->lock, flags);
260 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
262 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
264 if (ieee->seq_ctrl[0] == 0xFFF)
265 ieee->seq_ctrl[0] = 0;
269 /* check whether the managed packet queued greater than 5 */
270 if(!ieee->check_nic_enough_desc(ieee->dev,tcb_desc->queue_index)||\
271 (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)||\
272 (ieee->queue_stop) ) {
273 /* insert the skb packet to the management queue */
274 /* as for the completion function, it does not need
275 * to check it any more.
277 printk("%s():insert to waitqueue!\n",__func__);
278 skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb);
280 //printk("TX packet!\n");
281 ieee->softmac_hard_start_xmit(skb, ieee->dev);
282 //dev_kfree_skb_any(skb);//edit by thomas
284 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
288 inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
291 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
292 struct ieee80211_hdr_3addr *header =
293 (struct ieee80211_hdr_3addr *) skb->data;
298 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
300 if (ieee->seq_ctrl[0] == 0xFFF)
301 ieee->seq_ctrl[0] = 0;
305 /* avoid watchdog triggers */
306 ieee->dev->trans_start = jiffies;
307 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
311 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
313 if (ieee->seq_ctrl[0] == 0xFFF)
314 ieee->seq_ctrl[0] = 0;
318 ieee->softmac_hard_start_xmit(skb, ieee->dev);
321 //dev_kfree_skb_any(skb);//edit by thomas
324 inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
326 unsigned int len, rate_len;
329 struct ieee80211_probe_request *req;
331 len = ieee->current_network.ssid_len;
333 rate_len = ieee80211_MFIE_rate_len(ieee);
335 skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
336 2 + len + rate_len + ieee->tx_headroom);
340 skb_reserve(skb, ieee->tx_headroom);
342 req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
343 req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
344 req->header.duration_id = 0; //FIXME: is this OK ?
346 memset(req->header.addr1, 0xff, ETH_ALEN);
347 memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
348 memset(req->header.addr3, 0xff, ETH_ALEN);
350 tag = (u8 *) skb_put(skb,len+2+rate_len);
352 *tag++ = MFIE_TYPE_SSID;
354 memcpy(tag, ieee->current_network.ssid, len);
357 ieee80211_MFIE_Brate(ieee,&tag);
358 ieee80211_MFIE_Grate(ieee,&tag);
362 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
364 static void ieee80211_send_beacon(struct ieee80211_device *ieee)
369 //unsigned long flags;
370 skb = ieee80211_get_beacon_(ieee);
373 softmac_mgmt_xmit(skb, ieee);
374 ieee->softmac_stats.tx_beacons++;
375 //dev_kfree_skb_any(skb);//edit by thomas
377 // ieee->beacon_timer.expires = jiffies +
378 // (MSECS( ieee->current_network.beacon_interval -5));
380 //spin_lock_irqsave(&ieee->beacon_lock,flags);
381 if(ieee->beacon_txing && ieee->ieee_up){
382 // if(!timer_pending(&ieee->beacon_timer))
383 // add_timer(&ieee->beacon_timer);
384 mod_timer(&ieee->beacon_timer,jiffies+(MSECS(ieee->current_network.beacon_interval-5)));
386 //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
390 static void ieee80211_send_beacon_cb(unsigned long _ieee)
392 struct ieee80211_device *ieee =
393 (struct ieee80211_device *) _ieee;
396 spin_lock_irqsave(&ieee->beacon_lock, flags);
397 ieee80211_send_beacon(ieee);
398 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
402 static void ieee80211_send_probe(struct ieee80211_device *ieee)
406 skb = ieee80211_probe_req(ieee);
408 softmac_mgmt_xmit(skb, ieee);
409 ieee->softmac_stats.tx_probe_rq++;
410 //dev_kfree_skb_any(skb);//edit by thomas
414 static void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
416 if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){
417 ieee80211_send_probe(ieee);
418 ieee80211_send_probe(ieee);
421 EXPORT_SYMBOL(ieee80211_send_probe_requests);
423 /* this performs syncro scan blocking the caller until all channels
424 * in the allowed channel map has been checked.
426 void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
429 u8 channel_map[MAX_CHANNEL_NUMBER+1];
430 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
431 down(&ieee->scan_sem);
438 if (ch > MAX_CHANNEL_NUMBER)
439 goto out; /* scan completed */
440 }while(!channel_map[ch]);
442 /* this function can be called in two situations
443 * 1- We have switched to ad-hoc mode and we are
444 * performing a complete syncro scan before conclude
445 * there are no interesting cell and to create a
446 * new one. In this case the link state is
447 * IEEE80211_NOLINK until we found an interesting cell.
448 * If so the ieee8021_new_net, called by the RX path
449 * will set the state to IEEE80211_LINKED, so we stop
451 * 2- We are linked and the root uses run iwlist scan.
452 * So we switch to IEEE80211_LINKED_SCANNING to remember
453 * that we are still logically linked (not interested in
454 * new network events, despite for updating the net list,
455 * but we are temporarly 'unlinked' as the driver shall
456 * not filter RX frames and the channel is changing.
457 * So the only situation in witch are interested is to check
458 * if the state become LINKED because of the #1 situation
461 if (ieee->state == IEEE80211_LINKED)
463 ieee->set_chan(ieee->dev, ch);
464 if(channel_map[ch] == 1)
465 ieee80211_send_probe_requests(ieee);
467 /* this prevent excessive time wait when we
468 * need to wait for a syncro scan to end..
470 if(ieee->state < IEEE80211_LINKED)
473 if (ieee->sync_scan_hurryup)
477 msleep_interruptible_rsl(IEEE80211_SOFTMAC_SCAN_TIME);
481 if(ieee->state < IEEE80211_LINKED){
482 ieee->actscanning = false;
486 ieee->sync_scan_hurryup = 0;
487 if(IS_DOT11D_ENABLE(ieee))
488 DOT11D_ScanComplete(ieee);
492 EXPORT_SYMBOL(ieee80211_softmac_scan_syncro);
494 static void ieee80211_softmac_scan_wq(struct work_struct *work)
496 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
497 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
498 static short watchdog;
499 u8 channel_map[MAX_CHANNEL_NUMBER+1];
500 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
503 down(&ieee->scan_sem);
505 ieee->current_network.channel =
506 (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
507 if (watchdog++ > MAX_CHANNEL_NUMBER)
509 //if current channel is not in channel map, set to default channel.
510 if (!channel_map[ieee->current_network.channel]) {
511 ieee->current_network.channel = 6;
512 goto out; /* no good chans */
515 }while(!channel_map[ieee->current_network.channel]);
516 if (ieee->scanning == 0 )
518 ieee->set_chan(ieee->dev, ieee->current_network.channel);
519 if(channel_map[ieee->current_network.channel] == 1)
520 ieee80211_send_probe_requests(ieee);
523 queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
528 if(IS_DOT11D_ENABLE(ieee))
529 DOT11D_ScanComplete(ieee);
530 ieee->actscanning = false;
538 static void ieee80211_beacons_start(struct ieee80211_device *ieee)
541 spin_lock_irqsave(&ieee->beacon_lock,flags);
543 ieee->beacon_txing = 1;
544 ieee80211_send_beacon(ieee);
546 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
549 static void ieee80211_beacons_stop(struct ieee80211_device *ieee)
553 spin_lock_irqsave(&ieee->beacon_lock, flags);
555 ieee->beacon_txing = 0;
556 del_timer_sync(&ieee->beacon_timer);
558 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
563 void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
565 if(ieee->stop_send_beacons)
566 ieee->stop_send_beacons(ieee->dev);
567 if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
568 ieee80211_beacons_stop(ieee);
570 EXPORT_SYMBOL(ieee80211_stop_send_beacons);
572 void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
574 if(ieee->start_send_beacons)
575 ieee->start_send_beacons(ieee->dev, ieee->basic_rate);
576 if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
577 ieee80211_beacons_start(ieee);
579 EXPORT_SYMBOL(ieee80211_start_send_beacons);
581 static void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
583 // unsigned long flags;
585 //ieee->sync_scan_hurryup = 1;
587 down(&ieee->scan_sem);
588 // spin_lock_irqsave(&ieee->lock, flags);
590 if (ieee->scanning == 1){
593 cancel_delayed_work(&ieee->softmac_scan_wq);
596 // spin_unlock_irqrestore(&ieee->lock, flags);
600 void ieee80211_stop_scan(struct ieee80211_device *ieee)
602 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
603 ieee80211_softmac_stop_scan(ieee);
605 ieee->stop_scan(ieee->dev);
607 EXPORT_SYMBOL(ieee80211_stop_scan);
609 /* called with ieee->lock held */
610 static void ieee80211_start_scan(struct ieee80211_device *ieee)
612 if(IS_DOT11D_ENABLE(ieee) )
614 if(IS_COUNTRY_IE_VALID(ieee))
616 RESET_CIE_WATCHDOG(ieee);
619 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
620 if (ieee->scanning == 0){
622 queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0);
625 ieee->start_scan(ieee->dev);
629 /* called with wx_sem held */
630 void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
632 if(IS_DOT11D_ENABLE(ieee) )
634 if(IS_COUNTRY_IE_VALID(ieee))
636 RESET_CIE_WATCHDOG(ieee);
639 ieee->sync_scan_hurryup = 0;
640 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
641 ieee80211_softmac_scan_syncro(ieee);
643 ieee->scan_syncro(ieee->dev);
646 EXPORT_SYMBOL(ieee80211_start_scan_syncro);
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",__func__,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 beacon_buf->capability |= cpu_to_le16(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 static struct sk_buff *ieee80211_assoc_resp(struct ieee80211_device *ieee,
849 struct ieee80211_crypt_data *crypt;
850 struct ieee80211_assoc_response_frame *assoc;
853 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
854 int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len + ieee->tx_headroom;
856 skb = dev_alloc_skb(len);
861 skb_reserve(skb, ieee->tx_headroom);
863 assoc = (struct ieee80211_assoc_response_frame *)
864 skb_put(skb, sizeof(struct ieee80211_assoc_response_frame));
866 assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
867 memcpy(assoc->header.addr1, dest,ETH_ALEN);
868 memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
869 memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
870 assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
871 WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
875 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
877 if (ieee->host_encrypt)
878 crypt = ieee->crypt[ieee->tx_keyidx];
881 encrypt = (crypt && crypt->ops);
884 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
887 assoc->aid = cpu_to_le16(ieee->assoc_id);
888 if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
889 else ieee->assoc_id++;
891 tag = (u8 *) skb_put(skb, rate_len);
893 ieee80211_MFIE_Brate(ieee, &tag);
894 ieee80211_MFIE_Grate(ieee, &tag);
899 static struct sk_buff *ieee80211_auth_resp(struct ieee80211_device *ieee,
900 int status, u8 *dest)
903 struct ieee80211_authentication *auth;
904 int len = ieee->tx_headroom + sizeof(struct ieee80211_authentication)+1;
906 skb = dev_alloc_skb(len);
911 skb->len = sizeof(struct ieee80211_authentication);
913 auth = (struct ieee80211_authentication *)skb->data;
915 auth->status = cpu_to_le16(status);
916 auth->transaction = cpu_to_le16(2);
917 auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
919 memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
920 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
921 memcpy(auth->header.addr1, dest, ETH_ALEN);
922 auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
928 static struct sk_buff *ieee80211_null_func(struct ieee80211_device *ieee,
932 struct ieee80211_hdr_3addr *hdr;
934 skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
939 hdr = (struct ieee80211_hdr_3addr *)skb_put(skb,sizeof(struct ieee80211_hdr_3addr));
941 memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
942 memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
943 memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
945 hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
946 IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
947 (pwr ? IEEE80211_FCTL_PM:0));
955 static void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8 *dest)
957 struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
960 softmac_mgmt_xmit(buf, ieee);
964 static void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s,
967 struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
970 softmac_mgmt_xmit(buf, ieee);
974 static void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
978 struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
980 softmac_mgmt_xmit(buf, ieee);
984 inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
987 //unsigned long flags;
989 struct ieee80211_assoc_request_frame *hdr;
991 //short info_addr = 0;
993 //u16 suite_count = 0;
994 //u8 suit_select = 0;
995 //unsigned int wpa_len = beacon->wpa_ie_len;
997 u8 *ht_cap_buf = NULL;
999 u8 *realtek_ie_buf=NULL;
1000 u8 realtek_ie_len=0;
1001 int wpa_ie_len= ieee->wpa_ie_len;
1002 unsigned int ckip_ie_len=0;
1003 unsigned int ccxrm_ie_len=0;
1004 unsigned int cxvernum_ie_len=0;
1005 struct ieee80211_crypt_data *crypt;
1008 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
1009 unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
1011 unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
1016 crypt = ieee->crypt[ieee->tx_keyidx];
1017 encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len));
1019 //Include High Throuput capability && Realtek proprietary
1020 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1022 ht_cap_buf = (u8 *)&(ieee->pHTInfo->SelfHTCap);
1023 ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
1024 HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt);
1025 if(ieee->pHTInfo->bCurrentRT2RTAggregation)
1027 realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
1028 realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer);
1029 HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len);
1033 if(ieee->qos_support){
1034 wmm_info_len = beacon->qos_data.supported?9:0;
1038 if(beacon->bCkipSupported)
1042 if(beacon->bCcxRmEnable)
1046 if( beacon->BssCcxVerNumber >= 2 )
1048 cxvernum_ie_len = 5+2;
1051 len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1052 + beacon->ssid_len//essid tagged val
1053 + rate_len//rates tagged val
1062 + ieee->tx_headroom;
1064 len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1065 + beacon->ssid_len//essid tagged val
1066 + rate_len//rates tagged val
1074 + ieee->tx_headroom;
1077 skb = dev_alloc_skb(len);
1082 skb_reserve(skb, ieee->tx_headroom);
1084 hdr = (struct ieee80211_assoc_request_frame *)
1085 skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)+2);
1088 hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
1089 hdr->header.duration_id= 37; //FIXME
1090 memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
1091 memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1092 memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
1094 memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John
1096 hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
1097 if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
1098 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1100 if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1101 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); //add short_preamble here
1103 if(ieee->short_slot)
1104 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
1105 if (wmm_info_len) //QOS
1106 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS);
1108 hdr->listen_interval = 0xa; //FIXME
1110 hdr->info_element[0].id = MFIE_TYPE_SSID;
1112 hdr->info_element[0].len = beacon->ssid_len;
1113 tag = skb_put(skb, beacon->ssid_len);
1114 memcpy(tag, beacon->ssid, beacon->ssid_len);
1116 tag = skb_put(skb, rate_len);
1118 ieee80211_MFIE_Brate(ieee, &tag);
1119 ieee80211_MFIE_Grate(ieee, &tag);
1120 // For CCX 1 S13, CKIP. Added by Annie, 2006-08-14.
1121 if( beacon->bCkipSupported )
1123 static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client"
1124 u8 CcxAironetBuf[30];
1125 OCTET_STRING osCcxAironetIE;
1127 memset(CcxAironetBuf, 0, 30);
1128 osCcxAironetIE.Octet = CcxAironetBuf;
1129 osCcxAironetIE.Length = sizeof(CcxAironetBuf);
1131 // Ref. CCX test plan v3.61, 3.2.3.1 step 13.
1132 // We want to make the device type as "4500-client". 060926, by CCW.
1134 memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui));
1136 // CCX1 spec V1.13, A01.1 CKIP Negotiation (page23):
1137 // "The CKIP negotiation is started with the associate request from the client to the access point,
1138 // containing an Aironet element with both the MIC and KP bits set."
1139 osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |= (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ;
1140 tag = skb_put(skb, ckip_ie_len);
1141 *tag++ = MFIE_TYPE_AIRONET;
1142 *tag++ = osCcxAironetIE.Length;
1143 memcpy(tag, osCcxAironetIE.Octet, osCcxAironetIE.Length);
1144 tag += osCcxAironetIE.Length;
1147 if(beacon->bCcxRmEnable)
1149 static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
1150 OCTET_STRING osCcxRmCap;
1152 osCcxRmCap.Octet = CcxRmCapBuf;
1153 osCcxRmCap.Length = sizeof(CcxRmCapBuf);
1154 tag = skb_put(skb, ccxrm_ie_len);
1155 *tag++ = MFIE_TYPE_GENERIC;
1156 *tag++ = osCcxRmCap.Length;
1157 memcpy(tag, osCcxRmCap.Octet, osCcxRmCap.Length);
1158 tag += osCcxRmCap.Length;
1161 if( beacon->BssCcxVerNumber >= 2 )
1163 u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
1164 OCTET_STRING osCcxVerNum;
1165 CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
1166 osCcxVerNum.Octet = CcxVerNumBuf;
1167 osCcxVerNum.Length = sizeof(CcxVerNumBuf);
1168 tag = skb_put(skb, cxvernum_ie_len);
1169 *tag++ = MFIE_TYPE_GENERIC;
1170 *tag++ = osCcxVerNum.Length;
1171 memcpy(tag, osCcxVerNum.Octet, osCcxVerNum.Length);
1172 tag += osCcxVerNum.Length;
1175 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
1176 if(ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC)
1178 tag = skb_put(skb, ht_cap_len);
1179 *tag++ = MFIE_TYPE_HT_CAP;
1180 *tag++ = ht_cap_len - 2;
1181 memcpy(tag, ht_cap_buf,ht_cap_len -2);
1182 tag += ht_cap_len -2;
1187 //choose what wpa_supplicant gives to associate.
1188 tag = skb_put(skb, wpa_ie_len);
1190 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
1193 tag = skb_put(skb, wmm_info_len);
1195 ieee80211_WMM_Info(ieee, &tag);
1198 tag = skb_put(skb, turbo_info_len);
1199 if(turbo_info_len) {
1200 ieee80211_TURBO_Info(ieee, &tag);
1204 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
1205 if(ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC)
1207 tag = skb_put(skb, ht_cap_len);
1208 *tag++ = MFIE_TYPE_GENERIC;
1209 *tag++ = ht_cap_len - 2;
1210 memcpy(tag, ht_cap_buf, ht_cap_len - 2);
1211 tag += ht_cap_len -2;
1214 if(ieee->pHTInfo->bCurrentRT2RTAggregation){
1215 tag = skb_put(skb, realtek_ie_len);
1216 *tag++ = MFIE_TYPE_GENERIC;
1217 *tag++ = realtek_ie_len - 2;
1218 memcpy(tag, realtek_ie_buf,realtek_ie_len -2 );
1221 // printk("<=====%s(), %p, %p\n", __func__, ieee->dev, ieee->dev->dev_addr);
1222 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
1226 void ieee80211_associate_abort(struct ieee80211_device *ieee)
1229 unsigned long flags;
1230 spin_lock_irqsave(&ieee->lock, flags);
1232 ieee->associate_seq++;
1234 /* don't scan, and avoid to have the RX path possibily
1235 * try again to associate. Even do not react to AUTH or
1236 * ASSOC response. Just wait for the retry wq to be scheduled.
1237 * Here we will check if there are good nets to associate
1238 * with, so we retry or just get back to NO_LINK and scanning
1240 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
1241 IEEE80211_DEBUG_MGMT("Authentication failed\n");
1242 ieee->softmac_stats.no_auth_rs++;
1244 IEEE80211_DEBUG_MGMT("Association failed\n");
1245 ieee->softmac_stats.no_ass_rs++;
1248 ieee->state = IEEE80211_ASSOCIATING_RETRY;
1250 queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \
1251 IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
1253 spin_unlock_irqrestore(&ieee->lock, flags);
1256 static void ieee80211_associate_abort_cb(unsigned long dev)
1258 ieee80211_associate_abort((struct ieee80211_device *) dev);
1262 static void ieee80211_associate_step1(struct ieee80211_device *ieee)
1264 struct ieee80211_network *beacon = &ieee->current_network;
1265 struct sk_buff *skb;
1267 IEEE80211_DEBUG_MGMT("Stopping scan\n");
1269 ieee->softmac_stats.tx_auth_rq++;
1270 skb=ieee80211_authentication_req(beacon, ieee, 0);
1273 ieee80211_associate_abort(ieee);
1275 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
1276 IEEE80211_DEBUG_MGMT("Sending authentication request\n");
1277 //printk(KERN_WARNING "Sending authentication request\n");
1278 softmac_mgmt_xmit(skb, ieee);
1279 //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
1280 if(!timer_pending(&ieee->associate_timer)){
1281 ieee->associate_timer.expires = jiffies + (HZ / 2);
1282 add_timer(&ieee->associate_timer);
1284 //dev_kfree_skb_any(skb);//edit by thomas
1288 static void ieee80211_auth_challenge(struct ieee80211_device *ieee,
1293 struct sk_buff *skb;
1294 struct ieee80211_network *beacon = &ieee->current_network;
1295 // int hlen = sizeof(struct ieee80211_authentication);
1297 ieee->associate_seq++;
1298 ieee->softmac_stats.tx_auth_rq++;
1300 skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
1302 ieee80211_associate_abort(ieee);
1304 c = skb_put(skb, chlen+2);
1305 *(c++) = MFIE_TYPE_CHALLENGE;
1307 memcpy(c, challenge, chlen);
1309 IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
1311 ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr ));
1313 softmac_mgmt_xmit(skb, ieee);
1314 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1315 //dev_kfree_skb_any(skb);//edit by thomas
1320 static void ieee80211_associate_step2(struct ieee80211_device *ieee)
1322 struct sk_buff *skb;
1323 struct ieee80211_network *beacon = &ieee->current_network;
1325 del_timer_sync(&ieee->associate_timer);
1327 IEEE80211_DEBUG_MGMT("Sending association request\n");
1329 ieee->softmac_stats.tx_ass_rq++;
1330 skb=ieee80211_association_req(beacon, ieee);
1332 ieee80211_associate_abort(ieee);
1334 softmac_mgmt_xmit(skb, ieee);
1335 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1336 //dev_kfree_skb_any(skb);//edit by thomas
1339 static void ieee80211_associate_complete_wq(struct work_struct *work)
1341 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
1342 printk(KERN_INFO "Associated successfully\n");
1343 if(ieee80211_is_54g(&ieee->current_network) &&
1344 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1347 printk(KERN_INFO"Using G rates:%d\n", ieee->rate);
1350 printk(KERN_INFO"Using B rates:%d\n", ieee->rate);
1352 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1354 printk("Successfully associated, ht enabled\n");
1359 printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
1360 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1361 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1363 ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500);
1364 // To prevent the immediately calling watch_dog after association.
1365 if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
1367 ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
1368 ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
1370 ieee->link_change(ieee->dev);
1371 if(ieee->is_silent_reset == 0){
1372 printk("============>normal associate\n");
1373 notify_wx_assoc_event(ieee);
1375 else if(ieee->is_silent_reset == 1)
1377 printk("==================>silent reset associate\n");
1378 ieee->is_silent_reset = 0;
1381 if (ieee->data_hard_resume)
1382 ieee->data_hard_resume(ieee->dev);
1383 netif_carrier_on(ieee->dev);
1386 static void ieee80211_associate_complete(struct ieee80211_device *ieee)
1389 // struct net_device* dev = ieee->dev;
1390 del_timer_sync(&ieee->associate_timer);
1392 ieee->state = IEEE80211_LINKED;
1393 //ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet);
1394 queue_work(ieee->wq, &ieee->associate_complete_wq);
1397 static void ieee80211_associate_procedure_wq(struct work_struct *work)
1399 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
1400 ieee->sync_scan_hurryup = 1;
1401 down(&ieee->wx_sem);
1403 if (ieee->data_hard_stop)
1404 ieee->data_hard_stop(ieee->dev);
1406 ieee80211_stop_scan(ieee);
1407 printk("===>%s(), chan:%d\n", __func__, ieee->current_network.channel);
1408 //ieee->set_chan(ieee->dev, ieee->current_network.channel);
1409 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1411 ieee->associate_seq = 1;
1412 ieee80211_associate_step1(ieee);
1417 inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
1419 u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
1420 int tmp_ssid_len = 0;
1422 short apset, ssidset, ssidbroad, apmatch, ssidmatch;
1424 /* we are interested in new new only if we are not associated
1425 * and we are not associating / authenticating
1427 if (ieee->state != IEEE80211_NOLINK)
1430 if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
1433 if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
1437 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){
1438 /* if the user specified the AP MAC, we need also the essid
1439 * This could be obtained by beacons or, if the network does not
1440 * broadcast it, it can be put manually.
1442 apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
1443 ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
1444 ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0');
1445 apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
1446 ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\
1447 (!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
1450 if ( /* if the user set the AP check if match.
1451 * if the network does not broadcast essid we check the user supplyed ANY essid
1452 * if the network does broadcast and the user does not set essid it is OK
1453 * if the network does broadcast and the user did set essid chech if essid match
1455 (apset && apmatch &&
1456 ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
1457 /* if the ap is not set, check that the user set the bssid
1458 * and the network does broadcast and that those two bssid matches
1460 (!apset && ssidset && ssidbroad && ssidmatch)
1462 /* if the essid is hidden replace it with the
1463 * essid provided by the user.
1466 strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
1467 tmp_ssid_len = ieee->current_network.ssid_len;
1469 memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
1472 strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
1473 ieee->current_network.ssid_len = tmp_ssid_len;
1475 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);
1477 //ieee->pHTInfo->IOTAction = 0;
1478 HTResetIOTSetting(ieee->pHTInfo);
1479 if (ieee->iw_mode == IW_MODE_INFRA){
1480 /* Join the network for the first time */
1481 ieee->AsocRetryCount = 0;
1482 //for HT by amy 080514
1483 if((ieee->current_network.qos_data.supported == 1) &&
1484 // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT))
1485 ieee->current_network.bssht.bdSupportHT)
1486 /*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.*/
1488 // ieee->pHTInfo->bCurrentHTSupport = true;
1489 HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network));
1493 ieee->pHTInfo->bCurrentHTSupport = false;
1496 ieee->state = IEEE80211_ASSOCIATING;
1497 queue_work(ieee->wq, &ieee->associate_procedure_wq);
1499 if(ieee80211_is_54g(&ieee->current_network) &&
1500 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1502 ieee->SetWirelessMode(ieee->dev, IEEE_G);
1503 printk(KERN_INFO"Using G rates\n");
1506 ieee->SetWirelessMode(ieee->dev, IEEE_B);
1507 printk(KERN_INFO"Using B rates\n");
1509 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1510 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1511 ieee->state = IEEE80211_LINKED;
1519 void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
1521 unsigned long flags;
1522 struct ieee80211_network *target;
1524 spin_lock_irqsave(&ieee->lock, flags);
1526 list_for_each_entry(target, &ieee->network_list, list) {
1528 /* if the state become different that NOLINK means
1529 * we had found what we are searching for
1532 if (ieee->state != IEEE80211_NOLINK)
1535 if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
1536 ieee80211_softmac_new_net(ieee, target);
1539 spin_unlock_irqrestore(&ieee->lock, flags);
1544 static inline u16 auth_parse(struct sk_buff *skb, u8 **challenge, int *chlen)
1546 struct ieee80211_authentication *a;
1548 if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
1549 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
1553 a = (struct ieee80211_authentication *) skb->data;
1554 if(skb->len > (sizeof(struct ieee80211_authentication) +3)){
1555 t = skb->data + sizeof(struct ieee80211_authentication);
1557 if(*(t++) == MFIE_TYPE_CHALLENGE){
1559 *challenge = kmemdup(t, *chlen, GFP_ATOMIC);
1565 return cpu_to_le16(a->status);
1570 static int auth_rq_parse(struct sk_buff *skb, u8 *dest)
1572 struct ieee80211_authentication *a;
1574 if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
1575 IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
1578 a = (struct ieee80211_authentication *) skb->data;
1580 memcpy(dest,a->header.addr2, ETH_ALEN);
1582 if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
1583 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1585 return WLAN_STATUS_SUCCESS;
1588 static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
1595 struct ieee80211_hdr_3addr *header =
1596 (struct ieee80211_hdr_3addr *) skb->data;
1598 if (skb->len < sizeof (struct ieee80211_hdr_3addr ))
1599 return -1; /* corrupted */
1601 memcpy(src,header->addr2, ETH_ALEN);
1603 skbend = (u8 *)skb->data + skb->len;
1605 tag = skb->data + sizeof (struct ieee80211_hdr_3addr );
1607 while (tag+1 < skbend){
1613 tag++; /* point to the len field */
1614 tag = tag + *(tag); /* point to the last data byte of the tag */
1615 tag++; /* point to the next tag */
1618 //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
1619 if (ssidlen == 0) return 1;
1621 if (!ssid) return 1; /* ssid not found in tagged param */
1622 return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
1626 static int assoc_rq_parse(struct sk_buff *skb, u8 *dest)
1628 struct ieee80211_assoc_request_frame *a;
1630 if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
1631 sizeof(struct ieee80211_info_element))) {
1633 IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
1637 a = (struct ieee80211_assoc_request_frame *) skb->data;
1639 memcpy(dest,a->header.addr2,ETH_ALEN);
1644 static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid)
1646 struct ieee80211_assoc_response_frame *response_head;
1649 if (skb->len < sizeof(struct ieee80211_assoc_response_frame)){
1650 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
1654 response_head = (struct ieee80211_assoc_response_frame *) skb->data;
1655 *aid = le16_to_cpu(response_head->aid) & 0x3fff;
1657 status_code = le16_to_cpu(response_head->status);
1658 if((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \
1659 status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&&
1660 ((ieee->mode == IEEE_G) &&
1661 (ieee->current_network.mode == IEEE_N_24G) &&
1662 (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) {
1663 ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
1665 ieee->AsocRetryCount = 0;
1668 return le16_to_cpu(response_head->status);
1672 ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1676 //IEEE80211DMESG("Rx probe");
1677 ieee->softmac_stats.rx_probe_rq++;
1678 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1679 if (probe_rq_parse(ieee, skb, dest)){
1680 //IEEE80211DMESG("Was for me!");
1681 ieee->softmac_stats.tx_probe_rs++;
1682 ieee80211_resp_to_probe(ieee, dest);
1687 ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1691 //IEEE80211DMESG("Rx probe");
1692 ieee->softmac_stats.rx_auth_rq++;
1694 status = auth_rq_parse(skb, dest);
1696 ieee80211_resp_to_auth(ieee, status, dest);
1698 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1703 ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1707 //unsigned long flags;
1709 ieee->softmac_stats.rx_ass_rq++;
1710 if (assoc_rq_parse(skb,dest) != -1){
1711 ieee80211_resp_to_assoc_rq(ieee, dest);
1714 printk(KERN_INFO"New client associated: %pM\n", dest);
1718 static void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee,
1722 struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
1725 softmac_ps_mgmt_xmit(buf, ieee);
1728 /* EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame); */
1730 static short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h,
1733 int timeout = ieee->ps_timeout;
1735 /*if(ieee->ps == IEEE80211_PS_DISABLED ||
1736 ieee->iw_mode != IW_MODE_INFRA ||
1737 ieee->state != IEEE80211_LINKED)
1741 dtim = ieee->current_network.dtim_data;
1743 if(!(dtim & IEEE80211_DTIM_VALID))
1745 timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
1746 //printk("VALID\n");
1747 ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
1749 if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
1752 if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
1755 if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
1758 if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
1759 (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
1763 *time_l = ieee->current_network.last_dtim_sta_time[0]
1764 + (ieee->current_network.beacon_interval
1765 * ieee->current_network.dtim_period) * 1000;
1769 *time_h = ieee->current_network.last_dtim_sta_time[1];
1770 if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
1779 static inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
1785 unsigned long flags, flags2;
1787 spin_lock_irqsave(&ieee->lock, flags);
1789 if((ieee->ps == IEEE80211_PS_DISABLED ||
1790 ieee->iw_mode != IW_MODE_INFRA ||
1791 ieee->state != IEEE80211_LINKED)){
1793 // #warning CHECK_LOCK_HERE
1794 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1796 ieee80211_sta_wakeup(ieee, 1);
1798 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1801 sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
1802 /* 2 wake, 1 sleep, 0 do nothing */
1808 if(ieee->sta_sleep == 1)
1809 ieee->enter_sleep_state(ieee->dev, th, tl);
1811 else if(ieee->sta_sleep == 0){
1812 // printk("send null 1\n");
1813 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1815 if(ieee->ps_is_queue_empty(ieee->dev)){
1818 ieee->sta_sleep = 2;
1820 ieee->ps_request_tx_ack(ieee->dev);
1822 ieee80211_sta_ps_send_null_frame(ieee, 1);
1827 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1832 }else if(sleep == 2){
1833 //#warning CHECK_LOCK_HERE
1834 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1836 ieee80211_sta_wakeup(ieee, 1);
1838 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1842 spin_unlock_irqrestore(&ieee->lock, flags);
1846 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
1848 if(ieee->sta_sleep == 0){
1850 printk("Warning: driver is probably failing to report TX ps error\n");
1851 ieee->ps_request_tx_ack(ieee->dev);
1852 ieee80211_sta_ps_send_null_frame(ieee, 0);
1858 if(ieee->sta_sleep == 1)
1859 ieee->sta_wake_up(ieee->dev);
1861 ieee->sta_sleep = 0;
1864 ieee->ps_request_tx_ack(ieee->dev);
1865 ieee80211_sta_ps_send_null_frame(ieee, 0);
1869 void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
1871 unsigned long flags, flags2;
1873 spin_lock_irqsave(&ieee->lock, flags);
1875 if(ieee->sta_sleep == 2){
1876 /* Null frame with PS bit set */
1878 ieee->sta_sleep = 1;
1879 ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
1881 /* if the card report not success we can't be sure the AP
1882 * has not RXed so we can't assume the AP believe us awake
1885 /* 21112005 - tx again null without PS bit if lost */
1888 if((ieee->sta_sleep == 0) && !success){
1889 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1890 ieee80211_sta_ps_send_null_frame(ieee, 0);
1891 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1894 spin_unlock_irqrestore(&ieee->lock, flags);
1896 EXPORT_SYMBOL(ieee80211_ps_tx_ack);
1898 static void ieee80211_process_action(struct ieee80211_device *ieee,
1899 struct sk_buff *skb)
1901 struct ieee80211_hdr *header = (struct ieee80211_hdr *)skb->data;
1902 u8 *act = ieee80211_get_payload(header);
1904 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
1907 IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
1914 if (*act == ACT_ADDBAREQ)
1915 ieee80211_rx_ADDBAReq(ieee, skb);
1916 else if (*act == ACT_ADDBARSP)
1917 ieee80211_rx_ADDBARsp(ieee, skb);
1918 else if (*act == ACT_DELBA)
1919 ieee80211_rx_DELBA(ieee, skb);
1928 ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
1929 struct ieee80211_rx_stats *rx_stats, u16 type,
1932 struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
1937 struct ieee80211_assoc_response_frame *assoc_resp;
1938 // struct ieee80211_info_element *info_element;
1939 bool bSupportNmode = true, bHalfSupportNmode = false; //default support N mode, disable halfNmode
1941 if(!ieee->proto_started)
1944 if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
1945 ieee->iw_mode == IW_MODE_INFRA &&
1946 ieee->state == IEEE80211_LINKED))
1948 tasklet_schedule(&ieee->ps_task);
1950 if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
1951 WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
1952 ieee->last_rx_ps_time = jiffies;
1954 switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
1956 case IEEE80211_STYPE_ASSOC_RESP:
1957 case IEEE80211_STYPE_REASSOC_RESP:
1959 IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
1960 WLAN_FC_GET_STYPE(header->frame_ctl));
1961 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
1962 ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
1963 ieee->iw_mode == IW_MODE_INFRA){
1964 struct ieee80211_network network_resp;
1965 struct ieee80211_network *network = &network_resp;
1967 errcode = assoc_parse(ieee, skb, &aid);
1969 ieee->state=IEEE80211_LINKED;
1970 ieee->assoc_id = aid;
1971 ieee->softmac_stats.rx_ass_ok++;
1972 /* station support qos */
1973 /* Let the register setting defaultly with Legacy station */
1974 if(ieee->qos_support) {
1975 assoc_resp = (struct ieee80211_assoc_response_frame *)skb->data;
1976 memset(network, 0, sizeof(*network));
1977 if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\
1978 rx_stats->len - sizeof(*assoc_resp),\
1983 { //filling the PeerHTCap. //maybe not necessary as we can get its info from current_network.
1984 memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
1985 memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
1987 if (ieee->handle_assoc_response != NULL)
1988 ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame *)header, network);
1990 ieee80211_associate_complete(ieee);
1992 /* aid could not been allocated */
1993 ieee->softmac_stats.rx_ass_err++;
1995 "Association response status code 0x%x\n",
1997 IEEE80211_DEBUG_MGMT(
1998 "Association response status code 0x%x\n",
2000 if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
2001 queue_work(ieee->wq, &ieee->associate_procedure_wq);
2003 ieee80211_associate_abort(ieee);
2009 case IEEE80211_STYPE_ASSOC_REQ:
2010 case IEEE80211_STYPE_REASSOC_REQ:
2012 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2013 ieee->iw_mode == IW_MODE_MASTER)
2015 ieee80211_rx_assoc_rq(ieee, skb);
2018 case IEEE80211_STYPE_AUTH:
2020 if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){
2021 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
2022 ieee->iw_mode == IW_MODE_INFRA){
2024 IEEE80211_DEBUG_MGMT("Received authentication response");
2026 errcode = auth_parse(skb, &challenge, &chlen);
2028 if(ieee->open_wep || !challenge){
2029 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
2030 ieee->softmac_stats.rx_auth_rs_ok++;
2031 if(!(ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE))
2033 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
2035 // WEP or TKIP encryption
2036 if(IsHTHalfNmodeAPs(ieee))
2038 bSupportNmode = true;
2039 bHalfSupportNmode = true;
2043 bSupportNmode = false;
2044 bHalfSupportNmode = false;
2046 printk("==========>to link with AP using SEC(%d, %d)", bSupportNmode, bHalfSupportNmode);
2049 /* Dummy wirless mode setting to avoid encryption issue */
2052 ieee->SetWirelessMode(ieee->dev, \
2053 ieee->current_network.mode);
2057 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2060 if (ieee->current_network.mode == IEEE_N_24G && bHalfSupportNmode == true)
2062 printk("===============>entern half N mode\n");
2063 ieee->bHalfWirelessN24GMode = true;
2066 ieee->bHalfWirelessN24GMode = false;
2068 ieee80211_associate_step2(ieee);
2070 ieee80211_auth_challenge(ieee, challenge, chlen);
2073 ieee->softmac_stats.rx_auth_rs_err++;
2074 IEEE80211_DEBUG_MGMT("Authentication response status code 0x%x",errcode);
2075 ieee80211_associate_abort(ieee);
2078 }else if (ieee->iw_mode == IW_MODE_MASTER){
2079 ieee80211_rx_auth_rq(ieee, skb);
2084 case IEEE80211_STYPE_PROBE_REQ:
2086 if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
2087 ((ieee->iw_mode == IW_MODE_ADHOC ||
2088 ieee->iw_mode == IW_MODE_MASTER) &&
2089 ieee->state == IEEE80211_LINKED)){
2090 ieee80211_rx_probe_rq(ieee, skb);
2094 case IEEE80211_STYPE_DISASSOC:
2095 case IEEE80211_STYPE_DEAUTH:
2096 /* FIXME for now repeat all the association procedure
2097 * both for disassociation and deauthentication
2099 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2100 ieee->state == IEEE80211_LINKED &&
2101 ieee->iw_mode == IW_MODE_INFRA){
2103 ieee->state = IEEE80211_ASSOCIATING;
2104 ieee->softmac_stats.reassoc++;
2106 notify_wx_assoc_event(ieee);
2107 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2108 RemovePeerTS(ieee, header->addr2);
2109 queue_work(ieee->wq, &ieee->associate_procedure_wq);
2112 case IEEE80211_STYPE_MANAGE_ACT:
2113 ieee80211_process_action(ieee, skb);
2120 //dev_kfree_skb_any(skb);
2124 /* following are for a simpler TX queue management.
2125 * Instead of using netif_[stop/wake]_queue the driver
2126 * will uses these two function (plus a reset one), that
2127 * will internally uses the kernel netif_* and takes
2128 * care of the ieee802.11 fragmentation.
2129 * So the driver receives a fragment per time and might
2130 * call the stop function when it want without take care
2131 * to have enought room to TX an entire packet.
2132 * This might be useful if each fragment need it's own
2133 * descriptor, thus just keep a total free memory > than
2134 * the max fragmentation treshold is not enought.. If the
2135 * ieee802.11 stack passed a TXB struct then you needed
2136 * to keep N free descriptors where
2137 * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
2138 * In this way you need just one and the 802.11 stack
2139 * will take care of buffering fragments and pass them to
2140 * to the driver later, when it wakes the queue.
2142 void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
2145 unsigned int queue_index = txb->queue_index;
2146 unsigned long flags;
2148 cb_desc *tcb_desc = NULL;
2150 spin_lock_irqsave(&ieee->lock, flags);
2152 /* called with 2nd parm 0, no tx mgmt lock required */
2153 ieee80211_sta_wakeup(ieee, 0);
2155 /* update the tx status */
2156 ieee->stats.tx_bytes += txb->payload_size;
2157 ieee->stats.tx_packets++;
2158 tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
2159 if(tcb_desc->bMulticast) {
2160 ieee->stats.multicast++;
2162 /* if xmit available, just xmit it immediately, else just insert it to the wait queue */
2163 for(i = 0; i < txb->nr_frags; i++) {
2164 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2165 if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) ||
2167 if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
2169 (!ieee->check_nic_enough_desc(ieee->dev,queue_index))||\
2170 (ieee->queue_stop)) {
2171 /* insert the skb packet to the wait queue */
2172 /* as for the completion function, it does not need
2173 * to check it any more.
2175 //printk("error:no descriptor left@queue_index %d\n", queue_index);
2176 //ieee80211_stop_queue(ieee);
2177 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2178 skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]);
2180 skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
2183 ieee->softmac_data_hard_start_xmit(
2185 ieee->dev, ieee->rate);
2186 //ieee->stats.tx_packets++;
2187 //ieee->stats.tx_bytes += txb->fragments[i]->len;
2188 //ieee->dev->trans_start = jiffies;
2191 ieee80211_txb_free(txb);
2194 spin_unlock_irqrestore(&ieee->lock, flags);
2197 EXPORT_SYMBOL(ieee80211_softmac_xmit);
2199 /* called with ieee->lock acquired */
2200 static void ieee80211_resume_tx(struct ieee80211_device *ieee)
2203 for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
2205 if (ieee->queue_stop){
2206 ieee->tx_pending.frag = i;
2210 ieee->softmac_data_hard_start_xmit(
2211 ieee->tx_pending.txb->fragments[i],
2212 ieee->dev, ieee->rate);
2213 //(i+1)<ieee->tx_pending.txb->nr_frags);
2214 ieee->stats.tx_packets++;
2215 ieee->dev->trans_start = jiffies;
2220 ieee80211_txb_free(ieee->tx_pending.txb);
2221 ieee->tx_pending.txb = NULL;
2225 void ieee80211_reset_queue(struct ieee80211_device *ieee)
2227 unsigned long flags;
2229 spin_lock_irqsave(&ieee->lock, flags);
2230 init_mgmt_queue(ieee);
2231 if (ieee->tx_pending.txb){
2232 ieee80211_txb_free(ieee->tx_pending.txb);
2233 ieee->tx_pending.txb = NULL;
2235 ieee->queue_stop = 0;
2236 spin_unlock_irqrestore(&ieee->lock, flags);
2239 EXPORT_SYMBOL(ieee80211_reset_queue);
2241 void ieee80211_wake_queue(struct ieee80211_device *ieee)
2244 unsigned long flags;
2245 struct sk_buff *skb;
2246 struct ieee80211_hdr_3addr *header;
2248 spin_lock_irqsave(&ieee->lock, flags);
2249 if (! ieee->queue_stop) goto exit;
2251 ieee->queue_stop = 0;
2253 if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){
2254 while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
2256 header = (struct ieee80211_hdr_3addr *) skb->data;
2258 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2260 if (ieee->seq_ctrl[0] == 0xFFF)
2261 ieee->seq_ctrl[0] = 0;
2263 ieee->seq_ctrl[0]++;
2265 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
2266 //dev_kfree_skb_any(skb);//edit by thomas
2269 if (!ieee->queue_stop && ieee->tx_pending.txb)
2270 ieee80211_resume_tx(ieee);
2272 if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){
2273 ieee->softmac_stats.swtxawake++;
2274 netif_wake_queue(ieee->dev);
2278 spin_unlock_irqrestore(&ieee->lock, flags);
2280 EXPORT_SYMBOL(ieee80211_wake_queue);
2282 void ieee80211_stop_queue(struct ieee80211_device *ieee)
2284 //unsigned long flags;
2285 //spin_lock_irqsave(&ieee->lock,flags);
2287 if (! netif_queue_stopped(ieee->dev)){
2288 netif_stop_queue(ieee->dev);
2289 ieee->softmac_stats.swtxstop++;
2291 ieee->queue_stop = 1;
2292 //spin_unlock_irqrestore(&ieee->lock,flags);
2295 EXPORT_SYMBOL(ieee80211_stop_queue);
2297 inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
2300 random_ether_addr(ieee->current_network.bssid);
2303 /* called in user context only */
2304 void ieee80211_start_master_bss(struct ieee80211_device *ieee)
2308 if (ieee->current_network.ssid_len == 0){
2309 strncpy(ieee->current_network.ssid,
2310 IEEE80211_DEFAULT_TX_ESSID,
2313 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2317 memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
2319 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2320 ieee->state = IEEE80211_LINKED;
2321 ieee->link_change(ieee->dev);
2322 notify_wx_assoc_event(ieee);
2324 if (ieee->data_hard_resume)
2325 ieee->data_hard_resume(ieee->dev);
2327 netif_carrier_on(ieee->dev);
2330 static void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
2334 if (ieee->data_hard_resume)
2335 ieee->data_hard_resume(ieee->dev);
2337 netif_carrier_on(ieee->dev);
2340 static void ieee80211_start_ibss_wq(struct work_struct *work)
2343 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2344 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
2345 /* iwconfig mode ad-hoc will schedule this and return
2346 * on the other hand this will block further iwconfig SET
2347 * operations because of the wx_sem hold.
2348 * Anyway some most set operations set a flag to speed-up
2349 * (abort) this wq (when syncro scanning) before sleeping
2352 if(!ieee->proto_started){
2353 printk("==========oh driver down return\n");
2356 down(&ieee->wx_sem);
2358 if (ieee->current_network.ssid_len == 0){
2359 strcpy(ieee->current_network.ssid, IEEE80211_DEFAULT_TX_ESSID);
2360 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2364 /* check if we have this cell in our network list */
2365 ieee80211_softmac_check_all_nets(ieee);
2368 // if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK))
2369 if (ieee->state == IEEE80211_NOLINK)
2370 ieee->current_network.channel = 6;
2371 /* if not then the state is not linked. Maybe the user swithced to
2372 * ad-hoc mode just after being in monitor mode, or just after
2373 * being very few time in managed mode (so the card have had no
2374 * time to scan all the chans..) or we have just run up the iface
2375 * after setting ad-hoc mode. So we have to give another try..
2376 * Here, in ibss mode, should be safe to do this without extra care
2377 * (in bss mode we had to make sure no-one tryed to associate when
2378 * we had just checked the ieee->state and we was going to start the
2379 * scan) beacause in ibss mode the ieee80211_new_net function, when
2380 * finds a good net, just set the ieee->state to IEEE80211_LINKED,
2381 * so, at worst, we waste a bit of time to initiate an unneeded syncro
2382 * scan, that will stop at the first round because it sees the state
2385 if (ieee->state == IEEE80211_NOLINK)
2386 ieee80211_start_scan_syncro(ieee);
2388 /* the network definitively is not here.. create a new cell */
2389 if (ieee->state == IEEE80211_NOLINK){
2390 printk("creating new IBSS cell\n");
2392 ieee80211_randomize_cell(ieee);
2394 if(ieee->modulation & IEEE80211_CCK_MODULATION){
2396 ieee->current_network.rates_len = 4;
2398 ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
2399 ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
2400 ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
2401 ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
2404 ieee->current_network.rates_len = 0;
2406 if(ieee->modulation & IEEE80211_OFDM_MODULATION){
2407 ieee->current_network.rates_ex_len = 8;
2409 ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
2410 ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
2411 ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
2412 ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
2413 ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
2414 ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
2415 ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
2416 ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
2420 ieee->current_network.rates_ex_len = 0;
2424 // By default, WMM function will be disabled in IBSS mode
2425 ieee->current_network.QoS_Enable = 0;
2426 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2427 ieee->current_network.atim_window = 0;
2428 ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
2429 if(ieee->short_slot)
2430 ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
2434 ieee->state = IEEE80211_LINKED;
2436 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2437 ieee->link_change(ieee->dev);
2439 notify_wx_assoc_event(ieee);
2441 ieee80211_start_send_beacons(ieee);
2443 if (ieee->data_hard_resume)
2444 ieee->data_hard_resume(ieee->dev);
2445 netif_carrier_on(ieee->dev);
2450 inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
2452 queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150);
2455 /* this is called only in user context, with wx_sem held */
2456 void ieee80211_start_bss(struct ieee80211_device *ieee)
2458 unsigned long flags;
2460 // Ref: 802.11d 11.1.3.3
2461 // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
2463 if(IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
2465 if(! ieee->bGlobalDomain)
2470 /* check if we have already found the net we
2471 * are interested in (if any).
2472 * if not (we are disassociated and we are not
2473 * in associating / authenticating phase) start the background scanning.
2475 ieee80211_softmac_check_all_nets(ieee);
2477 /* ensure no-one start an associating process (thus setting
2478 * the ieee->state to ieee80211_ASSOCIATING) while we
2479 * have just cheked it and we are going to enable scan.
2480 * The ieee80211_new_net function is always called with
2481 * lock held (from both ieee80211_softmac_check_all_nets and
2482 * the rx path), so we cannot be in the middle of such function
2484 spin_lock_irqsave(&ieee->lock, flags);
2486 if (ieee->state == IEEE80211_NOLINK){
2487 ieee->actscanning = true;
2488 ieee80211_start_scan(ieee);
2490 spin_unlock_irqrestore(&ieee->lock, flags);
2493 /* called only in userspace context */
2494 void ieee80211_disassociate(struct ieee80211_device *ieee)
2498 netif_carrier_off(ieee->dev);
2499 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
2500 ieee80211_reset_queue(ieee);
2502 if (ieee->data_hard_stop)
2503 ieee->data_hard_stop(ieee->dev);
2504 if(IS_DOT11D_ENABLE(ieee))
2506 ieee->state = IEEE80211_NOLINK;
2507 ieee->is_set_key = false;
2508 ieee->link_change(ieee->dev);
2509 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2510 notify_wx_assoc_event(ieee);
2513 EXPORT_SYMBOL(ieee80211_disassociate);
2515 static void ieee80211_associate_retry_wq(struct work_struct *work)
2517 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2518 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
2519 unsigned long flags;
2521 down(&ieee->wx_sem);
2522 if(!ieee->proto_started)
2525 if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
2528 /* until we do not set the state to IEEE80211_NOLINK
2529 * there are no possibility to have someone else trying
2530 * to start an association procedure (we get here with
2531 * ieee->state = IEEE80211_ASSOCIATING).
2532 * When we set the state to IEEE80211_NOLINK it is possible
2533 * that the RX path run an attempt to associate, but
2534 * both ieee80211_softmac_check_all_nets and the
2535 * RX path works with ieee->lock held so there are no
2536 * problems. If we are still disassociated then start a scan.
2537 * the lock here is necessary to ensure no one try to start
2538 * an association procedure when we have just checked the
2539 * state and we are going to start the scan.
2541 ieee->state = IEEE80211_NOLINK;
2543 ieee80211_softmac_check_all_nets(ieee);
2545 spin_lock_irqsave(&ieee->lock, flags);
2547 if(ieee->state == IEEE80211_NOLINK)
2548 ieee80211_start_scan(ieee);
2550 spin_unlock_irqrestore(&ieee->lock, flags);
2556 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
2558 u8 broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2560 struct sk_buff *skb;
2561 struct ieee80211_probe_response *b;
2563 skb = ieee80211_probe_resp(ieee, broadcast_addr);
2568 b = (struct ieee80211_probe_response *) skb->data;
2569 b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
2575 struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
2577 struct sk_buff *skb;
2578 struct ieee80211_probe_response *b;
2580 skb = ieee80211_get_beacon_(ieee);
2584 b = (struct ieee80211_probe_response *) skb->data;
2585 b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2587 if (ieee->seq_ctrl[0] == 0xFFF)
2588 ieee->seq_ctrl[0] = 0;
2590 ieee->seq_ctrl[0]++;
2594 EXPORT_SYMBOL(ieee80211_get_beacon);
2596 void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
2598 ieee->sync_scan_hurryup = 1;
2599 down(&ieee->wx_sem);
2600 ieee80211_stop_protocol(ieee);
2603 EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
2605 void ieee80211_stop_protocol(struct ieee80211_device *ieee)
2607 if (!ieee->proto_started)
2610 ieee->proto_started = 0;
2612 ieee80211_stop_send_beacons(ieee);
2613 del_timer_sync(&ieee->associate_timer);
2614 cancel_delayed_work(&ieee->associate_retry_wq);
2615 cancel_delayed_work(&ieee->start_ibss_wq);
2616 ieee80211_stop_scan(ieee);
2618 ieee80211_disassociate(ieee);
2619 RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
2622 void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
2624 ieee->sync_scan_hurryup = 0;
2625 down(&ieee->wx_sem);
2626 ieee80211_start_protocol(ieee);
2629 EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
2631 void ieee80211_start_protocol(struct ieee80211_device *ieee)
2635 if (ieee->proto_started)
2638 ieee->proto_started = 1;
2640 if (ieee->current_network.channel == 0){
2643 if (ch > MAX_CHANNEL_NUMBER)
2644 return; /* no channel found */
2645 }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
2646 ieee->current_network.channel = ch;
2649 if (ieee->current_network.beacon_interval == 0)
2650 ieee->current_network.beacon_interval = 100;
2651 // printk("===>%s(), chan:%d\n", __func__, ieee->current_network.channel);
2652 // ieee->set_chan(ieee->dev,ieee->current_network.channel);
2654 for(i = 0; i < 17; i++) {
2655 ieee->last_rxseq_num[i] = -1;
2656 ieee->last_rxfrag_num[i] = -1;
2657 ieee->last_packet_time[i] = 0;
2660 ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
2663 /* if the user set the MAC of the ad-hoc cell and then
2664 * switch to managed mode, shall we make sure that association
2665 * attempts does not fail just because the user provide the essid
2666 * and the nic is still checking for the AP MAC ??
2668 if (ieee->iw_mode == IW_MODE_INFRA)
2669 ieee80211_start_bss(ieee);
2671 else if (ieee->iw_mode == IW_MODE_ADHOC)
2672 ieee80211_start_ibss(ieee);
2674 else if (ieee->iw_mode == IW_MODE_MASTER)
2675 ieee80211_start_master_bss(ieee);
2677 else if(ieee->iw_mode == IW_MODE_MONITOR)
2678 ieee80211_start_monitor_mode(ieee);
2682 #define DRV_NAME "Ieee80211"
2683 void ieee80211_softmac_init(struct ieee80211_device *ieee)
2686 memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
2688 ieee->state = IEEE80211_NOLINK;
2689 ieee->sync_scan_hurryup = 0;
2690 for(i = 0; i < 5; i++) {
2691 ieee->seq_ctrl[i] = 0;
2693 ieee->pDot11dInfo = kzalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
2694 if (!ieee->pDot11dInfo)
2695 IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
2696 //added for AP roaming
2697 ieee->LinkDetectInfo.SlotNum = 2;
2698 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
2699 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
2702 ieee->queue_stop = 0;
2704 ieee->softmac_features = 0; //so IEEE2100-like driver are happy
2707 ieee->proto_started = 0;
2708 ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
2710 ieee->ps = IEEE80211_PS_DISABLED;
2711 ieee->sta_sleep = 0;
2712 ieee->Regdot11HTOperationalRateSet[0]= 0xff;//support MCS 0~7
2713 ieee->Regdot11HTOperationalRateSet[1]= 0xff;//support MCS 8~15
2714 ieee->Regdot11HTOperationalRateSet[4]= 0x01;
2716 ieee->actscanning = false;
2717 ieee->beinretry = false;
2718 ieee->is_set_key = false;
2719 init_mgmt_queue(ieee);
2721 ieee->sta_edca_param[0] = 0x0000A403;
2722 ieee->sta_edca_param[1] = 0x0000A427;
2723 ieee->sta_edca_param[2] = 0x005E4342;
2724 ieee->sta_edca_param[3] = 0x002F3262;
2725 ieee->aggregation = true;
2726 ieee->enable_rx_imm_BA = 1;
2727 ieee->tx_pending.txb = NULL;
2729 init_timer(&ieee->associate_timer);
2730 ieee->associate_timer.data = (unsigned long)ieee;
2731 ieee->associate_timer.function = ieee80211_associate_abort_cb;
2733 init_timer(&ieee->beacon_timer);
2734 ieee->beacon_timer.data = (unsigned long) ieee;
2735 ieee->beacon_timer.function = ieee80211_send_beacon_cb;
2737 ieee->wq = create_workqueue(DRV_NAME);
2739 INIT_DELAYED_WORK(&ieee->start_ibss_wq, ieee80211_start_ibss_wq);
2740 INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
2741 INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
2742 INIT_DELAYED_WORK(&ieee->softmac_scan_wq, ieee80211_softmac_scan_wq);
2743 INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
2744 INIT_WORK(&ieee->wx_sync_scan_wq, ieee80211_wx_sync_scan_wq);
2747 sema_init(&ieee->wx_sem, 1);
2748 sema_init(&ieee->scan_sem, 1);
2750 spin_lock_init(&ieee->mgmt_tx_lock);
2751 spin_lock_init(&ieee->beacon_lock);
2753 tasklet_init(&ieee->ps_task,
2754 (void(*)(unsigned long)) ieee80211_sta_ps,
2755 (unsigned long)ieee);
2759 void ieee80211_softmac_free(struct ieee80211_device *ieee)
2761 down(&ieee->wx_sem);
2762 kfree(ieee->pDot11dInfo);
2763 ieee->pDot11dInfo = NULL;
2764 del_timer_sync(&ieee->associate_timer);
2766 cancel_delayed_work(&ieee->associate_retry_wq);
2767 destroy_workqueue(ieee->wq);
2772 /********************************************************
2773 * Start of WPA code. *
2774 * this is stolen from the ipw2200 driver *
2775 ********************************************************/
2778 static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
2780 /* This is called when wpa_supplicant loads and closes the driver
2782 printk("%s WPA\n",value ? "enabling" : "disabling");
2783 ieee->wpa_enabled = value;
2788 static void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee,
2789 char *wpa_ie, int wpa_ie_len)
2791 /* make sure WPA is enabled */
2792 ieee80211_wpa_enable(ieee, 1);
2794 ieee80211_disassociate(ieee);
2798 static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
2804 case IEEE_MLME_STA_DEAUTH:
2808 case IEEE_MLME_STA_DISASSOC:
2809 ieee80211_disassociate(ieee);
2813 printk("Unknown MLME request: %d\n", command);
2821 static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
2822 struct ieee_param *param, int plen)
2826 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
2827 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
2830 if (param->u.wpa_ie.len) {
2831 buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len,
2836 kfree(ieee->wpa_ie);
2838 ieee->wpa_ie_len = param->u.wpa_ie.len;
2840 kfree(ieee->wpa_ie);
2841 ieee->wpa_ie = NULL;
2842 ieee->wpa_ie_len = 0;
2845 ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
2849 #define AUTH_ALG_OPEN_SYSTEM 0x1
2850 #define AUTH_ALG_SHARED_KEY 0x2
2852 static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
2855 struct ieee80211_security sec = {
2856 .flags = SEC_AUTH_MODE,
2859 if (value & AUTH_ALG_SHARED_KEY) {
2860 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
2862 ieee->auth_mode = 1;
2863 } else if (value & AUTH_ALG_OPEN_SYSTEM){
2864 sec.auth_mode = WLAN_AUTH_OPEN;
2866 ieee->auth_mode = 0;
2868 else if (value & IW_AUTH_ALG_LEAP){
2869 sec.auth_mode = WLAN_AUTH_LEAP;
2871 ieee->auth_mode = 2;
2875 if (ieee->set_security)
2876 ieee->set_security(ieee->dev, &sec);
2878 // ret = -EOPNOTSUPP;
2883 static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
2886 unsigned long flags;
2889 case IEEE_PARAM_WPA_ENABLED:
2890 ret = ieee80211_wpa_enable(ieee, value);
2893 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2894 ieee->tkip_countermeasures=value;
2897 case IEEE_PARAM_DROP_UNENCRYPTED: {
2900 * wpa_supplicant calls set_wpa_enabled when the driver
2901 * is loaded and unloaded, regardless of if WPA is being
2902 * used. No other calls are made which can be used to
2903 * determine if encryption will be used or not prior to
2904 * association being expected. If encryption is not being
2905 * used, drop_unencrypted is set to false, else true -- we
2906 * can use this to determine if the CAP_PRIVACY_ON bit should
2909 struct ieee80211_security sec = {
2910 .flags = SEC_ENABLED,
2913 ieee->drop_unencrypted = value;
2914 /* We only change SEC_LEVEL for open mode. Others
2915 * are set by ipw_wpa_set_encryption.
2918 sec.flags |= SEC_LEVEL;
2919 sec.level = SEC_LEVEL_0;
2922 sec.flags |= SEC_LEVEL;
2923 sec.level = SEC_LEVEL_1;
2925 if (ieee->set_security)
2926 ieee->set_security(ieee->dev, &sec);
2930 case IEEE_PARAM_PRIVACY_INVOKED:
2931 ieee->privacy_invoked=value;
2934 case IEEE_PARAM_AUTH_ALGS:
2935 ret = ieee80211_wpa_set_auth_algs(ieee, value);
2938 case IEEE_PARAM_IEEE_802_1X:
2939 ieee->ieee802_1x=value;
2941 case IEEE_PARAM_WPAX_SELECT:
2942 // added for WPA2 mixed mode
2943 spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags);
2944 ieee->wpax_type_set = 1;
2945 ieee->wpax_type_notify = value;
2946 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags);
2950 printk("Unknown WPA param: %d\n",name);
2957 /* implementation borrowed from hostap driver */
2959 static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
2960 struct ieee_param *param, int param_len)
2964 struct ieee80211_crypto_ops *ops;
2965 struct ieee80211_crypt_data **crypt;
2967 struct ieee80211_security sec = {
2971 param->u.crypt.err = 0;
2972 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
2975 (int) ((char *) param->u.crypt.key - (char *) param) +
2976 param->u.crypt.key_len) {
2977 printk("Len mismatch %d, %d\n", param_len,
2978 param->u.crypt.key_len);
2981 if (is_broadcast_ether_addr(param->sta_addr)) {
2982 if (param->u.crypt.idx >= WEP_KEYS)
2984 crypt = &ieee->crypt[param->u.crypt.idx];
2989 if (strcmp(param->u.crypt.alg, "none") == 0) {
2994 sec.level = SEC_LEVEL_0;
2995 sec.flags |= SEC_ENABLED | SEC_LEVEL;
2996 ieee80211_crypt_delayed_deinit(ieee, crypt);
3003 sec.flags |= SEC_ENABLED;
3005 /* IPW HW cannot build TKIP MIC, host decryption still needed. */
3006 if (!(ieee->host_encrypt || ieee->host_decrypt) &&
3007 strcmp(param->u.crypt.alg, "TKIP"))
3008 goto skip_host_crypt;
3010 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3011 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
3012 request_module("ieee80211_crypt_wep");
3013 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3014 //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
3015 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
3016 request_module("ieee80211_crypt_tkip");
3017 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3018 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
3019 request_module("ieee80211_crypt_ccmp");
3020 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3023 printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
3024 param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
3029 if (*crypt == NULL || (*crypt)->ops != ops) {
3030 struct ieee80211_crypt_data *new_crypt;
3032 ieee80211_crypt_delayed_deinit(ieee, crypt);
3034 new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL);
3035 if (new_crypt == NULL) {
3039 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
3040 new_crypt->ops = ops;
3041 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
3043 new_crypt->ops->init(param->u.crypt.idx);
3045 if (new_crypt->priv == NULL) {
3047 param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
3055 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
3056 (*crypt)->ops->set_key(param->u.crypt.key,
3057 param->u.crypt.key_len, param->u.crypt.seq,
3058 (*crypt)->priv) < 0) {
3059 printk("key setting failed\n");
3060 param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
3066 if (param->u.crypt.set_tx) {
3067 ieee->tx_keyidx = param->u.crypt.idx;
3068 sec.active_key = param->u.crypt.idx;
3069 sec.flags |= SEC_ACTIVE_KEY;
3071 sec.flags &= ~SEC_ACTIVE_KEY;
3073 if (param->u.crypt.alg != NULL) {
3074 memcpy(sec.keys[param->u.crypt.idx],
3076 param->u.crypt.key_len);
3077 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
3078 sec.flags |= (1 << param->u.crypt.idx);
3080 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3081 sec.flags |= SEC_LEVEL;
3082 sec.level = SEC_LEVEL_1;
3083 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3084 sec.flags |= SEC_LEVEL;
3085 sec.level = SEC_LEVEL_2;
3086 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3087 sec.flags |= SEC_LEVEL;
3088 sec.level = SEC_LEVEL_3;
3092 if (ieee->set_security)
3093 ieee->set_security(ieee->dev, &sec);
3095 /* Do not reset port if card is in Managed mode since resetting will
3096 * generate new IEEE 802.11 authentication which may end up in looping
3097 * with IEEE 802.1X. If your hardware requires a reset after WEP
3098 * configuration (for example... Prism2), implement the reset_port in
3099 * the callbacks structures used to initialize the 802.11 stack. */
3100 if (ieee->reset_on_keychange &&
3101 ieee->iw_mode != IW_MODE_INFRA &&
3103 ieee->reset_port(ieee->dev)) {
3104 printk("reset_port failed\n");
3105 param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
3112 inline struct sk_buff *ieee80211_disassociate_skb(
3113 struct ieee80211_network *beacon,
3114 struct ieee80211_device *ieee,
3117 struct sk_buff *skb;
3118 struct ieee80211_disassoc *disass;
3120 skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc));
3124 disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc));
3125 disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
3126 disass->header.duration_id = 0;
3128 memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
3129 memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
3130 memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
3132 disass->reason = asRsn;
3139 struct ieee80211_device *ieee,
3144 struct ieee80211_network *beacon = &ieee->current_network;
3145 struct sk_buff *skb;
3146 skb = ieee80211_disassociate_skb(beacon,ieee,asRsn);
3148 softmac_mgmt_xmit(skb, ieee);
3149 //dev_kfree_skb_any(skb);//edit by thomas
3152 EXPORT_SYMBOL(SendDisassociation);
3154 int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
3156 struct ieee_param *param;
3159 down(&ieee->wx_sem);
3160 //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
3162 if (p->length < sizeof(struct ieee_param) || !p->pointer){
3167 param = memdup_user(p->pointer, p->length);
3168 if (IS_ERR(param)) {
3169 ret = PTR_ERR(param);
3173 switch (param->cmd) {
3175 case IEEE_CMD_SET_WPA_PARAM:
3176 ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
3177 param->u.wpa_param.value);
3180 case IEEE_CMD_SET_WPA_IE:
3181 ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
3184 case IEEE_CMD_SET_ENCRYPTION:
3185 ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
3189 ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
3190 param->u.mlme.reason_code);
3194 printk("Unknown WPA supplicant request: %d\n",param->cmd);
3199 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
3208 EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
3210 void notify_wx_assoc_event(struct ieee80211_device *ieee)
3212 union iwreq_data wrqu;
3213 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3214 if (ieee->state == IEEE80211_LINKED)
3215 memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
3217 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
3218 wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
3220 EXPORT_SYMBOL(notify_wx_assoc_event);