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 <linux/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 */
111 *tag++ = 0x02; /* 5 */
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 */
136 *tag++ = 0x01; /* 5 */
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 rtl_80211_hdr_3addr *header=
226 (struct rtl_80211_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 netif_trans_update(ieee->dev);
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 ieee->softmac_hard_start_xmit(skb, ieee->dev);
281 //dev_kfree_skb_any(skb);//edit by thomas
283 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
288 softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
291 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
292 struct rtl_80211_hdr_3addr *header =
293 (struct rtl_80211_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 netif_trans_update(ieee->dev);
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 static 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 eth_broadcast_addr(req->header.addr1);
347 memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
348 eth_broadcast_addr(req->header.addr3);
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,
385 jiffies + msecs_to_jiffies(ieee->current_network.beacon_interval-5));
387 //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
391 static void ieee80211_send_beacon_cb(unsigned long _ieee)
393 struct ieee80211_device *ieee =
394 (struct ieee80211_device *) _ieee;
397 spin_lock_irqsave(&ieee->beacon_lock, flags);
398 ieee80211_send_beacon(ieee);
399 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
403 static void ieee80211_send_probe(struct ieee80211_device *ieee)
407 skb = ieee80211_probe_req(ieee);
409 softmac_mgmt_xmit(skb, ieee);
410 ieee->softmac_stats.tx_probe_rq++;
411 //dev_kfree_skb_any(skb);//edit by thomas
415 static void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
417 if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)) {
418 ieee80211_send_probe(ieee);
419 ieee80211_send_probe(ieee);
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 mutex_lock(&ieee->scan_mutex);
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 && ieee->sync_scan_hurryup)
473 msleep_interruptible(IEEE80211_SOFTMAC_SCAN_TIME);
477 if(ieee->state < IEEE80211_LINKED){
478 ieee->actscanning = false;
479 mutex_unlock(&ieee->scan_mutex);
482 ieee->sync_scan_hurryup = 0;
483 if(IS_DOT11D_ENABLE(ieee))
484 DOT11D_ScanComplete(ieee);
485 mutex_unlock(&ieee->scan_mutex);
488 EXPORT_SYMBOL(ieee80211_softmac_scan_syncro);
490 static void ieee80211_softmac_scan_wq(struct work_struct *work)
492 struct delayed_work *dwork = to_delayed_work(work);
493 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
494 static short watchdog;
495 u8 channel_map[MAX_CHANNEL_NUMBER+1];
496 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
499 mutex_lock(&ieee->scan_mutex);
501 ieee->current_network.channel =
502 (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
503 if (watchdog++ > MAX_CHANNEL_NUMBER)
505 //if current channel is not in channel map, set to default channel.
506 if (!channel_map[ieee->current_network.channel]) {
507 ieee->current_network.channel = 6;
508 goto out; /* no good chans */
511 }while(!channel_map[ieee->current_network.channel]);
512 if (ieee->scanning == 0 )
514 ieee->set_chan(ieee->dev, ieee->current_network.channel);
515 if(channel_map[ieee->current_network.channel] == 1)
516 ieee80211_send_probe_requests(ieee);
519 schedule_delayed_work(&ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
521 mutex_unlock(&ieee->scan_mutex);
524 if(IS_DOT11D_ENABLE(ieee))
525 DOT11D_ScanComplete(ieee);
526 ieee->actscanning = false;
529 mutex_unlock(&ieee->scan_mutex);
534 static void ieee80211_beacons_start(struct ieee80211_device *ieee)
537 spin_lock_irqsave(&ieee->beacon_lock,flags);
539 ieee->beacon_txing = 1;
540 ieee80211_send_beacon(ieee);
542 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
545 static void ieee80211_beacons_stop(struct ieee80211_device *ieee)
549 spin_lock_irqsave(&ieee->beacon_lock, flags);
551 ieee->beacon_txing = 0;
552 del_timer_sync(&ieee->beacon_timer);
554 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
559 void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
561 if(ieee->stop_send_beacons)
562 ieee->stop_send_beacons(ieee->dev);
563 if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
564 ieee80211_beacons_stop(ieee);
566 EXPORT_SYMBOL(ieee80211_stop_send_beacons);
568 void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
570 if(ieee->start_send_beacons)
571 ieee->start_send_beacons(ieee->dev, ieee->basic_rate);
572 if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
573 ieee80211_beacons_start(ieee);
575 EXPORT_SYMBOL(ieee80211_start_send_beacons);
577 static void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
579 // unsigned long flags;
581 //ieee->sync_scan_hurryup = 1;
583 mutex_lock(&ieee->scan_mutex);
584 // spin_lock_irqsave(&ieee->lock, flags);
586 if (ieee->scanning == 1) {
589 cancel_delayed_work(&ieee->softmac_scan_wq);
592 // spin_unlock_irqrestore(&ieee->lock, flags);
593 mutex_unlock(&ieee->scan_mutex);
596 void ieee80211_stop_scan(struct ieee80211_device *ieee)
598 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
599 ieee80211_softmac_stop_scan(ieee);
601 ieee->stop_scan(ieee->dev);
603 EXPORT_SYMBOL(ieee80211_stop_scan);
605 /* called with ieee->lock held */
606 static void ieee80211_start_scan(struct ieee80211_device *ieee)
608 if (IS_DOT11D_ENABLE(ieee) )
610 if (IS_COUNTRY_IE_VALID(ieee))
612 RESET_CIE_WATCHDOG(ieee);
615 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
616 if (ieee->scanning == 0) {
618 schedule_delayed_work(&ieee->softmac_scan_wq, 0);
621 ieee->start_scan(ieee->dev);
625 /* called with wx_mutex held */
626 void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
628 if (IS_DOT11D_ENABLE(ieee) )
630 if (IS_COUNTRY_IE_VALID(ieee))
632 RESET_CIE_WATCHDOG(ieee);
635 ieee->sync_scan_hurryup = 0;
636 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
637 ieee80211_softmac_scan_syncro(ieee);
639 ieee->scan_syncro(ieee->dev);
642 EXPORT_SYMBOL(ieee80211_start_scan_syncro);
644 static inline struct sk_buff *
645 ieee80211_authentication_req(struct ieee80211_network *beacon,
646 struct ieee80211_device *ieee, int challengelen)
649 struct ieee80211_authentication *auth;
650 int len = sizeof(struct ieee80211_authentication) + challengelen + ieee->tx_headroom;
653 skb = dev_alloc_skb(len);
654 if (!skb) return NULL;
656 skb_reserve(skb, ieee->tx_headroom);
657 auth = (struct ieee80211_authentication *)
658 skb_put(skb, sizeof(struct ieee80211_authentication));
661 auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH
662 | IEEE80211_FCTL_WEP);
664 auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
666 auth->header.duration_id = cpu_to_le16(0x013a);
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 = cpu_to_le16(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));
733 /* HT ralated element */
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 rtl_80211_hdr_3addr *hdr;
933 skb = dev_alloc_skb(sizeof(struct rtl_80211_hdr_3addr));
938 hdr = (struct rtl_80211_hdr_3addr *)skb_put(skb,sizeof(struct rtl_80211_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 static inline struct sk_buff *
984 ieee80211_association_req(struct ieee80211_network *beacon,
985 struct ieee80211_device *ieee)
988 //unsigned long flags;
990 struct ieee80211_assoc_request_frame *hdr;
992 //short info_addr = 0;
994 //u16 suite_count = 0;
995 //u8 suit_select = 0;
996 //unsigned int wpa_len = beacon->wpa_ie_len;
998 u8 *ht_cap_buf = NULL;
1000 u8 *realtek_ie_buf=NULL;
1001 u8 realtek_ie_len=0;
1002 int wpa_ie_len= ieee->wpa_ie_len;
1003 unsigned int ckip_ie_len=0;
1004 unsigned int ccxrm_ie_len=0;
1005 unsigned int cxvernum_ie_len=0;
1006 struct ieee80211_crypt_data *crypt;
1009 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
1010 unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
1012 unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
1017 crypt = ieee->crypt[ieee->tx_keyidx];
1018 encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len));
1020 /* Include High Throuput capability && Realtek proprietary */
1021 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1023 ht_cap_buf = (u8 *)&(ieee->pHTInfo->SelfHTCap);
1024 ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
1025 HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt);
1026 if (ieee->pHTInfo->bCurrentRT2RTAggregation)
1028 realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
1029 realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer);
1030 HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len);
1034 if (ieee->qos_support) {
1035 wmm_info_len = beacon->qos_data.supported?9:0;
1039 if (beacon->bCkipSupported)
1043 if (beacon->bCcxRmEnable)
1047 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 = cpu_to_le16(37);
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 = cpu_to_le16(0xa);
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) {
1122 static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client"
1123 u8 CcxAironetBuf[30];
1124 OCTET_STRING osCcxAironetIE;
1126 memset(CcxAironetBuf, 0, 30);
1127 osCcxAironetIE.Octet = CcxAironetBuf;
1128 osCcxAironetIE.Length = sizeof(CcxAironetBuf);
1130 // Ref. CCX test plan v3.61, 3.2.3.1 step 13.
1131 // We want to make the device type as "4500-client". 060926, by CCW.
1133 memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui));
1135 // CCX1 spec V1.13, A01.1 CKIP Negotiation (page23):
1136 // "The CKIP negotiation is started with the associate request from the client to the access point,
1137 // containing an Aironet element with both the MIC and KP bits set."
1138 osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |= (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ;
1139 tag = skb_put(skb, ckip_ie_len);
1140 *tag++ = MFIE_TYPE_AIRONET;
1141 *tag++ = osCcxAironetIE.Length;
1142 memcpy(tag, osCcxAironetIE.Octet, osCcxAironetIE.Length);
1143 tag += osCcxAironetIE.Length;
1146 if (beacon->bCcxRmEnable)
1148 static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
1149 OCTET_STRING osCcxRmCap;
1151 osCcxRmCap.Octet = CcxRmCapBuf;
1152 osCcxRmCap.Length = sizeof(CcxRmCapBuf);
1153 tag = skb_put(skb, ccxrm_ie_len);
1154 *tag++ = MFIE_TYPE_GENERIC;
1155 *tag++ = osCcxRmCap.Length;
1156 memcpy(tag, osCcxRmCap.Octet, osCcxRmCap.Length);
1157 tag += osCcxRmCap.Length;
1160 if (beacon->BssCcxVerNumber >= 2) {
1161 u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
1162 OCTET_STRING osCcxVerNum;
1163 CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
1164 osCcxVerNum.Octet = CcxVerNumBuf;
1165 osCcxVerNum.Length = sizeof(CcxVerNumBuf);
1166 tag = skb_put(skb, cxvernum_ie_len);
1167 *tag++ = MFIE_TYPE_GENERIC;
1168 *tag++ = osCcxVerNum.Length;
1169 memcpy(tag, osCcxVerNum.Octet, osCcxVerNum.Length);
1170 tag += osCcxVerNum.Length;
1173 if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
1174 if (ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC)
1176 tag = skb_put(skb, ht_cap_len);
1177 *tag++ = MFIE_TYPE_HT_CAP;
1178 *tag++ = ht_cap_len - 2;
1179 memcpy(tag, ht_cap_buf, ht_cap_len - 2);
1180 tag += ht_cap_len -2;
1185 //choose what wpa_supplicant gives to associate.
1186 tag = skb_put(skb, wpa_ie_len);
1188 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
1191 tag = skb_put(skb, wmm_info_len);
1193 ieee80211_WMM_Info(ieee, &tag);
1196 tag = skb_put(skb, turbo_info_len);
1197 if (turbo_info_len) {
1198 ieee80211_TURBO_Info(ieee, &tag);
1202 if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
1203 if(ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC)
1205 tag = skb_put(skb, ht_cap_len);
1206 *tag++ = MFIE_TYPE_GENERIC;
1207 *tag++ = ht_cap_len - 2;
1208 memcpy(tag, ht_cap_buf, ht_cap_len - 2);
1209 tag += ht_cap_len -2;
1212 if (ieee->pHTInfo->bCurrentRT2RTAggregation) {
1213 tag = skb_put(skb, realtek_ie_len);
1214 *tag++ = MFIE_TYPE_GENERIC;
1215 *tag++ = realtek_ie_len - 2;
1216 memcpy(tag, realtek_ie_buf, realtek_ie_len - 2);
1219 // printk("<=====%s(), %p, %p\n", __func__, ieee->dev, ieee->dev->dev_addr);
1220 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
1224 void ieee80211_associate_abort(struct ieee80211_device *ieee)
1227 unsigned long flags;
1228 spin_lock_irqsave(&ieee->lock, flags);
1230 ieee->associate_seq++;
1232 /* don't scan, and avoid to have the RX path possibily
1233 * try again to associate. Even do not react to AUTH or
1234 * ASSOC response. Just wait for the retry wq to be scheduled.
1235 * Here we will check if there are good nets to associate
1236 * with, so we retry or just get back to NO_LINK and scanning
1238 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
1239 IEEE80211_DEBUG_MGMT("Authentication failed\n");
1240 ieee->softmac_stats.no_auth_rs++;
1242 IEEE80211_DEBUG_MGMT("Association failed\n");
1243 ieee->softmac_stats.no_ass_rs++;
1246 ieee->state = IEEE80211_ASSOCIATING_RETRY;
1248 schedule_delayed_work(&ieee->associate_retry_wq, \
1249 IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
1251 spin_unlock_irqrestore(&ieee->lock, flags);
1254 static void ieee80211_associate_abort_cb(unsigned long dev)
1256 ieee80211_associate_abort((struct ieee80211_device *) dev);
1260 static void ieee80211_associate_step1(struct ieee80211_device *ieee)
1262 struct ieee80211_network *beacon = &ieee->current_network;
1263 struct sk_buff *skb;
1265 IEEE80211_DEBUG_MGMT("Stopping scan\n");
1267 ieee->softmac_stats.tx_auth_rq++;
1268 skb=ieee80211_authentication_req(beacon, ieee, 0);
1271 ieee80211_associate_abort(ieee);
1273 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
1274 IEEE80211_DEBUG_MGMT("Sending authentication request\n");
1275 softmac_mgmt_xmit(skb, ieee);
1276 //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
1277 if (!timer_pending(&ieee->associate_timer)) {
1278 ieee->associate_timer.expires = jiffies + (HZ / 2);
1279 add_timer(&ieee->associate_timer);
1281 //dev_kfree_skb_any(skb);//edit by thomas
1285 static void ieee80211_auth_challenge(struct ieee80211_device *ieee,
1290 struct sk_buff *skb;
1291 struct ieee80211_network *beacon = &ieee->current_network;
1292 // int hlen = sizeof(struct ieee80211_authentication);
1294 ieee->associate_seq++;
1295 ieee->softmac_stats.tx_auth_rq++;
1297 skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
1299 ieee80211_associate_abort(ieee);
1301 c = skb_put(skb, chlen+2);
1302 *(c++) = MFIE_TYPE_CHALLENGE;
1304 memcpy(c, challenge, chlen);
1306 IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
1308 ieee80211_encrypt_fragment(ieee, skb, sizeof(struct rtl_80211_hdr_3addr ));
1310 softmac_mgmt_xmit(skb, ieee);
1311 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1312 //dev_kfree_skb_any(skb);//edit by thomas
1317 static void ieee80211_associate_step2(struct ieee80211_device *ieee)
1319 struct sk_buff *skb;
1320 struct ieee80211_network *beacon = &ieee->current_network;
1322 del_timer_sync(&ieee->associate_timer);
1324 IEEE80211_DEBUG_MGMT("Sending association request\n");
1326 ieee->softmac_stats.tx_ass_rq++;
1327 skb=ieee80211_association_req(beacon, ieee);
1329 ieee80211_associate_abort(ieee);
1331 softmac_mgmt_xmit(skb, ieee);
1332 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1333 //dev_kfree_skb_any(skb);//edit by thomas
1336 static void ieee80211_associate_complete_wq(struct work_struct *work)
1338 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
1339 printk(KERN_INFO "Associated successfully\n");
1340 if(ieee80211_is_54g(&ieee->current_network) &&
1341 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1344 printk(KERN_INFO"Using G rates:%d\n", ieee->rate);
1347 printk(KERN_INFO"Using B rates:%d\n", ieee->rate);
1349 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1351 printk("Successfully associated, ht enabled\n");
1356 printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
1357 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1358 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1360 ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500);
1361 // To prevent the immediately calling watch_dog after association.
1362 if (ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
1364 ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
1365 ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
1367 ieee->link_change(ieee->dev);
1368 if (!ieee->is_silent_reset) {
1369 printk("============>normal associate\n");
1370 notify_wx_assoc_event(ieee);
1372 printk("==================>silent reset associate\n");
1373 ieee->is_silent_reset = false;
1376 if (ieee->data_hard_resume)
1377 ieee->data_hard_resume(ieee->dev);
1378 netif_carrier_on(ieee->dev);
1381 static void ieee80211_associate_complete(struct ieee80211_device *ieee)
1384 // struct net_device* dev = ieee->dev;
1385 del_timer_sync(&ieee->associate_timer);
1387 ieee->state = IEEE80211_LINKED;
1388 //ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet);
1389 schedule_work(&ieee->associate_complete_wq);
1392 static void ieee80211_associate_procedure_wq(struct work_struct *work)
1394 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
1395 ieee->sync_scan_hurryup = 1;
1396 mutex_lock(&ieee->wx_mutex);
1398 if (ieee->data_hard_stop)
1399 ieee->data_hard_stop(ieee->dev);
1401 ieee80211_stop_scan(ieee);
1402 printk("===>%s(), chan:%d\n", __func__, ieee->current_network.channel);
1403 //ieee->set_chan(ieee->dev, ieee->current_network.channel);
1404 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1406 ieee->associate_seq = 1;
1407 ieee80211_associate_step1(ieee);
1409 mutex_unlock(&ieee->wx_mutex);
1412 inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
1414 u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
1415 int tmp_ssid_len = 0;
1417 short apset, ssidset, ssidbroad, apmatch, ssidmatch;
1419 /* we are interested in new new only if we are not associated
1420 * and we are not associating / authenticating
1422 if (ieee->state != IEEE80211_NOLINK)
1425 if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
1428 if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
1432 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) {
1433 /* if the user specified the AP MAC, we need also the essid
1434 * This could be obtained by beacons or, if the network does not
1435 * broadcast it, it can be put manually.
1437 apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
1438 ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
1439 ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0');
1440 apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
1441 ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\
1442 (!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
1445 if ( /* if the user set the AP check if match.
1446 * if the network does not broadcast essid we check the user supplyed ANY essid
1447 * if the network does broadcast and the user does not set essid it is OK
1448 * if the network does broadcast and the user did set essid chech if essid match
1450 (apset && apmatch &&
1451 ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
1452 /* if the ap is not set, check that the user set the bssid
1453 * and the network does broadcast and that those two bssid matches
1455 (!apset && ssidset && ssidbroad && ssidmatch)
1457 /* if the essid is hidden replace it with the
1458 * essid provided by the user.
1461 strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
1462 tmp_ssid_len = ieee->current_network.ssid_len;
1464 memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
1466 strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
1467 ieee->current_network.ssid_len = tmp_ssid_len;
1468 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);
1470 //ieee->pHTInfo->IOTAction = 0;
1471 HTResetIOTSetting(ieee->pHTInfo);
1472 if (ieee->iw_mode == IW_MODE_INFRA){
1473 /* Join the network for the first time */
1474 ieee->AsocRetryCount = 0;
1475 //for HT by amy 080514
1476 if((ieee->current_network.qos_data.supported == 1) &&
1477 // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT))
1478 ieee->current_network.bssht.bdSupportHT)
1479 /*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.*/
1481 // ieee->pHTInfo->bCurrentHTSupport = true;
1482 HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network));
1486 ieee->pHTInfo->bCurrentHTSupport = false;
1489 ieee->state = IEEE80211_ASSOCIATING;
1490 schedule_work(&ieee->associate_procedure_wq);
1492 if(ieee80211_is_54g(&ieee->current_network) &&
1493 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1495 ieee->SetWirelessMode(ieee->dev, IEEE_G);
1496 printk(KERN_INFO"Using G rates\n");
1499 ieee->SetWirelessMode(ieee->dev, IEEE_B);
1500 printk(KERN_INFO"Using B rates\n");
1502 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1503 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1504 ieee->state = IEEE80211_LINKED;
1512 void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
1514 unsigned long flags;
1515 struct ieee80211_network *target;
1517 spin_lock_irqsave(&ieee->lock, flags);
1519 list_for_each_entry(target, &ieee->network_list, list) {
1521 /* if the state become different that NOLINK means
1522 * we had found what we are searching for
1525 if (ieee->state != IEEE80211_NOLINK)
1528 if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
1529 ieee80211_softmac_new_net(ieee, target);
1532 spin_unlock_irqrestore(&ieee->lock, flags);
1537 static inline u16 auth_parse(struct sk_buff *skb, u8 **challenge, int *chlen)
1539 struct ieee80211_authentication *a;
1541 if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
1542 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
1546 a = (struct ieee80211_authentication *) skb->data;
1547 if (skb->len > (sizeof(struct ieee80211_authentication) + 3)) {
1548 t = skb->data + sizeof(struct ieee80211_authentication);
1550 if (*(t++) == MFIE_TYPE_CHALLENGE) {
1552 *challenge = kmemdup(t, *chlen, GFP_ATOMIC);
1558 return le16_to_cpu(a->status);
1563 static int auth_rq_parse(struct sk_buff *skb, u8 *dest)
1565 struct ieee80211_authentication *a;
1567 if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
1568 IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
1571 a = (struct ieee80211_authentication *) skb->data;
1573 memcpy(dest,a->header.addr2, ETH_ALEN);
1575 if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
1576 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1578 return WLAN_STATUS_SUCCESS;
1581 static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
1588 struct rtl_80211_hdr_3addr *header =
1589 (struct rtl_80211_hdr_3addr *) skb->data;
1591 if (skb->len < sizeof (struct rtl_80211_hdr_3addr ))
1592 return -1; /* corrupted */
1594 memcpy(src,header->addr2, ETH_ALEN);
1596 skbend = (u8 *)skb->data + skb->len;
1598 tag = skb->data + sizeof (struct rtl_80211_hdr_3addr );
1600 while (tag+1 < skbend){
1606 tag++; /* point to the len field */
1607 tag = tag + *(tag); /* point to the last data byte of the tag */
1608 tag++; /* point to the next tag */
1611 //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
1612 if (ssidlen == 0) return 1;
1614 if (!ssid) return 1; /* ssid not found in tagged param */
1615 return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
1619 static int assoc_rq_parse(struct sk_buff *skb, u8 *dest)
1621 struct ieee80211_assoc_request_frame *a;
1623 if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
1624 sizeof(struct ieee80211_info_element))) {
1626 IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
1630 a = (struct ieee80211_assoc_request_frame *) skb->data;
1632 memcpy(dest,a->header.addr2,ETH_ALEN);
1637 static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid)
1639 struct ieee80211_assoc_response_frame *response_head;
1642 if (skb->len < sizeof(struct ieee80211_assoc_response_frame)) {
1643 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
1647 response_head = (struct ieee80211_assoc_response_frame *) skb->data;
1648 *aid = le16_to_cpu(response_head->aid) & 0x3fff;
1650 status_code = le16_to_cpu(response_head->status);
1651 if((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \
1652 status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&&
1653 ((ieee->mode == IEEE_G) &&
1654 (ieee->current_network.mode == IEEE_N_24G) &&
1655 (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) {
1656 ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
1658 ieee->AsocRetryCount = 0;
1661 return le16_to_cpu(response_head->status);
1665 ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1669 //IEEE80211DMESG("Rx probe");
1670 ieee->softmac_stats.rx_probe_rq++;
1671 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1672 if (probe_rq_parse(ieee, skb, dest)) {
1673 //IEEE80211DMESG("Was for me!");
1674 ieee->softmac_stats.tx_probe_rs++;
1675 ieee80211_resp_to_probe(ieee, dest);
1680 ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1684 //IEEE80211DMESG("Rx probe");
1685 ieee->softmac_stats.rx_auth_rq++;
1687 status = auth_rq_parse(skb, dest);
1689 ieee80211_resp_to_auth(ieee, status, dest);
1691 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1696 ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1700 //unsigned long flags;
1702 ieee->softmac_stats.rx_ass_rq++;
1703 if (assoc_rq_parse(skb, dest) != -1) {
1704 ieee80211_resp_to_assoc_rq(ieee, dest);
1707 printk(KERN_INFO"New client associated: %pM\n", dest);
1711 static void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee,
1715 struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
1718 softmac_ps_mgmt_xmit(buf, ieee);
1721 /* EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame); */
1723 static short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h,
1726 int timeout = ieee->ps_timeout;
1728 /*if(ieee->ps == IEEE80211_PS_DISABLED ||
1729 ieee->iw_mode != IW_MODE_INFRA ||
1730 ieee->state != IEEE80211_LINKED)
1734 dtim = ieee->current_network.dtim_data;
1735 if(!(dtim & IEEE80211_DTIM_VALID))
1737 timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
1738 ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
1740 if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
1743 if(!time_after(jiffies,
1744 dev_trans_start(ieee->dev) + msecs_to_jiffies(timeout)))
1747 if(!time_after(jiffies,
1748 ieee->last_rx_ps_time + msecs_to_jiffies(timeout)))
1751 if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
1752 (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
1756 *time_l = ieee->current_network.last_dtim_sta_time[0]
1757 + (ieee->current_network.beacon_interval
1758 * ieee->current_network.dtim_period) * 1000;
1762 *time_h = ieee->current_network.last_dtim_sta_time[1];
1763 if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
1772 static inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
1778 unsigned long flags, flags2;
1780 spin_lock_irqsave(&ieee->lock, flags);
1782 if ((ieee->ps == IEEE80211_PS_DISABLED ||
1783 ieee->iw_mode != IW_MODE_INFRA ||
1784 ieee->state != IEEE80211_LINKED)){
1786 // #warning CHECK_LOCK_HERE
1787 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1789 ieee80211_sta_wakeup(ieee, 1);
1791 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1794 sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
1795 /* 2 wake, 1 sleep, 0 do nothing */
1801 if(ieee->sta_sleep == 1)
1802 ieee->enter_sleep_state(ieee->dev, th, tl);
1804 else if(ieee->sta_sleep == 0){
1805 // printk("send null 1\n");
1806 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1808 if(ieee->ps_is_queue_empty(ieee->dev)){
1811 ieee->sta_sleep = 2;
1813 ieee->ps_request_tx_ack(ieee->dev);
1815 ieee80211_sta_ps_send_null_frame(ieee, 1);
1820 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1825 }else if(sleep == 2){
1826 //#warning CHECK_LOCK_HERE
1827 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1829 ieee80211_sta_wakeup(ieee, 1);
1831 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1835 spin_unlock_irqrestore(&ieee->lock, flags);
1839 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
1841 if (ieee->sta_sleep == 0) {
1843 printk("Warning: driver is probably failing to report TX ps error\n");
1844 ieee->ps_request_tx_ack(ieee->dev);
1845 ieee80211_sta_ps_send_null_frame(ieee, 0);
1851 if(ieee->sta_sleep == 1)
1852 ieee->sta_wake_up(ieee->dev);
1854 ieee->sta_sleep = 0;
1857 ieee->ps_request_tx_ack(ieee->dev);
1858 ieee80211_sta_ps_send_null_frame(ieee, 0);
1862 void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
1864 unsigned long flags, flags2;
1866 spin_lock_irqsave(&ieee->lock, flags);
1868 if(ieee->sta_sleep == 2){
1869 /* Null frame with PS bit set */
1871 ieee->sta_sleep = 1;
1872 ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
1874 /* if the card report not success we can't be sure the AP
1875 * has not RXed so we can't assume the AP believe us awake
1878 /* 21112005 - tx again null without PS bit if lost */
1881 if ((ieee->sta_sleep == 0) && !success) {
1882 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1883 ieee80211_sta_ps_send_null_frame(ieee, 0);
1884 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1887 spin_unlock_irqrestore(&ieee->lock, flags);
1889 EXPORT_SYMBOL(ieee80211_ps_tx_ack);
1891 static void ieee80211_process_action(struct ieee80211_device *ieee,
1892 struct sk_buff *skb)
1894 struct rtl_80211_hdr *header = (struct rtl_80211_hdr *)skb->data;
1895 u8 *act = ieee80211_get_payload(header);
1897 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
1900 IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
1907 if (*act == ACT_ADDBAREQ)
1908 ieee80211_rx_ADDBAReq(ieee, skb);
1909 else if (*act == ACT_ADDBARSP)
1910 ieee80211_rx_ADDBARsp(ieee, skb);
1911 else if (*act == ACT_DELBA)
1912 ieee80211_rx_DELBA(ieee, skb);
1921 static void ieee80211_check_auth_response(struct ieee80211_device *ieee,
1922 struct sk_buff *skb)
1924 /* default support N mode, disable halfNmode */
1925 bool bSupportNmode = true, bHalfSupportNmode = false;
1931 errcode = auth_parse(skb, &challenge, &chlen);
1933 if (ieee->open_wep || !challenge) {
1934 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
1935 ieee->softmac_stats.rx_auth_rs_ok++;
1936 iotAction = ieee->pHTInfo->IOTAction;
1937 if (!(iotAction & HT_IOT_ACT_PURE_N_MODE)) {
1938 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) {
1939 /* WEP or TKIP encryption */
1940 if (IsHTHalfNmodeAPs(ieee)) {
1941 bSupportNmode = true;
1942 bHalfSupportNmode = true;
1944 bSupportNmode = false;
1945 bHalfSupportNmode = false;
1947 netdev_dbg(ieee->dev, "SEC(%d, %d)\n",
1952 /* Dummy wirless mode setting- avoid encryption issue */
1953 if (bSupportNmode) {
1954 /* N mode setting */
1955 ieee->SetWirelessMode(ieee->dev,
1956 ieee->current_network.mode);
1958 /* b/g mode setting - TODO */
1959 ieee->SetWirelessMode(ieee->dev, IEEE_G);
1962 if (ieee->current_network.mode == IEEE_N_24G &&
1963 bHalfSupportNmode) {
1964 netdev_dbg(ieee->dev, "enter half N mode\n");
1965 ieee->bHalfWirelessN24GMode = true;
1967 ieee->bHalfWirelessN24GMode = false;
1969 ieee80211_associate_step2(ieee);
1971 ieee80211_auth_challenge(ieee, challenge, chlen);
1974 ieee->softmac_stats.rx_auth_rs_err++;
1975 IEEE80211_DEBUG_MGMT("Auth response status code 0x%x", errcode);
1976 ieee80211_associate_abort(ieee);
1981 ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
1982 struct ieee80211_rx_stats *rx_stats, u16 type,
1985 struct rtl_80211_hdr_3addr *header = (struct rtl_80211_hdr_3addr *) skb->data;
1988 struct ieee80211_assoc_response_frame *assoc_resp;
1989 // struct ieee80211_info_element *info_element;
1991 if(!ieee->proto_started)
1994 if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
1995 ieee->iw_mode == IW_MODE_INFRA &&
1996 ieee->state == IEEE80211_LINKED))
1998 tasklet_schedule(&ieee->ps_task);
2000 if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
2001 WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
2002 ieee->last_rx_ps_time = jiffies;
2004 switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
2006 case IEEE80211_STYPE_ASSOC_RESP:
2007 case IEEE80211_STYPE_REASSOC_RESP:
2009 IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
2010 WLAN_FC_GET_STYPE(header->frame_ctl));
2011 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2012 ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
2013 ieee->iw_mode == IW_MODE_INFRA){
2014 struct ieee80211_network network_resp;
2015 struct ieee80211_network *network = &network_resp;
2017 errcode = assoc_parse(ieee, skb, &aid);
2019 ieee->state=IEEE80211_LINKED;
2020 ieee->assoc_id = aid;
2021 ieee->softmac_stats.rx_ass_ok++;
2022 /* station support qos */
2023 /* Let the register setting defaultly with Legacy station */
2024 if (ieee->qos_support) {
2025 assoc_resp = (struct ieee80211_assoc_response_frame *)skb->data;
2026 memset(network, 0, sizeof(*network));
2027 if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\
2028 rx_stats->len - sizeof(*assoc_resp),\
2033 { //filling the PeerHTCap. //maybe not necessary as we can get its info from current_network.
2034 memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
2035 memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
2037 if (ieee->handle_assoc_response != NULL)
2038 ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame *)header, network);
2040 ieee80211_associate_complete(ieee);
2042 /* aid could not been allocated */
2043 ieee->softmac_stats.rx_ass_err++;
2045 "Association response status code 0x%x\n",
2047 IEEE80211_DEBUG_MGMT(
2048 "Association response status code 0x%x\n",
2050 if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
2051 schedule_work(&ieee->associate_procedure_wq);
2053 ieee80211_associate_abort(ieee);
2059 case IEEE80211_STYPE_ASSOC_REQ:
2060 case IEEE80211_STYPE_REASSOC_REQ:
2062 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2063 ieee->iw_mode == IW_MODE_MASTER)
2065 ieee80211_rx_assoc_rq(ieee, skb);
2068 case IEEE80211_STYPE_AUTH:
2070 if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) {
2071 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING
2072 && ieee->iw_mode == IW_MODE_INFRA) {
2074 IEEE80211_DEBUG_MGMT("Received auth response");
2075 ieee80211_check_auth_response(ieee, skb);
2076 } else if (ieee->iw_mode == IW_MODE_MASTER) {
2077 ieee80211_rx_auth_rq(ieee, skb);
2082 case IEEE80211_STYPE_PROBE_REQ:
2084 if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
2085 ((ieee->iw_mode == IW_MODE_ADHOC ||
2086 ieee->iw_mode == IW_MODE_MASTER) &&
2087 ieee->state == IEEE80211_LINKED)){
2088 ieee80211_rx_probe_rq(ieee, skb);
2092 case IEEE80211_STYPE_DISASSOC:
2093 case IEEE80211_STYPE_DEAUTH:
2094 /* FIXME for now repeat all the association procedure
2095 * both for disassociation and deauthentication
2097 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2098 ieee->state == IEEE80211_LINKED &&
2099 ieee->iw_mode == IW_MODE_INFRA){
2101 ieee->state = IEEE80211_ASSOCIATING;
2102 ieee->softmac_stats.reassoc++;
2104 notify_wx_assoc_event(ieee);
2105 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2106 RemovePeerTS(ieee, header->addr2);
2107 schedule_work(&ieee->associate_procedure_wq);
2110 case IEEE80211_STYPE_MANAGE_ACT:
2111 ieee80211_process_action(ieee, skb);
2117 //dev_kfree_skb_any(skb);
2121 /* The following are for a simpler TX queue management.
2122 * Instead of using netif_[stop/wake]_queue, the driver
2123 * will use these two functions (plus a reset one) that
2124 * will internally call the kernel netif_* and take care
2125 * of the ieee802.11 fragmentation.
2126 * So, the driver receives a fragment at a time and might
2127 * call the stop function when it wants, without taking
2128 * care to have enough room to TX an entire packet.
2129 * This might be useful if each fragment needs its own
2130 * descriptor. Thus, just keeping a total free memory > than
2131 * the max fragmentation threshold is not enough. If the
2132 * ieee802.11 stack passed a TXB struct, then you would need
2133 * to keep N free descriptors where
2134 * N = MAX_PACKET_SIZE / MIN_FRAG_THRESHOLD.
2135 * In this way you need just one and the 802.11 stack
2136 * will take care of buffering fragments and pass them to
2137 * to the driver later, when it wakes the queue.
2139 void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
2142 unsigned int queue_index = txb->queue_index;
2143 unsigned long flags;
2145 cb_desc *tcb_desc = NULL;
2147 spin_lock_irqsave(&ieee->lock, flags);
2149 /* called with 2nd parm 0, no tx mgmt lock required */
2150 ieee80211_sta_wakeup(ieee, 0);
2152 /* update the tx status */
2153 ieee->stats.tx_bytes += le16_to_cpu(txb->payload_size);
2154 ieee->stats.tx_packets++;
2155 tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
2156 if (tcb_desc->bMulticast) {
2157 ieee->stats.multicast++;
2159 /* if xmit available, just xmit it immediately, else just insert it to the wait queue */
2160 for(i = 0; i < txb->nr_frags; i++) {
2161 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2162 if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) ||
2164 if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
2166 (!ieee->check_nic_enough_desc(ieee->dev,queue_index))||\
2167 (ieee->queue_stop)) {
2168 /* insert the skb packet to the wait queue */
2169 /* as for the completion function, it does not need
2170 * to check it any more.
2172 //printk("error:no descriptor left@queue_index %d\n", queue_index);
2173 //ieee80211_stop_queue(ieee);
2174 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2175 skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]);
2177 skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
2180 ieee->softmac_data_hard_start_xmit(
2182 ieee->dev, ieee->rate);
2183 //ieee->stats.tx_packets++;
2184 //ieee->stats.tx_bytes += txb->fragments[i]->len;
2185 //ieee->dev->trans_start = jiffies;
2188 ieee80211_txb_free(txb);
2191 spin_unlock_irqrestore(&ieee->lock, flags);
2194 EXPORT_SYMBOL(ieee80211_softmac_xmit);
2196 /* called with ieee->lock acquired */
2197 static void ieee80211_resume_tx(struct ieee80211_device *ieee)
2200 for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
2202 if (ieee->queue_stop){
2203 ieee->tx_pending.frag = i;
2207 ieee->softmac_data_hard_start_xmit(
2208 ieee->tx_pending.txb->fragments[i],
2209 ieee->dev, ieee->rate);
2210 //(i+1)<ieee->tx_pending.txb->nr_frags);
2211 ieee->stats.tx_packets++;
2212 netif_trans_update(ieee->dev);
2217 ieee80211_txb_free(ieee->tx_pending.txb);
2218 ieee->tx_pending.txb = NULL;
2222 void ieee80211_reset_queue(struct ieee80211_device *ieee)
2224 unsigned long flags;
2226 spin_lock_irqsave(&ieee->lock, flags);
2227 init_mgmt_queue(ieee);
2228 if (ieee->tx_pending.txb) {
2229 ieee80211_txb_free(ieee->tx_pending.txb);
2230 ieee->tx_pending.txb = NULL;
2232 ieee->queue_stop = 0;
2233 spin_unlock_irqrestore(&ieee->lock, flags);
2236 EXPORT_SYMBOL(ieee80211_reset_queue);
2238 void ieee80211_wake_queue(struct ieee80211_device *ieee)
2241 unsigned long flags;
2242 struct sk_buff *skb;
2243 struct rtl_80211_hdr_3addr *header;
2245 spin_lock_irqsave(&ieee->lock, flags);
2246 if (! ieee->queue_stop) goto exit;
2248 ieee->queue_stop = 0;
2250 if (ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) {
2251 while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
2253 header = (struct rtl_80211_hdr_3addr *) skb->data;
2255 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2257 if (ieee->seq_ctrl[0] == 0xFFF)
2258 ieee->seq_ctrl[0] = 0;
2260 ieee->seq_ctrl[0]++;
2262 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
2263 //dev_kfree_skb_any(skb);//edit by thomas
2266 if (!ieee->queue_stop && ieee->tx_pending.txb)
2267 ieee80211_resume_tx(ieee);
2269 if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)) {
2270 ieee->softmac_stats.swtxawake++;
2271 netif_wake_queue(ieee->dev);
2275 spin_unlock_irqrestore(&ieee->lock, flags);
2277 EXPORT_SYMBOL(ieee80211_wake_queue);
2279 void ieee80211_stop_queue(struct ieee80211_device *ieee)
2281 //unsigned long flags;
2282 //spin_lock_irqsave(&ieee->lock,flags);
2284 if (!netif_queue_stopped(ieee->dev)) {
2285 netif_stop_queue(ieee->dev);
2286 ieee->softmac_stats.swtxstop++;
2288 ieee->queue_stop = 1;
2289 //spin_unlock_irqrestore(&ieee->lock,flags);
2292 EXPORT_SYMBOL(ieee80211_stop_queue);
2294 /* called in user context only */
2295 void ieee80211_start_master_bss(struct ieee80211_device *ieee)
2299 if (ieee->current_network.ssid_len == 0) {
2300 strncpy(ieee->current_network.ssid,
2301 IEEE80211_DEFAULT_TX_ESSID,
2304 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2308 memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
2310 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2311 ieee->state = IEEE80211_LINKED;
2312 ieee->link_change(ieee->dev);
2313 notify_wx_assoc_event(ieee);
2315 if (ieee->data_hard_resume)
2316 ieee->data_hard_resume(ieee->dev);
2318 netif_carrier_on(ieee->dev);
2321 static void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
2325 if (ieee->data_hard_resume)
2326 ieee->data_hard_resume(ieee->dev);
2328 netif_carrier_on(ieee->dev);
2331 static void ieee80211_start_ibss_wq(struct work_struct *work)
2334 struct delayed_work *dwork = to_delayed_work(work);
2335 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
2336 /* iwconfig mode ad-hoc will schedule this and return
2337 * on the other hand this will block further iwconfig SET
2338 * operations because of the wx_mutex hold.
2339 * Anyway some most set operations set a flag to speed-up
2340 * (abort) this wq (when syncro scanning) before sleeping
2343 if (!ieee->proto_started) {
2344 printk("==========oh driver down return\n");
2347 mutex_lock(&ieee->wx_mutex);
2349 if (ieee->current_network.ssid_len == 0) {
2350 strcpy(ieee->current_network.ssid, IEEE80211_DEFAULT_TX_ESSID);
2351 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2355 /* check if we have this cell in our network list */
2356 ieee80211_softmac_check_all_nets(ieee);
2359 // if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK))
2360 if (ieee->state == IEEE80211_NOLINK)
2361 ieee->current_network.channel = 6;
2362 /* if not then the state is not linked. Maybe the user swithced to
2363 * ad-hoc mode just after being in monitor mode, or just after
2364 * being very few time in managed mode (so the card have had no
2365 * time to scan all the chans..) or we have just run up the iface
2366 * after setting ad-hoc mode. So we have to give another try..
2367 * Here, in ibss mode, should be safe to do this without extra care
2368 * (in bss mode we had to make sure no-one tryed to associate when
2369 * we had just checked the ieee->state and we was going to start the
2370 * scan) beacause in ibss mode the ieee80211_new_net function, when
2371 * finds a good net, just set the ieee->state to IEEE80211_LINKED,
2372 * so, at worst, we waste a bit of time to initiate an unneeded syncro
2373 * scan, that will stop at the first round because it sees the state
2376 if (ieee->state == IEEE80211_NOLINK)
2377 ieee80211_start_scan_syncro(ieee);
2379 /* the network definitively is not here.. create a new cell */
2380 if (ieee->state == IEEE80211_NOLINK) {
2381 printk("creating new IBSS cell\n");
2383 random_ether_addr(ieee->current_network.bssid);
2385 if(ieee->modulation & IEEE80211_CCK_MODULATION){
2387 ieee->current_network.rates_len = 4;
2389 ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
2390 ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
2391 ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
2392 ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
2395 ieee->current_network.rates_len = 0;
2397 if(ieee->modulation & IEEE80211_OFDM_MODULATION){
2398 ieee->current_network.rates_ex_len = 8;
2400 ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
2401 ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
2402 ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
2403 ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
2404 ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
2405 ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
2406 ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
2407 ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
2411 ieee->current_network.rates_ex_len = 0;
2415 // By default, WMM function will be disabled in IBSS mode
2416 ieee->current_network.QoS_Enable = 0;
2417 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2418 ieee->current_network.atim_window = 0;
2419 ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
2420 if(ieee->short_slot)
2421 ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
2425 ieee->state = IEEE80211_LINKED;
2427 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2428 ieee->link_change(ieee->dev);
2430 notify_wx_assoc_event(ieee);
2432 ieee80211_start_send_beacons(ieee);
2434 if (ieee->data_hard_resume)
2435 ieee->data_hard_resume(ieee->dev);
2436 netif_carrier_on(ieee->dev);
2438 mutex_unlock(&ieee->wx_mutex);
2441 inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
2443 schedule_delayed_work(&ieee->start_ibss_wq, 150);
2446 /* this is called only in user context, with wx_mutex held */
2447 void ieee80211_start_bss(struct ieee80211_device *ieee)
2449 unsigned long flags;
2451 // Ref: 802.11d 11.1.3.3
2452 // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
2454 if (IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
2456 if (! ieee->bGlobalDomain)
2461 /* check if we have already found the net we
2462 * are interested in (if any).
2463 * if not (we are disassociated and we are not
2464 * in associating / authenticating phase) start the background scanning.
2466 ieee80211_softmac_check_all_nets(ieee);
2468 /* ensure no-one start an associating process (thus setting
2469 * the ieee->state to ieee80211_ASSOCIATING) while we
2470 * have just cheked it and we are going to enable scan.
2471 * The ieee80211_new_net function is always called with
2472 * lock held (from both ieee80211_softmac_check_all_nets and
2473 * the rx path), so we cannot be in the middle of such function
2475 spin_lock_irqsave(&ieee->lock, flags);
2477 if (ieee->state == IEEE80211_NOLINK) {
2478 ieee->actscanning = true;
2479 ieee80211_start_scan(ieee);
2481 spin_unlock_irqrestore(&ieee->lock, flags);
2484 /* called only in userspace context */
2485 void ieee80211_disassociate(struct ieee80211_device *ieee)
2489 netif_carrier_off(ieee->dev);
2490 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
2491 ieee80211_reset_queue(ieee);
2493 if (ieee->data_hard_stop)
2494 ieee->data_hard_stop(ieee->dev);
2495 if(IS_DOT11D_ENABLE(ieee))
2497 ieee->state = IEEE80211_NOLINK;
2498 ieee->is_set_key = false;
2499 ieee->link_change(ieee->dev);
2500 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2501 notify_wx_assoc_event(ieee);
2504 EXPORT_SYMBOL(ieee80211_disassociate);
2506 static void ieee80211_associate_retry_wq(struct work_struct *work)
2508 struct delayed_work *dwork = to_delayed_work(work);
2509 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
2510 unsigned long flags;
2512 mutex_lock(&ieee->wx_mutex);
2513 if(!ieee->proto_started)
2516 if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
2519 /* until we do not set the state to IEEE80211_NOLINK
2520 * there are no possibility to have someone else trying
2521 * to start an association procedure (we get here with
2522 * ieee->state = IEEE80211_ASSOCIATING).
2523 * When we set the state to IEEE80211_NOLINK it is possible
2524 * that the RX path run an attempt to associate, but
2525 * both ieee80211_softmac_check_all_nets and the
2526 * RX path works with ieee->lock held so there are no
2527 * problems. If we are still disassociated then start a scan.
2528 * the lock here is necessary to ensure no one try to start
2529 * an association procedure when we have just checked the
2530 * state and we are going to start the scan.
2532 ieee->state = IEEE80211_NOLINK;
2534 ieee80211_softmac_check_all_nets(ieee);
2536 spin_lock_irqsave(&ieee->lock, flags);
2538 if(ieee->state == IEEE80211_NOLINK)
2539 ieee80211_start_scan(ieee);
2541 spin_unlock_irqrestore(&ieee->lock, flags);
2544 mutex_unlock(&ieee->wx_mutex);
2547 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
2549 u8 broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2551 struct sk_buff *skb;
2552 struct ieee80211_probe_response *b;
2554 skb = ieee80211_probe_resp(ieee, broadcast_addr);
2559 b = (struct ieee80211_probe_response *) skb->data;
2560 b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
2566 struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
2568 struct sk_buff *skb;
2569 struct ieee80211_probe_response *b;
2571 skb = ieee80211_get_beacon_(ieee);
2575 b = (struct ieee80211_probe_response *) skb->data;
2576 b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2578 if (ieee->seq_ctrl[0] == 0xFFF)
2579 ieee->seq_ctrl[0] = 0;
2581 ieee->seq_ctrl[0]++;
2585 EXPORT_SYMBOL(ieee80211_get_beacon);
2587 void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
2589 ieee->sync_scan_hurryup = 1;
2590 mutex_lock(&ieee->wx_mutex);
2591 ieee80211_stop_protocol(ieee);
2592 mutex_unlock(&ieee->wx_mutex);
2594 EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
2596 void ieee80211_stop_protocol(struct ieee80211_device *ieee)
2598 if (!ieee->proto_started)
2601 ieee->proto_started = 0;
2603 ieee80211_stop_send_beacons(ieee);
2604 del_timer_sync(&ieee->associate_timer);
2605 cancel_delayed_work(&ieee->associate_retry_wq);
2606 cancel_delayed_work(&ieee->start_ibss_wq);
2607 ieee80211_stop_scan(ieee);
2609 ieee80211_disassociate(ieee);
2610 RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
2613 void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
2615 ieee->sync_scan_hurryup = 0;
2616 mutex_lock(&ieee->wx_mutex);
2617 ieee80211_start_protocol(ieee);
2618 mutex_unlock(&ieee->wx_mutex);
2620 EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
2622 void ieee80211_start_protocol(struct ieee80211_device *ieee)
2626 if (ieee->proto_started)
2629 ieee->proto_started = 1;
2631 if (ieee->current_network.channel == 0) {
2634 if (ch > MAX_CHANNEL_NUMBER)
2635 return; /* no channel found */
2636 }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
2637 ieee->current_network.channel = ch;
2640 if (ieee->current_network.beacon_interval == 0)
2641 ieee->current_network.beacon_interval = 100;
2642 // printk("===>%s(), chan:%d\n", __func__, ieee->current_network.channel);
2643 // ieee->set_chan(ieee->dev,ieee->current_network.channel);
2645 for(i = 0; i < 17; i++) {
2646 ieee->last_rxseq_num[i] = -1;
2647 ieee->last_rxfrag_num[i] = -1;
2648 ieee->last_packet_time[i] = 0;
2651 ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
2654 /* if the user set the MAC of the ad-hoc cell and then
2655 * switch to managed mode, shall we make sure that association
2656 * attempts does not fail just because the user provide the essid
2657 * and the nic is still checking for the AP MAC ??
2659 if (ieee->iw_mode == IW_MODE_INFRA)
2660 ieee80211_start_bss(ieee);
2662 else if (ieee->iw_mode == IW_MODE_ADHOC)
2663 ieee80211_start_ibss(ieee);
2665 else if (ieee->iw_mode == IW_MODE_MASTER)
2666 ieee80211_start_master_bss(ieee);
2668 else if(ieee->iw_mode == IW_MODE_MONITOR)
2669 ieee80211_start_monitor_mode(ieee);
2673 #define DRV_NAME "Ieee80211"
2674 void ieee80211_softmac_init(struct ieee80211_device *ieee)
2677 memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
2679 ieee->state = IEEE80211_NOLINK;
2680 ieee->sync_scan_hurryup = 0;
2681 for(i = 0; i < 5; i++) {
2682 ieee->seq_ctrl[i] = 0;
2684 ieee->pDot11dInfo = kzalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
2685 if (!ieee->pDot11dInfo)
2686 IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
2687 //added for AP roaming
2688 ieee->LinkDetectInfo.SlotNum = 2;
2689 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
2690 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
2693 ieee->queue_stop = 0;
2695 ieee->softmac_features = 0; //so IEEE2100-like driver are happy
2698 ieee->proto_started = 0;
2699 ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
2701 ieee->ps = IEEE80211_PS_DISABLED;
2702 ieee->sta_sleep = 0;
2703 ieee->Regdot11HTOperationalRateSet[0]= 0xff;//support MCS 0~7
2704 ieee->Regdot11HTOperationalRateSet[1]= 0xff;//support MCS 8~15
2705 ieee->Regdot11HTOperationalRateSet[4]= 0x01;
2707 ieee->actscanning = false;
2708 ieee->beinretry = false;
2709 ieee->is_set_key = false;
2710 init_mgmt_queue(ieee);
2712 ieee->sta_edca_param[0] = 0x0000A403;
2713 ieee->sta_edca_param[1] = 0x0000A427;
2714 ieee->sta_edca_param[2] = 0x005E4342;
2715 ieee->sta_edca_param[3] = 0x002F3262;
2716 ieee->aggregation = true;
2717 ieee->enable_rx_imm_BA = true;
2718 ieee->tx_pending.txb = NULL;
2720 setup_timer(&ieee->associate_timer, ieee80211_associate_abort_cb,
2721 (unsigned long)ieee);
2723 setup_timer(&ieee->beacon_timer, ieee80211_send_beacon_cb,
2724 (unsigned long)ieee);
2727 INIT_DELAYED_WORK(&ieee->start_ibss_wq, ieee80211_start_ibss_wq);
2728 INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
2729 INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
2730 INIT_DELAYED_WORK(&ieee->softmac_scan_wq, ieee80211_softmac_scan_wq);
2731 INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
2732 INIT_WORK(&ieee->wx_sync_scan_wq, ieee80211_wx_sync_scan_wq);
2735 mutex_init(&ieee->wx_mutex);
2736 mutex_init(&ieee->scan_mutex);
2738 spin_lock_init(&ieee->mgmt_tx_lock);
2739 spin_lock_init(&ieee->beacon_lock);
2741 tasklet_init(&ieee->ps_task,
2742 (void(*)(unsigned long)) ieee80211_sta_ps,
2743 (unsigned long)ieee);
2747 void ieee80211_softmac_free(struct ieee80211_device *ieee)
2749 mutex_lock(&ieee->wx_mutex);
2750 kfree(ieee->pDot11dInfo);
2751 ieee->pDot11dInfo = NULL;
2752 del_timer_sync(&ieee->associate_timer);
2754 cancel_delayed_work(&ieee->associate_retry_wq);
2756 mutex_unlock(&ieee->wx_mutex);
2759 /********************************************************
2760 * Start of WPA code. *
2761 * this is stolen from the ipw2200 driver *
2762 ********************************************************/
2765 static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
2767 /* This is called when wpa_supplicant loads and closes the driver
2769 printk("%s WPA\n",value ? "enabling" : "disabling");
2770 ieee->wpa_enabled = value;
2775 static void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee,
2776 char *wpa_ie, int wpa_ie_len)
2778 /* make sure WPA is enabled */
2779 ieee80211_wpa_enable(ieee, 1);
2781 ieee80211_disassociate(ieee);
2785 static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
2791 case IEEE_MLME_STA_DEAUTH:
2795 case IEEE_MLME_STA_DISASSOC:
2796 ieee80211_disassociate(ieee);
2800 printk("Unknown MLME request: %d\n", command);
2808 static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
2809 struct ieee_param *param, int plen)
2813 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
2814 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
2817 if (param->u.wpa_ie.len) {
2818 buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len,
2823 kfree(ieee->wpa_ie);
2825 ieee->wpa_ie_len = param->u.wpa_ie.len;
2827 kfree(ieee->wpa_ie);
2828 ieee->wpa_ie = NULL;
2829 ieee->wpa_ie_len = 0;
2832 ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
2836 #define AUTH_ALG_OPEN_SYSTEM 0x1
2837 #define AUTH_ALG_SHARED_KEY 0x2
2839 static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
2842 struct ieee80211_security sec = {
2843 .flags = SEC_AUTH_MODE,
2846 if (value & AUTH_ALG_SHARED_KEY) {
2847 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
2849 ieee->auth_mode = 1;
2850 } else if (value & AUTH_ALG_OPEN_SYSTEM){
2851 sec.auth_mode = WLAN_AUTH_OPEN;
2853 ieee->auth_mode = 0;
2855 else if (value & IW_AUTH_ALG_LEAP){
2856 sec.auth_mode = WLAN_AUTH_LEAP;
2858 ieee->auth_mode = 2;
2862 if (ieee->set_security)
2863 ieee->set_security(ieee->dev, &sec);
2865 // ret = -EOPNOTSUPP;
2870 static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
2873 unsigned long flags;
2876 case IEEE_PARAM_WPA_ENABLED:
2877 ret = ieee80211_wpa_enable(ieee, value);
2880 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2881 ieee->tkip_countermeasures=value;
2884 case IEEE_PARAM_DROP_UNENCRYPTED: {
2887 * wpa_supplicant calls set_wpa_enabled when the driver
2888 * is loaded and unloaded, regardless of if WPA is being
2889 * used. No other calls are made which can be used to
2890 * determine if encryption will be used or not prior to
2891 * association being expected. If encryption is not being
2892 * used, drop_unencrypted is set to false, else true -- we
2893 * can use this to determine if the CAP_PRIVACY_ON bit should
2896 struct ieee80211_security sec = {
2897 .flags = SEC_ENABLED,
2900 ieee->drop_unencrypted = value;
2901 /* We only change SEC_LEVEL for open mode. Others
2902 * are set by ipw_wpa_set_encryption.
2905 sec.flags |= SEC_LEVEL;
2906 sec.level = SEC_LEVEL_0;
2909 sec.flags |= SEC_LEVEL;
2910 sec.level = SEC_LEVEL_1;
2912 if (ieee->set_security)
2913 ieee->set_security(ieee->dev, &sec);
2917 case IEEE_PARAM_PRIVACY_INVOKED:
2918 ieee->privacy_invoked=value;
2921 case IEEE_PARAM_AUTH_ALGS:
2922 ret = ieee80211_wpa_set_auth_algs(ieee, value);
2925 case IEEE_PARAM_IEEE_802_1X:
2926 ieee->ieee802_1x=value;
2928 case IEEE_PARAM_WPAX_SELECT:
2929 // added for WPA2 mixed mode
2930 spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags);
2931 ieee->wpax_type_set = 1;
2932 ieee->wpax_type_notify = value;
2933 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags);
2937 printk("Unknown WPA param: %d\n",name);
2944 /* implementation borrowed from hostap driver */
2946 static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
2947 struct ieee_param *param, int param_len)
2951 struct ieee80211_crypto_ops *ops;
2952 struct ieee80211_crypt_data **crypt;
2954 struct ieee80211_security sec = {
2958 param->u.crypt.err = 0;
2959 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
2962 (int) ((char *) param->u.crypt.key - (char *) param) +
2963 param->u.crypt.key_len) {
2964 printk("Len mismatch %d, %d\n", param_len,
2965 param->u.crypt.key_len);
2968 if (is_broadcast_ether_addr(param->sta_addr)) {
2969 if (param->u.crypt.idx >= WEP_KEYS)
2971 crypt = &ieee->crypt[param->u.crypt.idx];
2976 if (strcmp(param->u.crypt.alg, "none") == 0) {
2981 sec.level = SEC_LEVEL_0;
2982 sec.flags |= SEC_ENABLED | SEC_LEVEL;
2983 ieee80211_crypt_delayed_deinit(ieee, crypt);
2990 sec.flags |= SEC_ENABLED;
2992 /* IPW HW cannot build TKIP MIC, host decryption still needed. */
2993 if (!(ieee->host_encrypt || ieee->host_decrypt) &&
2994 strcmp(param->u.crypt.alg, "TKIP"))
2995 goto skip_host_crypt;
2997 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
2998 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
2999 request_module("ieee80211_crypt_wep");
3000 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3001 //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
3002 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
3003 request_module("ieee80211_crypt_tkip");
3004 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3005 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
3006 request_module("ieee80211_crypt_ccmp");
3007 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3010 printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
3011 param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
3016 if (*crypt == NULL || (*crypt)->ops != ops) {
3017 struct ieee80211_crypt_data *new_crypt;
3019 ieee80211_crypt_delayed_deinit(ieee, crypt);
3021 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
3022 if (new_crypt == NULL) {
3026 new_crypt->ops = ops;
3027 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
3029 new_crypt->ops->init(param->u.crypt.idx);
3031 if (new_crypt->priv == NULL) {
3033 param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
3041 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
3042 (*crypt)->ops->set_key(param->u.crypt.key,
3043 param->u.crypt.key_len, param->u.crypt.seq,
3044 (*crypt)->priv) < 0) {
3045 printk("key setting failed\n");
3046 param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
3052 if (param->u.crypt.set_tx) {
3053 ieee->tx_keyidx = param->u.crypt.idx;
3054 sec.active_key = param->u.crypt.idx;
3055 sec.flags |= SEC_ACTIVE_KEY;
3057 sec.flags &= ~SEC_ACTIVE_KEY;
3059 if (param->u.crypt.alg != NULL) {
3060 memcpy(sec.keys[param->u.crypt.idx],
3062 param->u.crypt.key_len);
3063 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
3064 sec.flags |= (1 << param->u.crypt.idx);
3066 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3067 sec.flags |= SEC_LEVEL;
3068 sec.level = SEC_LEVEL_1;
3069 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3070 sec.flags |= SEC_LEVEL;
3071 sec.level = SEC_LEVEL_2;
3072 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3073 sec.flags |= SEC_LEVEL;
3074 sec.level = SEC_LEVEL_3;
3078 if (ieee->set_security)
3079 ieee->set_security(ieee->dev, &sec);
3081 /* Do not reset port if card is in Managed mode since resetting will
3082 * generate new IEEE 802.11 authentication which may end up in looping
3083 * with IEEE 802.1X. If your hardware requires a reset after WEP
3084 * configuration (for example... Prism2), implement the reset_port in
3085 * the callbacks structures used to initialize the 802.11 stack. */
3086 if (ieee->reset_on_keychange &&
3087 ieee->iw_mode != IW_MODE_INFRA &&
3089 ieee->reset_port(ieee->dev)) {
3090 printk("reset_port failed\n");
3091 param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
3098 static inline struct sk_buff *ieee80211_disassociate_skb(
3099 struct ieee80211_network *beacon,
3100 struct ieee80211_device *ieee,
3103 struct sk_buff *skb;
3104 struct ieee80211_disassoc *disass;
3106 skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc));
3110 disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc));
3111 disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
3112 disass->header.duration_id = 0;
3114 memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
3115 memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
3116 memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
3118 disass->reason = cpu_to_le16(asRsn);
3125 struct ieee80211_device *ieee,
3130 struct ieee80211_network *beacon = &ieee->current_network;
3131 struct sk_buff *skb;
3132 skb = ieee80211_disassociate_skb(beacon,ieee,asRsn);
3134 softmac_mgmt_xmit(skb, ieee);
3135 //dev_kfree_skb_any(skb);//edit by thomas
3138 EXPORT_SYMBOL(SendDisassociation);
3140 int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
3142 struct ieee_param *param;
3145 mutex_lock(&ieee->wx_mutex);
3146 //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
3148 if (p->length < sizeof(struct ieee_param) || !p->pointer) {
3153 param = memdup_user(p->pointer, p->length);
3154 if (IS_ERR(param)) {
3155 ret = PTR_ERR(param);
3159 switch (param->cmd) {
3161 case IEEE_CMD_SET_WPA_PARAM:
3162 ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
3163 param->u.wpa_param.value);
3166 case IEEE_CMD_SET_WPA_IE:
3167 ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
3170 case IEEE_CMD_SET_ENCRYPTION:
3171 ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
3175 ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
3176 param->u.mlme.reason_code);
3180 printk("Unknown WPA supplicant request: %d\n",param->cmd);
3185 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
3190 mutex_unlock(&ieee->wx_mutex);
3194 EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
3196 void notify_wx_assoc_event(struct ieee80211_device *ieee)
3198 union iwreq_data wrqu;
3199 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3200 if (ieee->state == IEEE80211_LINKED)
3201 memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
3203 eth_zero_addr(wrqu.ap_addr.sa_data);
3204 wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
3206 EXPORT_SYMBOL(notify_wx_assoc_event);