1 /* IEEE 802.11 SoftMAC layer
2 * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
4 * Mostly extracted from the rtl8180-sa2400 driver for the
5 * in-kernel generic ieee802.11 stack.
7 * Few lines might be stolen from other part of the ieee80211
8 * stack. Copyright who own it's copyright
10 * WPA code stolen from the ipw2200 driver.
11 * Copyright who own it's copyright.
13 * released under the GPL
17 #include "ieee80211.h"
19 #include <linux/random.h>
20 #include <linux/delay.h>
21 #include <linux/slab.h>
22 #include <asm/uaccess.h>
27 u8 rsn_authen_cipher_suite[16][4] = {
28 {0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved
29 {0x00,0x0F,0xAC,0x01}, //WEP-40 //RSNA default
30 {0x00,0x0F,0xAC,0x02}, //TKIP //NONE //{used just as default}
31 {0x00,0x0F,0xAC,0x03}, //WRAP-historical
32 {0x00,0x0F,0xAC,0x04}, //CCMP
33 {0x00,0x0F,0xAC,0x05}, //WEP-104
36 short ieee80211_is_54g(struct ieee80211_network net)
38 return ((net.rates_ex_len > 0) || (net.rates_len > 4));
41 short ieee80211_is_shortslot(struct ieee80211_network net)
43 return (net.capability & WLAN_CAPABILITY_SHORT_SLOT);
46 /* returns the total length needed for pleacing the RATE MFIE
47 * tag and the EXTENDED RATE MFIE tag if needed.
48 * It encludes two bytes per tag for the tag itself and its len
50 unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
52 unsigned int rate_len = 0;
54 if (ieee->modulation & IEEE80211_CCK_MODULATION)
55 rate_len = IEEE80211_CCK_RATE_LEN + 2;
57 if (ieee->modulation & IEEE80211_OFDM_MODULATION)
59 rate_len += IEEE80211_OFDM_RATE_LEN + 2;
64 /* pleace the MFIE rate, tag to the memory (double) poined.
65 * Then it updates the pointer so that
66 * it points after the new MFIE tag added.
68 void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
72 if (ieee->modulation & IEEE80211_CCK_MODULATION){
73 *tag++ = MFIE_TYPE_RATES;
75 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
76 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
77 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
78 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
81 /* We may add an option for custom rates that specific HW might support */
85 void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
89 if (ieee->modulation & IEEE80211_OFDM_MODULATION){
91 *tag++ = MFIE_TYPE_RATES_EX;
93 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
94 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
95 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
96 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
97 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
98 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
99 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
100 *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
104 /* We may add an option for custom rates that specific HW might support */
109 void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) {
112 *tag++ = MFIE_TYPE_GENERIC; //0
121 if(ieee->current_network.wmm_info & 0x80) {
122 *tag++ = 0x0f|MAX_SP_Len;
133 void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
136 *tag++ = MFIE_TYPE_GENERIC; //0
147 printk(KERN_ALERT "This is enable turbo mode IE process\n");
151 void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
154 nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
157 * if the queue is full but we have newer frames then
158 * just overwrites the oldest.
160 * if (nh == ieee->mgmt_queue_tail)
163 ieee->mgmt_queue_head = nh;
164 ieee->mgmt_queue_ring[nh] = skb;
167 struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
171 if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
174 ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
176 ieee->mgmt_queue_tail =
177 (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
182 void init_mgmt_queue(struct ieee80211_device *ieee)
184 ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
187 u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee)
189 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
192 // 2008/01/25 MH For broadcom, MGNT frame set as OFDM 6M.
193 if(pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M)
196 rate = ieee->basic_rate & 0x7f;
199 // 2005.01.26, by rcnjko.
200 if(ieee->mode == IEEE_A||
201 ieee->mode== IEEE_N_5G||
202 (ieee->mode== IEEE_N_24G&&!pHTInfo->bCurSuppCCK))
212 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
214 inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
217 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
218 struct ieee80211_hdr_3addr *header=
219 (struct ieee80211_hdr_3addr *) skb->data;
221 cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8);
222 spin_lock_irqsave(&ieee->lock, flags);
224 /* called with 2nd param 0, no mgmt lock required */
225 ieee80211_sta_wakeup(ieee,0);
227 tcb_desc->queue_index = MGNT_QUEUE;
228 tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
229 tcb_desc->RATRIndex = 7;
230 tcb_desc->bTxDisableRateFallBack = 1;
231 tcb_desc->bTxUseDriverAssingedRate = 1;
234 if(ieee->queue_stop){
235 enqueue_mgmt(ieee,skb);
237 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
239 if (ieee->seq_ctrl[0] == 0xFFF)
240 ieee->seq_ctrl[0] = 0;
244 /* avoid watchdog triggers */
245 ieee->softmac_data_hard_start_xmit(skb, ieee, ieee->basic_rate);
248 spin_unlock_irqrestore(&ieee->lock, flags);
250 spin_unlock_irqrestore(&ieee->lock, flags);
251 spin_lock(&ieee->mgmt_tx_lock);
253 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
255 if (ieee->seq_ctrl[0] == 0xFFF)
256 ieee->seq_ctrl[0] = 0;
260 /* check wether the managed packet queued greater than 5 */
261 if(!ieee->check_nic_enough_desc(ieee, tcb_desc->queue_index)||
262 (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)||
263 (ieee->queue_stop) ) {
264 /* insert the skb packet to the management queue */
265 /* as for the completion function, it does not need
266 * to check it any more.
268 skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb);
270 ieee->softmac_hard_start_xmit(skb, ieee);
272 spin_unlock(&ieee->mgmt_tx_lock);
276 inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
279 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
280 struct ieee80211_hdr_3addr *header =
281 (struct ieee80211_hdr_3addr *) skb->data;
282 cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8);
284 tcb_desc->queue_index = MGNT_QUEUE;
285 tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
286 tcb_desc->RATRIndex = 7;
287 tcb_desc->bTxDisableRateFallBack = 1;
288 tcb_desc->bTxUseDriverAssingedRate = 1;
291 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
293 if (ieee->seq_ctrl[0] == 0xFFF)
294 ieee->seq_ctrl[0] = 0;
298 /* avoid watchdog triggers */
299 ieee->softmac_data_hard_start_xmit(skb, ieee, ieee->basic_rate);
303 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
305 if (ieee->seq_ctrl[0] == 0xFFF)
306 ieee->seq_ctrl[0] = 0;
310 ieee->softmac_hard_start_xmit(skb, ieee);
315 inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
317 unsigned int len,rate_len;
320 struct ieee80211_probe_request *req;
322 len = ieee->current_network.ssid_len;
324 rate_len = ieee80211_MFIE_rate_len(ieee);
326 skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
327 2 + len + rate_len + ieee->tx_headroom);
331 skb_reserve(skb, ieee->tx_headroom);
333 req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
334 req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
335 req->header.duration_id = 0; //FIXME: is this OK ?
337 memset(req->header.addr1, 0xff, ETH_ALEN);
338 memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
339 memset(req->header.addr3, 0xff, ETH_ALEN);
341 tag = (u8 *) skb_put(skb,len+2+rate_len);
343 *tag++ = MFIE_TYPE_SSID;
345 memcpy(tag, ieee->current_network.ssid, len);
348 ieee80211_MFIE_Brate(ieee,&tag);
349 ieee80211_MFIE_Grate(ieee,&tag);
353 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
354 void ieee80211_send_beacon(struct ieee80211_device *ieee)
360 skb = ieee80211_get_beacon_(ieee);
363 softmac_mgmt_xmit(skb, ieee);
364 ieee->softmac_stats.tx_beacons++;
367 if(ieee->beacon_txing && ieee->ieee_up){
368 mod_timer(&ieee->beacon_timer,jiffies+(MSECS(ieee->current_network.beacon_interval-5)));
373 void ieee80211_send_beacon_cb(unsigned long _ieee)
375 struct ieee80211_device *ieee =
376 (struct ieee80211_device *) _ieee;
379 spin_lock_irqsave(&ieee->beacon_lock, flags);
380 ieee80211_send_beacon(ieee);
381 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
385 void ieee80211_send_probe(struct ieee80211_device *ieee)
389 skb = ieee80211_probe_req(ieee);
391 softmac_mgmt_xmit(skb, ieee);
392 ieee->softmac_stats.tx_probe_rq++;
396 void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
398 if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){
399 ieee80211_send_probe(ieee);
400 ieee80211_send_probe(ieee);
404 /* this performs syncro scan blocking the caller until all channels
405 * in the allowed channel map has been checked.
407 void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
411 u8 channel_map[MAX_CHANNEL_NUMBER+1];
412 memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
414 down(&ieee->scan_sem);
421 if (ch > MAX_CHANNEL_NUMBER)
422 goto out; /* scan completed */
424 }while(!channel_map[ch]);
426 }while(!ieee->channel_map[ch]);
429 /* this function can be called in two situations
430 * 1- We have switched to ad-hoc mode and we are
431 * performing a complete syncro scan before conclude
432 * there are no interesting cell and to create a
433 * new one. In this case the link state is
434 * IEEE80211_NOLINK until we found an interesting cell.
435 * If so the ieee8021_new_net, called by the RX path
436 * will set the state to IEEE80211_LINKED, so we stop
438 * 2- We are linked and the root uses run iwlist scan.
439 * So we switch to IEEE80211_LINKED_SCANNING to remember
440 * that we are still logically linked (not interested in
441 * new network events, despite for updating the net list,
442 * but we are temporarly 'unlinked' as the driver shall
443 * not filter RX frames and the channel is changing.
444 * So the only situation in witch are interested is to check
445 * if the state become LINKED because of the #1 situation
448 if (ieee->state == IEEE80211_LINKED)
450 ieee->set_chan(ieee, ch);
452 if(channel_map[ch] == 1)
454 ieee80211_send_probe_requests(ieee);
456 /* this prevent excessive time wait when we
457 * need to wait for a syncro scan to end..
459 if(ieee->state < IEEE80211_LINKED)
462 if (ieee->sync_scan_hurryup)
466 msleep_interruptible_rsl(IEEE80211_SOFTMAC_SCAN_TIME);
470 if(ieee->state < IEEE80211_LINKED){
471 ieee->actscanning = false;
475 ieee->sync_scan_hurryup = 0;
477 if(IS_DOT11D_ENABLE(ieee))
478 DOT11D_ScanComplete(ieee);
485 void ieee80211_softmac_scan_wq(struct work_struct *work)
487 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
488 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
489 static short watchdog = 0;
490 u8 last_channel = ieee->current_network.channel;
492 u8 channel_map[MAX_CHANNEL_NUMBER+1];
493 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) {
502 /* if current channel is not in channel map, set to default channel. */
504 if (!channel_map[ieee->current_network.channel]) {
506 if (!ieee->channel_map[ieee->current_network.channel]) {
508 ieee->current_network.channel = 6;
509 goto out; /* no good chans */
513 }while(!channel_map[ieee->current_network.channel]);
515 }while(!ieee->channel_map[ieee->current_network.channel]);
517 if (ieee->scanning == 0 )
519 ieee->set_chan(ieee, ieee->current_network.channel);
521 if(channel_map[ieee->current_network.channel] == 1)
523 ieee80211_send_probe_requests(ieee);
526 queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
532 if(IS_DOT11D_ENABLE(ieee))
533 DOT11D_ScanComplete(ieee);
535 ieee->current_network.channel = last_channel;
536 ieee->actscanning = false;
542 void ieee80211_beacons_start(struct ieee80211_device *ieee)
545 spin_lock_irqsave(&ieee->beacon_lock,flags);
547 ieee->beacon_txing = 1;
548 ieee80211_send_beacon(ieee);
550 spin_unlock_irqrestore(&ieee->beacon_lock,flags);
553 void ieee80211_beacons_stop(struct ieee80211_device *ieee)
557 spin_lock_irqsave(&ieee->beacon_lock,flags);
559 ieee->beacon_txing = 0;
560 del_timer_sync(&ieee->beacon_timer);
562 spin_unlock_irqrestore(&ieee->beacon_lock,flags);
567 void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
569 if(ieee->stop_send_beacons)
570 ieee->stop_send_beacons(ieee);
571 if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
572 ieee80211_beacons_stop(ieee);
576 void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
578 if(ieee->start_send_beacons)
579 ieee->start_send_beacons(ieee);
580 if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
581 ieee80211_beacons_start(ieee);
585 void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
587 down(&ieee->scan_sem);
589 if (ieee->scanning == 1){
592 cancel_delayed_work(&ieee->softmac_scan_wq);
598 void ieee80211_stop_scan(struct ieee80211_device *ieee)
600 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
601 ieee80211_softmac_stop_scan(ieee);
603 ieee->stop_scan(ieee);
606 /* called with ieee->lock held */
607 void ieee80211_rtl_start_scan(struct ieee80211_device *ieee)
610 if(ieee->ieee80211_ips_leave_wq != NULL)
611 ieee->ieee80211_ips_leave_wq(ieee);
615 if(IS_DOT11D_ENABLE(ieee) )
617 if(IS_COUNTRY_IE_VALID(ieee))
619 RESET_CIE_WATCHDOG(ieee);
623 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
624 if (ieee->scanning == 0){
626 queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0);
629 ieee->start_scan(ieee);
633 /* called with wx_sem held */
634 void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
637 if(IS_DOT11D_ENABLE(ieee) )
639 if(IS_COUNTRY_IE_VALID(ieee))
641 RESET_CIE_WATCHDOG(ieee);
645 ieee->sync_scan_hurryup = 0;
646 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
647 ieee80211_softmac_scan_syncro(ieee);
649 ieee->scan_syncro(ieee);
653 inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
654 struct ieee80211_device *ieee, int challengelen)
657 struct ieee80211_authentication *auth;
658 int len = sizeof(struct ieee80211_authentication) + challengelen + ieee->tx_headroom;
661 skb = dev_alloc_skb(len);
662 if (!skb) return NULL;
664 skb_reserve(skb, ieee->tx_headroom);
665 auth = (struct ieee80211_authentication *)
666 skb_put(skb, sizeof(struct ieee80211_authentication));
668 auth->header.frame_ctl = IEEE80211_STYPE_AUTH;
669 if (challengelen) auth->header.frame_ctl |= IEEE80211_FCTL_WEP;
671 auth->header.duration_id = 0x013a; //FIXME
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 if(ieee->auth_mode == 0)
678 auth->algorithm = WLAN_AUTH_OPEN;
679 else if(ieee->auth_mode == 1)
680 auth->algorithm = WLAN_AUTH_SHARED_KEY;
681 else if(ieee->auth_mode == 2)
682 auth->algorithm = WLAN_AUTH_OPEN;//0x80;
683 printk("=================>%s():auth->algorithm is %d\n",__FUNCTION__,auth->algorithm);
684 auth->transaction = cpu_to_le16(ieee->associate_seq);
685 ieee->associate_seq++;
687 auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
694 static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
698 struct ieee80211_probe_response *beacon_buf;
699 struct sk_buff *skb = NULL;
701 int atim_len,erp_len;
702 struct ieee80211_crypt_data* crypt;
704 char *ssid = ieee->current_network.ssid;
705 int ssid_len = ieee->current_network.ssid_len;
706 int rate_len = ieee->current_network.rates_len+2;
707 int rate_ex_len = ieee->current_network.rates_ex_len;
708 int wpa_ie_len = ieee->wpa_ie_len;
709 u8 erpinfo_content = 0;
714 u8 tmp_ht_info_len=0;
715 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
716 u8* tmp_generic_ie_buf=NULL;
717 u8 tmp_generic_ie_len=0;
719 if(rate_ex_len > 0) rate_ex_len+=2;
721 if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
726 if(ieee80211_is_54g(ieee->current_network))
731 crypt = ieee->crypt[ieee->tx_keyidx];
734 encrypt = ieee->host_encrypt && crypt && crypt->ops &&
735 ((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len));
738 tmp_ht_cap_buf =(u8*) &(ieee->pHTInfo->SelfHTCap);
739 tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
740 tmp_ht_info_buf =(u8*) &(ieee->pHTInfo->SelfHTInfo);
741 tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo);
742 HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len,encrypt);
743 HTConstructInfoElement(ieee,tmp_ht_info_buf,&tmp_ht_info_len, encrypt);
746 if(pHTInfo->bRegRT2RTAggregation)
748 tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
749 tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer);
750 HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len);
753 beacon_size = sizeof(struct ieee80211_probe_response)+2+
762 skb = dev_alloc_skb(beacon_size);
765 skb_reserve(skb, ieee->tx_headroom);
766 beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, (beacon_size - ieee->tx_headroom));
767 memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
768 memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
769 memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
771 beacon_buf->header.duration_id = 0; //FIXME
772 beacon_buf->beacon_interval =
773 cpu_to_le16(ieee->current_network.beacon_interval);
774 beacon_buf->capability =
775 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
776 beacon_buf->capability |=
777 cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE); //add short preamble here
779 if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
780 beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
782 crypt = ieee->crypt[ieee->tx_keyidx];
784 beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
787 beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
788 beacon_buf->info_element[0].id = MFIE_TYPE_SSID;
789 beacon_buf->info_element[0].len = ssid_len;
791 tag = (u8*) beacon_buf->info_element[0].data;
793 memcpy(tag, ssid, ssid_len);
797 *(tag++) = MFIE_TYPE_RATES;
798 *(tag++) = rate_len-2;
799 memcpy(tag,ieee->current_network.rates,rate_len-2);
802 *(tag++) = MFIE_TYPE_DS_SET;
804 *(tag++) = ieee->current_network.channel;
808 *(tag++) = MFIE_TYPE_IBSS_SET;
810 val16 = cpu_to_le16(ieee->current_network.atim_window);
811 memcpy((u8 *)tag, (u8 *)&val16, 2);
816 *(tag++) = MFIE_TYPE_ERP;
818 *(tag++) = erpinfo_content;
821 *(tag++) = MFIE_TYPE_RATES_EX;
822 *(tag++) = rate_ex_len-2;
823 memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
829 if (ieee->iw_mode == IW_MODE_ADHOC)
830 {//as Windows will set pairwise key same as the group key which is not allowed in Linux, so set this for IOT issue. WB 2008.07.07
831 memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
833 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
841 struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
846 struct ieee80211_crypt_data* crypt;
847 struct ieee80211_assoc_response_frame *assoc;
850 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
851 int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len + ieee->tx_headroom;
853 skb = dev_alloc_skb(len);
858 skb_reserve(skb, ieee->tx_headroom);
860 assoc = (struct ieee80211_assoc_response_frame *)
861 skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
863 assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
864 memcpy(assoc->header.addr1, dest,ETH_ALEN);
865 memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
866 memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
867 assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
868 WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
872 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
874 if (ieee->host_encrypt)
875 crypt = ieee->crypt[ieee->tx_keyidx];
878 encrypt = ( crypt && crypt->ops);
881 assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
884 assoc->aid = cpu_to_le16(ieee->assoc_id);
885 if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
886 else ieee->assoc_id++;
888 tag = (u8*) skb_put(skb, rate_len);
890 ieee80211_MFIE_Brate(ieee, &tag);
891 ieee80211_MFIE_Grate(ieee, &tag);
896 struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,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 struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
927 struct ieee80211_hdr_3addr* hdr;
929 skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
934 hdr = (struct ieee80211_hdr_3addr*)skb_put(skb,sizeof(struct ieee80211_hdr_3addr));
936 memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
937 memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
938 memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
940 hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
941 IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
942 (pwr ? IEEE80211_FCTL_PM:0));
949 struct sk_buff* ieee80211_pspoll_func(struct ieee80211_device *ieee)
952 struct ieee80211_pspoll_hdr* hdr;
954 #ifdef USB_USE_ALIGNMENT
957 skb = dev_alloc_skb(sizeof(struct ieee80211_pspoll_hdr) + ieee->tx_headroom + USB_512B_ALIGNMENT_SIZE);
959 skb = dev_alloc_skb(sizeof(struct ieee80211_pspoll_hdr)+ieee->tx_headroom);
964 #ifdef USB_USE_ALIGNMENT
965 Tmpaddr = (u32)skb->data;
966 alignment = Tmpaddr & 0x1ff;
967 skb_reserve(skb,(USB_512B_ALIGNMENT_SIZE - alignment));
969 skb_reserve(skb, ieee->tx_headroom);
971 hdr = (struct ieee80211_pspoll_hdr*)skb_put(skb,sizeof(struct ieee80211_pspoll_hdr));
973 memcpy(hdr->bssid, ieee->current_network.bssid, ETH_ALEN);
974 memcpy(hdr->ta, ieee->dev->dev_addr, ETH_ALEN);
976 hdr->aid = cpu_to_le16(ieee->assoc_id | 0xc000);
977 hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_CTL |IEEE80211_STYPE_PSPOLL | IEEE80211_FCTL_PM);
984 void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest)
986 struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
989 softmac_mgmt_xmit(buf, ieee);
993 void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest)
995 struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
998 softmac_mgmt_xmit(buf, ieee);
1002 void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
1006 struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
1008 softmac_mgmt_xmit(buf, ieee);
1012 inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
1014 struct sk_buff *skb;
1015 struct ieee80211_assoc_request_frame *hdr;
1017 u8* ht_cap_buf = NULL;
1019 u8* realtek_ie_buf=NULL;
1020 u8 realtek_ie_len=0;
1021 int wpa_ie_len= ieee->wpa_ie_len;
1022 unsigned int ckip_ie_len=0;
1023 unsigned int ccxrm_ie_len=0;
1024 unsigned int cxvernum_ie_len=0;
1025 struct ieee80211_crypt_data* crypt;
1028 unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
1029 unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
1031 unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
1036 crypt = ieee->crypt[ieee->tx_keyidx];
1037 encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len));
1039 //Include High Throuput capability && Realtek proprietary
1040 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1042 ht_cap_buf = (u8*)&(ieee->pHTInfo->SelfHTCap);
1043 ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
1044 HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt);
1045 if(ieee->pHTInfo->bCurrentRT2RTAggregation)
1047 realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
1048 realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer);
1049 HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len);
1053 if(ieee->qos_support){
1054 wmm_info_len = beacon->qos_data.supported?9:0;
1058 if(beacon->bCkipSupported)
1062 if(beacon->bCcxRmEnable)
1066 if( beacon->BssCcxVerNumber >= 2 )
1068 cxvernum_ie_len = 5+2;
1071 len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1072 + beacon->ssid_len//essid tagged val
1073 + rate_len//rates tagged val
1082 + ieee->tx_headroom;
1084 len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1085 + beacon->ssid_len//essid tagged val
1086 + rate_len//rates tagged val
1094 + ieee->tx_headroom;
1097 skb = dev_alloc_skb(len);
1102 skb_reserve(skb, ieee->tx_headroom);
1104 hdr = (struct ieee80211_assoc_request_frame *)
1105 skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)+2);
1108 hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
1109 hdr->header.duration_id= 37; //FIXME
1110 memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
1111 memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1112 memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
1114 memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John
1116 hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
1117 if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
1118 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1120 if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1121 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); //add short_preamble here
1123 if(ieee->short_slot)
1124 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
1125 if (wmm_info_len) //QOS
1126 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS);
1128 hdr->listen_interval = 0xa; //FIXME
1130 hdr->info_element[0].id = MFIE_TYPE_SSID;
1132 hdr->info_element[0].len = beacon->ssid_len;
1133 tag = skb_put(skb, beacon->ssid_len);
1134 memcpy(tag, beacon->ssid, beacon->ssid_len);
1136 tag = skb_put(skb, rate_len);
1138 ieee80211_MFIE_Brate(ieee, &tag);
1139 ieee80211_MFIE_Grate(ieee, &tag);
1140 // For CCX 1 S13, CKIP. Added by Annie, 2006-08-14.
1141 if( beacon->bCkipSupported )
1143 static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client"
1144 u8 CcxAironetBuf[30];
1145 OCTET_STRING osCcxAironetIE;
1147 memset(CcxAironetBuf, 0,30);
1148 osCcxAironetIE.Octet = CcxAironetBuf;
1149 osCcxAironetIE.Length = sizeof(CcxAironetBuf);
1151 // Ref. CCX test plan v3.61, 3.2.3.1 step 13.
1152 // We want to make the device type as "4500-client". 060926, by CCW.
1154 memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui));
1156 // CCX1 spec V1.13, A01.1 CKIP Negotiation (page23):
1157 // "The CKIP negotiation is started with the associate request from the client to the access point,
1158 // containing an Aironet element with both the MIC and KP bits set."
1159 osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |= (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ;
1160 tag = skb_put(skb, ckip_ie_len);
1161 *tag++ = MFIE_TYPE_AIRONET;
1162 *tag++ = osCcxAironetIE.Length;
1163 memcpy(tag,osCcxAironetIE.Octet,osCcxAironetIE.Length);
1164 tag += osCcxAironetIE.Length;
1167 if(beacon->bCcxRmEnable)
1169 static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
1170 OCTET_STRING osCcxRmCap;
1172 osCcxRmCap.Octet = CcxRmCapBuf;
1173 osCcxRmCap.Length = sizeof(CcxRmCapBuf);
1174 tag = skb_put(skb,ccxrm_ie_len);
1175 *tag++ = MFIE_TYPE_GENERIC;
1176 *tag++ = osCcxRmCap.Length;
1177 memcpy(tag,osCcxRmCap.Octet,osCcxRmCap.Length);
1178 tag += osCcxRmCap.Length;
1181 if( beacon->BssCcxVerNumber >= 2 )
1183 u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
1184 OCTET_STRING osCcxVerNum;
1185 CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
1186 osCcxVerNum.Octet = CcxVerNumBuf;
1187 osCcxVerNum.Length = sizeof(CcxVerNumBuf);
1188 tag = skb_put(skb,cxvernum_ie_len);
1189 *tag++ = MFIE_TYPE_GENERIC;
1190 *tag++ = osCcxVerNum.Length;
1191 memcpy(tag,osCcxVerNum.Octet,osCcxVerNum.Length);
1192 tag += osCcxVerNum.Length;
1195 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
1196 if(ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC)
1198 tag = skb_put(skb, ht_cap_len);
1199 *tag++ = MFIE_TYPE_HT_CAP;
1200 *tag++ = ht_cap_len - 2;
1201 memcpy(tag, ht_cap_buf,ht_cap_len -2);
1202 tag += ht_cap_len -2;
1207 //choose what wpa_supplicant gives to associate.
1208 tag = skb_put(skb, wpa_ie_len);
1210 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
1213 tag = skb_put(skb,wmm_info_len);
1215 ieee80211_WMM_Info(ieee, &tag);
1218 tag = skb_put(skb,turbo_info_len);
1219 if(turbo_info_len) {
1220 ieee80211_TURBO_Info(ieee, &tag);
1224 if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
1225 if(ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC)
1227 tag = skb_put(skb, ht_cap_len);
1228 *tag++ = MFIE_TYPE_GENERIC;
1229 *tag++ = ht_cap_len - 2;
1230 memcpy(tag, ht_cap_buf,ht_cap_len - 2);
1231 tag += ht_cap_len -2;
1234 if(ieee->pHTInfo->bCurrentRT2RTAggregation){
1235 tag = skb_put(skb, realtek_ie_len);
1236 *tag++ = MFIE_TYPE_GENERIC;
1237 *tag++ = realtek_ie_len - 2;
1238 memcpy(tag, realtek_ie_buf,realtek_ie_len -2 );
1244 void ieee80211_associate_abort(struct ieee80211_device *ieee)
1247 unsigned long flags;
1248 spin_lock_irqsave(&ieee->lock, flags);
1250 ieee->associate_seq++;
1252 /* don't scan, and avoid to have the RX path possibily
1253 * try again to associate. Even do not react to AUTH or
1254 * ASSOC response. Just wait for the retry wq to be scheduled.
1255 * Here we will check if there are good nets to associate
1256 * with, so we retry or just get back to NO_LINK and scanning
1258 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
1259 IEEE80211_DEBUG_MGMT("Authentication failed\n");
1260 ieee->softmac_stats.no_auth_rs++;
1262 IEEE80211_DEBUG_MGMT("Association failed\n");
1263 ieee->softmac_stats.no_ass_rs++;
1266 ieee->state = IEEE80211_ASSOCIATING_RETRY;
1268 queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \
1269 IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
1270 spin_unlock_irqrestore(&ieee->lock, flags);
1273 void ieee80211_associate_abort_cb(unsigned long dev)
1275 ieee80211_associate_abort((struct ieee80211_device *) dev);
1279 void ieee80211_associate_step1(struct ieee80211_device *ieee)
1281 struct ieee80211_network *beacon = &ieee->current_network;
1282 struct sk_buff *skb;
1284 IEEE80211_DEBUG_MGMT("Stopping scan\n");
1286 ieee->softmac_stats.tx_auth_rq++;
1287 skb=ieee80211_authentication_req(beacon, ieee, 0);
1290 ieee80211_associate_abort(ieee);
1292 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
1293 IEEE80211_DEBUG_MGMT("Sending authentication request\n");
1294 softmac_mgmt_xmit(skb, ieee);
1295 //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
1296 if(!timer_pending(&ieee->associate_timer)){
1297 ieee->associate_timer.expires = jiffies + (HZ / 2);
1298 add_timer(&ieee->associate_timer);
1303 void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
1306 struct sk_buff *skb;
1307 struct ieee80211_network *beacon = &ieee->current_network;
1309 ieee->associate_seq++;
1310 ieee->softmac_stats.tx_auth_rq++;
1312 skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
1314 ieee80211_associate_abort(ieee);
1316 c = skb_put(skb, chlen+2);
1317 *(c++) = MFIE_TYPE_CHALLENGE;
1319 memcpy(c, challenge, chlen);
1321 IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
1323 ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr ));
1325 softmac_mgmt_xmit(skb, ieee);
1326 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1331 void ieee80211_associate_step2(struct ieee80211_device *ieee)
1333 struct sk_buff* skb;
1334 struct ieee80211_network *beacon = &ieee->current_network;
1336 del_timer_sync(&ieee->associate_timer);
1338 IEEE80211_DEBUG_MGMT("Sending association request\n");
1340 ieee->softmac_stats.tx_ass_rq++;
1341 skb=ieee80211_association_req(beacon, ieee);
1343 ieee80211_associate_abort(ieee);
1345 softmac_mgmt_xmit(skb, ieee);
1346 mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1349 void ieee80211_associate_complete_wq(struct work_struct *work)
1351 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
1352 printk(KERN_INFO "Associated successfully\n");
1353 ieee->is_roaming = false;
1354 if(ieee80211_is_54g(ieee->current_network) &&
1355 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1358 printk(KERN_INFO"Using G rates:%d\n", ieee->rate);
1361 printk(KERN_INFO"Using B rates:%d\n", ieee->rate);
1363 if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1365 printk("Successfully associated, ht enabled\n");
1370 printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
1371 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1373 ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500);
1374 // To prevent the immediately calling watch_dog after association.
1375 if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
1377 ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
1378 ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
1380 ieee->link_change(ieee);
1381 if(ieee->is_silent_reset == 0){
1382 printk("============>normal associate\n");
1383 notify_wx_assoc_event(ieee);
1385 else if(ieee->is_silent_reset == 1)
1387 printk("==================>silent reset associate\n");
1388 ieee->is_silent_reset = 0;
1391 if (ieee->data_hard_resume)
1392 ieee->data_hard_resume(ieee);
1393 netif_carrier_on(ieee->dev);
1396 void ieee80211_associate_complete(struct ieee80211_device *ieee)
1398 del_timer_sync(&ieee->associate_timer);
1400 ieee->state = IEEE80211_LINKED;
1401 queue_work(ieee->wq, &ieee->associate_complete_wq);
1404 void ieee80211_associate_procedure_wq(struct work_struct *work)
1406 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
1407 ieee->sync_scan_hurryup = 1;
1409 if(ieee->ieee80211_ips_leave != NULL)
1410 ieee->ieee80211_ips_leave(ieee);
1413 down(&ieee->wx_sem);
1415 if (ieee->data_hard_stop)
1416 ieee->data_hard_stop(ieee);
1418 ieee80211_stop_scan(ieee);
1419 printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);
1420 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1422 ieee->associate_seq = 1;
1423 ieee80211_associate_step1(ieee);
1428 inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
1430 u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
1431 int tmp_ssid_len = 0;
1433 short apset,ssidset,ssidbroad,apmatch,ssidmatch;
1435 /* we are interested in new new only if we are not associated
1436 * and we are not associating / authenticating
1438 if (ieee->state != IEEE80211_NOLINK)
1441 if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
1444 if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
1448 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){
1449 /* if the user specified the AP MAC, we need also the essid
1450 * This could be obtained by beacons or, if the network does not
1451 * broadcast it, it can be put manually.
1453 apset = ieee->wap_set;
1454 ssidset = ieee->ssid_set;
1455 ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0');
1456 apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
1457 ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\
1458 (!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
1461 if ( /* if the user set the AP check if match.
1462 * if the network does not broadcast essid we check the user supplyed ANY essid
1463 * if the network does broadcast and the user does not set essid it is OK
1464 * if the network does broadcast and the user did set essid chech if essid match
1466 ( apset && apmatch &&
1467 ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
1468 /* if the ap is not set, check that the user set the bssid
1469 * and the network does bradcast and that those two bssid matches
1471 (!apset && ssidset && ssidbroad && ssidmatch)
1473 /* if the essid is hidden replace it with the
1474 * essid provided by the user.
1477 strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
1478 tmp_ssid_len = ieee->current_network.ssid_len;
1480 memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
1483 strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
1484 ieee->current_network.ssid_len = tmp_ssid_len;
1486 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);
1488 HTResetIOTSetting(ieee->pHTInfo);
1489 if (ieee->iw_mode == IW_MODE_INFRA){
1490 /* Join the network for the first time */
1491 ieee->AsocRetryCount = 0;
1492 //for HT by amy 080514
1493 if((ieee->current_network.qos_data.supported == 1) &&
1494 ieee->current_network.bssht.bdSupportHT)
1495 /*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.*/
1497 HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network));
1501 ieee->pHTInfo->bCurrentHTSupport = false;
1504 ieee->state = IEEE80211_ASSOCIATING;
1505 queue_work(ieee->wq, &ieee->associate_procedure_wq);
1507 if(ieee80211_is_54g(ieee->current_network) &&
1508 (ieee->modulation & IEEE80211_OFDM_MODULATION)){
1510 ieee->SetWirelessMode(ieee, IEEE_G);
1511 printk(KERN_INFO"Using G rates\n");
1514 ieee->SetWirelessMode(ieee, IEEE_B);
1515 printk(KERN_INFO"Using B rates\n");
1517 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1518 ieee->state = IEEE80211_LINKED;
1526 void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
1528 unsigned long flags;
1529 struct ieee80211_network *target;
1531 spin_lock_irqsave(&ieee->lock, flags);
1533 list_for_each_entry(target, &ieee->network_list, list) {
1535 /* if the state become different that NOLINK means
1536 * we had found what we are searching for
1539 if (ieee->state != IEEE80211_NOLINK)
1542 if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
1543 ieee80211_softmac_new_net(ieee, target);
1546 spin_unlock_irqrestore(&ieee->lock, flags);
1551 static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen)
1553 struct ieee80211_authentication *a;
1555 if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
1556 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
1560 a = (struct ieee80211_authentication*) skb->data;
1561 if(skb->len > (sizeof(struct ieee80211_authentication) +3)){
1562 t = skb->data + sizeof(struct ieee80211_authentication);
1564 if(*(t++) == MFIE_TYPE_CHALLENGE){
1566 *challenge = kmemdup(t, *chlen, GFP_ATOMIC);
1572 return cpu_to_le16(a->status);
1577 int auth_rq_parse(struct sk_buff *skb,u8* dest)
1579 struct ieee80211_authentication *a;
1581 if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
1582 IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
1585 a = (struct ieee80211_authentication*) skb->data;
1587 memcpy(dest,a->header.addr2, ETH_ALEN);
1589 if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
1590 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1592 return WLAN_STATUS_SUCCESS;
1595 static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
1602 struct ieee80211_hdr_3addr *header =
1603 (struct ieee80211_hdr_3addr *) skb->data;
1605 if (skb->len < sizeof (struct ieee80211_hdr_3addr ))
1606 return -1; /* corrupted */
1608 memcpy(src,header->addr2, ETH_ALEN);
1610 skbend = (u8*)skb->data + skb->len;
1612 tag = skb->data + sizeof (struct ieee80211_hdr_3addr );
1614 while (tag+1 < skbend){
1620 tag++; /* point to the len field */
1621 tag = tag + *(tag); /* point to the last data byte of the tag */
1622 tag++; /* point to the next tag */
1625 if (ssidlen == 0) return 1;
1627 if (!ssid) return 1; /* ssid not found in tagged param */
1628 return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
1632 int assoc_rq_parse(struct sk_buff *skb,u8* dest)
1634 struct ieee80211_assoc_request_frame *a;
1636 if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
1637 sizeof(struct ieee80211_info_element))) {
1639 IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
1643 a = (struct ieee80211_assoc_request_frame*) skb->data;
1645 memcpy(dest,a->header.addr2,ETH_ALEN);
1650 static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid)
1652 struct ieee80211_assoc_response_frame *response_head;
1655 if (skb->len < sizeof(struct ieee80211_assoc_response_frame)){
1656 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
1660 response_head = (struct ieee80211_assoc_response_frame*) skb->data;
1661 *aid = le16_to_cpu(response_head->aid) & 0x3fff;
1663 status_code = le16_to_cpu(response_head->status);
1664 if((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \
1665 status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&&
1666 ((ieee->mode == IEEE_G) &&
1667 (ieee->current_network.mode == IEEE_N_24G) &&
1668 (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) {
1669 ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
1671 ieee->AsocRetryCount = 0;
1674 return le16_to_cpu(response_head->status);
1678 ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1682 ieee->softmac_stats.rx_probe_rq++;
1683 if (probe_rq_parse(ieee, skb, dest)){
1684 ieee->softmac_stats.tx_probe_rs++;
1685 ieee80211_resp_to_probe(ieee, dest);
1690 ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1694 ieee->softmac_stats.rx_auth_rq++;
1696 status = auth_rq_parse(skb, dest);
1698 ieee80211_resp_to_auth(ieee, status, dest);
1703 ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
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);
1717 void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
1720 struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
1723 softmac_ps_mgmt_xmit(buf, ieee);
1727 void ieee80211_sta_ps_send_pspoll_frame(struct ieee80211_device *ieee)
1730 struct sk_buff *buf = ieee80211_pspoll_func(ieee);
1733 softmac_ps_mgmt_xmit(buf, ieee);
1737 short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
1739 int timeout = ieee->ps_timeout;
1742 if(ieee->LPSDelayCnt)
1744 ieee->LPSDelayCnt --;
1748 dtim = ieee->current_network.dtim_data;
1749 if(!(dtim & IEEE80211_DTIM_VALID))
1751 timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
1752 ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
1753 /* there's no need to nofity AP that I find you buffered with broadcast packet */
1754 if(dtim & (IEEE80211_DTIM_UCAST & ieee->ps))
1757 if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout))){
1760 if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout))){
1763 if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
1764 (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
1768 if(ieee->bAwakePktSent == true) {
1769 ieee->LPSAwakeIntvl = 1;//tx wake one beacon
1773 if(ieee->LPSAwakeIntvl == 0)
1774 ieee->LPSAwakeIntvl = 1;
1775 if(ieee->RegMaxLPSAwakeIntvl == 0) // Default (0x0 - eFastPs, 0xFF -DTIM, 0xNN - 0xNN * BeaconIntvl)
1776 MaxPeriod = 1; // 1 Beacon interval
1777 else if(ieee->RegMaxLPSAwakeIntvl == 0xFF) // DTIM
1778 MaxPeriod = ieee->current_network.dtim_period;
1780 MaxPeriod = ieee->RegMaxLPSAwakeIntvl;
1781 ieee->LPSAwakeIntvl = (ieee->LPSAwakeIntvl >= MaxPeriod) ? MaxPeriod : (ieee->LPSAwakeIntvl + 1);
1784 u8 LPSAwakeIntvl_tmp = 0;
1785 u8 period = ieee->current_network.dtim_period;
1786 u8 count = ieee->current_network.tim.tim_count;
1788 if(ieee->LPSAwakeIntvl > period)
1789 LPSAwakeIntvl_tmp = period + (ieee->LPSAwakeIntvl - period) -((ieee->LPSAwakeIntvl-period)%period);
1791 LPSAwakeIntvl_tmp = ieee->LPSAwakeIntvl;
1794 if(ieee->LPSAwakeIntvl > ieee->current_network.tim.tim_count)
1795 LPSAwakeIntvl_tmp = count + (ieee->LPSAwakeIntvl - count) -((ieee->LPSAwakeIntvl-count)%period);
1797 LPSAwakeIntvl_tmp = ieee->LPSAwakeIntvl;
1800 *time_l = ieee->current_network.last_dtim_sta_time[0]
1801 + MSECS(ieee->current_network.beacon_interval * LPSAwakeIntvl_tmp);
1806 *time_h = ieee->current_network.last_dtim_sta_time[1];
1807 if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
1816 inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
1821 unsigned long flags;
1823 spin_lock_irqsave(&ieee->lock, flags);
1825 if((ieee->ps == IEEE80211_PS_DISABLED ||
1826 ieee->iw_mode != IW_MODE_INFRA ||
1827 ieee->state != IEEE80211_LINKED)){
1829 // #warning CHECK_LOCK_HERE
1830 printk("=====>%s(): no need to ps,wake up!! ieee->ps is %d,ieee->iw_mode is %d,ieee->state is %d\n",
1831 __FUNCTION__,ieee->ps,ieee->iw_mode,ieee->state);
1832 spin_lock(&ieee->mgmt_tx_lock);
1834 ieee80211_sta_wakeup(ieee, 1);
1836 spin_unlock(&ieee->mgmt_tx_lock);
1839 sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
1840 /* 2 wake, 1 sleep, 0 do nothing */
1841 if(sleep == 0)//it is not time out or dtim is not valid
1846 if(ieee->sta_sleep == 1){
1847 ieee->enter_sleep_state(ieee, th, tl);
1850 else if(ieee->sta_sleep == 0){
1851 spin_lock(&ieee->mgmt_tx_lock);
1853 if (ieee->ps_is_queue_empty(ieee)) {
1854 ieee->sta_sleep = 2;
1855 ieee->ack_tx_to_ieee = 1;
1856 ieee80211_sta_ps_send_null_frame(ieee,1);
1860 spin_unlock(&ieee->mgmt_tx_lock);
1864 ieee->bAwakePktSent = false;//after null to power save we set it to false. not listen every beacon.
1866 }else if(sleep == 2){
1867 spin_lock(&ieee->mgmt_tx_lock);
1869 ieee80211_sta_wakeup(ieee,1);
1871 spin_unlock(&ieee->mgmt_tx_lock);
1875 spin_unlock_irqrestore(&ieee->lock, flags);
1879 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
1881 if(ieee->sta_sleep == 0){
1883 if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING)
1885 ieee->ack_tx_to_ieee = 1;
1886 ieee80211_sta_ps_send_null_frame(ieee, 0);
1890 ieee->ack_tx_to_ieee = 1;
1891 ieee80211_sta_ps_send_pspoll_frame(ieee);
1898 if(ieee->sta_sleep == 1)
1899 ieee->sta_wake_up(ieee);
1902 if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING)
1904 ieee->ack_tx_to_ieee = 1;
1905 ieee80211_sta_ps_send_null_frame(ieee, 0);
1909 ieee->ack_tx_to_ieee = 1;
1910 ieee->polling = true;
1911 //ieee80211_sta_ps_send_null_frame(ieee, 0);
1912 ieee80211_sta_ps_send_pspoll_frame(ieee);
1916 ieee->sta_sleep = 0;
1917 ieee->polling = false;
1921 void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
1923 unsigned long flags;
1925 spin_lock_irqsave(&ieee->lock, flags);
1927 if(ieee->sta_sleep == 2){
1928 /* Null frame with PS bit set */
1930 ieee->sta_sleep = 1;
1931 ieee->enter_sleep_state(ieee, ieee->ps_th, ieee->ps_tl);
1933 } else {/* 21112005 - tx again null without PS bit if lost */
1935 if((ieee->sta_sleep == 0) && !success){
1936 spin_lock(&ieee->mgmt_tx_lock);
1937 //ieee80211_sta_ps_send_null_frame(ieee, 0);
1938 if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING)
1940 ieee80211_sta_ps_send_null_frame(ieee, 0);
1944 ieee80211_sta_ps_send_pspoll_frame(ieee);
1946 spin_unlock(&ieee->mgmt_tx_lock);
1949 spin_unlock_irqrestore(&ieee->lock, flags);
1952 void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb)
1954 struct ieee80211_hdr* header = (struct ieee80211_hdr*)skb->data;
1955 u8* act = ieee80211_get_payload(header);
1960 IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
1968 if (*act == ACT_ADDBAREQ)
1969 ieee80211_rx_ADDBAReq(ieee, skb);
1970 else if (*act == ACT_ADDBARSP)
1971 ieee80211_rx_ADDBARsp(ieee, skb);
1972 else if (*act == ACT_DELBA)
1973 ieee80211_rx_DELBA(ieee, skb);
1982 ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
1983 struct ieee80211_rx_stats *rx_stats, u16 type,
1986 struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
1991 struct ieee80211_assoc_response_frame *assoc_resp;
1992 bool bSupportNmode = true, bHalfSupportNmode = false; //default support N mode, disable halfNmode
1994 if(!ieee->proto_started)
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 if (0 == (errcode=assoc_parse(ieee,skb, &aid))){
2011 ieee->state=IEEE80211_LINKED;
2012 ieee->assoc_id = aid;
2013 ieee->softmac_stats.rx_ass_ok++;
2014 /* station support qos */
2015 /* Let the register setting defaultly with Legacy station */
2016 if(ieee->qos_support) {
2017 assoc_resp = (struct ieee80211_assoc_response_frame*)skb->data;
2018 memset(network, 0, sizeof(*network));
2019 if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\
2020 rx_stats->len - sizeof(*assoc_resp),\
2025 { //filling the PeerHTCap. //maybe not necessary as we can get its info from current_network.
2026 memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
2027 memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
2029 if (ieee->handle_assoc_response != NULL)
2030 ieee->handle_assoc_response(ieee, (struct ieee80211_assoc_response_frame*)header, network);
2032 ieee80211_associate_complete(ieee);
2034 /* aid could not been allocated */
2035 ieee->softmac_stats.rx_ass_err++;
2037 "Association response status code 0x%x\n",
2039 IEEE80211_DEBUG_MGMT(
2040 "Association response status code 0x%x\n",
2042 if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
2043 queue_work(ieee->wq, &ieee->associate_procedure_wq);
2045 ieee80211_associate_abort(ieee);
2051 case IEEE80211_STYPE_ASSOC_REQ:
2052 case IEEE80211_STYPE_REASSOC_REQ:
2054 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2055 ieee->iw_mode == IW_MODE_MASTER)
2057 ieee80211_rx_assoc_rq(ieee, skb);
2060 case IEEE80211_STYPE_AUTH:
2062 if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){
2063 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
2064 ieee->iw_mode == IW_MODE_INFRA){
2066 IEEE80211_DEBUG_MGMT("Received authentication response");
2068 if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){
2069 if(ieee->open_wep || !challenge){
2070 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
2071 ieee->softmac_stats.rx_auth_rs_ok++;
2072 if(!(ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE))
2074 if (!ieee->GetNmodeSupportBySecCfg(ieee))
2076 // WEP or TKIP encryption
2077 if(IsHTHalfNmodeAPs(ieee))
2079 bSupportNmode = true;
2080 bHalfSupportNmode = true;
2084 bSupportNmode = false;
2085 bHalfSupportNmode = false;
2087 printk("==========>to link with AP using SEC(%d, %d)\n", bSupportNmode, bHalfSupportNmode);
2090 /* Dummy wirless mode setting to avoid encryption issue */
2093 ieee->SetWirelessMode(ieee,
2094 ieee->current_network.mode);
2098 ieee->SetWirelessMode(ieee, IEEE_G);
2101 if (ieee->current_network.mode == IEEE_N_24G && bHalfSupportNmode == true)
2103 printk("===============>entern half N mode\n");
2104 ieee->bHalfWirelessN24GMode = true;
2107 ieee->bHalfWirelessN24GMode = false;
2109 ieee80211_associate_step2(ieee);
2111 ieee80211_rtl_auth_challenge(ieee, challenge, chlen);
2114 ieee->softmac_stats.rx_auth_rs_err++;
2115 IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode);
2117 printk("Authentication respose status code 0x%x",errcode);
2118 ieee80211_associate_abort(ieee);
2121 }else if (ieee->iw_mode == IW_MODE_MASTER){
2122 ieee80211_rx_auth_rq(ieee, skb);
2127 case IEEE80211_STYPE_PROBE_REQ:
2129 if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
2130 ((ieee->iw_mode == IW_MODE_ADHOC ||
2131 ieee->iw_mode == IW_MODE_MASTER) &&
2132 ieee->state == IEEE80211_LINKED)){
2133 ieee80211_rx_probe_rq(ieee, skb);
2137 case IEEE80211_STYPE_DISASSOC:
2138 case IEEE80211_STYPE_DEAUTH:
2139 /* FIXME for now repeat all the association procedure
2140 * both for disassociation and deauthentication
2142 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2143 ieee->state == IEEE80211_LINKED &&
2144 ieee->iw_mode == IW_MODE_INFRA){
2146 ieee->state = IEEE80211_ASSOCIATING;
2147 ieee->softmac_stats.reassoc++;
2148 ieee->is_roaming = true;
2149 ieee80211_disassociate(ieee);
2150 RemovePeerTS(ieee, header->addr2);
2151 queue_work(ieee->wq, &ieee->associate_procedure_wq);
2154 case IEEE80211_STYPE_MANAGE_ACT:
2155 ieee80211_process_action(ieee,skb);
2165 /* following are for a simpler TX queue management.
2166 * Instead of using netif_[stop/wake]_queue the driver
2167 * will uses these two function (plus a reset one), that
2168 * will internally uses the kernel netif_* and takes
2169 * care of the ieee802.11 fragmentation.
2170 * So the driver receives a fragment per time and might
2171 * call the stop function when it want without take care
2172 * to have enough room to TX an entire packet.
2173 * This might be useful if each fragment need it's own
2174 * descriptor, thus just keep a total free memory > than
2175 * the max fragmentation threshold is not enough.. If the
2176 * ieee802.11 stack passed a TXB struct then you needed
2177 * to keep N free descriptors where
2178 * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
2179 * In this way you need just one and the 802.11 stack
2180 * will take care of buffering fragments and pass them to
2181 * to the driver later, when it wakes the queue.
2183 void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
2186 unsigned int queue_index = txb->queue_index;
2187 unsigned long flags;
2189 cb_desc *tcb_desc = NULL;
2191 spin_lock_irqsave(&ieee->lock,flags);
2193 /* called with 2nd parm 0, no tx mgmt lock required */
2194 ieee80211_sta_wakeup(ieee,0);
2196 /* update the tx status */
2197 tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
2198 if(tcb_desc->bMulticast) {
2199 ieee->stats.multicast++;
2202 /* if xmit available, just xmit it immediately, else just insert it to the wait queue */
2203 for(i = 0; i < txb->nr_frags; i++) {
2204 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2205 if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) ||
2207 if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
2209 (!ieee->check_nic_enough_desc(ieee, queue_index))||
2210 (ieee->queue_stop)) {
2211 /* insert the skb packet to the wait queue */
2212 /* as for the completion function, it does not need
2213 * to check it any more.
2215 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2216 skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]);
2218 skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
2221 ieee->softmac_data_hard_start_xmit(
2227 ieee80211_txb_free(txb);
2229 spin_unlock_irqrestore(&ieee->lock,flags);
2233 /* called with ieee->lock acquired */
2234 void ieee80211_resume_tx(struct ieee80211_device *ieee)
2237 for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
2239 if (ieee->queue_stop){
2240 ieee->tx_pending.frag = i;
2244 ieee->softmac_data_hard_start_xmit(
2245 ieee->tx_pending.txb->fragments[i],
2247 ieee->stats.tx_packets++;
2252 ieee80211_txb_free(ieee->tx_pending.txb);
2253 ieee->tx_pending.txb = NULL;
2257 void ieee80211_reset_queue(struct ieee80211_device *ieee)
2259 unsigned long flags;
2261 spin_lock_irqsave(&ieee->lock,flags);
2262 init_mgmt_queue(ieee);
2263 if (ieee->tx_pending.txb){
2264 ieee80211_txb_free(ieee->tx_pending.txb);
2265 ieee->tx_pending.txb = NULL;
2267 ieee->queue_stop = 0;
2268 spin_unlock_irqrestore(&ieee->lock,flags);
2272 void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee)
2275 unsigned long flags;
2276 struct sk_buff *skb;
2277 struct ieee80211_hdr_3addr *header;
2279 spin_lock_irqsave(&ieee->lock,flags);
2280 if (! ieee->queue_stop) goto exit;
2282 ieee->queue_stop = 0;
2284 if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){
2285 while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
2287 header = (struct ieee80211_hdr_3addr *) skb->data;
2289 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2291 if (ieee->seq_ctrl[0] == 0xFFF)
2292 ieee->seq_ctrl[0] = 0;
2294 ieee->seq_ctrl[0]++;
2296 ieee->softmac_data_hard_start_xmit(skb, ieee, ieee->basic_rate);
2299 if (!ieee->queue_stop && ieee->tx_pending.txb)
2300 ieee80211_resume_tx(ieee);
2302 if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){
2303 ieee->softmac_stats.swtxawake++;
2304 netif_wake_queue(ieee->dev);
2308 spin_unlock_irqrestore(&ieee->lock,flags);
2312 void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee)
2314 if (! netif_queue_stopped(ieee->dev)){
2315 netif_stop_queue(ieee->dev);
2316 ieee->softmac_stats.swtxstop++;
2318 ieee->queue_stop = 1;
2322 inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
2325 get_random_bytes(ieee->current_network.bssid, ETH_ALEN);
2327 /* an IBSS cell address must have the two less significant
2328 * bits of the first byte = 2
2330 ieee->current_network.bssid[0] &= ~0x01;
2331 ieee->current_network.bssid[0] |= 0x02;
2334 /* called in user context only */
2335 void ieee80211_start_master_bss(struct ieee80211_device *ieee)
2339 if (ieee->current_network.ssid_len == 0){
2340 strncpy(ieee->current_network.ssid,
2341 IEEE80211_DEFAULT_TX_ESSID,
2344 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2348 memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
2350 ieee->set_chan(ieee, ieee->current_network.channel);
2351 ieee->state = IEEE80211_LINKED;
2352 ieee->link_change(ieee);
2353 notify_wx_assoc_event(ieee);
2355 if (ieee->data_hard_resume)
2356 ieee->data_hard_resume(ieee);
2358 netif_carrier_on(ieee->dev);
2361 void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
2365 if (ieee->data_hard_resume)
2366 ieee->data_hard_resume(ieee);
2368 netif_carrier_on(ieee->dev);
2371 void ieee80211_start_ibss_wq(struct work_struct *work)
2374 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2375 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
2376 /* iwconfig mode ad-hoc will schedule this and return
2377 * on the other hand this will block further iwconfig SET
2378 * operations because of the wx_sem hold.
2379 * Anyway some most set operations set a flag to speed-up
2380 * (abort) this wq (when syncro scanning) before sleeping
2383 if(!ieee->proto_started){
2384 printk("==========oh driver down return\n");
2387 down(&ieee->wx_sem);
2389 if (ieee->current_network.ssid_len == 0){
2390 strcpy(ieee->current_network.ssid,IEEE80211_DEFAULT_TX_ESSID);
2391 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2395 ieee->state = IEEE80211_NOLINK;
2396 /* check if we have this cell in our network list */
2397 ieee80211_softmac_check_all_nets(ieee);
2400 #ifdef ENABLE_DOT11D //if creating an ad-hoc, set its channel to 10 temporarily--this is the requirement for ASUS, not 11D, so disable 11d.
2401 if (ieee->state == IEEE80211_NOLINK)
2402 ieee->current_network.channel = 6;
2404 /* if not then the state is not linked. Maybe the user swithced to
2405 * ad-hoc mode just after being in monitor mode, or just after
2406 * being very few time in managed mode (so the card have had no
2407 * time to scan all the chans..) or we have just run up the iface
2408 * after setting ad-hoc mode. So we have to give another try..
2409 * Here, in ibss mode, should be safe to do this without extra care
2410 * (in bss mode we had to make sure no-one tryed to associate when
2411 * we had just checked the ieee->state and we was going to start the
2412 * scan) beacause in ibss mode the ieee80211_new_net function, when
2413 * finds a good net, just set the ieee->state to IEEE80211_LINKED,
2414 * so, at worst, we waste a bit of time to initiate an unneeded syncro
2415 * scan, that will stop at the first round because it sees the state
2418 if (ieee->state == IEEE80211_NOLINK)
2419 ieee80211_start_scan_syncro(ieee);
2421 /* the network definitively is not here.. create a new cell */
2422 if (ieee->state == IEEE80211_NOLINK){
2423 printk("creating new IBSS cell\n");
2425 ieee80211_randomize_cell(ieee);
2427 if(ieee->modulation & IEEE80211_CCK_MODULATION){
2429 ieee->current_network.rates_len = 4;
2431 ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
2432 ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
2433 ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
2434 ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
2437 ieee->current_network.rates_len = 0;
2439 if(ieee->modulation & IEEE80211_OFDM_MODULATION){
2440 ieee->current_network.rates_ex_len = 8;
2442 ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
2443 ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
2444 ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
2445 ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
2446 ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
2447 ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
2448 ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
2449 ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
2453 ieee->current_network.rates_ex_len = 0;
2457 // By default, WMM function will be disabled in IBSS mode
2458 ieee->current_network.QoS_Enable = 0;
2459 ieee->SetWirelessMode(ieee, IEEE_G);
2460 ieee->current_network.atim_window = 0;
2461 ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
2462 if(ieee->short_slot)
2463 ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
2467 ieee->state = IEEE80211_LINKED;
2469 ieee->set_chan(ieee, ieee->current_network.channel);
2470 ieee->link_change(ieee);
2472 notify_wx_assoc_event(ieee);
2474 ieee80211_start_send_beacons(ieee);
2476 if (ieee->data_hard_resume)
2477 ieee->data_hard_resume(ieee);
2478 netif_carrier_on(ieee->dev);
2483 inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
2485 queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150);
2488 /* this is called only in user context, with wx_sem held */
2489 void ieee80211_start_bss(struct ieee80211_device *ieee)
2491 unsigned long flags;
2492 #ifdef ENABLE_DOT11D
2494 // Ref: 802.11d 11.1.3.3
2495 // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
2497 if(IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
2499 if(! ieee->bGlobalDomain)
2505 /* check if we have already found the net we
2506 * are interested in (if any).
2507 * if not (we are disassociated and we are not
2508 * in associating / authenticating phase) start the background scanning.
2510 ieee80211_softmac_check_all_nets(ieee);
2512 /* ensure no-one start an associating process (thus setting
2513 * the ieee->state to ieee80211_ASSOCIATING) while we
2514 * have just cheked it and we are going to enable scan.
2515 * The ieee80211_new_net function is always called with
2516 * lock held (from both ieee80211_softmac_check_all_nets and
2517 * the rx path), so we cannot be in the middle of such function
2519 spin_lock_irqsave(&ieee->lock, flags);
2521 if (ieee->state == IEEE80211_NOLINK){
2523 if(ieee->ieee80211_ips_leave_wq != NULL)
2524 ieee->ieee80211_ips_leave_wq(ieee);
2526 ieee->actscanning = true;
2527 ieee80211_rtl_start_scan(ieee);
2529 spin_unlock_irqrestore(&ieee->lock, flags);
2532 /* called only in userspace context */
2533 void ieee80211_disassociate(struct ieee80211_device *ieee)
2537 netif_carrier_off(ieee->dev);
2538 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
2539 ieee80211_reset_queue(ieee);
2541 if (ieee->data_hard_stop)
2542 ieee->data_hard_stop(ieee);
2543 #ifdef ENABLE_DOT11D
2544 if(IS_DOT11D_ENABLE(ieee))
2547 ieee->is_set_key = false;
2548 ieee->link_change(ieee);
2549 if (ieee->state == IEEE80211_LINKED ||
2550 ieee->state == IEEE80211_ASSOCIATING) {
2551 ieee->state = IEEE80211_NOLINK;
2552 notify_wx_assoc_event(ieee);
2555 ieee->state = IEEE80211_NOLINK;
2558 void ieee80211_associate_retry_wq(struct work_struct *work)
2560 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2561 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
2562 unsigned long flags;
2564 down(&ieee->wx_sem);
2565 if(!ieee->proto_started)
2568 if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
2571 /* until we do not set the state to IEEE80211_NOLINK
2572 * there are no possibility to have someone else trying
2573 * to start an association procdure (we get here with
2574 * ieee->state = IEEE80211_ASSOCIATING).
2575 * When we set the state to IEEE80211_NOLINK it is possible
2576 * that the RX path run an attempt to associate, but
2577 * both ieee80211_softmac_check_all_nets and the
2578 * RX path works with ieee->lock held so there are no
2579 * problems. If we are still disassociated then start a scan.
2580 * the lock here is necessary to ensure no one try to start
2581 * an association procedure when we have just checked the
2582 * state and we are going to start the scan.
2584 ieee->beinretry = true;
2585 ieee->state = IEEE80211_NOLINK;
2587 ieee80211_softmac_check_all_nets(ieee);
2589 spin_lock_irqsave(&ieee->lock, flags);
2591 if(ieee->state == IEEE80211_NOLINK)
2593 ieee->is_roaming= false;
2594 ieee->actscanning = true;
2595 ieee80211_rtl_start_scan(ieee);
2597 spin_unlock_irqrestore(&ieee->lock, flags);
2599 ieee->beinretry = false;
2604 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
2606 u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
2608 struct sk_buff *skb;
2609 struct ieee80211_probe_response *b;
2611 skb = ieee80211_probe_resp(ieee, broadcast_addr);
2616 b = (struct ieee80211_probe_response *) skb->data;
2617 b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
2623 struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
2625 struct sk_buff *skb;
2626 struct ieee80211_probe_response *b;
2628 skb = ieee80211_get_beacon_(ieee);
2632 b = (struct ieee80211_probe_response *) skb->data;
2633 b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2635 if (ieee->seq_ctrl[0] == 0xFFF)
2636 ieee->seq_ctrl[0] = 0;
2638 ieee->seq_ctrl[0]++;
2643 void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee, u8 shutdown)
2645 ieee->sync_scan_hurryup = 1;
2646 down(&ieee->wx_sem);
2647 ieee80211_stop_protocol(ieee, shutdown);
2652 void ieee80211_stop_protocol(struct ieee80211_device *ieee, u8 shutdown)
2654 if (!ieee->proto_started)
2658 ieee->proto_started = 0;
2659 ieee->proto_stoppping = 1;
2661 ieee80211_stop_send_beacons(ieee);
2662 del_timer_sync(&ieee->associate_timer);
2663 cancel_delayed_work(&ieee->associate_retry_wq);
2664 cancel_delayed_work(&ieee->start_ibss_wq);
2665 ieee80211_stop_scan(ieee);
2667 ieee80211_disassociate(ieee);
2668 RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
2670 ieee->proto_stoppping = 0;
2673 void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
2675 ieee->sync_scan_hurryup = 0;
2676 down(&ieee->wx_sem);
2677 ieee80211_start_protocol(ieee);
2681 void ieee80211_start_protocol(struct ieee80211_device *ieee)
2685 if (ieee->proto_started)
2688 ieee->proto_started = 1;
2690 if (ieee->current_network.channel == 0){
2693 if (ch > MAX_CHANNEL_NUMBER)
2694 return; /* no channel found */
2695 #ifdef ENABLE_DOT11D
2696 }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
2698 }while(!ieee->channel_map[ch]);
2700 ieee->current_network.channel = ch;
2703 if (ieee->current_network.beacon_interval == 0)
2704 ieee->current_network.beacon_interval = 100;
2706 for(i = 0; i < 17; i++) {
2707 ieee->last_rxseq_num[i] = -1;
2708 ieee->last_rxfrag_num[i] = -1;
2709 ieee->last_packet_time[i] = 0;
2712 ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
2714 ieee->state = IEEE80211_NOLINK;
2717 /* if the user set the MAC of the ad-hoc cell and then
2718 * switch to managed mode, shall we make sure that association
2719 * attempts does not fail just because the user provide the essid
2720 * and the nic is still checking for the AP MAC ??
2722 if (ieee->iw_mode == IW_MODE_INFRA)
2723 ieee80211_start_bss(ieee);
2725 else if (ieee->iw_mode == IW_MODE_ADHOC)
2726 ieee80211_start_ibss(ieee);
2728 else if (ieee->iw_mode == IW_MODE_MASTER)
2729 ieee80211_start_master_bss(ieee);
2731 else if(ieee->iw_mode == IW_MODE_MONITOR)
2732 ieee80211_start_monitor_mode(ieee);
2736 #define DRV_NAME "Ieee80211"
2737 void ieee80211_softmac_init(struct ieee80211_device *ieee)
2740 memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
2742 ieee->state = IEEE80211_NOLINK;
2743 ieee->sync_scan_hurryup = 0;
2744 for(i = 0; i < 5; i++) {
2745 ieee->seq_ctrl[i] = 0;
2747 #ifdef ENABLE_DOT11D
2748 ieee->pDot11dInfo = kzalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
2749 if (!ieee->pDot11dInfo)
2750 IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
2752 //added for AP roaming
2753 ieee->LinkDetectInfo.SlotNum = 2;
2754 ieee->LinkDetectInfo.NumRecvBcnInPeriod=0;
2755 ieee->LinkDetectInfo.NumRecvDataInPeriod=0;
2758 ieee->queue_stop = 0;
2760 ieee->softmac_features = 0; //so IEEE2100-like driver are happy
2763 ieee->proto_started = 0;
2764 ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
2766 ieee->ps = IEEE80211_PS_DISABLED;
2767 ieee->sta_sleep = 0;
2768 ieee->Regdot11HTOperationalRateSet[0]= 0xff;//support MCS 0~7
2769 ieee->Regdot11HTOperationalRateSet[1]= 0xff;//support MCS 8~15
2770 ieee->Regdot11HTOperationalRateSet[4]= 0x01;
2772 ieee->actscanning = false;
2773 ieee->beinretry = false;
2774 ieee->is_set_key = false;
2775 init_mgmt_queue(ieee);
2777 ieee->sta_edca_param[0] = 0x0000A403;
2778 ieee->sta_edca_param[1] = 0x0000A427;
2779 ieee->sta_edca_param[2] = 0x005E4342;
2780 ieee->sta_edca_param[3] = 0x002F3262;
2781 ieee->aggregation = true;
2782 ieee->enable_rx_imm_BA = 1;
2783 ieee->tx_pending.txb = NULL;
2785 init_timer(&ieee->associate_timer);
2786 ieee->associate_timer.data = (unsigned long)ieee;
2787 ieee->associate_timer.function = ieee80211_associate_abort_cb;
2789 init_timer(&ieee->beacon_timer);
2790 ieee->beacon_timer.data = (unsigned long) ieee;
2791 ieee->beacon_timer.function = ieee80211_send_beacon_cb;
2793 ieee->wq = create_workqueue(DRV_NAME);
2795 INIT_DELAYED_WORK(&ieee->start_ibss_wq,ieee80211_start_ibss_wq);
2796 INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
2797 INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
2798 INIT_DELAYED_WORK(&ieee->softmac_scan_wq,ieee80211_softmac_scan_wq);
2799 INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
2800 INIT_WORK(&ieee->wx_sync_scan_wq,ieee80211_wx_sync_scan_wq);
2802 sema_init(&ieee->wx_sem, 1);
2803 sema_init(&ieee->scan_sem, 1);
2805 sema_init(&ieee->ips_sem,1);
2807 spin_lock_init(&ieee->mgmt_tx_lock);
2808 spin_lock_init(&ieee->beacon_lock);
2810 tasklet_init(&ieee->ps_task,
2811 (void(*)(unsigned long)) ieee80211_sta_ps,
2812 (unsigned long)ieee);
2816 void ieee80211_softmac_free(struct ieee80211_device *ieee)
2818 down(&ieee->wx_sem);
2819 #ifdef ENABLE_DOT11D
2820 kfree(ieee->pDot11dInfo);
2821 ieee->pDot11dInfo = NULL;
2823 del_timer_sync(&ieee->associate_timer);
2825 cancel_delayed_work(&ieee->associate_retry_wq);
2826 destroy_workqueue(ieee->wq);
2831 /********************************************************
2832 * Start of WPA code. *
2833 * this is stolen from the ipw2200 driver *
2834 ********************************************************/
2837 static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
2839 /* This is called when wpa_supplicant loads and closes the driver
2841 printk("%s WPA\n",value ? "enabling" : "disabling");
2842 ieee->wpa_enabled = value;
2847 void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len)
2849 /* make sure WPA is enabled */
2850 ieee80211_wpa_enable(ieee, 1);
2852 ieee80211_disassociate(ieee);
2856 static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
2862 case IEEE_MLME_STA_DEAUTH:
2866 case IEEE_MLME_STA_DISASSOC:
2867 ieee80211_disassociate(ieee);
2871 printk("Unknown MLME request: %d\n", command);
2879 static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
2880 struct ieee_param *param, int plen)
2884 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
2885 (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
2888 if (param->u.wpa_ie.len) {
2889 buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len,
2894 kfree(ieee->wpa_ie);
2896 ieee->wpa_ie_len = param->u.wpa_ie.len;
2898 kfree(ieee->wpa_ie);
2899 ieee->wpa_ie = NULL;
2900 ieee->wpa_ie_len = 0;
2903 ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
2907 #define AUTH_ALG_OPEN_SYSTEM 0x1
2908 #define AUTH_ALG_SHARED_KEY 0x2
2910 static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
2913 struct ieee80211_security sec = {
2914 .flags = SEC_AUTH_MODE,
2918 if (value & AUTH_ALG_SHARED_KEY) {
2919 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
2921 ieee->auth_mode = 1;
2922 } else if (value & AUTH_ALG_OPEN_SYSTEM){
2923 sec.auth_mode = WLAN_AUTH_OPEN;
2925 ieee->auth_mode = 0;
2927 else if (value & IW_AUTH_ALG_LEAP){
2928 sec.auth_mode = WLAN_AUTH_LEAP;
2930 ieee->auth_mode = 2;
2934 if (ieee->set_security)
2935 ieee->set_security(ieee, &sec);
2940 static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
2943 unsigned long flags;
2946 case IEEE_PARAM_WPA_ENABLED:
2947 ret = ieee80211_wpa_enable(ieee, value);
2950 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2951 ieee->tkip_countermeasures=value;
2954 case IEEE_PARAM_DROP_UNENCRYPTED: {
2957 * wpa_supplicant calls set_wpa_enabled when the driver
2958 * is loaded and unloaded, regardless of if WPA is being
2959 * used. No other calls are made which can be used to
2960 * determine if encryption will be used or not prior to
2961 * association being expected. If encryption is not being
2962 * used, drop_unencrypted is set to false, else true -- we
2963 * can use this to determine if the CAP_PRIVACY_ON bit should
2966 struct ieee80211_security sec = {
2967 .flags = SEC_ENABLED,
2970 ieee->drop_unencrypted = value;
2971 /* We only change SEC_LEVEL for open mode. Others
2972 * are set by ipw_wpa_set_encryption.
2975 sec.flags |= SEC_LEVEL;
2976 sec.level = SEC_LEVEL_0;
2979 sec.flags |= SEC_LEVEL;
2980 sec.level = SEC_LEVEL_1;
2982 if (ieee->set_security)
2983 ieee->set_security(ieee, &sec);
2987 case IEEE_PARAM_PRIVACY_INVOKED:
2988 ieee->privacy_invoked=value;
2991 case IEEE_PARAM_AUTH_ALGS:
2992 ret = ieee80211_wpa_set_auth_algs(ieee, value);
2995 case IEEE_PARAM_IEEE_802_1X:
2996 ieee->ieee802_1x=value;
2998 case IEEE_PARAM_WPAX_SELECT:
2999 // added for WPA2 mixed mode
3000 spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
3001 ieee->wpax_type_set = 1;
3002 ieee->wpax_type_notify = value;
3003 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
3007 printk("Unknown WPA param: %d\n",name);
3014 /* implementation borrowed from hostap driver */
3016 static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
3017 struct ieee_param *param, int param_len)
3021 struct ieee80211_crypto_ops *ops;
3022 struct ieee80211_crypt_data **crypt;
3024 struct ieee80211_security sec = {
3028 param->u.crypt.err = 0;
3029 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
3032 (int) ((char *) param->u.crypt.key - (char *) param) +
3033 param->u.crypt.key_len) {
3034 printk("Len mismatch %d, %d\n", param_len,
3035 param->u.crypt.key_len);
3038 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
3039 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
3040 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
3041 if (param->u.crypt.idx >= WEP_KEYS)
3043 crypt = &ieee->crypt[param->u.crypt.idx];
3048 if (strcmp(param->u.crypt.alg, "none") == 0) {
3053 sec.level = SEC_LEVEL_0;
3054 sec.flags |= SEC_ENABLED | SEC_LEVEL;
3055 ieee80211_crypt_delayed_deinit(ieee, crypt);
3062 sec.flags |= SEC_ENABLED;
3064 /* IPW HW cannot build TKIP MIC, host decryption still needed. */
3065 if (!(ieee->host_encrypt || ieee->host_decrypt) &&
3066 strcmp(param->u.crypt.alg, "TKIP"))
3067 goto skip_host_crypt;
3069 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3070 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0)
3071 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3072 /* set WEP40 first, it will be modified according to WEP104 or
3073 * WEP40 at other place */
3074 else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0)
3075 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3076 else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0)
3077 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3079 printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
3080 param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
3085 if (*crypt == NULL || (*crypt)->ops != ops) {
3086 struct ieee80211_crypt_data *new_crypt;
3088 ieee80211_crypt_delayed_deinit(ieee, crypt);
3090 new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL);
3091 if (new_crypt == NULL) {
3095 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
3096 new_crypt->ops = ops;
3099 new_crypt->ops->init(param->u.crypt.idx);
3101 if (new_crypt->priv == NULL) {
3103 param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
3111 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
3112 (*crypt)->ops->set_key(param->u.crypt.key,
3113 param->u.crypt.key_len, param->u.crypt.seq,
3114 (*crypt)->priv) < 0) {
3115 printk("key setting failed\n");
3116 param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
3122 if (param->u.crypt.set_tx) {
3123 ieee->tx_keyidx = param->u.crypt.idx;
3124 sec.active_key = param->u.crypt.idx;
3125 sec.flags |= SEC_ACTIVE_KEY;
3127 sec.flags &= ~SEC_ACTIVE_KEY;
3129 if (param->u.crypt.alg != NULL) {
3130 memcpy(sec.keys[param->u.crypt.idx],
3132 param->u.crypt.key_len);
3133 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
3134 sec.flags |= (1 << param->u.crypt.idx);
3136 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3137 sec.flags |= SEC_LEVEL;
3138 sec.level = SEC_LEVEL_1;
3139 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3140 sec.flags |= SEC_LEVEL;
3141 sec.level = SEC_LEVEL_2;
3142 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3143 sec.flags |= SEC_LEVEL;
3144 sec.level = SEC_LEVEL_3;
3148 if (ieee->set_security)
3149 ieee->set_security(ieee, &sec);
3151 /* Do not reset port if card is in Managed mode since resetting will
3152 * generate new IEEE 802.11 authentication which may end up in looping
3153 * with IEEE 802.1X. If your hardware requires a reset after WEP
3154 * configuration (for example... Prism2), implement the reset_port in
3155 * the callbacks structures used to initialize the 802.11 stack. */
3156 if (ieee->reset_on_keychange &&
3157 ieee->iw_mode != IW_MODE_INFRA &&
3159 ieee->reset_port(ieee)) {
3160 printk("reset_port failed\n");
3161 param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
3168 inline struct sk_buff *ieee80211_disassociate_skb(
3169 struct ieee80211_network *beacon,
3170 struct ieee80211_device *ieee,
3173 struct sk_buff *skb;
3174 struct ieee80211_disassoc *disass;
3176 skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc));
3180 disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc));
3181 disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
3182 disass->header.duration_id = 0;
3184 memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
3185 memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
3186 memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
3188 disass->reason = asRsn;
3195 struct ieee80211_device *ieee,
3200 struct ieee80211_network *beacon = &ieee->current_network;
3201 struct sk_buff *skb;
3202 skb = ieee80211_disassociate_skb(beacon,ieee,asRsn);
3204 softmac_mgmt_xmit(skb, ieee);
3205 //dev_kfree_skb_any(skb);//edit by thomas
3209 int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
3211 struct ieee_param *param;
3214 down(&ieee->wx_sem);
3215 //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
3217 if (p->length < sizeof(struct ieee_param) || !p->pointer){
3222 param = kmalloc(p->length, GFP_KERNEL);
3227 if (copy_from_user(param, p->pointer, p->length)) {
3233 switch (param->cmd) {
3235 case IEEE_CMD_SET_WPA_PARAM:
3236 ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
3237 param->u.wpa_param.value);
3240 case IEEE_CMD_SET_WPA_IE:
3241 ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
3244 case IEEE_CMD_SET_ENCRYPTION:
3245 ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
3249 ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
3250 param->u.mlme.reason_code);
3254 printk("Unknown WPA supplicant request: %d\n",param->cmd);
3259 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
3269 void notify_wx_assoc_event(struct ieee80211_device *ieee)
3271 union iwreq_data wrqu;
3272 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3273 if (ieee->state == IEEE80211_LINKED)
3274 memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
3276 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
3277 wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);