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
115 if(ieee->current_network.wmm_info & 0x80) {
116 *tag++ = 0x0f|MAX_SP_Len;
127 static void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p)
131 *tag++ = MFIE_TYPE_GENERIC; //0
142 printk(KERN_ALERT "This is enable turbo mode IE process\n");
146 static void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
149 nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
152 * if the queue is full but we have newer frames then
153 * just overwrites the oldest.
155 * if (nh == ieee->mgmt_queue_tail)
158 ieee->mgmt_queue_head = nh;
159 ieee->mgmt_queue_ring[nh] = skb;
164 static struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
168 if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
171 ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
173 ieee->mgmt_queue_tail =
174 (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
179 static void init_mgmt_queue(struct ieee80211_device *ieee)
181 ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
184 static u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee)
186 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
189 // 2008/01/25 MH For broadcom, MGNT frame set as OFDM 6M.
190 if(pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M)
193 rate = ieee->basic_rate & 0x7f;
196 // 2005.01.26, by rcnjko.
197 if(ieee->mode == IEEE_A||
198 ieee->mode== IEEE_N_5G||
199 (ieee->mode== IEEE_N_24G&&!pHTInfo->bCurSuppCCK))
206 // Data rate of ProbeReq is already decided. Annie, 2005-03-31
207 if( pMgntInfo->bScanInProgress || (pMgntInfo->bDualModeScanStep!=0) )
209 if(pMgntInfo->dot11CurrentWirelessMode==WIRELESS_MODE_A)
219 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
221 inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
224 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
225 struct 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 ieee->dev->trans_start = jiffies;
253 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
254 //dev_kfree_skb_any(skb);//edit by thomas
257 spin_unlock_irqrestore(&ieee->lock, flags);
259 spin_unlock_irqrestore(&ieee->lock, flags);
260 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
262 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
264 if (ieee->seq_ctrl[0] == 0xFFF)
265 ieee->seq_ctrl[0] = 0;
269 /* check whether the managed packet queued greater than 5 */
270 if(!ieee->check_nic_enough_desc(ieee->dev,tcb_desc->queue_index)||\
271 (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)||\
272 (ieee->queue_stop) ) {
273 /* insert the skb packet to the management queue */
274 /* as for the completion function, it does not need
275 * to check it any more.
277 printk("%s():insert to waitqueue!\n",__func__);
278 skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb);
280 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);
287 inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
290 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
291 struct rtl_80211_hdr_3addr *header =
292 (struct rtl_80211_hdr_3addr *) skb->data;
297 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
299 if (ieee->seq_ctrl[0] == 0xFFF)
300 ieee->seq_ctrl[0] = 0;
304 /* avoid watchdog triggers */
305 ieee->dev->trans_start = jiffies;
306 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
310 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
312 if (ieee->seq_ctrl[0] == 0xFFF)
313 ieee->seq_ctrl[0] = 0;
317 ieee->softmac_hard_start_xmit(skb, ieee->dev);
320 //dev_kfree_skb_any(skb);//edit by thomas
323 inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
325 unsigned int len, rate_len;
328 struct ieee80211_probe_request *req;
330 len = ieee->current_network.ssid_len;
332 rate_len = ieee80211_MFIE_rate_len(ieee);
334 skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
335 2 + len + rate_len + ieee->tx_headroom);
339 skb_reserve(skb, ieee->tx_headroom);
341 req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
342 req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
343 req->header.duration_id = 0; //FIXME: is this OK ?
345 memset(req->header.addr1, 0xff, ETH_ALEN);
346 memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
347 memset(req->header.addr3, 0xff, ETH_ALEN);
349 tag = (u8 *) skb_put(skb,len+2+rate_len);
351 *tag++ = MFIE_TYPE_SSID;
353 memcpy(tag, ieee->current_network.ssid, len);
356 ieee80211_MFIE_Brate(ieee,&tag);
357 ieee80211_MFIE_Grate(ieee,&tag);
361 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
363 static void ieee80211_send_beacon(struct ieee80211_device *ieee)
368 //unsigned long flags;
369 skb = ieee80211_get_beacon_(ieee);
372 softmac_mgmt_xmit(skb, ieee);
373 ieee->softmac_stats.tx_beacons++;
374 //dev_kfree_skb_any(skb);//edit by thomas
376 // ieee->beacon_timer.expires = jiffies +
377 // (MSECS( ieee->current_network.beacon_interval -5));
379 //spin_lock_irqsave(&ieee->beacon_lock,flags);
380 if (ieee->beacon_txing && ieee->ieee_up) {
381 // if(!timer_pending(&ieee->beacon_timer))
382 // add_timer(&ieee->beacon_timer);
383 mod_timer(&ieee->beacon_timer,jiffies+(MSECS(ieee->current_network.beacon_interval-5)));
385 //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
389 static void ieee80211_send_beacon_cb(unsigned long _ieee)
391 struct ieee80211_device *ieee =
392 (struct ieee80211_device *) _ieee;
395 spin_lock_irqsave(&ieee->beacon_lock, flags);
396 ieee80211_send_beacon(ieee);
397 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
401 static void ieee80211_send_probe(struct ieee80211_device *ieee)
405 skb = ieee80211_probe_req(ieee);
407 softmac_mgmt_xmit(skb, ieee);
408 ieee->softmac_stats.tx_probe_rq++;
409 //dev_kfree_skb_any(skb);//edit by thomas
413 static void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
415 if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)) {
416 ieee80211_send_probe(ieee);
417 ieee80211_send_probe(ieee);
421 /* this performs syncro scan blocking the caller until all channels
422 * in the allowed channel map has been checked.
424 void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
427 u8 channel_map[MAX_CHANNEL_NUMBER+1];
428 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
429 down(&ieee->scan_sem);
436 if (ch > MAX_CHANNEL_NUMBER)
437 goto out; /* scan completed */
438 }while(!channel_map[ch]);
440 /* this function can be called in two situations
441 * 1- We have switched to ad-hoc mode and we are
442 * performing a complete syncro scan before conclude
443 * there are no interesting cell and to create a
444 * new one. In this case the link state is
445 * IEEE80211_NOLINK until we found an interesting cell.
446 * If so the ieee8021_new_net, called by the RX path
447 * will set the state to IEEE80211_LINKED, so we stop
449 * 2- We are linked and the root uses run iwlist scan.
450 * So we switch to IEEE80211_LINKED_SCANNING to remember
451 * that we are still logically linked (not interested in
452 * new network events, despite for updating the net list,
453 * but we are temporarly 'unlinked' as the driver shall
454 * not filter RX frames and the channel is changing.
455 * So the only situation in witch are interested is to check
456 * if the state become LINKED because of the #1 situation
459 if (ieee->state == IEEE80211_LINKED)
461 ieee->set_chan(ieee->dev, ch);
462 if(channel_map[ch] == 1)
463 ieee80211_send_probe_requests(ieee);
465 /* this prevent excessive time wait when we
466 * need to wait for a syncro scan to end..
468 if (ieee->state >= IEEE80211_LINKED && ieee->sync_scan_hurryup)
471 msleep_interruptible_rsl(IEEE80211_SOFTMAC_SCAN_TIME);
475 if(ieee->state < IEEE80211_LINKED){
476 ieee->actscanning = false;
480 ieee->sync_scan_hurryup = 0;
481 if(IS_DOT11D_ENABLE(ieee))
482 DOT11D_ScanComplete(ieee);
486 EXPORT_SYMBOL(ieee80211_softmac_scan_syncro);
488 static void ieee80211_softmac_scan_wq(struct work_struct *work)
490 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
491 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
492 static short watchdog;
493 u8 channel_map[MAX_CHANNEL_NUMBER+1];
494 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
497 down(&ieee->scan_sem);
499 ieee->current_network.channel =
500 (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
501 if (watchdog++ > MAX_CHANNEL_NUMBER)
503 //if current channel is not in channel map, set to default channel.
504 if (!channel_map[ieee->current_network.channel]) {
505 ieee->current_network.channel = 6;
506 goto out; /* no good chans */
509 }while(!channel_map[ieee->current_network.channel]);
510 if (ieee->scanning == 0 )
512 ieee->set_chan(ieee->dev, ieee->current_network.channel);
513 if(channel_map[ieee->current_network.channel] == 1)
514 ieee80211_send_probe_requests(ieee);
517 queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
522 if(IS_DOT11D_ENABLE(ieee))
523 DOT11D_ScanComplete(ieee);
524 ieee->actscanning = false;
532 static void ieee80211_beacons_start(struct ieee80211_device *ieee)
535 spin_lock_irqsave(&ieee->beacon_lock,flags);
537 ieee->beacon_txing = 1;
538 ieee80211_send_beacon(ieee);
540 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
543 static void ieee80211_beacons_stop(struct ieee80211_device *ieee)
547 spin_lock_irqsave(&ieee->beacon_lock, flags);
549 ieee->beacon_txing = 0;
550 del_timer_sync(&ieee->beacon_timer);
552 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
557 void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
559 if(ieee->stop_send_beacons)
560 ieee->stop_send_beacons(ieee->dev);
561 if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
562 ieee80211_beacons_stop(ieee);
564 EXPORT_SYMBOL(ieee80211_stop_send_beacons);
566 void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
568 if(ieee->start_send_beacons)
569 ieee->start_send_beacons(ieee->dev, ieee->basic_rate);
570 if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
571 ieee80211_beacons_start(ieee);
573 EXPORT_SYMBOL(ieee80211_start_send_beacons);
575 static void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
577 // unsigned long flags;
579 //ieee->sync_scan_hurryup = 1;
581 down(&ieee->scan_sem);
582 // spin_lock_irqsave(&ieee->lock, flags);
584 if (ieee->scanning == 1) {
587 cancel_delayed_work(&ieee->softmac_scan_wq);
590 // spin_unlock_irqrestore(&ieee->lock, flags);
594 void ieee80211_stop_scan(struct ieee80211_device *ieee)
596 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
597 ieee80211_softmac_stop_scan(ieee);
599 ieee->stop_scan(ieee->dev);
601 EXPORT_SYMBOL(ieee80211_stop_scan);
603 /* called with ieee->lock held */
604 static void ieee80211_start_scan(struct ieee80211_device *ieee)
606 if (IS_DOT11D_ENABLE(ieee) )
608 if (IS_COUNTRY_IE_VALID(ieee))
610 RESET_CIE_WATCHDOG(ieee);
613 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
614 if (ieee->scanning == 0) {
616 queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0);
619 ieee->start_scan(ieee->dev);
623 /* called with wx_sem held */
624 void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
626 if (IS_DOT11D_ENABLE(ieee) )
628 if (IS_COUNTRY_IE_VALID(ieee))
630 RESET_CIE_WATCHDOG(ieee);
633 ieee->sync_scan_hurryup = 0;
634 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
635 ieee80211_softmac_scan_syncro(ieee);
637 ieee->scan_syncro(ieee->dev);
640 EXPORT_SYMBOL(ieee80211_start_scan_syncro);
642 inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
643 struct ieee80211_device *ieee, int challengelen)
646 struct ieee80211_authentication *auth;
647 int len = sizeof(struct ieee80211_authentication) + challengelen + ieee->tx_headroom;
650 skb = dev_alloc_skb(len);
651 if (!skb) return NULL;
653 skb_reserve(skb, ieee->tx_headroom);
654 auth = (struct ieee80211_authentication *)
655 skb_put(skb, sizeof(struct ieee80211_authentication));
658 auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH
659 | IEEE80211_FCTL_WEP);
661 auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
663 auth->header.duration_id = cpu_to_le16(0x013a);
665 memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
666 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
667 memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
669 //auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
670 if(ieee->auth_mode == 0)
671 auth->algorithm = WLAN_AUTH_OPEN;
672 else if(ieee->auth_mode == 1)
673 auth->algorithm = cpu_to_le16(WLAN_AUTH_SHARED_KEY);
674 else if(ieee->auth_mode == 2)
675 auth->algorithm = WLAN_AUTH_OPEN;//0x80;
676 printk("=================>%s():auth->algorithm is %d\n",__func__,auth->algorithm);
677 auth->transaction = cpu_to_le16(ieee->associate_seq);
678 ieee->associate_seq++;
680 auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
687 static struct sk_buff *ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
691 struct ieee80211_probe_response *beacon_buf;
692 struct sk_buff *skb = NULL;
694 int atim_len, erp_len;
695 struct ieee80211_crypt_data *crypt;
697 char *ssid = ieee->current_network.ssid;
698 int ssid_len = ieee->current_network.ssid_len;
699 int rate_len = ieee->current_network.rates_len+2;
700 int rate_ex_len = ieee->current_network.rates_ex_len;
701 int wpa_ie_len = ieee->wpa_ie_len;
702 u8 erpinfo_content = 0;
707 u8 tmp_ht_info_len=0;
708 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
709 u8 *tmp_generic_ie_buf=NULL;
710 u8 tmp_generic_ie_len=0;
712 if(rate_ex_len > 0) rate_ex_len+=2;
714 if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
719 if(ieee80211_is_54g(&ieee->current_network))
725 crypt = ieee->crypt[ieee->tx_keyidx];
728 encrypt = ieee->host_encrypt && crypt && crypt->ops &&
729 ((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len));
731 tmp_ht_cap_buf =(u8 *) &(ieee->pHTInfo->SelfHTCap);
732 tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
733 tmp_ht_info_buf =(u8 *) &(ieee->pHTInfo->SelfHTInfo);
734 tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo);
735 HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len,encrypt);
736 HTConstructInfoElement(ieee,tmp_ht_info_buf,&tmp_ht_info_len, encrypt);
739 if (pHTInfo->bRegRT2RTAggregation)
741 tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
742 tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer);
743 HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len);
745 // 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);
746 beacon_size = sizeof(struct ieee80211_probe_response)+2+
756 // +tmp_generic_ie_len
759 skb = dev_alloc_skb(beacon_size);
762 skb_reserve(skb, ieee->tx_headroom);
763 beacon_buf = (struct ieee80211_probe_response *) skb_put(skb, (beacon_size - ieee->tx_headroom));
764 memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
765 memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
766 memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
768 beacon_buf->header.duration_id = 0; //FIXME
769 beacon_buf->beacon_interval =
770 cpu_to_le16(ieee->current_network.beacon_interval);
771 beacon_buf->capability =
772 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
773 beacon_buf->capability |=
774 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE); //add short preamble here
776 if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
777 beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
779 crypt = ieee->crypt[ieee->tx_keyidx];
781 beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
784 beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
785 beacon_buf->info_element[0].id = MFIE_TYPE_SSID;
786 beacon_buf->info_element[0].len = ssid_len;
788 tag = (u8 *) beacon_buf->info_element[0].data;
790 memcpy(tag, ssid, ssid_len);
794 *(tag++) = MFIE_TYPE_RATES;
795 *(tag++) = rate_len-2;
796 memcpy(tag, ieee->current_network.rates, rate_len-2);
799 *(tag++) = MFIE_TYPE_DS_SET;
801 *(tag++) = ieee->current_network.channel;
804 *(tag++) = MFIE_TYPE_IBSS_SET;
807 put_unaligned_le16(ieee->current_network.atim_window,
813 *(tag++) = MFIE_TYPE_ERP;
815 *(tag++) = erpinfo_content;
818 *(tag++) = MFIE_TYPE_RATES_EX;
819 *(tag++) = rate_ex_len-2;
820 memcpy(tag, ieee->current_network.rates_ex, rate_ex_len-2);
826 if (ieee->iw_mode == IW_MODE_ADHOC)
827 {//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
828 memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
830 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
834 //skb->dev = ieee->dev;
839 static struct sk_buff *ieee80211_assoc_resp(struct ieee80211_device *ieee,
845 struct ieee80211_crypt_data *crypt;
846 struct ieee80211_assoc_response_frame *assoc;
849 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
850 int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len + ieee->tx_headroom;
852 skb = dev_alloc_skb(len);
857 skb_reserve(skb, ieee->tx_headroom);
859 assoc = (struct ieee80211_assoc_response_frame *)
860 skb_put(skb, sizeof(struct ieee80211_assoc_response_frame));
862 assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
863 memcpy(assoc->header.addr1, dest,ETH_ALEN);
864 memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
865 memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
866 assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
867 WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
871 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
873 if (ieee->host_encrypt)
874 crypt = ieee->crypt[ieee->tx_keyidx];
877 encrypt = crypt && crypt->ops;
880 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
883 assoc->aid = cpu_to_le16(ieee->assoc_id);
884 if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
885 else ieee->assoc_id++;
887 tag = (u8 *) skb_put(skb, rate_len);
889 ieee80211_MFIE_Brate(ieee, &tag);
890 ieee80211_MFIE_Grate(ieee, &tag);
895 static struct sk_buff *ieee80211_auth_resp(struct ieee80211_device *ieee,
896 int status, u8 *dest)
899 struct ieee80211_authentication *auth;
900 int len = ieee->tx_headroom + sizeof(struct ieee80211_authentication)+1;
902 skb = dev_alloc_skb(len);
907 skb->len = sizeof(struct ieee80211_authentication);
909 auth = (struct ieee80211_authentication *)skb->data;
911 auth->status = cpu_to_le16(status);
912 auth->transaction = cpu_to_le16(2);
913 auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
915 memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
916 memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
917 memcpy(auth->header.addr1, dest, ETH_ALEN);
918 auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
924 static struct sk_buff *ieee80211_null_func(struct ieee80211_device *ieee,
928 struct rtl_80211_hdr_3addr *hdr;
930 skb = dev_alloc_skb(sizeof(struct rtl_80211_hdr_3addr));
935 hdr = (struct rtl_80211_hdr_3addr *)skb_put(skb,sizeof(struct rtl_80211_hdr_3addr));
937 memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
938 memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
939 memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
941 hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
942 IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
943 (pwr ? IEEE80211_FCTL_PM:0));
951 static void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8 *dest)
953 struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
956 softmac_mgmt_xmit(buf, ieee);
960 static void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s,
963 struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
966 softmac_mgmt_xmit(buf, ieee);
970 static void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
974 struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
976 softmac_mgmt_xmit(buf, ieee);
980 inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
983 //unsigned long flags;
985 struct ieee80211_assoc_request_frame *hdr;
987 //short info_addr = 0;
989 //u16 suite_count = 0;
990 //u8 suit_select = 0;
991 //unsigned int wpa_len = beacon->wpa_ie_len;
993 u8 *ht_cap_buf = NULL;
995 u8 *realtek_ie_buf=NULL;
997 int wpa_ie_len= ieee->wpa_ie_len;
998 unsigned int ckip_ie_len=0;
999 unsigned int ccxrm_ie_len=0;
1000 unsigned int cxvernum_ie_len=0;
1001 struct ieee80211_crypt_data *crypt;
1004 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
1005 unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
1007 unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
1012 crypt = ieee->crypt[ieee->tx_keyidx];
1013 encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len));
1015 //Include High Throuput capability && Realtek proprietary
1016 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1018 ht_cap_buf = (u8 *)&(ieee->pHTInfo->SelfHTCap);
1019 ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
1020 HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt);
1021 if (ieee->pHTInfo->bCurrentRT2RTAggregation)
1023 realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
1024 realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer);
1025 HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len);
1029 if (ieee->qos_support) {
1030 wmm_info_len = beacon->qos_data.supported?9:0;
1034 if (beacon->bCkipSupported)
1038 if (beacon->bCcxRmEnable)
1042 if (beacon->BssCcxVerNumber >= 2)
1043 cxvernum_ie_len = 5+2;
1046 len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1047 + beacon->ssid_len//essid tagged val
1048 + rate_len//rates tagged val
1057 + ieee->tx_headroom;
1059 len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1060 + beacon->ssid_len//essid tagged val
1061 + rate_len//rates tagged val
1069 + ieee->tx_headroom;
1072 skb = dev_alloc_skb(len);
1077 skb_reserve(skb, ieee->tx_headroom);
1079 hdr = (struct ieee80211_assoc_request_frame *)
1080 skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)+2);
1083 hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
1084 hdr->header.duration_id = cpu_to_le16(37);
1085 memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
1086 memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1087 memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
1089 memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John
1091 hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
1092 if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
1093 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1095 if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1096 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); //add short_preamble here
1098 if(ieee->short_slot)
1099 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
1100 if (wmm_info_len) //QOS
1101 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS);
1103 hdr->listen_interval = cpu_to_le16(0xa);
1105 hdr->info_element[0].id = MFIE_TYPE_SSID;
1107 hdr->info_element[0].len = beacon->ssid_len;
1108 tag = skb_put(skb, beacon->ssid_len);
1109 memcpy(tag, beacon->ssid, beacon->ssid_len);
1111 tag = skb_put(skb, rate_len);
1113 ieee80211_MFIE_Brate(ieee, &tag);
1114 ieee80211_MFIE_Grate(ieee, &tag);
1115 // For CCX 1 S13, CKIP. Added by Annie, 2006-08-14.
1116 if (beacon->bCkipSupported) {
1117 static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client"
1118 u8 CcxAironetBuf[30];
1119 OCTET_STRING osCcxAironetIE;
1121 memset(CcxAironetBuf, 0, 30);
1122 osCcxAironetIE.Octet = CcxAironetBuf;
1123 osCcxAironetIE.Length = sizeof(CcxAironetBuf);
1125 // Ref. CCX test plan v3.61, 3.2.3.1 step 13.
1126 // We want to make the device type as "4500-client". 060926, by CCW.
1128 memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui));
1130 // CCX1 spec V1.13, A01.1 CKIP Negotiation (page23):
1131 // "The CKIP negotiation is started with the associate request from the client to the access point,
1132 // containing an Aironet element with both the MIC and KP bits set."
1133 osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |= (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ;
1134 tag = skb_put(skb, ckip_ie_len);
1135 *tag++ = MFIE_TYPE_AIRONET;
1136 *tag++ = osCcxAironetIE.Length;
1137 memcpy(tag, osCcxAironetIE.Octet, osCcxAironetIE.Length);
1138 tag += osCcxAironetIE.Length;
1141 if (beacon->bCcxRmEnable)
1143 static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
1144 OCTET_STRING osCcxRmCap;
1146 osCcxRmCap.Octet = CcxRmCapBuf;
1147 osCcxRmCap.Length = sizeof(CcxRmCapBuf);
1148 tag = skb_put(skb, ccxrm_ie_len);
1149 *tag++ = MFIE_TYPE_GENERIC;
1150 *tag++ = osCcxRmCap.Length;
1151 memcpy(tag, osCcxRmCap.Octet, osCcxRmCap.Length);
1152 tag += osCcxRmCap.Length;
1155 if (beacon->BssCcxVerNumber >= 2) {
1156 u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
1157 OCTET_STRING osCcxVerNum;
1158 CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
1159 osCcxVerNum.Octet = CcxVerNumBuf;
1160 osCcxVerNum.Length = sizeof(CcxVerNumBuf);
1161 tag = skb_put(skb, cxvernum_ie_len);
1162 *tag++ = MFIE_TYPE_GENERIC;
1163 *tag++ = osCcxVerNum.Length;
1164 memcpy(tag, osCcxVerNum.Octet, osCcxVerNum.Length);
1165 tag += osCcxVerNum.Length;
1168 if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
1169 if (ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC)
1171 tag = skb_put(skb, ht_cap_len);
1172 *tag++ = MFIE_TYPE_HT_CAP;
1173 *tag++ = ht_cap_len - 2;
1174 memcpy(tag, ht_cap_buf, ht_cap_len - 2);
1175 tag += ht_cap_len -2;
1180 //choose what wpa_supplicant gives to associate.
1181 tag = skb_put(skb, wpa_ie_len);
1183 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
1186 tag = skb_put(skb, wmm_info_len);
1188 ieee80211_WMM_Info(ieee, &tag);
1191 tag = skb_put(skb, turbo_info_len);
1192 if (turbo_info_len) {
1193 ieee80211_TURBO_Info(ieee, &tag);
1197 if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
1198 if(ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC)
1200 tag = skb_put(skb, ht_cap_len);
1201 *tag++ = MFIE_TYPE_GENERIC;
1202 *tag++ = ht_cap_len - 2;
1203 memcpy(tag, ht_cap_buf, ht_cap_len - 2);
1204 tag += ht_cap_len -2;
1207 if (ieee->pHTInfo->bCurrentRT2RTAggregation) {
1208 tag = skb_put(skb, realtek_ie_len);
1209 *tag++ = MFIE_TYPE_GENERIC;
1210 *tag++ = realtek_ie_len - 2;
1211 memcpy(tag, realtek_ie_buf, realtek_ie_len - 2);
1214 // printk("<=====%s(), %p, %p\n", __func__, ieee->dev, ieee->dev->dev_addr);
1215 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
1219 void ieee80211_associate_abort(struct ieee80211_device *ieee)
1222 unsigned long flags;
1223 spin_lock_irqsave(&ieee->lock, flags);
1225 ieee->associate_seq++;
1227 /* don't scan, and avoid to have the RX path possibily
1228 * try again to associate. Even do not react to AUTH or
1229 * ASSOC response. Just wait for the retry wq to be scheduled.
1230 * Here we will check if there are good nets to associate
1231 * with, so we retry or just get back to NO_LINK and scanning
1233 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
1234 IEEE80211_DEBUG_MGMT("Authentication failed\n");
1235 ieee->softmac_stats.no_auth_rs++;
1237 IEEE80211_DEBUG_MGMT("Association failed\n");
1238 ieee->softmac_stats.no_ass_rs++;
1241 ieee->state = IEEE80211_ASSOCIATING_RETRY;
1243 queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \
1244 IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
1246 spin_unlock_irqrestore(&ieee->lock, flags);
1249 static void ieee80211_associate_abort_cb(unsigned long dev)
1251 ieee80211_associate_abort((struct ieee80211_device *) dev);
1255 static void ieee80211_associate_step1(struct ieee80211_device *ieee)
1257 struct ieee80211_network *beacon = &ieee->current_network;
1258 struct sk_buff *skb;
1260 IEEE80211_DEBUG_MGMT("Stopping scan\n");
1262 ieee->softmac_stats.tx_auth_rq++;
1263 skb=ieee80211_authentication_req(beacon, ieee, 0);
1266 ieee80211_associate_abort(ieee);
1268 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
1269 IEEE80211_DEBUG_MGMT("Sending authentication request\n");
1270 softmac_mgmt_xmit(skb, ieee);
1271 //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
1272 if (!timer_pending(&ieee->associate_timer)) {
1273 ieee->associate_timer.expires = jiffies + (HZ / 2);
1274 add_timer(&ieee->associate_timer);
1276 //dev_kfree_skb_any(skb);//edit by thomas
1280 static void ieee80211_auth_challenge(struct ieee80211_device *ieee,
1285 struct sk_buff *skb;
1286 struct ieee80211_network *beacon = &ieee->current_network;
1287 // int hlen = sizeof(struct ieee80211_authentication);
1289 ieee->associate_seq++;
1290 ieee->softmac_stats.tx_auth_rq++;
1292 skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
1294 ieee80211_associate_abort(ieee);
1296 c = skb_put(skb, chlen+2);
1297 *(c++) = MFIE_TYPE_CHALLENGE;
1299 memcpy(c, challenge, chlen);
1301 IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
1303 ieee80211_encrypt_fragment(ieee, skb, sizeof(struct rtl_80211_hdr_3addr ));
1305 softmac_mgmt_xmit(skb, ieee);
1306 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1307 //dev_kfree_skb_any(skb);//edit by thomas
1312 static void ieee80211_associate_step2(struct ieee80211_device *ieee)
1314 struct sk_buff *skb;
1315 struct ieee80211_network *beacon = &ieee->current_network;
1317 del_timer_sync(&ieee->associate_timer);
1319 IEEE80211_DEBUG_MGMT("Sending association request\n");
1321 ieee->softmac_stats.tx_ass_rq++;
1322 skb=ieee80211_association_req(beacon, ieee);
1324 ieee80211_associate_abort(ieee);
1326 softmac_mgmt_xmit(skb, ieee);
1327 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1328 //dev_kfree_skb_any(skb);//edit by thomas
1331 static void ieee80211_associate_complete_wq(struct work_struct *work)
1333 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
1334 printk(KERN_INFO "Associated successfully\n");
1335 if(ieee80211_is_54g(&ieee->current_network) &&
1336 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1339 printk(KERN_INFO"Using G rates:%d\n", ieee->rate);
1342 printk(KERN_INFO"Using B rates:%d\n", ieee->rate);
1344 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1346 printk("Successfully associated, ht enabled\n");
1351 printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
1352 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1353 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1355 ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500);
1356 // To prevent the immediately calling watch_dog after association.
1357 if (ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
1359 ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
1360 ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
1362 ieee->link_change(ieee->dev);
1363 if (!ieee->is_silent_reset) {
1364 printk("============>normal associate\n");
1365 notify_wx_assoc_event(ieee);
1367 printk("==================>silent reset associate\n");
1368 ieee->is_silent_reset = false;
1371 if (ieee->data_hard_resume)
1372 ieee->data_hard_resume(ieee->dev);
1373 netif_carrier_on(ieee->dev);
1376 static void ieee80211_associate_complete(struct ieee80211_device *ieee)
1379 // struct net_device* dev = ieee->dev;
1380 del_timer_sync(&ieee->associate_timer);
1382 ieee->state = IEEE80211_LINKED;
1383 //ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet);
1384 queue_work(ieee->wq, &ieee->associate_complete_wq);
1387 static void ieee80211_associate_procedure_wq(struct work_struct *work)
1389 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
1390 ieee->sync_scan_hurryup = 1;
1391 down(&ieee->wx_sem);
1393 if (ieee->data_hard_stop)
1394 ieee->data_hard_stop(ieee->dev);
1396 ieee80211_stop_scan(ieee);
1397 printk("===>%s(), chan:%d\n", __func__, ieee->current_network.channel);
1398 //ieee->set_chan(ieee->dev, ieee->current_network.channel);
1399 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1401 ieee->associate_seq = 1;
1402 ieee80211_associate_step1(ieee);
1407 inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
1409 u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
1410 int tmp_ssid_len = 0;
1412 short apset, ssidset, ssidbroad, apmatch, ssidmatch;
1414 /* we are interested in new new only if we are not associated
1415 * and we are not associating / authenticating
1417 if (ieee->state != IEEE80211_NOLINK)
1420 if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
1423 if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
1427 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) {
1428 /* if the user specified the AP MAC, we need also the essid
1429 * This could be obtained by beacons or, if the network does not
1430 * broadcast it, it can be put manually.
1432 apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
1433 ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
1434 ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0');
1435 apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
1436 ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\
1437 (!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
1440 if ( /* if the user set the AP check if match.
1441 * if the network does not broadcast essid we check the user supplyed ANY essid
1442 * if the network does broadcast and the user does not set essid it is OK
1443 * if the network does broadcast and the user did set essid chech if essid match
1445 (apset && apmatch &&
1446 ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
1447 /* if the ap is not set, check that the user set the bssid
1448 * and the network does broadcast and that those two bssid matches
1450 (!apset && ssidset && ssidbroad && ssidmatch)
1452 /* if the essid is hidden replace it with the
1453 * essid provided by the user.
1456 strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
1457 tmp_ssid_len = ieee->current_network.ssid_len;
1459 memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
1461 strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
1462 ieee->current_network.ssid_len = tmp_ssid_len;
1463 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);
1465 //ieee->pHTInfo->IOTAction = 0;
1466 HTResetIOTSetting(ieee->pHTInfo);
1467 if (ieee->iw_mode == IW_MODE_INFRA){
1468 /* Join the network for the first time */
1469 ieee->AsocRetryCount = 0;
1470 //for HT by amy 080514
1471 if((ieee->current_network.qos_data.supported == 1) &&
1472 // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT))
1473 ieee->current_network.bssht.bdSupportHT)
1474 /*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.*/
1476 // ieee->pHTInfo->bCurrentHTSupport = true;
1477 HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network));
1481 ieee->pHTInfo->bCurrentHTSupport = false;
1484 ieee->state = IEEE80211_ASSOCIATING;
1485 queue_work(ieee->wq, &ieee->associate_procedure_wq);
1487 if(ieee80211_is_54g(&ieee->current_network) &&
1488 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1490 ieee->SetWirelessMode(ieee->dev, IEEE_G);
1491 printk(KERN_INFO"Using G rates\n");
1494 ieee->SetWirelessMode(ieee->dev, IEEE_B);
1495 printk(KERN_INFO"Using B rates\n");
1497 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1498 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1499 ieee->state = IEEE80211_LINKED;
1507 void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
1509 unsigned long flags;
1510 struct ieee80211_network *target;
1512 spin_lock_irqsave(&ieee->lock, flags);
1514 list_for_each_entry(target, &ieee->network_list, list) {
1516 /* if the state become different that NOLINK means
1517 * we had found what we are searching for
1520 if (ieee->state != IEEE80211_NOLINK)
1523 if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
1524 ieee80211_softmac_new_net(ieee, target);
1527 spin_unlock_irqrestore(&ieee->lock, flags);
1532 static inline u16 auth_parse(struct sk_buff *skb, u8 **challenge, int *chlen)
1534 struct ieee80211_authentication *a;
1536 if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
1537 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
1541 a = (struct ieee80211_authentication *) skb->data;
1542 if (skb->len > (sizeof(struct ieee80211_authentication) + 3)) {
1543 t = skb->data + sizeof(struct ieee80211_authentication);
1545 if (*(t++) == MFIE_TYPE_CHALLENGE) {
1547 *challenge = kmemdup(t, *chlen, GFP_ATOMIC);
1553 return le16_to_cpu(a->status);
1558 static int auth_rq_parse(struct sk_buff *skb, u8 *dest)
1560 struct ieee80211_authentication *a;
1562 if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
1563 IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
1566 a = (struct ieee80211_authentication *) skb->data;
1568 memcpy(dest,a->header.addr2, ETH_ALEN);
1570 if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
1571 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1573 return WLAN_STATUS_SUCCESS;
1576 static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
1583 struct rtl_80211_hdr_3addr *header =
1584 (struct rtl_80211_hdr_3addr *) skb->data;
1586 if (skb->len < sizeof (struct rtl_80211_hdr_3addr ))
1587 return -1; /* corrupted */
1589 memcpy(src,header->addr2, ETH_ALEN);
1591 skbend = (u8 *)skb->data + skb->len;
1593 tag = skb->data + sizeof (struct rtl_80211_hdr_3addr );
1595 while (tag+1 < skbend){
1601 tag++; /* point to the len field */
1602 tag = tag + *(tag); /* point to the last data byte of the tag */
1603 tag++; /* point to the next tag */
1606 //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
1607 if (ssidlen == 0) return 1;
1609 if (!ssid) return 1; /* ssid not found in tagged param */
1610 return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
1614 static int assoc_rq_parse(struct sk_buff *skb, u8 *dest)
1616 struct ieee80211_assoc_request_frame *a;
1618 if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
1619 sizeof(struct ieee80211_info_element))) {
1621 IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
1625 a = (struct ieee80211_assoc_request_frame *) skb->data;
1627 memcpy(dest,a->header.addr2,ETH_ALEN);
1632 static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid)
1634 struct ieee80211_assoc_response_frame *response_head;
1637 if (skb->len < sizeof(struct ieee80211_assoc_response_frame)) {
1638 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
1642 response_head = (struct ieee80211_assoc_response_frame *) skb->data;
1643 *aid = le16_to_cpu(response_head->aid) & 0x3fff;
1645 status_code = le16_to_cpu(response_head->status);
1646 if((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \
1647 status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&&
1648 ((ieee->mode == IEEE_G) &&
1649 (ieee->current_network.mode == IEEE_N_24G) &&
1650 (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) {
1651 ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
1653 ieee->AsocRetryCount = 0;
1656 return le16_to_cpu(response_head->status);
1660 ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1664 //IEEE80211DMESG("Rx probe");
1665 ieee->softmac_stats.rx_probe_rq++;
1666 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1667 if (probe_rq_parse(ieee, skb, dest)) {
1668 //IEEE80211DMESG("Was for me!");
1669 ieee->softmac_stats.tx_probe_rs++;
1670 ieee80211_resp_to_probe(ieee, dest);
1675 ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1679 //IEEE80211DMESG("Rx probe");
1680 ieee->softmac_stats.rx_auth_rq++;
1682 status = auth_rq_parse(skb, dest);
1684 ieee80211_resp_to_auth(ieee, status, dest);
1686 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1691 ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1695 //unsigned long flags;
1697 ieee->softmac_stats.rx_ass_rq++;
1698 if (assoc_rq_parse(skb, dest) != -1) {
1699 ieee80211_resp_to_assoc_rq(ieee, dest);
1702 printk(KERN_INFO"New client associated: %pM\n", dest);
1706 static void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee,
1710 struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
1713 softmac_ps_mgmt_xmit(buf, ieee);
1716 /* EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame); */
1718 static short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h,
1721 int timeout = ieee->ps_timeout;
1723 /*if(ieee->ps == IEEE80211_PS_DISABLED ||
1724 ieee->iw_mode != IW_MODE_INFRA ||
1725 ieee->state != IEEE80211_LINKED)
1729 dtim = ieee->current_network.dtim_data;
1730 if(!(dtim & IEEE80211_DTIM_VALID))
1732 timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
1733 ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
1735 if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
1738 if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
1741 if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
1744 if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
1745 (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
1749 *time_l = ieee->current_network.last_dtim_sta_time[0]
1750 + (ieee->current_network.beacon_interval
1751 * ieee->current_network.dtim_period) * 1000;
1755 *time_h = ieee->current_network.last_dtim_sta_time[1];
1756 if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
1765 static inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
1771 unsigned long flags, flags2;
1773 spin_lock_irqsave(&ieee->lock, flags);
1775 if ((ieee->ps == IEEE80211_PS_DISABLED ||
1776 ieee->iw_mode != IW_MODE_INFRA ||
1777 ieee->state != IEEE80211_LINKED)){
1779 // #warning CHECK_LOCK_HERE
1780 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1782 ieee80211_sta_wakeup(ieee, 1);
1784 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1787 sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
1788 /* 2 wake, 1 sleep, 0 do nothing */
1794 if(ieee->sta_sleep == 1)
1795 ieee->enter_sleep_state(ieee->dev, th, tl);
1797 else if(ieee->sta_sleep == 0){
1798 // printk("send null 1\n");
1799 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1801 if(ieee->ps_is_queue_empty(ieee->dev)){
1804 ieee->sta_sleep = 2;
1806 ieee->ps_request_tx_ack(ieee->dev);
1808 ieee80211_sta_ps_send_null_frame(ieee, 1);
1813 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1818 }else if(sleep == 2){
1819 //#warning CHECK_LOCK_HERE
1820 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1822 ieee80211_sta_wakeup(ieee, 1);
1824 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1828 spin_unlock_irqrestore(&ieee->lock, flags);
1832 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
1834 if (ieee->sta_sleep == 0) {
1836 printk("Warning: driver is probably failing to report TX ps error\n");
1837 ieee->ps_request_tx_ack(ieee->dev);
1838 ieee80211_sta_ps_send_null_frame(ieee, 0);
1844 if(ieee->sta_sleep == 1)
1845 ieee->sta_wake_up(ieee->dev);
1847 ieee->sta_sleep = 0;
1850 ieee->ps_request_tx_ack(ieee->dev);
1851 ieee80211_sta_ps_send_null_frame(ieee, 0);
1855 void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
1857 unsigned long flags, flags2;
1859 spin_lock_irqsave(&ieee->lock, flags);
1861 if(ieee->sta_sleep == 2){
1862 /* Null frame with PS bit set */
1864 ieee->sta_sleep = 1;
1865 ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
1867 /* if the card report not success we can't be sure the AP
1868 * has not RXed so we can't assume the AP believe us awake
1871 /* 21112005 - tx again null without PS bit if lost */
1874 if ((ieee->sta_sleep == 0) && !success) {
1875 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1876 ieee80211_sta_ps_send_null_frame(ieee, 0);
1877 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1880 spin_unlock_irqrestore(&ieee->lock, flags);
1882 EXPORT_SYMBOL(ieee80211_ps_tx_ack);
1884 static void ieee80211_process_action(struct ieee80211_device *ieee,
1885 struct sk_buff *skb)
1887 struct rtl_80211_hdr *header = (struct rtl_80211_hdr *)skb->data;
1888 u8 *act = ieee80211_get_payload(header);
1890 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
1893 IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
1900 if (*act == ACT_ADDBAREQ)
1901 ieee80211_rx_ADDBAReq(ieee, skb);
1902 else if (*act == ACT_ADDBARSP)
1903 ieee80211_rx_ADDBARsp(ieee, skb);
1904 else if (*act == ACT_DELBA)
1905 ieee80211_rx_DELBA(ieee, skb);
1914 static void ieee80211_check_auth_response(struct ieee80211_device *ieee,
1915 struct sk_buff *skb)
1917 /* default support N mode, disable halfNmode */
1918 bool bSupportNmode = true, bHalfSupportNmode = false;
1924 errcode = auth_parse(skb, &challenge, &chlen);
1926 if (ieee->open_wep || !challenge) {
1927 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
1928 ieee->softmac_stats.rx_auth_rs_ok++;
1929 iotAction = ieee->pHTInfo->IOTAction;
1930 if (!(iotAction & HT_IOT_ACT_PURE_N_MODE)) {
1931 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) {
1932 /* WEP or TKIP encryption */
1933 if (IsHTHalfNmodeAPs(ieee)) {
1934 bSupportNmode = true;
1935 bHalfSupportNmode = true;
1937 bSupportNmode = false;
1938 bHalfSupportNmode = false;
1940 netdev_dbg(ieee->dev, "SEC(%d, %d)\n",
1945 /* Dummy wirless mode setting- avoid encryption issue */
1946 if (bSupportNmode) {
1947 /* N mode setting */
1948 ieee->SetWirelessMode(ieee->dev,
1949 ieee->current_network.mode);
1951 /* b/g mode setting - TODO */
1952 ieee->SetWirelessMode(ieee->dev, IEEE_G);
1955 if (ieee->current_network.mode == IEEE_N_24G &&
1956 bHalfSupportNmode) {
1957 netdev_dbg(ieee->dev, "enter half N mode\n");
1958 ieee->bHalfWirelessN24GMode = true;
1960 ieee->bHalfWirelessN24GMode = false;
1962 ieee80211_associate_step2(ieee);
1964 ieee80211_auth_challenge(ieee, challenge, chlen);
1967 ieee->softmac_stats.rx_auth_rs_err++;
1968 IEEE80211_DEBUG_MGMT("Auth response status code 0x%x", errcode);
1969 ieee80211_associate_abort(ieee);
1974 ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
1975 struct ieee80211_rx_stats *rx_stats, u16 type,
1978 struct rtl_80211_hdr_3addr *header = (struct rtl_80211_hdr_3addr *) skb->data;
1981 struct ieee80211_assoc_response_frame *assoc_resp;
1982 // struct ieee80211_info_element *info_element;
1984 if(!ieee->proto_started)
1987 if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
1988 ieee->iw_mode == IW_MODE_INFRA &&
1989 ieee->state == IEEE80211_LINKED))
1991 tasklet_schedule(&ieee->ps_task);
1993 if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
1994 WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
1995 ieee->last_rx_ps_time = jiffies;
1997 switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
1999 case IEEE80211_STYPE_ASSOC_RESP:
2000 case IEEE80211_STYPE_REASSOC_RESP:
2002 IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
2003 WLAN_FC_GET_STYPE(header->frame_ctl));
2004 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2005 ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
2006 ieee->iw_mode == IW_MODE_INFRA){
2007 struct ieee80211_network network_resp;
2008 struct ieee80211_network *network = &network_resp;
2010 errcode = assoc_parse(ieee, skb, &aid);
2012 ieee->state=IEEE80211_LINKED;
2013 ieee->assoc_id = aid;
2014 ieee->softmac_stats.rx_ass_ok++;
2015 /* station support qos */
2016 /* Let the register setting defaultly with Legacy station */
2017 if (ieee->qos_support) {
2018 assoc_resp = (struct ieee80211_assoc_response_frame *)skb->data;
2019 memset(network, 0, sizeof(*network));
2020 if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\
2021 rx_stats->len - sizeof(*assoc_resp),\
2026 { //filling the PeerHTCap. //maybe not necessary as we can get its info from current_network.
2027 memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
2028 memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
2030 if (ieee->handle_assoc_response != NULL)
2031 ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame *)header, network);
2033 ieee80211_associate_complete(ieee);
2035 /* aid could not been allocated */
2036 ieee->softmac_stats.rx_ass_err++;
2038 "Association response status code 0x%x\n",
2040 IEEE80211_DEBUG_MGMT(
2041 "Association response status code 0x%x\n",
2043 if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
2044 queue_work(ieee->wq, &ieee->associate_procedure_wq);
2046 ieee80211_associate_abort(ieee);
2052 case IEEE80211_STYPE_ASSOC_REQ:
2053 case IEEE80211_STYPE_REASSOC_REQ:
2055 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2056 ieee->iw_mode == IW_MODE_MASTER)
2058 ieee80211_rx_assoc_rq(ieee, skb);
2061 case IEEE80211_STYPE_AUTH:
2063 if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) {
2064 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING
2065 && ieee->iw_mode == IW_MODE_INFRA) {
2067 IEEE80211_DEBUG_MGMT("Received auth response");
2068 ieee80211_check_auth_response(ieee, skb);
2069 } else if (ieee->iw_mode == IW_MODE_MASTER) {
2070 ieee80211_rx_auth_rq(ieee, skb);
2075 case IEEE80211_STYPE_PROBE_REQ:
2077 if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
2078 ((ieee->iw_mode == IW_MODE_ADHOC ||
2079 ieee->iw_mode == IW_MODE_MASTER) &&
2080 ieee->state == IEEE80211_LINKED)){
2081 ieee80211_rx_probe_rq(ieee, skb);
2085 case IEEE80211_STYPE_DISASSOC:
2086 case IEEE80211_STYPE_DEAUTH:
2087 /* FIXME for now repeat all the association procedure
2088 * both for disassociation and deauthentication
2090 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2091 ieee->state == IEEE80211_LINKED &&
2092 ieee->iw_mode == IW_MODE_INFRA){
2094 ieee->state = IEEE80211_ASSOCIATING;
2095 ieee->softmac_stats.reassoc++;
2097 notify_wx_assoc_event(ieee);
2098 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2099 RemovePeerTS(ieee, header->addr2);
2100 queue_work(ieee->wq, &ieee->associate_procedure_wq);
2103 case IEEE80211_STYPE_MANAGE_ACT:
2104 ieee80211_process_action(ieee, skb);
2110 //dev_kfree_skb_any(skb);
2114 /* The following are for a simpler TX queue management.
2115 * Instead of using netif_[stop/wake]_queue, the driver
2116 * will use these two functions (plus a reset one) that
2117 * will internally call the kernel netif_* and take care
2118 * of the ieee802.11 fragmentation.
2119 * So, the driver receives a fragment at a time and might
2120 * call the stop function when it wants, without taking
2121 * care to have enough room to TX an entire packet.
2122 * This might be useful if each fragment needs its own
2123 * descriptor. Thus, just keeping a total free memory > than
2124 * the max fragmentation threshold is not enough. If the
2125 * ieee802.11 stack passed a TXB struct, then you would need
2126 * to keep N free descriptors where
2127 * N = MAX_PACKET_SIZE / MIN_FRAG_THRESHOLD.
2128 * In this way you need just one and the 802.11 stack
2129 * will take care of buffering fragments and pass them to
2130 * to the driver later, when it wakes the queue.
2132 void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
2135 unsigned int queue_index = txb->queue_index;
2136 unsigned long flags;
2138 cb_desc *tcb_desc = NULL;
2140 spin_lock_irqsave(&ieee->lock, flags);
2142 /* called with 2nd parm 0, no tx mgmt lock required */
2143 ieee80211_sta_wakeup(ieee, 0);
2145 /* update the tx status */
2146 ieee->stats.tx_bytes += le16_to_cpu(txb->payload_size);
2147 ieee->stats.tx_packets++;
2148 tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
2149 if (tcb_desc->bMulticast) {
2150 ieee->stats.multicast++;
2152 /* if xmit available, just xmit it immediately, else just insert it to the wait queue */
2153 for(i = 0; i < txb->nr_frags; i++) {
2154 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2155 if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) ||
2157 if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
2159 (!ieee->check_nic_enough_desc(ieee->dev,queue_index))||\
2160 (ieee->queue_stop)) {
2161 /* insert the skb packet to the wait queue */
2162 /* as for the completion function, it does not need
2163 * to check it any more.
2165 //printk("error:no descriptor left@queue_index %d\n", queue_index);
2166 //ieee80211_stop_queue(ieee);
2167 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2168 skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]);
2170 skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
2173 ieee->softmac_data_hard_start_xmit(
2175 ieee->dev, ieee->rate);
2176 //ieee->stats.tx_packets++;
2177 //ieee->stats.tx_bytes += txb->fragments[i]->len;
2178 //ieee->dev->trans_start = jiffies;
2181 ieee80211_txb_free(txb);
2184 spin_unlock_irqrestore(&ieee->lock, flags);
2187 EXPORT_SYMBOL(ieee80211_softmac_xmit);
2189 /* called with ieee->lock acquired */
2190 static void ieee80211_resume_tx(struct ieee80211_device *ieee)
2193 for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
2195 if (ieee->queue_stop){
2196 ieee->tx_pending.frag = i;
2200 ieee->softmac_data_hard_start_xmit(
2201 ieee->tx_pending.txb->fragments[i],
2202 ieee->dev, ieee->rate);
2203 //(i+1)<ieee->tx_pending.txb->nr_frags);
2204 ieee->stats.tx_packets++;
2205 ieee->dev->trans_start = jiffies;
2210 ieee80211_txb_free(ieee->tx_pending.txb);
2211 ieee->tx_pending.txb = NULL;
2215 void ieee80211_reset_queue(struct ieee80211_device *ieee)
2217 unsigned long flags;
2219 spin_lock_irqsave(&ieee->lock, flags);
2220 init_mgmt_queue(ieee);
2221 if (ieee->tx_pending.txb) {
2222 ieee80211_txb_free(ieee->tx_pending.txb);
2223 ieee->tx_pending.txb = NULL;
2225 ieee->queue_stop = 0;
2226 spin_unlock_irqrestore(&ieee->lock, flags);
2229 EXPORT_SYMBOL(ieee80211_reset_queue);
2231 void ieee80211_wake_queue(struct ieee80211_device *ieee)
2234 unsigned long flags;
2235 struct sk_buff *skb;
2236 struct rtl_80211_hdr_3addr *header;
2238 spin_lock_irqsave(&ieee->lock, flags);
2239 if (! ieee->queue_stop) goto exit;
2241 ieee->queue_stop = 0;
2243 if (ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) {
2244 while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
2246 header = (struct rtl_80211_hdr_3addr *) skb->data;
2248 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2250 if (ieee->seq_ctrl[0] == 0xFFF)
2251 ieee->seq_ctrl[0] = 0;
2253 ieee->seq_ctrl[0]++;
2255 ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
2256 //dev_kfree_skb_any(skb);//edit by thomas
2259 if (!ieee->queue_stop && ieee->tx_pending.txb)
2260 ieee80211_resume_tx(ieee);
2262 if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)) {
2263 ieee->softmac_stats.swtxawake++;
2264 netif_wake_queue(ieee->dev);
2268 spin_unlock_irqrestore(&ieee->lock, flags);
2270 EXPORT_SYMBOL(ieee80211_wake_queue);
2272 void ieee80211_stop_queue(struct ieee80211_device *ieee)
2274 //unsigned long flags;
2275 //spin_lock_irqsave(&ieee->lock,flags);
2277 if (!netif_queue_stopped(ieee->dev)) {
2278 netif_stop_queue(ieee->dev);
2279 ieee->softmac_stats.swtxstop++;
2281 ieee->queue_stop = 1;
2282 //spin_unlock_irqrestore(&ieee->lock,flags);
2285 EXPORT_SYMBOL(ieee80211_stop_queue);
2287 inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
2290 random_ether_addr(ieee->current_network.bssid);
2293 /* called in user context only */
2294 void ieee80211_start_master_bss(struct ieee80211_device *ieee)
2298 if (ieee->current_network.ssid_len == 0) {
2299 strncpy(ieee->current_network.ssid,
2300 IEEE80211_DEFAULT_TX_ESSID,
2303 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2307 memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
2309 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2310 ieee->state = IEEE80211_LINKED;
2311 ieee->link_change(ieee->dev);
2312 notify_wx_assoc_event(ieee);
2314 if (ieee->data_hard_resume)
2315 ieee->data_hard_resume(ieee->dev);
2317 netif_carrier_on(ieee->dev);
2320 static void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
2324 if (ieee->data_hard_resume)
2325 ieee->data_hard_resume(ieee->dev);
2327 netif_carrier_on(ieee->dev);
2330 static void ieee80211_start_ibss_wq(struct work_struct *work)
2333 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2334 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
2335 /* iwconfig mode ad-hoc will schedule this and return
2336 * on the other hand this will block further iwconfig SET
2337 * operations because of the wx_sem hold.
2338 * Anyway some most set operations set a flag to speed-up
2339 * (abort) this wq (when syncro scanning) before sleeping
2342 if (!ieee->proto_started) {
2343 printk("==========oh driver down return\n");
2346 down(&ieee->wx_sem);
2348 if (ieee->current_network.ssid_len == 0) {
2349 strcpy(ieee->current_network.ssid, IEEE80211_DEFAULT_TX_ESSID);
2350 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2354 /* check if we have this cell in our network list */
2355 ieee80211_softmac_check_all_nets(ieee);
2358 // if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK))
2359 if (ieee->state == IEEE80211_NOLINK)
2360 ieee->current_network.channel = 6;
2361 /* if not then the state is not linked. Maybe the user swithced to
2362 * ad-hoc mode just after being in monitor mode, or just after
2363 * being very few time in managed mode (so the card have had no
2364 * time to scan all the chans..) or we have just run up the iface
2365 * after setting ad-hoc mode. So we have to give another try..
2366 * Here, in ibss mode, should be safe to do this without extra care
2367 * (in bss mode we had to make sure no-one tryed to associate when
2368 * we had just checked the ieee->state and we was going to start the
2369 * scan) beacause in ibss mode the ieee80211_new_net function, when
2370 * finds a good net, just set the ieee->state to IEEE80211_LINKED,
2371 * so, at worst, we waste a bit of time to initiate an unneeded syncro
2372 * scan, that will stop at the first round because it sees the state
2375 if (ieee->state == IEEE80211_NOLINK)
2376 ieee80211_start_scan_syncro(ieee);
2378 /* the network definitively is not here.. create a new cell */
2379 if (ieee->state == IEEE80211_NOLINK) {
2380 printk("creating new IBSS cell\n");
2382 ieee80211_randomize_cell(ieee);
2384 if(ieee->modulation & IEEE80211_CCK_MODULATION){
2386 ieee->current_network.rates_len = 4;
2388 ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
2389 ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
2390 ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
2391 ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
2394 ieee->current_network.rates_len = 0;
2396 if(ieee->modulation & IEEE80211_OFDM_MODULATION){
2397 ieee->current_network.rates_ex_len = 8;
2399 ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
2400 ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
2401 ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
2402 ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
2403 ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
2404 ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
2405 ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
2406 ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
2410 ieee->current_network.rates_ex_len = 0;
2414 // By default, WMM function will be disabled in IBSS mode
2415 ieee->current_network.QoS_Enable = 0;
2416 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2417 ieee->current_network.atim_window = 0;
2418 ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
2419 if(ieee->short_slot)
2420 ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
2424 ieee->state = IEEE80211_LINKED;
2426 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2427 ieee->link_change(ieee->dev);
2429 notify_wx_assoc_event(ieee);
2431 ieee80211_start_send_beacons(ieee);
2433 if (ieee->data_hard_resume)
2434 ieee->data_hard_resume(ieee->dev);
2435 netif_carrier_on(ieee->dev);
2440 inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
2442 queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150);
2445 /* this is called only in user context, with wx_sem held */
2446 void ieee80211_start_bss(struct ieee80211_device *ieee)
2448 unsigned long flags;
2450 // Ref: 802.11d 11.1.3.3
2451 // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
2453 if (IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
2455 if (! ieee->bGlobalDomain)
2460 /* check if we have already found the net we
2461 * are interested in (if any).
2462 * if not (we are disassociated and we are not
2463 * in associating / authenticating phase) start the background scanning.
2465 ieee80211_softmac_check_all_nets(ieee);
2467 /* ensure no-one start an associating process (thus setting
2468 * the ieee->state to ieee80211_ASSOCIATING) while we
2469 * have just cheked it and we are going to enable scan.
2470 * The ieee80211_new_net function is always called with
2471 * lock held (from both ieee80211_softmac_check_all_nets and
2472 * the rx path), so we cannot be in the middle of such function
2474 spin_lock_irqsave(&ieee->lock, flags);
2476 if (ieee->state == IEEE80211_NOLINK) {
2477 ieee->actscanning = true;
2478 ieee80211_start_scan(ieee);
2480 spin_unlock_irqrestore(&ieee->lock, flags);
2483 /* called only in userspace context */
2484 void ieee80211_disassociate(struct ieee80211_device *ieee)
2488 netif_carrier_off(ieee->dev);
2489 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
2490 ieee80211_reset_queue(ieee);
2492 if (ieee->data_hard_stop)
2493 ieee->data_hard_stop(ieee->dev);
2494 if(IS_DOT11D_ENABLE(ieee))
2496 ieee->state = IEEE80211_NOLINK;
2497 ieee->is_set_key = false;
2498 ieee->link_change(ieee->dev);
2499 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2500 notify_wx_assoc_event(ieee);
2503 EXPORT_SYMBOL(ieee80211_disassociate);
2505 static void ieee80211_associate_retry_wq(struct work_struct *work)
2507 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2508 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
2509 unsigned long flags;
2511 down(&ieee->wx_sem);
2512 if(!ieee->proto_started)
2515 if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
2518 /* until we do not set the state to IEEE80211_NOLINK
2519 * there are no possibility to have someone else trying
2520 * to start an association procedure (we get here with
2521 * ieee->state = IEEE80211_ASSOCIATING).
2522 * When we set the state to IEEE80211_NOLINK it is possible
2523 * that the RX path run an attempt to associate, but
2524 * both ieee80211_softmac_check_all_nets and the
2525 * RX path works with ieee->lock held so there are no
2526 * problems. If we are still disassociated then start a scan.
2527 * the lock here is necessary to ensure no one try to start
2528 * an association procedure when we have just checked the
2529 * state and we are going to start the scan.
2531 ieee->state = IEEE80211_NOLINK;
2533 ieee80211_softmac_check_all_nets(ieee);
2535 spin_lock_irqsave(&ieee->lock, flags);
2537 if(ieee->state == IEEE80211_NOLINK)
2538 ieee80211_start_scan(ieee);
2540 spin_unlock_irqrestore(&ieee->lock, flags);
2546 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
2548 u8 broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2550 struct sk_buff *skb;
2551 struct ieee80211_probe_response *b;
2553 skb = ieee80211_probe_resp(ieee, broadcast_addr);
2558 b = (struct ieee80211_probe_response *) skb->data;
2559 b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
2565 struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
2567 struct sk_buff *skb;
2568 struct ieee80211_probe_response *b;
2570 skb = ieee80211_get_beacon_(ieee);
2574 b = (struct ieee80211_probe_response *) skb->data;
2575 b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2577 if (ieee->seq_ctrl[0] == 0xFFF)
2578 ieee->seq_ctrl[0] = 0;
2580 ieee->seq_ctrl[0]++;
2584 EXPORT_SYMBOL(ieee80211_get_beacon);
2586 void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
2588 ieee->sync_scan_hurryup = 1;
2589 down(&ieee->wx_sem);
2590 ieee80211_stop_protocol(ieee);
2593 EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
2595 void ieee80211_stop_protocol(struct ieee80211_device *ieee)
2597 if (!ieee->proto_started)
2600 ieee->proto_started = 0;
2602 ieee80211_stop_send_beacons(ieee);
2603 del_timer_sync(&ieee->associate_timer);
2604 cancel_delayed_work(&ieee->associate_retry_wq);
2605 cancel_delayed_work(&ieee->start_ibss_wq);
2606 ieee80211_stop_scan(ieee);
2608 ieee80211_disassociate(ieee);
2609 RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
2612 void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
2614 ieee->sync_scan_hurryup = 0;
2615 down(&ieee->wx_sem);
2616 ieee80211_start_protocol(ieee);
2619 EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
2621 void ieee80211_start_protocol(struct ieee80211_device *ieee)
2625 if (ieee->proto_started)
2628 ieee->proto_started = 1;
2630 if (ieee->current_network.channel == 0) {
2633 if (ch > MAX_CHANNEL_NUMBER)
2634 return; /* no channel found */
2635 }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
2636 ieee->current_network.channel = ch;
2639 if (ieee->current_network.beacon_interval == 0)
2640 ieee->current_network.beacon_interval = 100;
2641 // printk("===>%s(), chan:%d\n", __func__, ieee->current_network.channel);
2642 // ieee->set_chan(ieee->dev,ieee->current_network.channel);
2644 for(i = 0; i < 17; i++) {
2645 ieee->last_rxseq_num[i] = -1;
2646 ieee->last_rxfrag_num[i] = -1;
2647 ieee->last_packet_time[i] = 0;
2650 ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
2653 /* if the user set the MAC of the ad-hoc cell and then
2654 * switch to managed mode, shall we make sure that association
2655 * attempts does not fail just because the user provide the essid
2656 * and the nic is still checking for the AP MAC ??
2658 if (ieee->iw_mode == IW_MODE_INFRA)
2659 ieee80211_start_bss(ieee);
2661 else if (ieee->iw_mode == IW_MODE_ADHOC)
2662 ieee80211_start_ibss(ieee);
2664 else if (ieee->iw_mode == IW_MODE_MASTER)
2665 ieee80211_start_master_bss(ieee);
2667 else if(ieee->iw_mode == IW_MODE_MONITOR)
2668 ieee80211_start_monitor_mode(ieee);
2672 #define DRV_NAME "Ieee80211"
2673 void ieee80211_softmac_init(struct ieee80211_device *ieee)
2676 memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
2678 ieee->state = IEEE80211_NOLINK;
2679 ieee->sync_scan_hurryup = 0;
2680 for(i = 0; i < 5; i++) {
2681 ieee->seq_ctrl[i] = 0;
2683 ieee->pDot11dInfo = kzalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
2684 if (!ieee->pDot11dInfo)
2685 IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
2686 //added for AP roaming
2687 ieee->LinkDetectInfo.SlotNum = 2;
2688 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
2689 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
2692 ieee->queue_stop = 0;
2694 ieee->softmac_features = 0; //so IEEE2100-like driver are happy
2697 ieee->proto_started = 0;
2698 ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
2700 ieee->ps = IEEE80211_PS_DISABLED;
2701 ieee->sta_sleep = 0;
2702 ieee->Regdot11HTOperationalRateSet[0]= 0xff;//support MCS 0~7
2703 ieee->Regdot11HTOperationalRateSet[1]= 0xff;//support MCS 8~15
2704 ieee->Regdot11HTOperationalRateSet[4]= 0x01;
2706 ieee->actscanning = false;
2707 ieee->beinretry = false;
2708 ieee->is_set_key = false;
2709 init_mgmt_queue(ieee);
2711 ieee->sta_edca_param[0] = 0x0000A403;
2712 ieee->sta_edca_param[1] = 0x0000A427;
2713 ieee->sta_edca_param[2] = 0x005E4342;
2714 ieee->sta_edca_param[3] = 0x002F3262;
2715 ieee->aggregation = true;
2716 ieee->enable_rx_imm_BA = true;
2717 ieee->tx_pending.txb = NULL;
2719 setup_timer(&ieee->associate_timer, ieee80211_associate_abort_cb,
2720 (unsigned long)ieee);
2722 setup_timer(&ieee->beacon_timer, ieee80211_send_beacon_cb,
2723 (unsigned long)ieee);
2725 ieee->wq = create_workqueue(DRV_NAME);
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 sema_init(&ieee->wx_sem, 1);
2736 sema_init(&ieee->scan_sem, 1);
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 down(&ieee->wx_sem);
2750 kfree(ieee->pDot11dInfo);
2751 ieee->pDot11dInfo = NULL;
2752 del_timer_sync(&ieee->associate_timer);
2754 cancel_delayed_work(&ieee->associate_retry_wq);
2755 destroy_workqueue(ieee->wq);
2760 /********************************************************
2761 * Start of WPA code. *
2762 * this is stolen from the ipw2200 driver *
2763 ********************************************************/
2766 static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
2768 /* This is called when wpa_supplicant loads and closes the driver
2770 printk("%s WPA\n",value ? "enabling" : "disabling");
2771 ieee->wpa_enabled = value;
2776 static void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee,
2777 char *wpa_ie, int wpa_ie_len)
2779 /* make sure WPA is enabled */
2780 ieee80211_wpa_enable(ieee, 1);
2782 ieee80211_disassociate(ieee);
2786 static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
2792 case IEEE_MLME_STA_DEAUTH:
2796 case IEEE_MLME_STA_DISASSOC:
2797 ieee80211_disassociate(ieee);
2801 printk("Unknown MLME request: %d\n", command);
2809 static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
2810 struct ieee_param *param, int plen)
2814 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
2815 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
2818 if (param->u.wpa_ie.len) {
2819 buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len,
2824 kfree(ieee->wpa_ie);
2826 ieee->wpa_ie_len = param->u.wpa_ie.len;
2828 kfree(ieee->wpa_ie);
2829 ieee->wpa_ie = NULL;
2830 ieee->wpa_ie_len = 0;
2833 ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
2837 #define AUTH_ALG_OPEN_SYSTEM 0x1
2838 #define AUTH_ALG_SHARED_KEY 0x2
2840 static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
2843 struct ieee80211_security sec = {
2844 .flags = SEC_AUTH_MODE,
2847 if (value & AUTH_ALG_SHARED_KEY) {
2848 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
2850 ieee->auth_mode = 1;
2851 } else if (value & AUTH_ALG_OPEN_SYSTEM){
2852 sec.auth_mode = WLAN_AUTH_OPEN;
2854 ieee->auth_mode = 0;
2856 else if (value & IW_AUTH_ALG_LEAP){
2857 sec.auth_mode = WLAN_AUTH_LEAP;
2859 ieee->auth_mode = 2;
2863 if (ieee->set_security)
2864 ieee->set_security(ieee->dev, &sec);
2866 // ret = -EOPNOTSUPP;
2871 static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
2874 unsigned long flags;
2877 case IEEE_PARAM_WPA_ENABLED:
2878 ret = ieee80211_wpa_enable(ieee, value);
2881 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2882 ieee->tkip_countermeasures=value;
2885 case IEEE_PARAM_DROP_UNENCRYPTED: {
2888 * wpa_supplicant calls set_wpa_enabled when the driver
2889 * is loaded and unloaded, regardless of if WPA is being
2890 * used. No other calls are made which can be used to
2891 * determine if encryption will be used or not prior to
2892 * association being expected. If encryption is not being
2893 * used, drop_unencrypted is set to false, else true -- we
2894 * can use this to determine if the CAP_PRIVACY_ON bit should
2897 struct ieee80211_security sec = {
2898 .flags = SEC_ENABLED,
2901 ieee->drop_unencrypted = value;
2902 /* We only change SEC_LEVEL for open mode. Others
2903 * are set by ipw_wpa_set_encryption.
2906 sec.flags |= SEC_LEVEL;
2907 sec.level = SEC_LEVEL_0;
2910 sec.flags |= SEC_LEVEL;
2911 sec.level = SEC_LEVEL_1;
2913 if (ieee->set_security)
2914 ieee->set_security(ieee->dev, &sec);
2918 case IEEE_PARAM_PRIVACY_INVOKED:
2919 ieee->privacy_invoked=value;
2922 case IEEE_PARAM_AUTH_ALGS:
2923 ret = ieee80211_wpa_set_auth_algs(ieee, value);
2926 case IEEE_PARAM_IEEE_802_1X:
2927 ieee->ieee802_1x=value;
2929 case IEEE_PARAM_WPAX_SELECT:
2930 // added for WPA2 mixed mode
2931 spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags);
2932 ieee->wpax_type_set = 1;
2933 ieee->wpax_type_notify = value;
2934 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags);
2938 printk("Unknown WPA param: %d\n",name);
2945 /* implementation borrowed from hostap driver */
2947 static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
2948 struct ieee_param *param, int param_len)
2952 struct ieee80211_crypto_ops *ops;
2953 struct ieee80211_crypt_data **crypt;
2955 struct ieee80211_security sec = {
2959 param->u.crypt.err = 0;
2960 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
2963 (int) ((char *) param->u.crypt.key - (char *) param) +
2964 param->u.crypt.key_len) {
2965 printk("Len mismatch %d, %d\n", param_len,
2966 param->u.crypt.key_len);
2969 if (is_broadcast_ether_addr(param->sta_addr)) {
2970 if (param->u.crypt.idx >= WEP_KEYS)
2972 crypt = &ieee->crypt[param->u.crypt.idx];
2977 if (strcmp(param->u.crypt.alg, "none") == 0) {
2982 sec.level = SEC_LEVEL_0;
2983 sec.flags |= SEC_ENABLED | SEC_LEVEL;
2984 ieee80211_crypt_delayed_deinit(ieee, crypt);
2991 sec.flags |= SEC_ENABLED;
2993 /* IPW HW cannot build TKIP MIC, host decryption still needed. */
2994 if (!(ieee->host_encrypt || ieee->host_decrypt) &&
2995 strcmp(param->u.crypt.alg, "TKIP"))
2996 goto skip_host_crypt;
2998 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
2999 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
3000 request_module("ieee80211_crypt_wep");
3001 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3002 //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
3003 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
3004 request_module("ieee80211_crypt_tkip");
3005 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3006 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
3007 request_module("ieee80211_crypt_ccmp");
3008 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3011 printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
3012 param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
3017 if (*crypt == NULL || (*crypt)->ops != ops) {
3018 struct ieee80211_crypt_data *new_crypt;
3020 ieee80211_crypt_delayed_deinit(ieee, crypt);
3022 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
3023 if (new_crypt == NULL) {
3027 new_crypt->ops = ops;
3028 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
3030 new_crypt->ops->init(param->u.crypt.idx);
3032 if (new_crypt->priv == NULL) {
3034 param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
3042 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
3043 (*crypt)->ops->set_key(param->u.crypt.key,
3044 param->u.crypt.key_len, param->u.crypt.seq,
3045 (*crypt)->priv) < 0) {
3046 printk("key setting failed\n");
3047 param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
3053 if (param->u.crypt.set_tx) {
3054 ieee->tx_keyidx = param->u.crypt.idx;
3055 sec.active_key = param->u.crypt.idx;
3056 sec.flags |= SEC_ACTIVE_KEY;
3058 sec.flags &= ~SEC_ACTIVE_KEY;
3060 if (param->u.crypt.alg != NULL) {
3061 memcpy(sec.keys[param->u.crypt.idx],
3063 param->u.crypt.key_len);
3064 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
3065 sec.flags |= (1 << param->u.crypt.idx);
3067 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3068 sec.flags |= SEC_LEVEL;
3069 sec.level = SEC_LEVEL_1;
3070 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3071 sec.flags |= SEC_LEVEL;
3072 sec.level = SEC_LEVEL_2;
3073 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3074 sec.flags |= SEC_LEVEL;
3075 sec.level = SEC_LEVEL_3;
3079 if (ieee->set_security)
3080 ieee->set_security(ieee->dev, &sec);
3082 /* Do not reset port if card is in Managed mode since resetting will
3083 * generate new IEEE 802.11 authentication which may end up in looping
3084 * with IEEE 802.1X. If your hardware requires a reset after WEP
3085 * configuration (for example... Prism2), implement the reset_port in
3086 * the callbacks structures used to initialize the 802.11 stack. */
3087 if (ieee->reset_on_keychange &&
3088 ieee->iw_mode != IW_MODE_INFRA &&
3090 ieee->reset_port(ieee->dev)) {
3091 printk("reset_port failed\n");
3092 param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
3099 inline struct sk_buff *ieee80211_disassociate_skb(
3100 struct ieee80211_network *beacon,
3101 struct ieee80211_device *ieee,
3104 struct sk_buff *skb;
3105 struct ieee80211_disassoc *disass;
3107 skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc));
3111 disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc));
3112 disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
3113 disass->header.duration_id = 0;
3115 memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
3116 memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
3117 memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
3119 disass->reason = cpu_to_le16(asRsn);
3126 struct ieee80211_device *ieee,
3131 struct ieee80211_network *beacon = &ieee->current_network;
3132 struct sk_buff *skb;
3133 skb = ieee80211_disassociate_skb(beacon,ieee,asRsn);
3135 softmac_mgmt_xmit(skb, ieee);
3136 //dev_kfree_skb_any(skb);//edit by thomas
3139 EXPORT_SYMBOL(SendDisassociation);
3141 int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
3143 struct ieee_param *param;
3146 down(&ieee->wx_sem);
3147 //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
3149 if (p->length < sizeof(struct ieee_param) || !p->pointer) {
3154 param = memdup_user(p->pointer, p->length);
3155 if (IS_ERR(param)) {
3156 ret = PTR_ERR(param);
3160 switch (param->cmd) {
3162 case IEEE_CMD_SET_WPA_PARAM:
3163 ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
3164 param->u.wpa_param.value);
3167 case IEEE_CMD_SET_WPA_IE:
3168 ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
3171 case IEEE_CMD_SET_ENCRYPTION:
3172 ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
3176 ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
3177 param->u.mlme.reason_code);
3181 printk("Unknown WPA supplicant request: %d\n",param->cmd);
3186 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
3195 EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
3197 void notify_wx_assoc_event(struct ieee80211_device *ieee)
3199 union iwreq_data wrqu;
3200 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3201 if (ieee->state == IEEE80211_LINKED)
3202 memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
3204 eth_zero_addr(wrqu.ap_addr.sa_data);
3205 wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
3207 EXPORT_SYMBOL(notify_wx_assoc_event);