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)
150 nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
153 * if the queue is full but we have newer frames then
154 * just overwrites the oldest.
156 * if (nh == ieee->mgmt_queue_tail)
159 ieee->mgmt_queue_head = nh;
160 ieee->mgmt_queue_ring[nh] = skb;
165 static struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
169 if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
172 ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
174 ieee->mgmt_queue_tail =
175 (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
180 static void init_mgmt_queue(struct ieee80211_device *ieee)
182 ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
185 static u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee)
187 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
190 /* 2008/01/25 MH For broadcom, MGNT frame set as OFDM 6M. */
191 if(pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M)
194 rate = ieee->basic_rate & 0x7f;
197 /* 2005.01.26, by rcnjko. */
198 if(ieee->mode == IEEE_A||
199 ieee->mode== IEEE_N_5G||
200 (ieee->mode== IEEE_N_24G&&!pHTInfo->bCurSuppCCK))
207 // Data rate of ProbeReq is already decided. Annie, 2005-03-31
208 if( pMgntInfo->bScanInProgress || (pMgntInfo->bDualModeScanStep!=0) )
210 if(pMgntInfo->dot11CurrentWirelessMode==WIRELESS_MODE_A)
220 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
222 inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
225 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
226 struct rtl_80211_hdr_3addr *header=
227 (struct rtl_80211_hdr_3addr *) skb->data;
229 struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8);
231 spin_lock_irqsave(&ieee->lock, flags);
233 /* called with 2nd param 0, no mgmt lock required */
234 ieee80211_sta_wakeup(ieee, 0);
236 tcb_desc->queue_index = MGNT_QUEUE;
237 tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
238 tcb_desc->RATRIndex = 7;
239 tcb_desc->bTxDisableRateFallBack = 1;
240 tcb_desc->bTxUseDriverAssingedRate = 1;
243 if(ieee->queue_stop){
244 enqueue_mgmt(ieee, skb);
246 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
248 if (ieee->seq_ctrl[0] == 0xFFF)
249 ieee->seq_ctrl[0] = 0;
253 /* avoid watchdog triggers */
254 netif_trans_update(ieee->dev);
255 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
256 //dev_kfree_skb_any(skb);//edit by thomas
259 spin_unlock_irqrestore(&ieee->lock, flags);
261 spin_unlock_irqrestore(&ieee->lock, flags);
262 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
264 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
266 if (ieee->seq_ctrl[0] == 0xFFF)
267 ieee->seq_ctrl[0] = 0;
271 /* check whether the managed packet queued greater than 5 */
272 if(!ieee->check_nic_enough_desc(ieee->dev,tcb_desc->queue_index)||\
273 (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)||\
274 (ieee->queue_stop) ) {
275 /* insert the skb packet to the management queue */
276 /* as for the completion function, it does not need
277 * to check it any more.
279 printk("%s():insert to waitqueue!\n",__func__);
280 skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb);
282 ieee->softmac_hard_start_xmit(skb, ieee->dev);
283 //dev_kfree_skb_any(skb);//edit by thomas
285 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
290 softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
293 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
294 struct rtl_80211_hdr_3addr *header =
295 (struct rtl_80211_hdr_3addr *) skb->data;
300 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
302 if (ieee->seq_ctrl[0] == 0xFFF)
303 ieee->seq_ctrl[0] = 0;
307 /* avoid watchdog triggers */
308 netif_trans_update(ieee->dev);
309 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
313 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
315 if (ieee->seq_ctrl[0] == 0xFFF)
316 ieee->seq_ctrl[0] = 0;
320 ieee->softmac_hard_start_xmit(skb, ieee->dev);
323 //dev_kfree_skb_any(skb);//edit by thomas
326 static inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
328 unsigned int len, rate_len;
331 struct ieee80211_probe_request *req;
333 len = ieee->current_network.ssid_len;
335 rate_len = ieee80211_MFIE_rate_len(ieee);
337 skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
338 2 + len + rate_len + ieee->tx_headroom);
342 skb_reserve(skb, ieee->tx_headroom);
344 req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
345 req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
346 req->header.duration_id = 0; /* FIXME: is this OK? */
348 eth_broadcast_addr(req->header.addr1);
349 memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
350 eth_broadcast_addr(req->header.addr3);
352 tag = (u8 *) skb_put(skb,len+2+rate_len);
354 *tag++ = MFIE_TYPE_SSID;
356 memcpy(tag, ieee->current_network.ssid, len);
359 ieee80211_MFIE_Brate(ieee,&tag);
360 ieee80211_MFIE_Grate(ieee,&tag);
364 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
366 static void ieee80211_send_beacon(struct ieee80211_device *ieee)
372 //unsigned long flags;
373 skb = ieee80211_get_beacon_(ieee);
376 softmac_mgmt_xmit(skb, ieee);
377 ieee->softmac_stats.tx_beacons++;
378 //dev_kfree_skb_any(skb);//edit by thomas
380 // ieee->beacon_timer.expires = jiffies +
381 // (MSECS( ieee->current_network.beacon_interval -5));
383 //spin_lock_irqsave(&ieee->beacon_lock,flags);
384 if (ieee->beacon_txing && ieee->ieee_up) {
385 // if(!timer_pending(&ieee->beacon_timer))
386 // add_timer(&ieee->beacon_timer);
387 mod_timer(&ieee->beacon_timer,
388 jiffies + msecs_to_jiffies(ieee->current_network.beacon_interval-5));
390 //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
394 static void ieee80211_send_beacon_cb(unsigned long _ieee)
396 struct ieee80211_device *ieee =
397 (struct ieee80211_device *) _ieee;
400 spin_lock_irqsave(&ieee->beacon_lock, flags);
401 ieee80211_send_beacon(ieee);
402 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
406 static void ieee80211_send_probe(struct ieee80211_device *ieee)
410 skb = ieee80211_probe_req(ieee);
412 softmac_mgmt_xmit(skb, ieee);
413 ieee->softmac_stats.tx_probe_rq++;
414 //dev_kfree_skb_any(skb);//edit by thomas
418 static void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
420 if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)) {
421 ieee80211_send_probe(ieee);
422 ieee80211_send_probe(ieee);
426 /* this performs syncro scan blocking the caller until all channels
427 * in the allowed channel map has been checked.
429 void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
432 u8 channel_map[MAX_CHANNEL_NUMBER+1];
434 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
435 mutex_lock(&ieee->scan_mutex);
442 if (ch > MAX_CHANNEL_NUMBER)
443 goto out; /* scan completed */
444 }while(!channel_map[ch]);
446 /* this function can be called in two situations
447 * 1- We have switched to ad-hoc mode and we are
448 * performing a complete syncro scan before conclude
449 * there are no interesting cell and to create a
450 * new one. In this case the link state is
451 * IEEE80211_NOLINK until we found an interesting cell.
452 * If so the ieee8021_new_net, called by the RX path
453 * will set the state to IEEE80211_LINKED, so we stop
455 * 2- We are linked and the root uses run iwlist scan.
456 * So we switch to IEEE80211_LINKED_SCANNING to remember
457 * that we are still logically linked (not interested in
458 * new network events, despite for updating the net list,
459 * but we are temporarly 'unlinked' as the driver shall
460 * not filter RX frames and the channel is changing.
461 * So the only situation in witch are interested is to check
462 * if the state become LINKED because of the #1 situation
465 if (ieee->state == IEEE80211_LINKED)
467 ieee->set_chan(ieee->dev, ch);
468 if(channel_map[ch] == 1)
469 ieee80211_send_probe_requests(ieee);
471 /* this prevent excessive time wait when we
472 * need to wait for a syncro scan to end..
474 if (ieee->state >= IEEE80211_LINKED && ieee->sync_scan_hurryup)
477 msleep_interruptible(IEEE80211_SOFTMAC_SCAN_TIME);
481 if(ieee->state < IEEE80211_LINKED){
482 ieee->actscanning = false;
483 mutex_unlock(&ieee->scan_mutex);
486 ieee->sync_scan_hurryup = 0;
487 if(IS_DOT11D_ENABLE(ieee))
488 DOT11D_ScanComplete(ieee);
489 mutex_unlock(&ieee->scan_mutex);
492 EXPORT_SYMBOL(ieee80211_softmac_scan_syncro);
494 static void ieee80211_softmac_scan_wq(struct work_struct *work)
496 struct delayed_work *dwork = to_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];
501 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
504 mutex_lock(&ieee->scan_mutex);
506 ieee->current_network.channel =
507 (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
508 if (watchdog++ > MAX_CHANNEL_NUMBER)
510 //if current channel is not in channel map, set to default channel.
511 if (!channel_map[ieee->current_network.channel]) {
512 ieee->current_network.channel = 6;
513 goto out; /* no good chans */
516 }while(!channel_map[ieee->current_network.channel]);
517 if (ieee->scanning == 0 )
519 ieee->set_chan(ieee->dev, ieee->current_network.channel);
520 if(channel_map[ieee->current_network.channel] == 1)
521 ieee80211_send_probe_requests(ieee);
524 schedule_delayed_work(&ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
526 mutex_unlock(&ieee->scan_mutex);
529 if(IS_DOT11D_ENABLE(ieee))
530 DOT11D_ScanComplete(ieee);
531 ieee->actscanning = false;
534 mutex_unlock(&ieee->scan_mutex);
539 static void ieee80211_beacons_start(struct ieee80211_device *ieee)
542 spin_lock_irqsave(&ieee->beacon_lock,flags);
544 ieee->beacon_txing = 1;
545 ieee80211_send_beacon(ieee);
547 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
550 static void ieee80211_beacons_stop(struct ieee80211_device *ieee)
554 spin_lock_irqsave(&ieee->beacon_lock, flags);
556 ieee->beacon_txing = 0;
557 del_timer_sync(&ieee->beacon_timer);
559 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
564 void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
566 if(ieee->stop_send_beacons)
567 ieee->stop_send_beacons(ieee->dev);
568 if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
569 ieee80211_beacons_stop(ieee);
571 EXPORT_SYMBOL(ieee80211_stop_send_beacons);
573 void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
575 if(ieee->start_send_beacons)
576 ieee->start_send_beacons(ieee->dev, ieee->basic_rate);
577 if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
578 ieee80211_beacons_start(ieee);
580 EXPORT_SYMBOL(ieee80211_start_send_beacons);
582 static void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
584 // unsigned long flags;
586 //ieee->sync_scan_hurryup = 1;
588 mutex_lock(&ieee->scan_mutex);
589 // spin_lock_irqsave(&ieee->lock, flags);
591 if (ieee->scanning == 1) {
594 cancel_delayed_work(&ieee->softmac_scan_wq);
597 // spin_unlock_irqrestore(&ieee->lock, flags);
598 mutex_unlock(&ieee->scan_mutex);
601 void ieee80211_stop_scan(struct ieee80211_device *ieee)
603 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
604 ieee80211_softmac_stop_scan(ieee);
606 ieee->stop_scan(ieee->dev);
608 EXPORT_SYMBOL(ieee80211_stop_scan);
610 /* called with ieee->lock held */
611 static void ieee80211_start_scan(struct ieee80211_device *ieee)
613 if (IS_DOT11D_ENABLE(ieee) )
615 if (IS_COUNTRY_IE_VALID(ieee))
617 RESET_CIE_WATCHDOG(ieee);
620 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
621 if (ieee->scanning == 0) {
623 schedule_delayed_work(&ieee->softmac_scan_wq, 0);
626 ieee->start_scan(ieee->dev);
630 /* called with wx_mutex held */
631 void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
633 if (IS_DOT11D_ENABLE(ieee) )
635 if (IS_COUNTRY_IE_VALID(ieee))
637 RESET_CIE_WATCHDOG(ieee);
640 ieee->sync_scan_hurryup = 0;
641 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
642 ieee80211_softmac_scan_syncro(ieee);
644 ieee->scan_syncro(ieee->dev);
647 EXPORT_SYMBOL(ieee80211_start_scan_syncro);
649 static inline struct sk_buff *
650 ieee80211_authentication_req(struct ieee80211_network *beacon,
651 struct ieee80211_device *ieee, int challengelen)
654 struct ieee80211_authentication *auth;
655 int len = sizeof(struct ieee80211_authentication) + challengelen + ieee->tx_headroom;
658 skb = dev_alloc_skb(len);
659 if (!skb) return NULL;
661 skb_reserve(skb, ieee->tx_headroom);
662 auth = (struct ieee80211_authentication *)
663 skb_put(skb, sizeof(struct ieee80211_authentication));
666 auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH
667 | IEEE80211_FCTL_WEP);
669 auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
671 auth->header.duration_id = cpu_to_le16(0x013a);
673 memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
674 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
675 memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
677 //auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
678 if(ieee->auth_mode == 0)
679 auth->algorithm = WLAN_AUTH_OPEN;
680 else if(ieee->auth_mode == 1)
681 auth->algorithm = cpu_to_le16(WLAN_AUTH_SHARED_KEY);
682 else if(ieee->auth_mode == 2)
683 auth->algorithm = WLAN_AUTH_OPEN; /* 0x80; */
684 printk("=================>%s():auth->algorithm is %d\n",__func__,auth->algorithm);
685 auth->transaction = cpu_to_le16(ieee->associate_seq);
686 ieee->associate_seq++;
688 auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
695 static struct sk_buff *ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
699 struct ieee80211_probe_response *beacon_buf;
700 struct sk_buff *skb = NULL;
702 int atim_len, erp_len;
703 struct ieee80211_crypt_data *crypt;
705 char *ssid = ieee->current_network.ssid;
706 int ssid_len = ieee->current_network.ssid_len;
707 int rate_len = ieee->current_network.rates_len+2;
708 int rate_ex_len = ieee->current_network.rates_ex_len;
709 int wpa_ie_len = ieee->wpa_ie_len;
710 u8 erpinfo_content = 0;
715 u8 tmp_ht_info_len=0;
716 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
717 u8 *tmp_generic_ie_buf=NULL;
718 u8 tmp_generic_ie_len=0;
720 if(rate_ex_len > 0) rate_ex_len+=2;
722 if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
727 if(ieee80211_is_54g(&ieee->current_network))
733 crypt = ieee->crypt[ieee->tx_keyidx];
736 encrypt = ieee->host_encrypt && crypt && crypt->ops &&
737 ((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len));
738 /* HT ralated element */
739 tmp_ht_cap_buf =(u8 *) &(ieee->pHTInfo->SelfHTCap);
740 tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
741 tmp_ht_info_buf =(u8 *) &(ieee->pHTInfo->SelfHTInfo);
742 tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo);
743 HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len,encrypt);
744 HTConstructInfoElement(ieee,tmp_ht_info_buf,&tmp_ht_info_len, encrypt);
747 if (pHTInfo->bRegRT2RTAggregation)
749 tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
750 tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer);
751 HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len);
753 // 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);
754 beacon_size = sizeof(struct ieee80211_probe_response)+2+
764 // +tmp_generic_ie_len
767 skb = dev_alloc_skb(beacon_size);
770 skb_reserve(skb, ieee->tx_headroom);
771 beacon_buf = (struct ieee80211_probe_response *) skb_put(skb, (beacon_size - ieee->tx_headroom));
772 memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
773 memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
774 memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
776 beacon_buf->header.duration_id = 0; /* FIXME */
777 beacon_buf->beacon_interval =
778 cpu_to_le16(ieee->current_network.beacon_interval);
779 beacon_buf->capability =
780 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
781 beacon_buf->capability |=
782 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE); /* add short preamble here */
784 if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
785 beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
787 crypt = ieee->crypt[ieee->tx_keyidx];
789 beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
792 beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
793 beacon_buf->info_element[0].id = MFIE_TYPE_SSID;
794 beacon_buf->info_element[0].len = ssid_len;
796 tag = (u8 *) beacon_buf->info_element[0].data;
798 memcpy(tag, ssid, ssid_len);
802 *(tag++) = MFIE_TYPE_RATES;
803 *(tag++) = rate_len-2;
804 memcpy(tag, ieee->current_network.rates, rate_len-2);
807 *(tag++) = MFIE_TYPE_DS_SET;
809 *(tag++) = ieee->current_network.channel;
812 *(tag++) = MFIE_TYPE_IBSS_SET;
815 put_unaligned_le16(ieee->current_network.atim_window,
821 *(tag++) = MFIE_TYPE_ERP;
823 *(tag++) = erpinfo_content;
826 *(tag++) = MFIE_TYPE_RATES_EX;
827 *(tag++) = rate_ex_len-2;
828 memcpy(tag, ieee->current_network.rates_ex, rate_ex_len-2);
834 if (ieee->iw_mode == IW_MODE_ADHOC)
835 {//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
836 memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
838 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
842 //skb->dev = ieee->dev;
847 static struct sk_buff *ieee80211_assoc_resp(struct ieee80211_device *ieee,
853 struct ieee80211_crypt_data *crypt;
854 struct ieee80211_assoc_response_frame *assoc;
857 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
858 int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len + ieee->tx_headroom;
860 skb = dev_alloc_skb(len);
865 skb_reserve(skb, ieee->tx_headroom);
867 assoc = (struct ieee80211_assoc_response_frame *)
868 skb_put(skb, sizeof(struct ieee80211_assoc_response_frame));
870 assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
871 memcpy(assoc->header.addr1, dest,ETH_ALEN);
872 memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
873 memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
874 assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
875 WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
879 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
881 if (ieee->host_encrypt)
882 crypt = ieee->crypt[ieee->tx_keyidx];
885 encrypt = crypt && crypt->ops;
888 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
891 assoc->aid = cpu_to_le16(ieee->assoc_id);
892 if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
893 else ieee->assoc_id++;
895 tag = (u8 *) skb_put(skb, rate_len);
897 ieee80211_MFIE_Brate(ieee, &tag);
898 ieee80211_MFIE_Grate(ieee, &tag);
903 static struct sk_buff *ieee80211_auth_resp(struct ieee80211_device *ieee,
904 int status, u8 *dest)
907 struct ieee80211_authentication *auth;
908 int len = ieee->tx_headroom + sizeof(struct ieee80211_authentication)+1;
910 skb = dev_alloc_skb(len);
915 skb->len = sizeof(struct ieee80211_authentication);
917 auth = (struct ieee80211_authentication *)skb->data;
919 auth->status = cpu_to_le16(status);
920 auth->transaction = cpu_to_le16(2);
921 auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
923 memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
924 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
925 memcpy(auth->header.addr1, dest, ETH_ALEN);
926 auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
932 static struct sk_buff *ieee80211_null_func(struct ieee80211_device *ieee,
936 struct rtl_80211_hdr_3addr *hdr;
938 skb = dev_alloc_skb(sizeof(struct rtl_80211_hdr_3addr));
943 hdr = (struct rtl_80211_hdr_3addr *)skb_put(skb,sizeof(struct rtl_80211_hdr_3addr));
945 memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
946 memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
947 memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
949 hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
950 IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
951 (pwr ? IEEE80211_FCTL_PM:0));
959 static void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8 *dest)
961 struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
964 softmac_mgmt_xmit(buf, ieee);
968 static void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s,
971 struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
974 softmac_mgmt_xmit(buf, ieee);
978 static void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
982 struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
984 softmac_mgmt_xmit(buf, ieee);
988 static inline struct sk_buff *
989 ieee80211_association_req(struct ieee80211_network *beacon,
990 struct ieee80211_device *ieee)
993 //unsigned long flags;
995 struct ieee80211_assoc_request_frame *hdr;
997 //short info_addr = 0;
999 //u16 suite_count = 0;
1000 //u8 suit_select = 0;
1001 //unsigned int wpa_len = beacon->wpa_ie_len;
1003 u8 *ht_cap_buf = NULL;
1005 u8 *realtek_ie_buf=NULL;
1006 u8 realtek_ie_len=0;
1007 int wpa_ie_len= ieee->wpa_ie_len;
1008 unsigned int ckip_ie_len=0;
1009 unsigned int ccxrm_ie_len=0;
1010 unsigned int cxvernum_ie_len=0;
1011 struct ieee80211_crypt_data *crypt;
1014 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
1015 unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
1017 unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
1022 crypt = ieee->crypt[ieee->tx_keyidx];
1023 encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len));
1025 /* Include High Throuput capability && Realtek proprietary */
1026 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1028 ht_cap_buf = (u8 *)&(ieee->pHTInfo->SelfHTCap);
1029 ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
1030 HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt);
1031 if (ieee->pHTInfo->bCurrentRT2RTAggregation)
1033 realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
1034 realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer);
1035 HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len);
1039 if (ieee->qos_support) {
1040 wmm_info_len = beacon->qos_data.supported?9:0;
1044 if (beacon->bCkipSupported)
1048 if (beacon->bCcxRmEnable)
1052 if (beacon->BssCcxVerNumber >= 2)
1053 cxvernum_ie_len = 5+2;
1056 len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1057 + beacon->ssid_len /* essid tagged val */
1058 + rate_len /* rates tagged val */
1067 + ieee->tx_headroom;
1069 len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1070 + beacon->ssid_len /* essid tagged val */
1071 + rate_len /* rates tagged val */
1079 + ieee->tx_headroom;
1082 skb = dev_alloc_skb(len);
1087 skb_reserve(skb, ieee->tx_headroom);
1089 hdr = (struct ieee80211_assoc_request_frame *)
1090 skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)+2);
1093 hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
1094 hdr->header.duration_id = cpu_to_le16(37);
1095 memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
1096 memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1097 memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
1099 memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John
1101 hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
1102 if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
1103 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1105 if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1106 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); //add short_preamble here
1108 if(ieee->short_slot)
1109 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
1110 if (wmm_info_len) //QOS
1111 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS);
1113 hdr->listen_interval = cpu_to_le16(0xa);
1115 hdr->info_element[0].id = MFIE_TYPE_SSID;
1117 hdr->info_element[0].len = beacon->ssid_len;
1118 tag = skb_put(skb, beacon->ssid_len);
1119 memcpy(tag, beacon->ssid, beacon->ssid_len);
1121 tag = skb_put(skb, rate_len);
1123 ieee80211_MFIE_Brate(ieee, &tag);
1124 ieee80211_MFIE_Grate(ieee, &tag);
1125 // For CCX 1 S13, CKIP. Added by Annie, 2006-08-14.
1126 if (beacon->bCkipSupported) {
1127 static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client"
1128 u8 CcxAironetBuf[30];
1129 OCTET_STRING osCcxAironetIE;
1131 memset(CcxAironetBuf, 0, 30);
1132 osCcxAironetIE.Octet = CcxAironetBuf;
1133 osCcxAironetIE.Length = sizeof(CcxAironetBuf);
1135 // Ref. CCX test plan v3.61, 3.2.3.1 step 13.
1136 // We want to make the device type as "4500-client". 060926, by CCW.
1138 memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui));
1140 // CCX1 spec V1.13, A01.1 CKIP Negotiation (page23):
1141 // "The CKIP negotiation is started with the associate request from the client to the access point,
1142 // containing an Aironet element with both the MIC and KP bits set."
1143 osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |= (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ;
1144 tag = skb_put(skb, ckip_ie_len);
1145 *tag++ = MFIE_TYPE_AIRONET;
1146 *tag++ = osCcxAironetIE.Length;
1147 memcpy(tag, osCcxAironetIE.Octet, osCcxAironetIE.Length);
1148 tag += osCcxAironetIE.Length;
1151 if (beacon->bCcxRmEnable)
1153 static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
1154 OCTET_STRING osCcxRmCap;
1156 osCcxRmCap.Octet = CcxRmCapBuf;
1157 osCcxRmCap.Length = sizeof(CcxRmCapBuf);
1158 tag = skb_put(skb, ccxrm_ie_len);
1159 *tag++ = MFIE_TYPE_GENERIC;
1160 *tag++ = osCcxRmCap.Length;
1161 memcpy(tag, osCcxRmCap.Octet, osCcxRmCap.Length);
1162 tag += osCcxRmCap.Length;
1165 if (beacon->BssCcxVerNumber >= 2) {
1166 u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
1167 OCTET_STRING osCcxVerNum;
1168 CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
1169 osCcxVerNum.Octet = CcxVerNumBuf;
1170 osCcxVerNum.Length = sizeof(CcxVerNumBuf);
1171 tag = skb_put(skb, cxvernum_ie_len);
1172 *tag++ = MFIE_TYPE_GENERIC;
1173 *tag++ = osCcxVerNum.Length;
1174 memcpy(tag, osCcxVerNum.Octet, osCcxVerNum.Length);
1175 tag += osCcxVerNum.Length;
1178 if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
1179 if (ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC)
1181 tag = skb_put(skb, ht_cap_len);
1182 *tag++ = MFIE_TYPE_HT_CAP;
1183 *tag++ = ht_cap_len - 2;
1184 memcpy(tag, ht_cap_buf, ht_cap_len - 2);
1185 tag += ht_cap_len -2;
1190 //choose what wpa_supplicant gives to associate.
1191 tag = skb_put(skb, wpa_ie_len);
1193 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
1196 tag = skb_put(skb, wmm_info_len);
1198 ieee80211_WMM_Info(ieee, &tag);
1201 tag = skb_put(skb, turbo_info_len);
1202 if (turbo_info_len) {
1203 ieee80211_TURBO_Info(ieee, &tag);
1207 if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
1208 if(ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC)
1210 tag = skb_put(skb, ht_cap_len);
1211 *tag++ = MFIE_TYPE_GENERIC;
1212 *tag++ = ht_cap_len - 2;
1213 memcpy(tag, ht_cap_buf, ht_cap_len - 2);
1214 tag += ht_cap_len -2;
1217 if (ieee->pHTInfo->bCurrentRT2RTAggregation) {
1218 tag = skb_put(skb, realtek_ie_len);
1219 *tag++ = MFIE_TYPE_GENERIC;
1220 *tag++ = realtek_ie_len - 2;
1221 memcpy(tag, realtek_ie_buf, realtek_ie_len - 2);
1224 // printk("<=====%s(), %p, %p\n", __func__, ieee->dev, ieee->dev->dev_addr);
1225 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
1229 void ieee80211_associate_abort(struct ieee80211_device *ieee)
1232 unsigned long flags;
1233 spin_lock_irqsave(&ieee->lock, flags);
1235 ieee->associate_seq++;
1237 /* don't scan, and avoid to have the RX path possibily
1238 * try again to associate. Even do not react to AUTH or
1239 * ASSOC response. Just wait for the retry wq to be scheduled.
1240 * Here we will check if there are good nets to associate
1241 * with, so we retry or just get back to NO_LINK and scanning
1243 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
1244 IEEE80211_DEBUG_MGMT("Authentication failed\n");
1245 ieee->softmac_stats.no_auth_rs++;
1247 IEEE80211_DEBUG_MGMT("Association failed\n");
1248 ieee->softmac_stats.no_ass_rs++;
1251 ieee->state = IEEE80211_ASSOCIATING_RETRY;
1253 schedule_delayed_work(&ieee->associate_retry_wq, \
1254 IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
1256 spin_unlock_irqrestore(&ieee->lock, flags);
1259 static void ieee80211_associate_abort_cb(unsigned long dev)
1261 ieee80211_associate_abort((struct ieee80211_device *) dev);
1265 static void ieee80211_associate_step1(struct ieee80211_device *ieee)
1267 struct ieee80211_network *beacon = &ieee->current_network;
1268 struct sk_buff *skb;
1270 IEEE80211_DEBUG_MGMT("Stopping scan\n");
1272 ieee->softmac_stats.tx_auth_rq++;
1273 skb=ieee80211_authentication_req(beacon, ieee, 0);
1276 ieee80211_associate_abort(ieee);
1278 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
1279 IEEE80211_DEBUG_MGMT("Sending authentication request\n");
1280 softmac_mgmt_xmit(skb, ieee);
1281 //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
1282 if (!timer_pending(&ieee->associate_timer)) {
1283 ieee->associate_timer.expires = jiffies + (HZ / 2);
1284 add_timer(&ieee->associate_timer);
1286 //dev_kfree_skb_any(skb);//edit by thomas
1290 static void ieee80211_auth_challenge(struct ieee80211_device *ieee,
1295 struct sk_buff *skb;
1296 struct ieee80211_network *beacon = &ieee->current_network;
1297 // int hlen = sizeof(struct ieee80211_authentication);
1299 ieee->associate_seq++;
1300 ieee->softmac_stats.tx_auth_rq++;
1302 skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
1304 ieee80211_associate_abort(ieee);
1306 c = skb_put(skb, chlen+2);
1307 *(c++) = MFIE_TYPE_CHALLENGE;
1309 memcpy(c, challenge, chlen);
1311 IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
1313 ieee80211_encrypt_fragment(ieee, skb, sizeof(struct rtl_80211_hdr_3addr ));
1315 softmac_mgmt_xmit(skb, ieee);
1316 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1317 //dev_kfree_skb_any(skb);//edit by thomas
1322 static void ieee80211_associate_step2(struct ieee80211_device *ieee)
1324 struct sk_buff *skb;
1325 struct ieee80211_network *beacon = &ieee->current_network;
1327 del_timer_sync(&ieee->associate_timer);
1329 IEEE80211_DEBUG_MGMT("Sending association request\n");
1331 ieee->softmac_stats.tx_ass_rq++;
1332 skb=ieee80211_association_req(beacon, ieee);
1334 ieee80211_associate_abort(ieee);
1336 softmac_mgmt_xmit(skb, ieee);
1337 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1338 //dev_kfree_skb_any(skb);//edit by thomas
1341 static void ieee80211_associate_complete_wq(struct work_struct *work)
1343 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
1344 printk(KERN_INFO "Associated successfully\n");
1345 if(ieee80211_is_54g(&ieee->current_network) &&
1346 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1349 printk(KERN_INFO"Using G rates:%d\n", ieee->rate);
1352 printk(KERN_INFO"Using B rates:%d\n", ieee->rate);
1354 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1356 printk("Successfully associated, ht enabled\n");
1361 printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
1362 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1363 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1365 ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500);
1366 // To prevent the immediately calling watch_dog after association.
1367 if (ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
1369 ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
1370 ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
1372 ieee->link_change(ieee->dev);
1373 if (!ieee->is_silent_reset) {
1374 printk("============>normal associate\n");
1375 notify_wx_assoc_event(ieee);
1377 printk("==================>silent reset associate\n");
1378 ieee->is_silent_reset = false;
1381 if (ieee->data_hard_resume)
1382 ieee->data_hard_resume(ieee->dev);
1383 netif_carrier_on(ieee->dev);
1386 static void ieee80211_associate_complete(struct ieee80211_device *ieee)
1389 // struct net_device* dev = ieee->dev;
1390 del_timer_sync(&ieee->associate_timer);
1392 ieee->state = IEEE80211_LINKED;
1393 //ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet);
1394 schedule_work(&ieee->associate_complete_wq);
1397 static void ieee80211_associate_procedure_wq(struct work_struct *work)
1399 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
1400 ieee->sync_scan_hurryup = 1;
1401 mutex_lock(&ieee->wx_mutex);
1403 if (ieee->data_hard_stop)
1404 ieee->data_hard_stop(ieee->dev);
1406 ieee80211_stop_scan(ieee);
1407 printk("===>%s(), chan:%d\n", __func__, ieee->current_network.channel);
1408 //ieee->set_chan(ieee->dev, ieee->current_network.channel);
1409 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1411 ieee->associate_seq = 1;
1412 ieee80211_associate_step1(ieee);
1414 mutex_unlock(&ieee->wx_mutex);
1417 inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
1419 u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
1420 int tmp_ssid_len = 0;
1422 short apset, ssidset, ssidbroad, apmatch, ssidmatch;
1424 /* we are interested in new new only if we are not associated
1425 * and we are not associating / authenticating
1427 if (ieee->state != IEEE80211_NOLINK)
1430 if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
1433 if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
1437 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) {
1438 /* if the user specified the AP MAC, we need also the essid
1439 * This could be obtained by beacons or, if the network does not
1440 * broadcast it, it can be put manually.
1442 apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
1443 ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
1444 ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0');
1445 apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
1446 ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\
1447 (!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
1450 if ( /* if the user set the AP check if match.
1451 * if the network does not broadcast essid we check the user supplyed ANY essid
1452 * if the network does broadcast and the user does not set essid it is OK
1453 * if the network does broadcast and the user did set essid chech if essid match
1455 (apset && apmatch &&
1456 ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
1457 /* if the ap is not set, check that the user set the bssid
1458 * and the network does broadcast and that those two bssid matches
1460 (!apset && ssidset && ssidbroad && ssidmatch)
1462 /* if the essid is hidden replace it with the
1463 * essid provided by the user.
1466 strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
1467 tmp_ssid_len = ieee->current_network.ssid_len;
1469 memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
1471 strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
1472 ieee->current_network.ssid_len = tmp_ssid_len;
1473 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);
1475 //ieee->pHTInfo->IOTAction = 0;
1476 HTResetIOTSetting(ieee->pHTInfo);
1477 if (ieee->iw_mode == IW_MODE_INFRA){
1478 /* Join the network for the first time */
1479 ieee->AsocRetryCount = 0;
1480 //for HT by amy 080514
1481 if((ieee->current_network.qos_data.supported == 1) &&
1482 // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT))
1483 ieee->current_network.bssht.bdSupportHT)
1484 /*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.*/
1486 // ieee->pHTInfo->bCurrentHTSupport = true;
1487 HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network));
1491 ieee->pHTInfo->bCurrentHTSupport = false;
1494 ieee->state = IEEE80211_ASSOCIATING;
1495 schedule_work(&ieee->associate_procedure_wq);
1497 if(ieee80211_is_54g(&ieee->current_network) &&
1498 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1500 ieee->SetWirelessMode(ieee->dev, IEEE_G);
1501 printk(KERN_INFO"Using G rates\n");
1504 ieee->SetWirelessMode(ieee->dev, IEEE_B);
1505 printk(KERN_INFO"Using B rates\n");
1507 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1508 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1509 ieee->state = IEEE80211_LINKED;
1517 void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
1519 unsigned long flags;
1520 struct ieee80211_network *target;
1522 spin_lock_irqsave(&ieee->lock, flags);
1524 list_for_each_entry(target, &ieee->network_list, list) {
1526 /* if the state become different that NOLINK means
1527 * we had found what we are searching for
1530 if (ieee->state != IEEE80211_NOLINK)
1533 if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
1534 ieee80211_softmac_new_net(ieee, target);
1537 spin_unlock_irqrestore(&ieee->lock, flags);
1542 static inline u16 auth_parse(struct sk_buff *skb, u8 **challenge, int *chlen)
1544 struct ieee80211_authentication *a;
1546 if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
1547 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
1551 a = (struct ieee80211_authentication *) skb->data;
1552 if (skb->len > (sizeof(struct ieee80211_authentication) + 3)) {
1553 t = skb->data + sizeof(struct ieee80211_authentication);
1555 if (*(t++) == MFIE_TYPE_CHALLENGE) {
1557 *challenge = kmemdup(t, *chlen, GFP_ATOMIC);
1563 return le16_to_cpu(a->status);
1568 static int auth_rq_parse(struct sk_buff *skb, u8 *dest)
1570 struct ieee80211_authentication *a;
1572 if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
1573 IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
1576 a = (struct ieee80211_authentication *) skb->data;
1578 memcpy(dest,a->header.addr2, ETH_ALEN);
1580 if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
1581 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1583 return WLAN_STATUS_SUCCESS;
1586 static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
1593 struct rtl_80211_hdr_3addr *header =
1594 (struct rtl_80211_hdr_3addr *) skb->data;
1596 if (skb->len < sizeof (struct rtl_80211_hdr_3addr ))
1597 return -1; /* corrupted */
1599 memcpy(src,header->addr2, ETH_ALEN);
1601 skbend = (u8 *)skb->data + skb->len;
1603 tag = skb->data + sizeof (struct rtl_80211_hdr_3addr );
1605 while (tag+1 < skbend){
1611 tag++; /* point to the len field */
1612 tag = tag + *(tag); /* point to the last data byte of the tag */
1613 tag++; /* point to the next tag */
1616 //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
1617 if (ssidlen == 0) return 1;
1619 if (!ssid) return 1; /* ssid not found in tagged param */
1620 return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
1624 static int assoc_rq_parse(struct sk_buff *skb, u8 *dest)
1626 struct ieee80211_assoc_request_frame *a;
1628 if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
1629 sizeof(struct ieee80211_info_element))) {
1631 IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
1635 a = (struct ieee80211_assoc_request_frame *) skb->data;
1637 memcpy(dest,a->header.addr2,ETH_ALEN);
1642 static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid)
1644 struct ieee80211_assoc_response_frame *response_head;
1647 if (skb->len < sizeof(struct ieee80211_assoc_response_frame)) {
1648 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
1652 response_head = (struct ieee80211_assoc_response_frame *) skb->data;
1653 *aid = le16_to_cpu(response_head->aid) & 0x3fff;
1655 status_code = le16_to_cpu(response_head->status);
1656 if((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \
1657 status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&&
1658 ((ieee->mode == IEEE_G) &&
1659 (ieee->current_network.mode == IEEE_N_24G) &&
1660 (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) {
1661 ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
1663 ieee->AsocRetryCount = 0;
1666 return le16_to_cpu(response_head->status);
1670 ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1674 //IEEE80211DMESG("Rx probe");
1675 ieee->softmac_stats.rx_probe_rq++;
1676 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1677 if (probe_rq_parse(ieee, skb, dest)) {
1678 //IEEE80211DMESG("Was for me!");
1679 ieee->softmac_stats.tx_probe_rs++;
1680 ieee80211_resp_to_probe(ieee, dest);
1685 ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1689 //IEEE80211DMESG("Rx probe");
1690 ieee->softmac_stats.rx_auth_rq++;
1692 status = auth_rq_parse(skb, dest);
1694 ieee80211_resp_to_auth(ieee, status, dest);
1696 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1701 ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1705 //unsigned long flags;
1707 ieee->softmac_stats.rx_ass_rq++;
1708 if (assoc_rq_parse(skb, dest) != -1) {
1709 ieee80211_resp_to_assoc_rq(ieee, dest);
1712 printk(KERN_INFO"New client associated: %pM\n", dest);
1716 static void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee,
1720 struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
1723 softmac_ps_mgmt_xmit(buf, ieee);
1726 /* EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame); */
1728 static short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h,
1731 int timeout = ieee->ps_timeout;
1733 /*if(ieee->ps == IEEE80211_PS_DISABLED ||
1734 ieee->iw_mode != IW_MODE_INFRA ||
1735 ieee->state != IEEE80211_LINKED)
1739 dtim = ieee->current_network.dtim_data;
1740 if(!(dtim & IEEE80211_DTIM_VALID))
1742 timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
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,
1749 dev_trans_start(ieee->dev) + msecs_to_jiffies(timeout)))
1752 if(!time_after(jiffies,
1753 ieee->last_rx_ps_time + msecs_to_jiffies(timeout)))
1756 if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
1757 (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
1761 *time_l = ieee->current_network.last_dtim_sta_time[0]
1762 + (ieee->current_network.beacon_interval
1763 * ieee->current_network.dtim_period) * 1000;
1767 *time_h = ieee->current_network.last_dtim_sta_time[1];
1768 if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
1777 static inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
1783 unsigned long flags, flags2;
1785 spin_lock_irqsave(&ieee->lock, flags);
1787 if ((ieee->ps == IEEE80211_PS_DISABLED ||
1788 ieee->iw_mode != IW_MODE_INFRA ||
1789 ieee->state != IEEE80211_LINKED)){
1791 // #warning CHECK_LOCK_HERE
1792 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1794 ieee80211_sta_wakeup(ieee, 1);
1796 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1799 sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
1800 /* 2 wake, 1 sleep, 0 do nothing */
1806 if(ieee->sta_sleep == 1)
1807 ieee->enter_sleep_state(ieee->dev, th, tl);
1809 else if(ieee->sta_sleep == 0){
1810 // printk("send null 1\n");
1811 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1813 if(ieee->ps_is_queue_empty(ieee->dev)){
1816 ieee->sta_sleep = 2;
1818 ieee->ps_request_tx_ack(ieee->dev);
1820 ieee80211_sta_ps_send_null_frame(ieee, 1);
1825 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1830 }else if(sleep == 2){
1831 //#warning CHECK_LOCK_HERE
1832 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1834 ieee80211_sta_wakeup(ieee, 1);
1836 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1840 spin_unlock_irqrestore(&ieee->lock, flags);
1844 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
1846 if (ieee->sta_sleep == 0) {
1848 printk("Warning: driver is probably failing to report TX ps error\n");
1849 ieee->ps_request_tx_ack(ieee->dev);
1850 ieee80211_sta_ps_send_null_frame(ieee, 0);
1856 if(ieee->sta_sleep == 1)
1857 ieee->sta_wake_up(ieee->dev);
1859 ieee->sta_sleep = 0;
1862 ieee->ps_request_tx_ack(ieee->dev);
1863 ieee80211_sta_ps_send_null_frame(ieee, 0);
1867 void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
1869 unsigned long flags, flags2;
1871 spin_lock_irqsave(&ieee->lock, flags);
1873 if(ieee->sta_sleep == 2){
1874 /* Null frame with PS bit set */
1876 ieee->sta_sleep = 1;
1877 ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
1879 /* if the card report not success we can't be sure the AP
1880 * has not RXed so we can't assume the AP believe us awake
1883 /* 21112005 - tx again null without PS bit if lost */
1886 if ((ieee->sta_sleep == 0) && !success) {
1887 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1888 ieee80211_sta_ps_send_null_frame(ieee, 0);
1889 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1892 spin_unlock_irqrestore(&ieee->lock, flags);
1894 EXPORT_SYMBOL(ieee80211_ps_tx_ack);
1896 static void ieee80211_process_action(struct ieee80211_device *ieee,
1897 struct sk_buff *skb)
1899 struct rtl_80211_hdr *header = (struct rtl_80211_hdr *)skb->data;
1900 u8 *act = ieee80211_get_payload(header);
1902 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
1905 IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
1912 if (*act == ACT_ADDBAREQ)
1913 ieee80211_rx_ADDBAReq(ieee, skb);
1914 else if (*act == ACT_ADDBARSP)
1915 ieee80211_rx_ADDBARsp(ieee, skb);
1916 else if (*act == ACT_DELBA)
1917 ieee80211_rx_DELBA(ieee, skb);
1926 static void ieee80211_check_auth_response(struct ieee80211_device *ieee,
1927 struct sk_buff *skb)
1929 /* default support N mode, disable halfNmode */
1930 bool bSupportNmode = true, bHalfSupportNmode = false;
1936 errcode = auth_parse(skb, &challenge, &chlen);
1938 if (ieee->open_wep || !challenge) {
1939 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
1940 ieee->softmac_stats.rx_auth_rs_ok++;
1941 iotAction = ieee->pHTInfo->IOTAction;
1942 if (!(iotAction & HT_IOT_ACT_PURE_N_MODE)) {
1943 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) {
1944 /* WEP or TKIP encryption */
1945 if (IsHTHalfNmodeAPs(ieee)) {
1946 bSupportNmode = true;
1947 bHalfSupportNmode = true;
1949 bSupportNmode = false;
1950 bHalfSupportNmode = false;
1952 netdev_dbg(ieee->dev, "SEC(%d, %d)\n",
1957 /* Dummy wirless mode setting- avoid encryption issue */
1958 if (bSupportNmode) {
1959 /* N mode setting */
1960 ieee->SetWirelessMode(ieee->dev,
1961 ieee->current_network.mode);
1963 /* b/g mode setting - TODO */
1964 ieee->SetWirelessMode(ieee->dev, IEEE_G);
1967 if (ieee->current_network.mode == IEEE_N_24G &&
1968 bHalfSupportNmode) {
1969 netdev_dbg(ieee->dev, "enter half N mode\n");
1970 ieee->bHalfWirelessN24GMode = true;
1972 ieee->bHalfWirelessN24GMode = false;
1974 ieee80211_associate_step2(ieee);
1976 ieee80211_auth_challenge(ieee, challenge, chlen);
1979 ieee->softmac_stats.rx_auth_rs_err++;
1980 IEEE80211_DEBUG_MGMT("Auth response status code 0x%x", errcode);
1981 ieee80211_associate_abort(ieee);
1986 ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
1987 struct ieee80211_rx_stats *rx_stats, u16 type,
1990 struct rtl_80211_hdr_3addr *header = (struct rtl_80211_hdr_3addr *) skb->data;
1993 struct ieee80211_assoc_response_frame *assoc_resp;
1994 // struct ieee80211_info_element *info_element;
1996 if(!ieee->proto_started)
1999 if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
2000 ieee->iw_mode == IW_MODE_INFRA &&
2001 ieee->state == IEEE80211_LINKED))
2003 tasklet_schedule(&ieee->ps_task);
2005 if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
2006 WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
2007 ieee->last_rx_ps_time = jiffies;
2009 switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
2011 case IEEE80211_STYPE_ASSOC_RESP:
2012 case IEEE80211_STYPE_REASSOC_RESP:
2014 IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
2015 WLAN_FC_GET_STYPE(header->frame_ctl));
2016 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2017 ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
2018 ieee->iw_mode == IW_MODE_INFRA){
2019 struct ieee80211_network network_resp;
2020 struct ieee80211_network *network = &network_resp;
2022 errcode = assoc_parse(ieee, skb, &aid);
2024 ieee->state=IEEE80211_LINKED;
2025 ieee->assoc_id = aid;
2026 ieee->softmac_stats.rx_ass_ok++;
2027 /* station support qos */
2028 /* Let the register setting defaultly with Legacy station */
2029 if (ieee->qos_support) {
2030 assoc_resp = (struct ieee80211_assoc_response_frame *)skb->data;
2031 memset(network, 0, sizeof(*network));
2032 if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\
2033 rx_stats->len - sizeof(*assoc_resp),\
2038 { //filling the PeerHTCap. //maybe not necessary as we can get its info from current_network.
2039 memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
2040 memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
2042 if (ieee->handle_assoc_response != NULL)
2043 ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame *)header, network);
2045 ieee80211_associate_complete(ieee);
2047 /* aid could not been allocated */
2048 ieee->softmac_stats.rx_ass_err++;
2050 "Association response status code 0x%x\n",
2052 IEEE80211_DEBUG_MGMT(
2053 "Association response status code 0x%x\n",
2055 if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
2056 schedule_work(&ieee->associate_procedure_wq);
2058 ieee80211_associate_abort(ieee);
2064 case IEEE80211_STYPE_ASSOC_REQ:
2065 case IEEE80211_STYPE_REASSOC_REQ:
2067 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2068 ieee->iw_mode == IW_MODE_MASTER)
2070 ieee80211_rx_assoc_rq(ieee, skb);
2073 case IEEE80211_STYPE_AUTH:
2075 if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) {
2076 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING
2077 && ieee->iw_mode == IW_MODE_INFRA) {
2079 IEEE80211_DEBUG_MGMT("Received auth response");
2080 ieee80211_check_auth_response(ieee, skb);
2081 } else if (ieee->iw_mode == IW_MODE_MASTER) {
2082 ieee80211_rx_auth_rq(ieee, skb);
2087 case IEEE80211_STYPE_PROBE_REQ:
2089 if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
2090 ((ieee->iw_mode == IW_MODE_ADHOC ||
2091 ieee->iw_mode == IW_MODE_MASTER) &&
2092 ieee->state == IEEE80211_LINKED)){
2093 ieee80211_rx_probe_rq(ieee, skb);
2097 case IEEE80211_STYPE_DISASSOC:
2098 case IEEE80211_STYPE_DEAUTH:
2099 /* FIXME for now repeat all the association procedure
2100 * both for disassociation and deauthentication
2102 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2103 ieee->state == IEEE80211_LINKED &&
2104 ieee->iw_mode == IW_MODE_INFRA){
2106 ieee->state = IEEE80211_ASSOCIATING;
2107 ieee->softmac_stats.reassoc++;
2109 notify_wx_assoc_event(ieee);
2110 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2111 RemovePeerTS(ieee, header->addr2);
2112 schedule_work(&ieee->associate_procedure_wq);
2115 case IEEE80211_STYPE_MANAGE_ACT:
2116 ieee80211_process_action(ieee, skb);
2122 //dev_kfree_skb_any(skb);
2126 /* The following are for a simpler TX queue management.
2127 * Instead of using netif_[stop/wake]_queue, the driver
2128 * will use these two functions (plus a reset one) that
2129 * will internally call the kernel netif_* and take care
2130 * of the ieee802.11 fragmentation.
2131 * So, the driver receives a fragment at a time and might
2132 * call the stop function when it wants, without taking
2133 * care to have enough room to TX an entire packet.
2134 * This might be useful if each fragment needs its own
2135 * descriptor. Thus, just keeping a total free memory > than
2136 * the max fragmentation threshold is not enough. If the
2137 * ieee802.11 stack passed a TXB struct, then you would need
2138 * to keep N free descriptors where
2139 * N = MAX_PACKET_SIZE / MIN_FRAG_THRESHOLD.
2140 * In this way you need just one and the 802.11 stack
2141 * will take care of buffering fragments and pass them to
2142 * to the driver later, when it wakes the queue.
2144 void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
2147 unsigned int queue_index = txb->queue_index;
2148 unsigned long flags;
2150 struct cb_desc *tcb_desc = NULL;
2152 spin_lock_irqsave(&ieee->lock, flags);
2154 /* called with 2nd parm 0, no tx mgmt lock required */
2155 ieee80211_sta_wakeup(ieee, 0);
2157 /* update the tx status */
2158 ieee->stats.tx_bytes += le16_to_cpu(txb->payload_size);
2159 ieee->stats.tx_packets++;
2160 tcb_desc = (struct cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
2161 if (tcb_desc->bMulticast) {
2162 ieee->stats.multicast++;
2164 /* if xmit available, just xmit it immediately, else just insert it to the wait queue */
2165 for(i = 0; i < txb->nr_frags; i++) {
2166 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2167 if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) ||
2169 if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
2171 (!ieee->check_nic_enough_desc(ieee->dev,queue_index))||\
2172 (ieee->queue_stop)) {
2173 /* insert the skb packet to the wait queue */
2174 /* as for the completion function, it does not need
2175 * to check it any more.
2177 //printk("error:no descriptor left@queue_index %d\n", queue_index);
2178 //ieee80211_stop_queue(ieee);
2179 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2180 skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]);
2182 skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
2185 ieee->softmac_data_hard_start_xmit(
2187 ieee->dev, ieee->rate);
2188 //ieee->stats.tx_packets++;
2189 //ieee->stats.tx_bytes += txb->fragments[i]->len;
2190 //ieee->dev->trans_start = jiffies;
2193 ieee80211_txb_free(txb);
2196 spin_unlock_irqrestore(&ieee->lock, flags);
2199 EXPORT_SYMBOL(ieee80211_softmac_xmit);
2201 /* called with ieee->lock acquired */
2202 static void ieee80211_resume_tx(struct ieee80211_device *ieee)
2205 for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
2207 if (ieee->queue_stop){
2208 ieee->tx_pending.frag = i;
2212 ieee->softmac_data_hard_start_xmit(
2213 ieee->tx_pending.txb->fragments[i],
2214 ieee->dev, ieee->rate);
2215 //(i+1)<ieee->tx_pending.txb->nr_frags);
2216 ieee->stats.tx_packets++;
2217 netif_trans_update(ieee->dev);
2222 ieee80211_txb_free(ieee->tx_pending.txb);
2223 ieee->tx_pending.txb = NULL;
2227 void ieee80211_reset_queue(struct ieee80211_device *ieee)
2229 unsigned long flags;
2231 spin_lock_irqsave(&ieee->lock, flags);
2232 init_mgmt_queue(ieee);
2233 if (ieee->tx_pending.txb) {
2234 ieee80211_txb_free(ieee->tx_pending.txb);
2235 ieee->tx_pending.txb = NULL;
2237 ieee->queue_stop = 0;
2238 spin_unlock_irqrestore(&ieee->lock, flags);
2241 EXPORT_SYMBOL(ieee80211_reset_queue);
2243 void ieee80211_wake_queue(struct ieee80211_device *ieee)
2246 unsigned long flags;
2247 struct sk_buff *skb;
2248 struct rtl_80211_hdr_3addr *header;
2250 spin_lock_irqsave(&ieee->lock, flags);
2251 if (! ieee->queue_stop) goto exit;
2253 ieee->queue_stop = 0;
2255 if (ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) {
2256 while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
2258 header = (struct rtl_80211_hdr_3addr *) skb->data;
2260 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2262 if (ieee->seq_ctrl[0] == 0xFFF)
2263 ieee->seq_ctrl[0] = 0;
2265 ieee->seq_ctrl[0]++;
2267 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
2268 //dev_kfree_skb_any(skb);//edit by thomas
2271 if (!ieee->queue_stop && ieee->tx_pending.txb)
2272 ieee80211_resume_tx(ieee);
2274 if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)) {
2275 ieee->softmac_stats.swtxawake++;
2276 netif_wake_queue(ieee->dev);
2280 spin_unlock_irqrestore(&ieee->lock, flags);
2282 EXPORT_SYMBOL(ieee80211_wake_queue);
2284 void ieee80211_stop_queue(struct ieee80211_device *ieee)
2286 //unsigned long flags;
2287 //spin_lock_irqsave(&ieee->lock,flags);
2289 if (!netif_queue_stopped(ieee->dev)) {
2290 netif_stop_queue(ieee->dev);
2291 ieee->softmac_stats.swtxstop++;
2293 ieee->queue_stop = 1;
2294 //spin_unlock_irqrestore(&ieee->lock,flags);
2297 EXPORT_SYMBOL(ieee80211_stop_queue);
2299 /* called in user context only */
2300 void ieee80211_start_master_bss(struct ieee80211_device *ieee)
2304 if (ieee->current_network.ssid_len == 0) {
2305 strncpy(ieee->current_network.ssid,
2306 IEEE80211_DEFAULT_TX_ESSID,
2309 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2313 memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
2315 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2316 ieee->state = IEEE80211_LINKED;
2317 ieee->link_change(ieee->dev);
2318 notify_wx_assoc_event(ieee);
2320 if (ieee->data_hard_resume)
2321 ieee->data_hard_resume(ieee->dev);
2323 netif_carrier_on(ieee->dev);
2326 static void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
2330 if (ieee->data_hard_resume)
2331 ieee->data_hard_resume(ieee->dev);
2333 netif_carrier_on(ieee->dev);
2336 static void ieee80211_start_ibss_wq(struct work_struct *work)
2339 struct delayed_work *dwork = to_delayed_work(work);
2340 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
2341 /* iwconfig mode ad-hoc will schedule this and return
2342 * on the other hand this will block further iwconfig SET
2343 * operations because of the wx_mutex hold.
2344 * Anyway some most set operations set a flag to speed-up
2345 * (abort) this wq (when syncro scanning) before sleeping
2348 if (!ieee->proto_started) {
2349 printk("==========oh driver down return\n");
2352 mutex_lock(&ieee->wx_mutex);
2354 if (ieee->current_network.ssid_len == 0) {
2355 strcpy(ieee->current_network.ssid, IEEE80211_DEFAULT_TX_ESSID);
2356 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2360 /* check if we have this cell in our network list */
2361 ieee80211_softmac_check_all_nets(ieee);
2364 // if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK))
2365 if (ieee->state == IEEE80211_NOLINK)
2366 ieee->current_network.channel = 6;
2367 /* if not then the state is not linked. Maybe the user swithced to
2368 * ad-hoc mode just after being in monitor mode, or just after
2369 * being very few time in managed mode (so the card have had no
2370 * time to scan all the chans..) or we have just run up the iface
2371 * after setting ad-hoc mode. So we have to give another try..
2372 * Here, in ibss mode, should be safe to do this without extra care
2373 * (in bss mode we had to make sure no-one tryed to associate when
2374 * we had just checked the ieee->state and we was going to start the
2375 * scan) beacause in ibss mode the ieee80211_new_net function, when
2376 * finds a good net, just set the ieee->state to IEEE80211_LINKED,
2377 * so, at worst, we waste a bit of time to initiate an unneeded syncro
2378 * scan, that will stop at the first round because it sees the state
2381 if (ieee->state == IEEE80211_NOLINK)
2382 ieee80211_start_scan_syncro(ieee);
2384 /* the network definitively is not here.. create a new cell */
2385 if (ieee->state == IEEE80211_NOLINK) {
2386 printk("creating new IBSS cell\n");
2388 random_ether_addr(ieee->current_network.bssid);
2390 if(ieee->modulation & IEEE80211_CCK_MODULATION){
2392 ieee->current_network.rates_len = 4;
2394 ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
2395 ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
2396 ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
2397 ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
2400 ieee->current_network.rates_len = 0;
2402 if(ieee->modulation & IEEE80211_OFDM_MODULATION){
2403 ieee->current_network.rates_ex_len = 8;
2405 ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
2406 ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
2407 ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
2408 ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
2409 ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
2410 ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
2411 ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
2412 ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
2416 ieee->current_network.rates_ex_len = 0;
2420 // By default, WMM function will be disabled in IBSS mode
2421 ieee->current_network.QoS_Enable = 0;
2422 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2423 ieee->current_network.atim_window = 0;
2424 ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
2425 if(ieee->short_slot)
2426 ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
2430 ieee->state = IEEE80211_LINKED;
2432 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2433 ieee->link_change(ieee->dev);
2435 notify_wx_assoc_event(ieee);
2437 ieee80211_start_send_beacons(ieee);
2439 if (ieee->data_hard_resume)
2440 ieee->data_hard_resume(ieee->dev);
2441 netif_carrier_on(ieee->dev);
2443 mutex_unlock(&ieee->wx_mutex);
2446 inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
2448 schedule_delayed_work(&ieee->start_ibss_wq, 150);
2451 /* this is called only in user context, with wx_mutex held */
2452 void ieee80211_start_bss(struct ieee80211_device *ieee)
2454 unsigned long flags;
2456 // Ref: 802.11d 11.1.3.3
2457 // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
2459 if (IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
2461 if (! ieee->bGlobalDomain)
2466 /* check if we have already found the net we
2467 * are interested in (if any).
2468 * if not (we are disassociated and we are not
2469 * in associating / authenticating phase) start the background scanning.
2471 ieee80211_softmac_check_all_nets(ieee);
2473 /* ensure no-one start an associating process (thus setting
2474 * the ieee->state to ieee80211_ASSOCIATING) while we
2475 * have just cheked it and we are going to enable scan.
2476 * The ieee80211_new_net function is always called with
2477 * lock held (from both ieee80211_softmac_check_all_nets and
2478 * the rx path), so we cannot be in the middle of such function
2480 spin_lock_irqsave(&ieee->lock, flags);
2482 if (ieee->state == IEEE80211_NOLINK) {
2483 ieee->actscanning = true;
2484 ieee80211_start_scan(ieee);
2486 spin_unlock_irqrestore(&ieee->lock, flags);
2489 /* called only in userspace context */
2490 void ieee80211_disassociate(struct ieee80211_device *ieee)
2494 netif_carrier_off(ieee->dev);
2495 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
2496 ieee80211_reset_queue(ieee);
2498 if (ieee->data_hard_stop)
2499 ieee->data_hard_stop(ieee->dev);
2500 if(IS_DOT11D_ENABLE(ieee))
2502 ieee->state = IEEE80211_NOLINK;
2503 ieee->is_set_key = false;
2504 ieee->link_change(ieee->dev);
2505 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2506 notify_wx_assoc_event(ieee);
2509 EXPORT_SYMBOL(ieee80211_disassociate);
2511 static void ieee80211_associate_retry_wq(struct work_struct *work)
2513 struct delayed_work *dwork = to_delayed_work(work);
2514 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
2515 unsigned long flags;
2517 mutex_lock(&ieee->wx_mutex);
2518 if(!ieee->proto_started)
2521 if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
2524 /* until we do not set the state to IEEE80211_NOLINK
2525 * there are no possibility to have someone else trying
2526 * to start an association procedure (we get here with
2527 * ieee->state = IEEE80211_ASSOCIATING).
2528 * When we set the state to IEEE80211_NOLINK it is possible
2529 * that the RX path run an attempt to associate, but
2530 * both ieee80211_softmac_check_all_nets and the
2531 * RX path works with ieee->lock held so there are no
2532 * problems. If we are still disassociated then start a scan.
2533 * the lock here is necessary to ensure no one try to start
2534 * an association procedure when we have just checked the
2535 * state and we are going to start the scan.
2537 ieee->state = IEEE80211_NOLINK;
2539 ieee80211_softmac_check_all_nets(ieee);
2541 spin_lock_irqsave(&ieee->lock, flags);
2543 if(ieee->state == IEEE80211_NOLINK)
2544 ieee80211_start_scan(ieee);
2546 spin_unlock_irqrestore(&ieee->lock, flags);
2549 mutex_unlock(&ieee->wx_mutex);
2552 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
2554 u8 broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2556 struct sk_buff *skb;
2557 struct ieee80211_probe_response *b;
2559 skb = ieee80211_probe_resp(ieee, broadcast_addr);
2564 b = (struct ieee80211_probe_response *) skb->data;
2565 b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
2571 struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
2573 struct sk_buff *skb;
2574 struct ieee80211_probe_response *b;
2576 skb = ieee80211_get_beacon_(ieee);
2580 b = (struct ieee80211_probe_response *) skb->data;
2581 b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2583 if (ieee->seq_ctrl[0] == 0xFFF)
2584 ieee->seq_ctrl[0] = 0;
2586 ieee->seq_ctrl[0]++;
2590 EXPORT_SYMBOL(ieee80211_get_beacon);
2592 void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
2594 ieee->sync_scan_hurryup = 1;
2595 mutex_lock(&ieee->wx_mutex);
2596 ieee80211_stop_protocol(ieee);
2597 mutex_unlock(&ieee->wx_mutex);
2599 EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
2601 void ieee80211_stop_protocol(struct ieee80211_device *ieee)
2603 if (!ieee->proto_started)
2606 ieee->proto_started = 0;
2608 ieee80211_stop_send_beacons(ieee);
2609 del_timer_sync(&ieee->associate_timer);
2610 cancel_delayed_work(&ieee->associate_retry_wq);
2611 cancel_delayed_work(&ieee->start_ibss_wq);
2612 ieee80211_stop_scan(ieee);
2614 ieee80211_disassociate(ieee);
2615 RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
2618 void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
2620 ieee->sync_scan_hurryup = 0;
2621 mutex_lock(&ieee->wx_mutex);
2622 ieee80211_start_protocol(ieee);
2623 mutex_unlock(&ieee->wx_mutex);
2625 EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
2627 void ieee80211_start_protocol(struct ieee80211_device *ieee)
2632 if (ieee->proto_started)
2635 ieee->proto_started = 1;
2637 if (ieee->current_network.channel == 0) {
2640 if (ch > MAX_CHANNEL_NUMBER)
2641 return; /* no channel found */
2642 }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
2643 ieee->current_network.channel = ch;
2646 if (ieee->current_network.beacon_interval == 0)
2647 ieee->current_network.beacon_interval = 100;
2648 // printk("===>%s(), chan:%d\n", __func__, ieee->current_network.channel);
2649 // ieee->set_chan(ieee->dev,ieee->current_network.channel);
2651 for(i = 0; i < 17; i++) {
2652 ieee->last_rxseq_num[i] = -1;
2653 ieee->last_rxfrag_num[i] = -1;
2654 ieee->last_packet_time[i] = 0;
2657 ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
2660 /* if the user set the MAC of the ad-hoc cell and then
2661 * switch to managed mode, shall we make sure that association
2662 * attempts does not fail just because the user provide the essid
2663 * and the nic is still checking for the AP MAC ??
2665 if (ieee->iw_mode == IW_MODE_INFRA)
2666 ieee80211_start_bss(ieee);
2668 else if (ieee->iw_mode == IW_MODE_ADHOC)
2669 ieee80211_start_ibss(ieee);
2671 else if (ieee->iw_mode == IW_MODE_MASTER)
2672 ieee80211_start_master_bss(ieee);
2674 else if(ieee->iw_mode == IW_MODE_MONITOR)
2675 ieee80211_start_monitor_mode(ieee);
2679 #define DRV_NAME "Ieee80211"
2680 void ieee80211_softmac_init(struct ieee80211_device *ieee)
2683 memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
2685 ieee->state = IEEE80211_NOLINK;
2686 ieee->sync_scan_hurryup = 0;
2687 for(i = 0; i < 5; i++) {
2688 ieee->seq_ctrl[i] = 0;
2690 ieee->pDot11dInfo = kzalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
2691 if (!ieee->pDot11dInfo)
2692 IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
2693 //added for AP roaming
2694 ieee->LinkDetectInfo.SlotNum = 2;
2695 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
2696 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
2699 ieee->queue_stop = 0;
2701 ieee->softmac_features = 0; //so IEEE2100-like driver are happy
2704 ieee->proto_started = 0;
2705 ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
2707 ieee->ps = IEEE80211_PS_DISABLED;
2708 ieee->sta_sleep = 0;
2709 ieee->Regdot11HTOperationalRateSet[0]= 0xff;//support MCS 0~7
2710 ieee->Regdot11HTOperationalRateSet[1]= 0xff;//support MCS 8~15
2711 ieee->Regdot11HTOperationalRateSet[4]= 0x01;
2713 ieee->actscanning = false;
2714 ieee->beinretry = false;
2715 ieee->is_set_key = false;
2716 init_mgmt_queue(ieee);
2718 ieee->sta_edca_param[0] = 0x0000A403;
2719 ieee->sta_edca_param[1] = 0x0000A427;
2720 ieee->sta_edca_param[2] = 0x005E4342;
2721 ieee->sta_edca_param[3] = 0x002F3262;
2722 ieee->aggregation = true;
2723 ieee->enable_rx_imm_BA = true;
2724 ieee->tx_pending.txb = NULL;
2726 setup_timer(&ieee->associate_timer, ieee80211_associate_abort_cb,
2727 (unsigned long)ieee);
2729 setup_timer(&ieee->beacon_timer, ieee80211_send_beacon_cb,
2730 (unsigned long)ieee);
2733 INIT_DELAYED_WORK(&ieee->start_ibss_wq, ieee80211_start_ibss_wq);
2734 INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
2735 INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
2736 INIT_DELAYED_WORK(&ieee->softmac_scan_wq, ieee80211_softmac_scan_wq);
2737 INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
2738 INIT_WORK(&ieee->wx_sync_scan_wq, ieee80211_wx_sync_scan_wq);
2741 mutex_init(&ieee->wx_mutex);
2742 mutex_init(&ieee->scan_mutex);
2744 spin_lock_init(&ieee->mgmt_tx_lock);
2745 spin_lock_init(&ieee->beacon_lock);
2747 tasklet_init(&ieee->ps_task,
2748 (void(*)(unsigned long)) ieee80211_sta_ps,
2749 (unsigned long)ieee);
2753 void ieee80211_softmac_free(struct ieee80211_device *ieee)
2755 mutex_lock(&ieee->wx_mutex);
2756 kfree(ieee->pDot11dInfo);
2757 ieee->pDot11dInfo = NULL;
2758 del_timer_sync(&ieee->associate_timer);
2760 cancel_delayed_work(&ieee->associate_retry_wq);
2762 mutex_unlock(&ieee->wx_mutex);
2765 /********************************************************
2766 * Start of WPA code. *
2767 * this is stolen from the ipw2200 driver *
2768 ********************************************************/
2771 static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
2773 /* This is called when wpa_supplicant loads and closes the driver
2775 printk("%s WPA\n", value ? "enabling" : "disabling");
2776 ieee->wpa_enabled = value;
2781 static void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee,
2782 char *wpa_ie, int wpa_ie_len)
2784 /* make sure WPA is enabled */
2785 ieee80211_wpa_enable(ieee, 1);
2787 ieee80211_disassociate(ieee);
2791 static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
2797 case IEEE_MLME_STA_DEAUTH:
2801 case IEEE_MLME_STA_DISASSOC:
2802 ieee80211_disassociate(ieee);
2806 printk("Unknown MLME request: %d\n", command);
2814 static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
2815 struct ieee_param *param, int plen)
2819 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
2820 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
2823 if (param->u.wpa_ie.len) {
2824 buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len,
2829 kfree(ieee->wpa_ie);
2831 ieee->wpa_ie_len = param->u.wpa_ie.len;
2833 kfree(ieee->wpa_ie);
2834 ieee->wpa_ie = NULL;
2835 ieee->wpa_ie_len = 0;
2838 ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
2842 #define AUTH_ALG_OPEN_SYSTEM 0x1
2843 #define AUTH_ALG_SHARED_KEY 0x2
2845 static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
2848 struct ieee80211_security sec = {
2849 .flags = SEC_AUTH_MODE,
2852 if (value & AUTH_ALG_SHARED_KEY) {
2853 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
2855 ieee->auth_mode = 1;
2856 } else if (value & AUTH_ALG_OPEN_SYSTEM){
2857 sec.auth_mode = WLAN_AUTH_OPEN;
2859 ieee->auth_mode = 0;
2861 else if (value & IW_AUTH_ALG_LEAP){
2862 sec.auth_mode = WLAN_AUTH_LEAP;
2864 ieee->auth_mode = 2;
2868 if (ieee->set_security)
2869 ieee->set_security(ieee->dev, &sec);
2871 // ret = -EOPNOTSUPP;
2876 static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
2879 unsigned long flags;
2882 case IEEE_PARAM_WPA_ENABLED:
2883 ret = ieee80211_wpa_enable(ieee, value);
2886 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2887 ieee->tkip_countermeasures = value;
2890 case IEEE_PARAM_DROP_UNENCRYPTED: {
2893 * wpa_supplicant calls set_wpa_enabled when the driver
2894 * is loaded and unloaded, regardless of if WPA is being
2895 * used. No other calls are made which can be used to
2896 * determine if encryption will be used or not prior to
2897 * association being expected. If encryption is not being
2898 * used, drop_unencrypted is set to false, else true -- we
2899 * can use this to determine if the CAP_PRIVACY_ON bit should
2902 struct ieee80211_security sec = {
2903 .flags = SEC_ENABLED,
2906 ieee->drop_unencrypted = value;
2907 /* We only change SEC_LEVEL for open mode. Others
2908 * are set by ipw_wpa_set_encryption.
2911 sec.flags |= SEC_LEVEL;
2912 sec.level = SEC_LEVEL_0;
2915 sec.flags |= SEC_LEVEL;
2916 sec.level = SEC_LEVEL_1;
2918 if (ieee->set_security)
2919 ieee->set_security(ieee->dev, &sec);
2923 case IEEE_PARAM_PRIVACY_INVOKED:
2924 ieee->privacy_invoked = value;
2927 case IEEE_PARAM_AUTH_ALGS:
2928 ret = ieee80211_wpa_set_auth_algs(ieee, value);
2931 case IEEE_PARAM_IEEE_802_1X:
2932 ieee->ieee802_1x = value;
2934 case IEEE_PARAM_WPAX_SELECT:
2935 // added for WPA2 mixed mode
2936 spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags);
2937 ieee->wpax_type_set = 1;
2938 ieee->wpax_type_notify = value;
2939 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags);
2943 printk("Unknown WPA param: %d\n", name);
2950 /* implementation borrowed from hostap driver */
2952 static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
2953 struct ieee_param *param, int param_len)
2957 struct ieee80211_crypto_ops *ops;
2958 struct ieee80211_crypt_data **crypt;
2960 struct ieee80211_security sec = {
2964 param->u.crypt.err = 0;
2965 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
2968 (int) ((char *) param->u.crypt.key - (char *) param) +
2969 param->u.crypt.key_len) {
2970 printk("Len mismatch %d, %d\n", param_len,
2971 param->u.crypt.key_len);
2974 if (is_broadcast_ether_addr(param->sta_addr)) {
2975 if (param->u.crypt.idx >= WEP_KEYS)
2977 crypt = &ieee->crypt[param->u.crypt.idx];
2982 if (strcmp(param->u.crypt.alg, "none") == 0) {
2987 sec.level = SEC_LEVEL_0;
2988 sec.flags |= SEC_ENABLED | SEC_LEVEL;
2989 ieee80211_crypt_delayed_deinit(ieee, crypt);
2996 sec.flags |= SEC_ENABLED;
2998 /* IPW HW cannot build TKIP MIC, host decryption still needed. */
2999 if (!(ieee->host_encrypt || ieee->host_decrypt) &&
3000 strcmp(param->u.crypt.alg, "TKIP"))
3001 goto skip_host_crypt;
3003 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3004 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
3005 request_module("ieee80211_crypt_wep");
3006 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3007 //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
3008 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
3009 request_module("ieee80211_crypt_tkip");
3010 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3011 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
3012 request_module("ieee80211_crypt_ccmp");
3013 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3016 printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
3017 param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
3022 if (*crypt == NULL || (*crypt)->ops != ops) {
3023 struct ieee80211_crypt_data *new_crypt;
3025 ieee80211_crypt_delayed_deinit(ieee, crypt);
3027 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
3028 if (new_crypt == NULL) {
3032 new_crypt->ops = ops;
3033 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
3035 new_crypt->ops->init(param->u.crypt.idx);
3037 if (new_crypt->priv == NULL) {
3039 param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
3047 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
3048 (*crypt)->ops->set_key(param->u.crypt.key,
3049 param->u.crypt.key_len, param->u.crypt.seq,
3050 (*crypt)->priv) < 0) {
3051 printk("key setting failed\n");
3052 param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
3058 if (param->u.crypt.set_tx) {
3059 ieee->tx_keyidx = param->u.crypt.idx;
3060 sec.active_key = param->u.crypt.idx;
3061 sec.flags |= SEC_ACTIVE_KEY;
3063 sec.flags &= ~SEC_ACTIVE_KEY;
3065 memcpy(sec.keys[param->u.crypt.idx],
3067 param->u.crypt.key_len);
3068 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
3069 sec.flags |= (1 << param->u.crypt.idx);
3071 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3072 sec.flags |= SEC_LEVEL;
3073 sec.level = SEC_LEVEL_1;
3074 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3075 sec.flags |= SEC_LEVEL;
3076 sec.level = SEC_LEVEL_2;
3077 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3078 sec.flags |= SEC_LEVEL;
3079 sec.level = SEC_LEVEL_3;
3082 if (ieee->set_security)
3083 ieee->set_security(ieee->dev, &sec);
3085 /* Do not reset port if card is in Managed mode since resetting will
3086 * generate new IEEE 802.11 authentication which may end up in looping
3087 * with IEEE 802.1X. If your hardware requires a reset after WEP
3088 * configuration (for example... Prism2), implement the reset_port in
3089 * the callbacks structures used to initialize the 802.11 stack. */
3090 if (ieee->reset_on_keychange &&
3091 ieee->iw_mode != IW_MODE_INFRA &&
3093 ieee->reset_port(ieee->dev)) {
3094 printk("reset_port failed\n");
3095 param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
3102 static inline struct sk_buff *ieee80211_disassociate_skb(
3103 struct ieee80211_network *beacon,
3104 struct ieee80211_device *ieee,
3107 struct sk_buff *skb;
3108 struct ieee80211_disassoc *disass;
3110 skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc));
3114 disass = (struct ieee80211_disassoc *) skb_put(skb, sizeof(struct ieee80211_disassoc));
3115 disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
3116 disass->header.duration_id = 0;
3118 memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
3119 memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
3120 memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
3122 disass->reason = cpu_to_le16(asRsn);
3129 struct ieee80211_device *ieee,
3134 struct ieee80211_network *beacon = &ieee->current_network;
3135 struct sk_buff *skb;
3137 skb = ieee80211_disassociate_skb(beacon, ieee, asRsn);
3139 softmac_mgmt_xmit(skb, ieee);
3140 //dev_kfree_skb_any(skb);//edit by thomas
3143 EXPORT_SYMBOL(SendDisassociation);
3145 int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
3147 struct ieee_param *param;
3150 mutex_lock(&ieee->wx_mutex);
3151 //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
3153 if (p->length < sizeof(struct ieee_param) || !p->pointer) {
3158 param = memdup_user(p->pointer, p->length);
3159 if (IS_ERR(param)) {
3160 ret = PTR_ERR(param);
3164 switch (param->cmd) {
3166 case IEEE_CMD_SET_WPA_PARAM:
3167 ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
3168 param->u.wpa_param.value);
3171 case IEEE_CMD_SET_WPA_IE:
3172 ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
3175 case IEEE_CMD_SET_ENCRYPTION:
3176 ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
3180 ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
3181 param->u.mlme.reason_code);
3185 printk("Unknown WPA supplicant request: %d\n",param->cmd);
3190 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
3195 mutex_unlock(&ieee->wx_mutex);
3199 EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
3201 void notify_wx_assoc_event(struct ieee80211_device *ieee)
3203 union iwreq_data wrqu;
3205 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3206 if (ieee->state == IEEE80211_LINKED)
3207 memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
3209 eth_zero_addr(wrqu.ap_addr.sa_data);
3210 wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
3212 EXPORT_SYMBOL(notify_wx_assoc_event);