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;
807 *(tag++) = MFIE_TYPE_IBSS_SET;
810 put_unaligned_le16(ieee->current_network.atim_window,
816 *(tag++) = MFIE_TYPE_ERP;
818 *(tag++) = erpinfo_content;
821 *(tag++) = MFIE_TYPE_RATES_EX;
822 *(tag++) = rate_ex_len-2;
823 memcpy(tag, ieee->current_network.rates_ex, rate_ex_len-2);
829 if (ieee->iw_mode == IW_MODE_ADHOC)
830 {//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
831 memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
833 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
837 //skb->dev = ieee->dev;
842 static struct sk_buff *ieee80211_assoc_resp(struct ieee80211_device *ieee,
848 struct ieee80211_crypt_data *crypt;
849 struct ieee80211_assoc_response_frame *assoc;
852 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
853 int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len + ieee->tx_headroom;
855 skb = dev_alloc_skb(len);
860 skb_reserve(skb, ieee->tx_headroom);
862 assoc = (struct ieee80211_assoc_response_frame *)
863 skb_put(skb, sizeof(struct ieee80211_assoc_response_frame));
865 assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
866 memcpy(assoc->header.addr1, dest,ETH_ALEN);
867 memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
868 memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
869 assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
870 WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
874 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
876 if (ieee->host_encrypt)
877 crypt = ieee->crypt[ieee->tx_keyidx];
880 encrypt = crypt && crypt->ops;
883 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
886 assoc->aid = cpu_to_le16(ieee->assoc_id);
887 if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
888 else ieee->assoc_id++;
890 tag = (u8 *) skb_put(skb, rate_len);
892 ieee80211_MFIE_Brate(ieee, &tag);
893 ieee80211_MFIE_Grate(ieee, &tag);
898 static struct sk_buff *ieee80211_auth_resp(struct ieee80211_device *ieee,
899 int status, u8 *dest)
902 struct ieee80211_authentication *auth;
903 int len = ieee->tx_headroom + sizeof(struct ieee80211_authentication)+1;
905 skb = dev_alloc_skb(len);
910 skb->len = sizeof(struct ieee80211_authentication);
912 auth = (struct ieee80211_authentication *)skb->data;
914 auth->status = cpu_to_le16(status);
915 auth->transaction = cpu_to_le16(2);
916 auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
918 memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
919 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
920 memcpy(auth->header.addr1, dest, ETH_ALEN);
921 auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
927 static struct sk_buff *ieee80211_null_func(struct ieee80211_device *ieee,
931 struct ieee80211_hdr_3addr *hdr;
933 skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
938 hdr = (struct ieee80211_hdr_3addr *)skb_put(skb,sizeof(struct ieee80211_hdr_3addr));
940 memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
941 memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
942 memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
944 hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
945 IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
946 (pwr ? IEEE80211_FCTL_PM:0));
954 static void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8 *dest)
956 struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
959 softmac_mgmt_xmit(buf, ieee);
963 static void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s,
966 struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
969 softmac_mgmt_xmit(buf, ieee);
973 static void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
977 struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
979 softmac_mgmt_xmit(buf, ieee);
983 inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
986 //unsigned long flags;
988 struct ieee80211_assoc_request_frame *hdr;
990 //short info_addr = 0;
992 //u16 suite_count = 0;
993 //u8 suit_select = 0;
994 //unsigned int wpa_len = beacon->wpa_ie_len;
996 u8 *ht_cap_buf = NULL;
998 u8 *realtek_ie_buf=NULL;
1000 int wpa_ie_len= ieee->wpa_ie_len;
1001 unsigned int ckip_ie_len=0;
1002 unsigned int ccxrm_ie_len=0;
1003 unsigned int cxvernum_ie_len=0;
1004 struct ieee80211_crypt_data *crypt;
1007 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
1008 unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
1010 unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
1015 crypt = ieee->crypt[ieee->tx_keyidx];
1016 encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len));
1018 //Include High Throuput capability && Realtek proprietary
1019 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1021 ht_cap_buf = (u8 *)&(ieee->pHTInfo->SelfHTCap);
1022 ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
1023 HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt);
1024 if (ieee->pHTInfo->bCurrentRT2RTAggregation)
1026 realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
1027 realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer);
1028 HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len);
1032 if (ieee->qos_support) {
1033 wmm_info_len = beacon->qos_data.supported?9:0;
1037 if (beacon->bCkipSupported)
1041 if (beacon->bCcxRmEnable)
1045 if (beacon->BssCcxVerNumber >= 2)
1046 cxvernum_ie_len = 5+2;
1049 len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1050 + beacon->ssid_len//essid tagged val
1051 + rate_len//rates tagged val
1060 + ieee->tx_headroom;
1062 len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1063 + beacon->ssid_len//essid tagged val
1064 + rate_len//rates tagged val
1072 + ieee->tx_headroom;
1075 skb = dev_alloc_skb(len);
1080 skb_reserve(skb, ieee->tx_headroom);
1082 hdr = (struct ieee80211_assoc_request_frame *)
1083 skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)+2);
1086 hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
1087 hdr->header.duration_id= 37; //FIXME
1088 memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
1089 memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1090 memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
1092 memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John
1094 hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
1095 if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
1096 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1098 if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1099 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); //add short_preamble here
1101 if(ieee->short_slot)
1102 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
1103 if (wmm_info_len) //QOS
1104 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS);
1106 hdr->listen_interval = 0xa; //FIXME
1108 hdr->info_element[0].id = MFIE_TYPE_SSID;
1110 hdr->info_element[0].len = beacon->ssid_len;
1111 tag = skb_put(skb, beacon->ssid_len);
1112 memcpy(tag, beacon->ssid, beacon->ssid_len);
1114 tag = skb_put(skb, rate_len);
1116 ieee80211_MFIE_Brate(ieee, &tag);
1117 ieee80211_MFIE_Grate(ieee, &tag);
1118 // For CCX 1 S13, CKIP. Added by Annie, 2006-08-14.
1119 if (beacon->bCkipSupported) {
1120 static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client"
1121 u8 CcxAironetBuf[30];
1122 OCTET_STRING osCcxAironetIE;
1124 memset(CcxAironetBuf, 0, 30);
1125 osCcxAironetIE.Octet = CcxAironetBuf;
1126 osCcxAironetIE.Length = sizeof(CcxAironetBuf);
1128 // Ref. CCX test plan v3.61, 3.2.3.1 step 13.
1129 // We want to make the device type as "4500-client". 060926, by CCW.
1131 memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui));
1133 // CCX1 spec V1.13, A01.1 CKIP Negotiation (page23):
1134 // "The CKIP negotiation is started with the associate request from the client to the access point,
1135 // containing an Aironet element with both the MIC and KP bits set."
1136 osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |= (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ;
1137 tag = skb_put(skb, ckip_ie_len);
1138 *tag++ = MFIE_TYPE_AIRONET;
1139 *tag++ = osCcxAironetIE.Length;
1140 memcpy(tag, osCcxAironetIE.Octet, osCcxAironetIE.Length);
1141 tag += osCcxAironetIE.Length;
1144 if (beacon->bCcxRmEnable)
1146 static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
1147 OCTET_STRING osCcxRmCap;
1149 osCcxRmCap.Octet = CcxRmCapBuf;
1150 osCcxRmCap.Length = sizeof(CcxRmCapBuf);
1151 tag = skb_put(skb, ccxrm_ie_len);
1152 *tag++ = MFIE_TYPE_GENERIC;
1153 *tag++ = osCcxRmCap.Length;
1154 memcpy(tag, osCcxRmCap.Octet, osCcxRmCap.Length);
1155 tag += osCcxRmCap.Length;
1158 if (beacon->BssCcxVerNumber >= 2) {
1159 u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
1160 OCTET_STRING osCcxVerNum;
1161 CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
1162 osCcxVerNum.Octet = CcxVerNumBuf;
1163 osCcxVerNum.Length = sizeof(CcxVerNumBuf);
1164 tag = skb_put(skb, cxvernum_ie_len);
1165 *tag++ = MFIE_TYPE_GENERIC;
1166 *tag++ = osCcxVerNum.Length;
1167 memcpy(tag, osCcxVerNum.Octet, osCcxVerNum.Length);
1168 tag += osCcxVerNum.Length;
1171 if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
1172 if (ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC)
1174 tag = skb_put(skb, ht_cap_len);
1175 *tag++ = MFIE_TYPE_HT_CAP;
1176 *tag++ = ht_cap_len - 2;
1177 memcpy(tag, ht_cap_buf,ht_cap_len -2);
1178 tag += ht_cap_len -2;
1183 //choose what wpa_supplicant gives to associate.
1184 tag = skb_put(skb, wpa_ie_len);
1186 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
1189 tag = skb_put(skb, wmm_info_len);
1191 ieee80211_WMM_Info(ieee, &tag);
1194 tag = skb_put(skb, turbo_info_len);
1195 if (turbo_info_len) {
1196 ieee80211_TURBO_Info(ieee, &tag);
1200 if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
1201 if(ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC)
1203 tag = skb_put(skb, ht_cap_len);
1204 *tag++ = MFIE_TYPE_GENERIC;
1205 *tag++ = ht_cap_len - 2;
1206 memcpy(tag, ht_cap_buf, ht_cap_len - 2);
1207 tag += ht_cap_len -2;
1210 if (ieee->pHTInfo->bCurrentRT2RTAggregation) {
1211 tag = skb_put(skb, realtek_ie_len);
1212 *tag++ = MFIE_TYPE_GENERIC;
1213 *tag++ = realtek_ie_len - 2;
1214 memcpy(tag, realtek_ie_buf,realtek_ie_len -2 );
1217 // printk("<=====%s(), %p, %p\n", __func__, ieee->dev, ieee->dev->dev_addr);
1218 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
1222 void ieee80211_associate_abort(struct ieee80211_device *ieee)
1225 unsigned long flags;
1226 spin_lock_irqsave(&ieee->lock, flags);
1228 ieee->associate_seq++;
1230 /* don't scan, and avoid to have the RX path possibily
1231 * try again to associate. Even do not react to AUTH or
1232 * ASSOC response. Just wait for the retry wq to be scheduled.
1233 * Here we will check if there are good nets to associate
1234 * with, so we retry or just get back to NO_LINK and scanning
1236 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
1237 IEEE80211_DEBUG_MGMT("Authentication failed\n");
1238 ieee->softmac_stats.no_auth_rs++;
1240 IEEE80211_DEBUG_MGMT("Association failed\n");
1241 ieee->softmac_stats.no_ass_rs++;
1244 ieee->state = IEEE80211_ASSOCIATING_RETRY;
1246 queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \
1247 IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
1249 spin_unlock_irqrestore(&ieee->lock, flags);
1252 static void ieee80211_associate_abort_cb(unsigned long dev)
1254 ieee80211_associate_abort((struct ieee80211_device *) dev);
1258 static void ieee80211_associate_step1(struct ieee80211_device *ieee)
1260 struct ieee80211_network *beacon = &ieee->current_network;
1261 struct sk_buff *skb;
1263 IEEE80211_DEBUG_MGMT("Stopping scan\n");
1265 ieee->softmac_stats.tx_auth_rq++;
1266 skb=ieee80211_authentication_req(beacon, ieee, 0);
1269 ieee80211_associate_abort(ieee);
1271 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
1272 IEEE80211_DEBUG_MGMT("Sending authentication request\n");
1273 //printk(KERN_WARNING "Sending authentication request\n");
1274 softmac_mgmt_xmit(skb, ieee);
1275 //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
1276 if (!timer_pending(&ieee->associate_timer)) {
1277 ieee->associate_timer.expires = jiffies + (HZ / 2);
1278 add_timer(&ieee->associate_timer);
1280 //dev_kfree_skb_any(skb);//edit by thomas
1284 static void ieee80211_auth_challenge(struct ieee80211_device *ieee,
1289 struct sk_buff *skb;
1290 struct ieee80211_network *beacon = &ieee->current_network;
1291 // int hlen = sizeof(struct ieee80211_authentication);
1293 ieee->associate_seq++;
1294 ieee->softmac_stats.tx_auth_rq++;
1296 skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
1298 ieee80211_associate_abort(ieee);
1300 c = skb_put(skb, chlen+2);
1301 *(c++) = MFIE_TYPE_CHALLENGE;
1303 memcpy(c, challenge, chlen);
1305 IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
1307 ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr ));
1309 softmac_mgmt_xmit(skb, ieee);
1310 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1311 //dev_kfree_skb_any(skb);//edit by thomas
1316 static void ieee80211_associate_step2(struct ieee80211_device *ieee)
1318 struct sk_buff *skb;
1319 struct ieee80211_network *beacon = &ieee->current_network;
1321 del_timer_sync(&ieee->associate_timer);
1323 IEEE80211_DEBUG_MGMT("Sending association request\n");
1325 ieee->softmac_stats.tx_ass_rq++;
1326 skb=ieee80211_association_req(beacon, ieee);
1328 ieee80211_associate_abort(ieee);
1330 softmac_mgmt_xmit(skb, ieee);
1331 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1332 //dev_kfree_skb_any(skb);//edit by thomas
1335 static void ieee80211_associate_complete_wq(struct work_struct *work)
1337 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
1338 printk(KERN_INFO "Associated successfully\n");
1339 if(ieee80211_is_54g(&ieee->current_network) &&
1340 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1343 printk(KERN_INFO"Using G rates:%d\n", ieee->rate);
1346 printk(KERN_INFO"Using B rates:%d\n", ieee->rate);
1348 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1350 printk("Successfully associated, ht enabled\n");
1355 printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
1356 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1357 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1359 ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500);
1360 // To prevent the immediately calling watch_dog after association.
1361 if (ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
1363 ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
1364 ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
1366 ieee->link_change(ieee->dev);
1367 if(ieee->is_silent_reset == 0){
1368 printk("============>normal associate\n");
1369 notify_wx_assoc_event(ieee);
1371 else if(ieee->is_silent_reset == 1)
1373 printk("==================>silent reset associate\n");
1374 ieee->is_silent_reset = false;
1377 if (ieee->data_hard_resume)
1378 ieee->data_hard_resume(ieee->dev);
1379 netif_carrier_on(ieee->dev);
1382 static void ieee80211_associate_complete(struct ieee80211_device *ieee)
1385 // struct net_device* dev = ieee->dev;
1386 del_timer_sync(&ieee->associate_timer);
1388 ieee->state = IEEE80211_LINKED;
1389 //ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet);
1390 queue_work(ieee->wq, &ieee->associate_complete_wq);
1393 static void ieee80211_associate_procedure_wq(struct work_struct *work)
1395 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
1396 ieee->sync_scan_hurryup = 1;
1397 down(&ieee->wx_sem);
1399 if (ieee->data_hard_stop)
1400 ieee->data_hard_stop(ieee->dev);
1402 ieee80211_stop_scan(ieee);
1403 printk("===>%s(), chan:%d\n", __func__, ieee->current_network.channel);
1404 //ieee->set_chan(ieee->dev, ieee->current_network.channel);
1405 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1407 ieee->associate_seq = 1;
1408 ieee80211_associate_step1(ieee);
1413 inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
1415 u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
1416 int tmp_ssid_len = 0;
1418 short apset, ssidset, ssidbroad, apmatch, ssidmatch;
1420 /* we are interested in new new only if we are not associated
1421 * and we are not associating / authenticating
1423 if (ieee->state != IEEE80211_NOLINK)
1426 if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
1429 if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
1433 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) {
1434 /* if the user specified the AP MAC, we need also the essid
1435 * This could be obtained by beacons or, if the network does not
1436 * broadcast it, it can be put manually.
1438 apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
1439 ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
1440 ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0');
1441 apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
1442 ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\
1443 (!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
1446 if ( /* if the user set the AP check if match.
1447 * if the network does not broadcast essid we check the user supplyed ANY essid
1448 * if the network does broadcast and the user does not set essid it is OK
1449 * if the network does broadcast and the user did set essid chech if essid match
1451 (apset && apmatch &&
1452 ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
1453 /* if the ap is not set, check that the user set the bssid
1454 * and the network does broadcast and that those two bssid matches
1456 (!apset && ssidset && ssidbroad && ssidmatch)
1458 /* if the essid is hidden replace it with the
1459 * essid provided by the user.
1462 strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
1463 tmp_ssid_len = ieee->current_network.ssid_len;
1465 memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
1468 strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
1469 ieee->current_network.ssid_len = tmp_ssid_len;
1471 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);
1473 //ieee->pHTInfo->IOTAction = 0;
1474 HTResetIOTSetting(ieee->pHTInfo);
1475 if (ieee->iw_mode == IW_MODE_INFRA){
1476 /* Join the network for the first time */
1477 ieee->AsocRetryCount = 0;
1478 //for HT by amy 080514
1479 if((ieee->current_network.qos_data.supported == 1) &&
1480 // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT))
1481 ieee->current_network.bssht.bdSupportHT)
1482 /*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.*/
1484 // ieee->pHTInfo->bCurrentHTSupport = true;
1485 HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network));
1489 ieee->pHTInfo->bCurrentHTSupport = false;
1492 ieee->state = IEEE80211_ASSOCIATING;
1493 queue_work(ieee->wq, &ieee->associate_procedure_wq);
1495 if(ieee80211_is_54g(&ieee->current_network) &&
1496 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1498 ieee->SetWirelessMode(ieee->dev, IEEE_G);
1499 printk(KERN_INFO"Using G rates\n");
1502 ieee->SetWirelessMode(ieee->dev, IEEE_B);
1503 printk(KERN_INFO"Using B rates\n");
1505 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1506 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1507 ieee->state = IEEE80211_LINKED;
1515 void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
1517 unsigned long flags;
1518 struct ieee80211_network *target;
1520 spin_lock_irqsave(&ieee->lock, flags);
1522 list_for_each_entry(target, &ieee->network_list, list) {
1524 /* if the state become different that NOLINK means
1525 * we had found what we are searching for
1528 if (ieee->state != IEEE80211_NOLINK)
1531 if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
1532 ieee80211_softmac_new_net(ieee, target);
1535 spin_unlock_irqrestore(&ieee->lock, flags);
1540 static inline u16 auth_parse(struct sk_buff *skb, u8 **challenge, int *chlen)
1542 struct ieee80211_authentication *a;
1544 if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
1545 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
1549 a = (struct ieee80211_authentication *) skb->data;
1550 if (skb->len > (sizeof(struct ieee80211_authentication) + 3)) {
1551 t = skb->data + sizeof(struct ieee80211_authentication);
1553 if (*(t++) == MFIE_TYPE_CHALLENGE) {
1555 *challenge = kmemdup(t, *chlen, GFP_ATOMIC);
1561 return cpu_to_le16(a->status);
1566 static int auth_rq_parse(struct sk_buff *skb, u8 *dest)
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 request: %d\n",skb->len);
1574 a = (struct ieee80211_authentication *) skb->data;
1576 memcpy(dest,a->header.addr2, ETH_ALEN);
1578 if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
1579 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1581 return WLAN_STATUS_SUCCESS;
1584 static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
1591 struct ieee80211_hdr_3addr *header =
1592 (struct ieee80211_hdr_3addr *) skb->data;
1594 if (skb->len < sizeof (struct ieee80211_hdr_3addr ))
1595 return -1; /* corrupted */
1597 memcpy(src,header->addr2, ETH_ALEN);
1599 skbend = (u8 *)skb->data + skb->len;
1601 tag = skb->data + sizeof (struct ieee80211_hdr_3addr );
1603 while (tag+1 < skbend){
1609 tag++; /* point to the len field */
1610 tag = tag + *(tag); /* point to the last data byte of the tag */
1611 tag++; /* point to the next tag */
1614 //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
1615 if (ssidlen == 0) return 1;
1617 if (!ssid) return 1; /* ssid not found in tagged param */
1618 return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
1622 static int assoc_rq_parse(struct sk_buff *skb, u8 *dest)
1624 struct ieee80211_assoc_request_frame *a;
1626 if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
1627 sizeof(struct ieee80211_info_element))) {
1629 IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
1633 a = (struct ieee80211_assoc_request_frame *) skb->data;
1635 memcpy(dest,a->header.addr2,ETH_ALEN);
1640 static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid)
1642 struct ieee80211_assoc_response_frame *response_head;
1645 if (skb->len < sizeof(struct ieee80211_assoc_response_frame)) {
1646 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
1650 response_head = (struct ieee80211_assoc_response_frame *) skb->data;
1651 *aid = le16_to_cpu(response_head->aid) & 0x3fff;
1653 status_code = le16_to_cpu(response_head->status);
1654 if((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \
1655 status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&&
1656 ((ieee->mode == IEEE_G) &&
1657 (ieee->current_network.mode == IEEE_N_24G) &&
1658 (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) {
1659 ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
1661 ieee->AsocRetryCount = 0;
1664 return le16_to_cpu(response_head->status);
1668 ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1672 //IEEE80211DMESG("Rx probe");
1673 ieee->softmac_stats.rx_probe_rq++;
1674 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1675 if (probe_rq_parse(ieee, skb, dest)) {
1676 //IEEE80211DMESG("Was for me!");
1677 ieee->softmac_stats.tx_probe_rs++;
1678 ieee80211_resp_to_probe(ieee, dest);
1683 ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1687 //IEEE80211DMESG("Rx probe");
1688 ieee->softmac_stats.rx_auth_rq++;
1690 status = auth_rq_parse(skb, dest);
1692 ieee80211_resp_to_auth(ieee, status, dest);
1694 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1699 ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1703 //unsigned long flags;
1705 ieee->softmac_stats.rx_ass_rq++;
1706 if (assoc_rq_parse(skb, dest) != -1) {
1707 ieee80211_resp_to_assoc_rq(ieee, dest);
1710 printk(KERN_INFO"New client associated: %pM\n", dest);
1714 static void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee,
1718 struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
1721 softmac_ps_mgmt_xmit(buf, ieee);
1724 /* EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame); */
1726 static short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h,
1729 int timeout = ieee->ps_timeout;
1731 /*if(ieee->ps == IEEE80211_PS_DISABLED ||
1732 ieee->iw_mode != IW_MODE_INFRA ||
1733 ieee->state != IEEE80211_LINKED)
1737 dtim = ieee->current_network.dtim_data;
1739 if(!(dtim & IEEE80211_DTIM_VALID))
1741 timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
1742 //printk("VALID\n");
1743 ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
1745 if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
1748 if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
1751 if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
1754 if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
1755 (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
1759 *time_l = ieee->current_network.last_dtim_sta_time[0]
1760 + (ieee->current_network.beacon_interval
1761 * ieee->current_network.dtim_period) * 1000;
1765 *time_h = ieee->current_network.last_dtim_sta_time[1];
1766 if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
1775 static inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
1781 unsigned long flags, flags2;
1783 spin_lock_irqsave(&ieee->lock, flags);
1785 if ((ieee->ps == IEEE80211_PS_DISABLED ||
1786 ieee->iw_mode != IW_MODE_INFRA ||
1787 ieee->state != IEEE80211_LINKED)){
1789 // #warning CHECK_LOCK_HERE
1790 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1792 ieee80211_sta_wakeup(ieee, 1);
1794 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1797 sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
1798 /* 2 wake, 1 sleep, 0 do nothing */
1804 if(ieee->sta_sleep == 1)
1805 ieee->enter_sleep_state(ieee->dev, th, tl);
1807 else if(ieee->sta_sleep == 0){
1808 // printk("send null 1\n");
1809 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1811 if(ieee->ps_is_queue_empty(ieee->dev)){
1814 ieee->sta_sleep = 2;
1816 ieee->ps_request_tx_ack(ieee->dev);
1818 ieee80211_sta_ps_send_null_frame(ieee, 1);
1823 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1828 }else if(sleep == 2){
1829 //#warning CHECK_LOCK_HERE
1830 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1832 ieee80211_sta_wakeup(ieee, 1);
1834 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1838 spin_unlock_irqrestore(&ieee->lock, flags);
1842 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
1844 if (ieee->sta_sleep == 0) {
1846 printk("Warning: driver is probably failing to report TX ps error\n");
1847 ieee->ps_request_tx_ack(ieee->dev);
1848 ieee80211_sta_ps_send_null_frame(ieee, 0);
1854 if(ieee->sta_sleep == 1)
1855 ieee->sta_wake_up(ieee->dev);
1857 ieee->sta_sleep = 0;
1860 ieee->ps_request_tx_ack(ieee->dev);
1861 ieee80211_sta_ps_send_null_frame(ieee, 0);
1865 void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
1867 unsigned long flags, flags2;
1869 spin_lock_irqsave(&ieee->lock, flags);
1871 if(ieee->sta_sleep == 2){
1872 /* Null frame with PS bit set */
1874 ieee->sta_sleep = 1;
1875 ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
1877 /* if the card report not success we can't be sure the AP
1878 * has not RXed so we can't assume the AP believe us awake
1881 /* 21112005 - tx again null without PS bit if lost */
1884 if ((ieee->sta_sleep == 0) && !success) {
1885 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1886 ieee80211_sta_ps_send_null_frame(ieee, 0);
1887 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1890 spin_unlock_irqrestore(&ieee->lock, flags);
1892 EXPORT_SYMBOL(ieee80211_ps_tx_ack);
1894 static void ieee80211_process_action(struct ieee80211_device *ieee,
1895 struct sk_buff *skb)
1897 struct ieee80211_hdr *header = (struct ieee80211_hdr *)skb->data;
1898 u8 *act = ieee80211_get_payload(header);
1900 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
1903 IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
1910 if (*act == ACT_ADDBAREQ)
1911 ieee80211_rx_ADDBAReq(ieee, skb);
1912 else if (*act == ACT_ADDBARSP)
1913 ieee80211_rx_ADDBARsp(ieee, skb);
1914 else if (*act == ACT_DELBA)
1915 ieee80211_rx_DELBA(ieee, skb);
1924 static void ieee80211_check_auth_response(struct ieee80211_device *ieee,
1925 struct sk_buff *skb)
1927 /* default support N mode, disable halfNmode */
1928 bool bSupportNmode = true, bHalfSupportNmode = false;
1934 errcode = auth_parse(skb, &challenge, &chlen);
1936 if (ieee->open_wep || !challenge) {
1937 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
1938 ieee->softmac_stats.rx_auth_rs_ok++;
1939 iotAction = ieee->pHTInfo->IOTAction;
1940 if (!(iotAction & HT_IOT_ACT_PURE_N_MODE)) {
1941 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) {
1942 /* WEP or TKIP encryption */
1943 if (IsHTHalfNmodeAPs(ieee)) {
1944 bSupportNmode = true;
1945 bHalfSupportNmode = true;
1947 bSupportNmode = false;
1948 bHalfSupportNmode = false;
1950 netdev_dbg(ieee->dev, "SEC(%d, %d)\n",
1955 /* Dummy wirless mode setting- avoid encryption issue */
1956 if (bSupportNmode) {
1957 /* N mode setting */
1958 ieee->SetWirelessMode(ieee->dev,
1959 ieee->current_network.mode);
1961 /* b/g mode setting - TODO */
1962 ieee->SetWirelessMode(ieee->dev, IEEE_G);
1965 if (ieee->current_network.mode == IEEE_N_24G &&
1966 bHalfSupportNmode == true) {
1967 netdev_dbg(ieee->dev, "enter half N mode\n");
1968 ieee->bHalfWirelessN24GMode = true;
1970 ieee->bHalfWirelessN24GMode = false;
1972 ieee80211_associate_step2(ieee);
1974 ieee80211_auth_challenge(ieee, challenge, chlen);
1977 ieee->softmac_stats.rx_auth_rs_err++;
1978 IEEE80211_DEBUG_MGMT("Auth response status code 0x%x", errcode);
1979 ieee80211_associate_abort(ieee);
1984 ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
1985 struct ieee80211_rx_stats *rx_stats, u16 type,
1988 struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
1991 struct ieee80211_assoc_response_frame *assoc_resp;
1992 // struct ieee80211_info_element *info_element;
1994 if(!ieee->proto_started)
1997 if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
1998 ieee->iw_mode == IW_MODE_INFRA &&
1999 ieee->state == IEEE80211_LINKED))
2001 tasklet_schedule(&ieee->ps_task);
2003 if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
2004 WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
2005 ieee->last_rx_ps_time = jiffies;
2007 switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
2009 case IEEE80211_STYPE_ASSOC_RESP:
2010 case IEEE80211_STYPE_REASSOC_RESP:
2012 IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
2013 WLAN_FC_GET_STYPE(header->frame_ctl));
2014 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2015 ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
2016 ieee->iw_mode == IW_MODE_INFRA){
2017 struct ieee80211_network network_resp;
2018 struct ieee80211_network *network = &network_resp;
2020 errcode = assoc_parse(ieee, skb, &aid);
2022 ieee->state=IEEE80211_LINKED;
2023 ieee->assoc_id = aid;
2024 ieee->softmac_stats.rx_ass_ok++;
2025 /* station support qos */
2026 /* Let the register setting defaultly with Legacy station */
2027 if (ieee->qos_support) {
2028 assoc_resp = (struct ieee80211_assoc_response_frame *)skb->data;
2029 memset(network, 0, sizeof(*network));
2030 if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\
2031 rx_stats->len - sizeof(*assoc_resp),\
2036 { //filling the PeerHTCap. //maybe not necessary as we can get its info from current_network.
2037 memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
2038 memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
2040 if (ieee->handle_assoc_response != NULL)
2041 ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame *)header, network);
2043 ieee80211_associate_complete(ieee);
2045 /* aid could not been allocated */
2046 ieee->softmac_stats.rx_ass_err++;
2048 "Association response status code 0x%x\n",
2050 IEEE80211_DEBUG_MGMT(
2051 "Association response status code 0x%x\n",
2053 if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
2054 queue_work(ieee->wq, &ieee->associate_procedure_wq);
2056 ieee80211_associate_abort(ieee);
2062 case IEEE80211_STYPE_ASSOC_REQ:
2063 case IEEE80211_STYPE_REASSOC_REQ:
2065 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2066 ieee->iw_mode == IW_MODE_MASTER)
2068 ieee80211_rx_assoc_rq(ieee, skb);
2071 case IEEE80211_STYPE_AUTH:
2073 if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) {
2074 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING
2075 && ieee->iw_mode == IW_MODE_INFRA) {
2077 IEEE80211_DEBUG_MGMT("Received auth response");
2078 ieee80211_check_auth_response(ieee, skb);
2079 } else if (ieee->iw_mode == IW_MODE_MASTER) {
2080 ieee80211_rx_auth_rq(ieee, skb);
2085 case IEEE80211_STYPE_PROBE_REQ:
2087 if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
2088 ((ieee->iw_mode == IW_MODE_ADHOC ||
2089 ieee->iw_mode == IW_MODE_MASTER) &&
2090 ieee->state == IEEE80211_LINKED)){
2091 ieee80211_rx_probe_rq(ieee, skb);
2095 case IEEE80211_STYPE_DISASSOC:
2096 case IEEE80211_STYPE_DEAUTH:
2097 /* FIXME for now repeat all the association procedure
2098 * both for disassociation and deauthentication
2100 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2101 ieee->state == IEEE80211_LINKED &&
2102 ieee->iw_mode == IW_MODE_INFRA){
2104 ieee->state = IEEE80211_ASSOCIATING;
2105 ieee->softmac_stats.reassoc++;
2107 notify_wx_assoc_event(ieee);
2108 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2109 RemovePeerTS(ieee, header->addr2);
2110 queue_work(ieee->wq, &ieee->associate_procedure_wq);
2113 case IEEE80211_STYPE_MANAGE_ACT:
2114 ieee80211_process_action(ieee, skb);
2120 //dev_kfree_skb_any(skb);
2124 /* The following are for a simpler TX queue management.
2125 * Instead of using netif_[stop/wake]_queue, the driver
2126 * will use these two functions (plus a reset one) that
2127 * will internally call the kernel netif_* and take care
2128 * of the ieee802.11 fragmentation.
2129 * So, the driver receives a fragment at a time and might
2130 * call the stop function when it wants, without taking
2131 * care to have enough room to TX an entire packet.
2132 * This might be useful if each fragment needs its own
2133 * descriptor. Thus, just keeping a total free memory > than
2134 * the max fragmentation threshold is not enough. If the
2135 * ieee802.11 stack passed a TXB struct, then you would need
2136 * to keep N free descriptors where
2137 * N = MAX_PACKET_SIZE / MIN_FRAG_THRESHOLD.
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 = true;
2727 ieee->tx_pending.txb = NULL;
2729 setup_timer(&ieee->associate_timer, ieee80211_associate_abort_cb,
2730 (unsigned long)ieee);
2732 setup_timer(&ieee->beacon_timer, ieee80211_send_beacon_cb,
2733 (unsigned long)ieee);
2735 ieee->wq = create_workqueue(DRV_NAME);
2737 INIT_DELAYED_WORK(&ieee->start_ibss_wq, ieee80211_start_ibss_wq);
2738 INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
2739 INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
2740 INIT_DELAYED_WORK(&ieee->softmac_scan_wq, ieee80211_softmac_scan_wq);
2741 INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
2742 INIT_WORK(&ieee->wx_sync_scan_wq, ieee80211_wx_sync_scan_wq);
2745 sema_init(&ieee->wx_sem, 1);
2746 sema_init(&ieee->scan_sem, 1);
2748 spin_lock_init(&ieee->mgmt_tx_lock);
2749 spin_lock_init(&ieee->beacon_lock);
2751 tasklet_init(&ieee->ps_task,
2752 (void(*)(unsigned long)) ieee80211_sta_ps,
2753 (unsigned long)ieee);
2757 void ieee80211_softmac_free(struct ieee80211_device *ieee)
2759 down(&ieee->wx_sem);
2760 kfree(ieee->pDot11dInfo);
2761 ieee->pDot11dInfo = NULL;
2762 del_timer_sync(&ieee->associate_timer);
2764 cancel_delayed_work(&ieee->associate_retry_wq);
2765 destroy_workqueue(ieee->wq);
2770 /********************************************************
2771 * Start of WPA code. *
2772 * this is stolen from the ipw2200 driver *
2773 ********************************************************/
2776 static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
2778 /* This is called when wpa_supplicant loads and closes the driver
2780 printk("%s WPA\n",value ? "enabling" : "disabling");
2781 ieee->wpa_enabled = value;
2786 static void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee,
2787 char *wpa_ie, int wpa_ie_len)
2789 /* make sure WPA is enabled */
2790 ieee80211_wpa_enable(ieee, 1);
2792 ieee80211_disassociate(ieee);
2796 static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
2802 case IEEE_MLME_STA_DEAUTH:
2806 case IEEE_MLME_STA_DISASSOC:
2807 ieee80211_disassociate(ieee);
2811 printk("Unknown MLME request: %d\n", command);
2819 static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
2820 struct ieee_param *param, int plen)
2824 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
2825 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
2828 if (param->u.wpa_ie.len) {
2829 buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len,
2834 kfree(ieee->wpa_ie);
2836 ieee->wpa_ie_len = param->u.wpa_ie.len;
2838 kfree(ieee->wpa_ie);
2839 ieee->wpa_ie = NULL;
2840 ieee->wpa_ie_len = 0;
2843 ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
2847 #define AUTH_ALG_OPEN_SYSTEM 0x1
2848 #define AUTH_ALG_SHARED_KEY 0x2
2850 static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
2853 struct ieee80211_security sec = {
2854 .flags = SEC_AUTH_MODE,
2857 if (value & AUTH_ALG_SHARED_KEY) {
2858 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
2860 ieee->auth_mode = 1;
2861 } else if (value & AUTH_ALG_OPEN_SYSTEM){
2862 sec.auth_mode = WLAN_AUTH_OPEN;
2864 ieee->auth_mode = 0;
2866 else if (value & IW_AUTH_ALG_LEAP){
2867 sec.auth_mode = WLAN_AUTH_LEAP;
2869 ieee->auth_mode = 2;
2873 if (ieee->set_security)
2874 ieee->set_security(ieee->dev, &sec);
2876 // ret = -EOPNOTSUPP;
2881 static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
2884 unsigned long flags;
2887 case IEEE_PARAM_WPA_ENABLED:
2888 ret = ieee80211_wpa_enable(ieee, value);
2891 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2892 ieee->tkip_countermeasures=value;
2895 case IEEE_PARAM_DROP_UNENCRYPTED: {
2898 * wpa_supplicant calls set_wpa_enabled when the driver
2899 * is loaded and unloaded, regardless of if WPA is being
2900 * used. No other calls are made which can be used to
2901 * determine if encryption will be used or not prior to
2902 * association being expected. If encryption is not being
2903 * used, drop_unencrypted is set to false, else true -- we
2904 * can use this to determine if the CAP_PRIVACY_ON bit should
2907 struct ieee80211_security sec = {
2908 .flags = SEC_ENABLED,
2911 ieee->drop_unencrypted = value;
2912 /* We only change SEC_LEVEL for open mode. Others
2913 * are set by ipw_wpa_set_encryption.
2916 sec.flags |= SEC_LEVEL;
2917 sec.level = SEC_LEVEL_0;
2920 sec.flags |= SEC_LEVEL;
2921 sec.level = SEC_LEVEL_1;
2923 if (ieee->set_security)
2924 ieee->set_security(ieee->dev, &sec);
2928 case IEEE_PARAM_PRIVACY_INVOKED:
2929 ieee->privacy_invoked=value;
2932 case IEEE_PARAM_AUTH_ALGS:
2933 ret = ieee80211_wpa_set_auth_algs(ieee, value);
2936 case IEEE_PARAM_IEEE_802_1X:
2937 ieee->ieee802_1x=value;
2939 case IEEE_PARAM_WPAX_SELECT:
2940 // added for WPA2 mixed mode
2941 spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags);
2942 ieee->wpax_type_set = 1;
2943 ieee->wpax_type_notify = value;
2944 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags);
2948 printk("Unknown WPA param: %d\n",name);
2955 /* implementation borrowed from hostap driver */
2957 static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
2958 struct ieee_param *param, int param_len)
2962 struct ieee80211_crypto_ops *ops;
2963 struct ieee80211_crypt_data **crypt;
2965 struct ieee80211_security sec = {
2969 param->u.crypt.err = 0;
2970 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
2973 (int) ((char *) param->u.crypt.key - (char *) param) +
2974 param->u.crypt.key_len) {
2975 printk("Len mismatch %d, %d\n", param_len,
2976 param->u.crypt.key_len);
2979 if (is_broadcast_ether_addr(param->sta_addr)) {
2980 if (param->u.crypt.idx >= WEP_KEYS)
2982 crypt = &ieee->crypt[param->u.crypt.idx];
2987 if (strcmp(param->u.crypt.alg, "none") == 0) {
2992 sec.level = SEC_LEVEL_0;
2993 sec.flags |= SEC_ENABLED | SEC_LEVEL;
2994 ieee80211_crypt_delayed_deinit(ieee, crypt);
3001 sec.flags |= SEC_ENABLED;
3003 /* IPW HW cannot build TKIP MIC, host decryption still needed. */
3004 if (!(ieee->host_encrypt || ieee->host_decrypt) &&
3005 strcmp(param->u.crypt.alg, "TKIP"))
3006 goto skip_host_crypt;
3008 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3009 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
3010 request_module("ieee80211_crypt_wep");
3011 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3012 //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
3013 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
3014 request_module("ieee80211_crypt_tkip");
3015 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3016 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
3017 request_module("ieee80211_crypt_ccmp");
3018 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3021 printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
3022 param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
3027 if (*crypt == NULL || (*crypt)->ops != ops) {
3028 struct ieee80211_crypt_data *new_crypt;
3030 ieee80211_crypt_delayed_deinit(ieee, crypt);
3032 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
3033 if (new_crypt == NULL) {
3037 new_crypt->ops = ops;
3038 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
3040 new_crypt->ops->init(param->u.crypt.idx);
3042 if (new_crypt->priv == NULL) {
3044 param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
3052 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
3053 (*crypt)->ops->set_key(param->u.crypt.key,
3054 param->u.crypt.key_len, param->u.crypt.seq,
3055 (*crypt)->priv) < 0) {
3056 printk("key setting failed\n");
3057 param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
3063 if (param->u.crypt.set_tx) {
3064 ieee->tx_keyidx = param->u.crypt.idx;
3065 sec.active_key = param->u.crypt.idx;
3066 sec.flags |= SEC_ACTIVE_KEY;
3068 sec.flags &= ~SEC_ACTIVE_KEY;
3070 if (param->u.crypt.alg != NULL) {
3071 memcpy(sec.keys[param->u.crypt.idx],
3073 param->u.crypt.key_len);
3074 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
3075 sec.flags |= (1 << param->u.crypt.idx);
3077 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3078 sec.flags |= SEC_LEVEL;
3079 sec.level = SEC_LEVEL_1;
3080 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3081 sec.flags |= SEC_LEVEL;
3082 sec.level = SEC_LEVEL_2;
3083 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3084 sec.flags |= SEC_LEVEL;
3085 sec.level = SEC_LEVEL_3;
3089 if (ieee->set_security)
3090 ieee->set_security(ieee->dev, &sec);
3092 /* Do not reset port if card is in Managed mode since resetting will
3093 * generate new IEEE 802.11 authentication which may end up in looping
3094 * with IEEE 802.1X. If your hardware requires a reset after WEP
3095 * configuration (for example... Prism2), implement the reset_port in
3096 * the callbacks structures used to initialize the 802.11 stack. */
3097 if (ieee->reset_on_keychange &&
3098 ieee->iw_mode != IW_MODE_INFRA &&
3100 ieee->reset_port(ieee->dev)) {
3101 printk("reset_port failed\n");
3102 param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
3109 inline struct sk_buff *ieee80211_disassociate_skb(
3110 struct ieee80211_network *beacon,
3111 struct ieee80211_device *ieee,
3114 struct sk_buff *skb;
3115 struct ieee80211_disassoc *disass;
3117 skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc));
3121 disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc));
3122 disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
3123 disass->header.duration_id = 0;
3125 memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
3126 memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
3127 memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
3129 disass->reason = asRsn;
3136 struct ieee80211_device *ieee,
3141 struct ieee80211_network *beacon = &ieee->current_network;
3142 struct sk_buff *skb;
3143 skb = ieee80211_disassociate_skb(beacon,ieee,asRsn);
3145 softmac_mgmt_xmit(skb, ieee);
3146 //dev_kfree_skb_any(skb);//edit by thomas
3149 EXPORT_SYMBOL(SendDisassociation);
3151 int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
3153 struct ieee_param *param;
3156 down(&ieee->wx_sem);
3157 //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
3159 if (p->length < sizeof(struct ieee_param) || !p->pointer) {
3164 param = memdup_user(p->pointer, p->length);
3165 if (IS_ERR(param)) {
3166 ret = PTR_ERR(param);
3170 switch (param->cmd) {
3172 case IEEE_CMD_SET_WPA_PARAM:
3173 ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
3174 param->u.wpa_param.value);
3177 case IEEE_CMD_SET_WPA_IE:
3178 ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
3181 case IEEE_CMD_SET_ENCRYPTION:
3182 ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
3186 ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
3187 param->u.mlme.reason_code);
3191 printk("Unknown WPA supplicant request: %d\n",param->cmd);
3196 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
3205 EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
3207 void notify_wx_assoc_event(struct ieee80211_device *ieee)
3209 union iwreq_data wrqu;
3210 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3211 if (ieee->state == IEEE80211_LINKED)
3212 memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
3214 eth_zero_addr(wrqu.ap_addr.sa_data);
3215 wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
3217 EXPORT_SYMBOL(notify_wx_assoc_event);