1 /* IEEE 802.11 SoftMAC layer
2 * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
4 * Mostly extracted from the rtl8180-sa2400 driver for the
5 * in-kernel generic ieee802.11 stack.
7 * Few lines might be stolen from other part of the ieee80211
8 * stack. Copyright who own it's copyright
10 * WPA code stolen from the ipw2200 driver.
11 * Copyright who own it's copyright.
13 * released under the GPL
17 #include "ieee80211.h"
19 #include <linux/random.h>
20 #include <linux/delay.h>
21 #include <linux/slab.h>
22 #include <linux/uaccess.h>
23 #include <linux/etherdevice.h>
27 short ieee80211_is_54g(const struct ieee80211_network
*net
)
29 return (net
->rates_ex_len
> 0) || (net
->rates_len
> 4);
31 EXPORT_SYMBOL(ieee80211_is_54g
);
33 short ieee80211_is_shortslot(const struct ieee80211_network
*net
)
35 return net
->capability
& WLAN_CAPABILITY_SHORT_SLOT
;
37 EXPORT_SYMBOL(ieee80211_is_shortslot
);
39 /* returns the total length needed for pleacing the RATE MFIE
40 * tag and the EXTENDED RATE MFIE tag if needed.
41 * It encludes two bytes per tag for the tag itself and its len
43 static unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device
*ieee
)
45 unsigned int rate_len
= 0;
47 if (ieee
->modulation
& IEEE80211_CCK_MODULATION
)
48 rate_len
= IEEE80211_CCK_RATE_LEN
+ 2;
50 if (ieee
->modulation
& IEEE80211_OFDM_MODULATION
)
52 rate_len
+= IEEE80211_OFDM_RATE_LEN
+ 2;
57 /* pleace the MFIE rate, tag to the memory (double) poined.
58 * Then it updates the pointer so that
59 * it points after the new MFIE tag added.
61 static void ieee80211_MFIE_Brate(struct ieee80211_device
*ieee
, u8
**tag_p
)
65 if (ieee
->modulation
& IEEE80211_CCK_MODULATION
) {
66 *tag
++ = MFIE_TYPE_RATES
;
68 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_1MB
;
69 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_2MB
;
70 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_5MB
;
71 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_11MB
;
74 /* We may add an option for custom rates that specific HW might support */
78 static void ieee80211_MFIE_Grate(struct ieee80211_device
*ieee
, u8
**tag_p
)
82 if (ieee
->modulation
& IEEE80211_OFDM_MODULATION
) {
84 *tag
++ = MFIE_TYPE_RATES_EX
;
86 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_6MB
;
87 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_9MB
;
88 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_12MB
;
89 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_18MB
;
90 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_24MB
;
91 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_36MB
;
92 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_48MB
;
93 *tag
++ = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_54MB
;
97 /* We may add an option for custom rates that specific HW might support */
102 static void ieee80211_WMM_Info(struct ieee80211_device
*ieee
, u8
**tag_p
)
106 *tag
++ = MFIE_TYPE_GENERIC
; /* 0 */
111 *tag
++ = 0x02; /* 5 */
115 if(ieee
->current_network
.wmm_info
& 0x80) {
116 *tag
++ = 0x0f|MAX_SP_Len
;
127 static void ieee80211_TURBO_Info(struct ieee80211_device
*ieee
, u8
**tag_p
)
131 *tag
++ = MFIE_TYPE_GENERIC
; /* 0 */
136 *tag
++ = 0x01; /* 5 */
142 printk(KERN_ALERT
"This is enable turbo mode IE process\n");
146 static void enqueue_mgmt(struct ieee80211_device
*ieee
, struct sk_buff
*skb
)
149 nh
= (ieee
->mgmt_queue_head
+1) % MGMT_QUEUE_NUM
;
152 * if the queue is full but we have newer frames then
153 * just overwrites the oldest.
155 * if (nh == ieee->mgmt_queue_tail)
158 ieee
->mgmt_queue_head
= nh
;
159 ieee
->mgmt_queue_ring
[nh
] = skb
;
164 static struct sk_buff
*dequeue_mgmt(struct ieee80211_device
*ieee
)
168 if(ieee
->mgmt_queue_tail
== ieee
->mgmt_queue_head
)
171 ret
= ieee
->mgmt_queue_ring
[ieee
->mgmt_queue_tail
];
173 ieee
->mgmt_queue_tail
=
174 (ieee
->mgmt_queue_tail
+1) % MGMT_QUEUE_NUM
;
179 static void init_mgmt_queue(struct ieee80211_device
*ieee
)
181 ieee
->mgmt_queue_tail
= ieee
->mgmt_queue_head
= 0;
184 static u8
MgntQuery_MgntFrameTxRate(struct ieee80211_device
*ieee
)
186 PRT_HIGH_THROUGHPUT pHTInfo
= ieee
->pHTInfo
;
189 /* 2008/01/25 MH For broadcom, MGNT frame set as OFDM 6M. */
190 if(pHTInfo
->IOTAction
& HT_IOT_ACT_MGNT_USE_CCK_6M
)
193 rate
= ieee
->basic_rate
& 0x7f;
196 /* 2005.01.26, by rcnjko. */
197 if(ieee
->mode
== IEEE_A
||
198 ieee
->mode
== IEEE_N_5G
||
199 (ieee
->mode
== IEEE_N_24G
&&!pHTInfo
->bCurSuppCCK
))
206 // Data rate of ProbeReq is already decided. Annie, 2005-03-31
207 if( pMgntInfo->bScanInProgress || (pMgntInfo->bDualModeScanStep!=0) )
209 if(pMgntInfo->dot11CurrentWirelessMode==WIRELESS_MODE_A)
219 void ieee80211_sta_wakeup(struct ieee80211_device
*ieee
, short nl
);
221 inline void softmac_mgmt_xmit(struct sk_buff
*skb
, struct ieee80211_device
*ieee
)
224 short single
= ieee
->softmac_features
& IEEE_SOFTMAC_SINGLE_QUEUE
;
225 struct rtl_80211_hdr_3addr
*header
=
226 (struct rtl_80211_hdr_3addr
*) skb
->data
;
228 cb_desc
*tcb_desc
= (cb_desc
*)(skb
->cb
+ 8);
229 spin_lock_irqsave(&ieee
->lock
, flags
);
231 /* called with 2nd param 0, no mgmt lock required */
232 ieee80211_sta_wakeup(ieee
, 0);
234 tcb_desc
->queue_index
= MGNT_QUEUE
;
235 tcb_desc
->data_rate
= MgntQuery_MgntFrameTxRate(ieee
);
236 tcb_desc
->RATRIndex
= 7;
237 tcb_desc
->bTxDisableRateFallBack
= 1;
238 tcb_desc
->bTxUseDriverAssingedRate
= 1;
241 if(ieee
->queue_stop
){
242 enqueue_mgmt(ieee
, skb
);
244 header
->seq_ctl
= cpu_to_le16(ieee
->seq_ctrl
[0]<<4);
246 if (ieee
->seq_ctrl
[0] == 0xFFF)
247 ieee
->seq_ctrl
[0] = 0;
251 /* avoid watchdog triggers */
252 netif_trans_update(ieee
->dev
);
253 ieee
->softmac_data_hard_start_xmit(skb
,ieee
->dev
,ieee
->basic_rate
);
254 //dev_kfree_skb_any(skb);//edit by thomas
257 spin_unlock_irqrestore(&ieee
->lock
, flags
);
259 spin_unlock_irqrestore(&ieee
->lock
, flags
);
260 spin_lock_irqsave(&ieee
->mgmt_tx_lock
, flags
);
262 header
->seq_ctl
= cpu_to_le16(ieee
->seq_ctrl
[0] << 4);
264 if (ieee
->seq_ctrl
[0] == 0xFFF)
265 ieee
->seq_ctrl
[0] = 0;
269 /* check whether the managed packet queued greater than 5 */
270 if(!ieee
->check_nic_enough_desc(ieee
->dev
,tcb_desc
->queue_index
)||\
271 (skb_queue_len(&ieee
->skb_waitQ
[tcb_desc
->queue_index
]) != 0)||\
272 (ieee
->queue_stop
) ) {
273 /* insert the skb packet to the management queue */
274 /* as for the completion function, it does not need
275 * to check it any more.
277 printk("%s():insert to waitqueue!\n",__func__
);
278 skb_queue_tail(&ieee
->skb_waitQ
[tcb_desc
->queue_index
], skb
);
280 ieee
->softmac_hard_start_xmit(skb
, ieee
->dev
);
281 //dev_kfree_skb_any(skb);//edit by thomas
283 spin_unlock_irqrestore(&ieee
->mgmt_tx_lock
, flags
);
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 netif_trans_update(ieee
->dev
);
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 eth_broadcast_addr(req
->header
.addr1
);
346 memcpy(req
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
347 eth_broadcast_addr(req
->header
.addr3
);
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
,
384 jiffies
+ msecs_to_jiffies(ieee
->current_network
.beacon_interval
-5));
386 //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
390 static void ieee80211_send_beacon_cb(unsigned long _ieee
)
392 struct ieee80211_device
*ieee
=
393 (struct ieee80211_device
*) _ieee
;
396 spin_lock_irqsave(&ieee
->beacon_lock
, flags
);
397 ieee80211_send_beacon(ieee
);
398 spin_unlock_irqrestore(&ieee
->beacon_lock
, flags
);
402 static void ieee80211_send_probe(struct ieee80211_device
*ieee
)
406 skb
= ieee80211_probe_req(ieee
);
408 softmac_mgmt_xmit(skb
, ieee
);
409 ieee
->softmac_stats
.tx_probe_rq
++;
410 //dev_kfree_skb_any(skb);//edit by thomas
414 static void ieee80211_send_probe_requests(struct ieee80211_device
*ieee
)
416 if (ieee
->active_scan
&& (ieee
->softmac_features
& IEEE_SOFTMAC_PROBERQ
)) {
417 ieee80211_send_probe(ieee
);
418 ieee80211_send_probe(ieee
);
422 /* this performs syncro scan blocking the caller until all channels
423 * in the allowed channel map has been checked.
425 void ieee80211_softmac_scan_syncro(struct ieee80211_device
*ieee
)
428 u8 channel_map
[MAX_CHANNEL_NUMBER
+1];
429 memcpy(channel_map
, GET_DOT11D_INFO(ieee
)->channel_map
, MAX_CHANNEL_NUMBER
+1);
430 down(&ieee
->scan_sem
);
437 if (ch
> MAX_CHANNEL_NUMBER
)
438 goto out
; /* scan completed */
439 }while(!channel_map
[ch
]);
441 /* this function can be called in two situations
442 * 1- We have switched to ad-hoc mode and we are
443 * performing a complete syncro scan before conclude
444 * there are no interesting cell and to create a
445 * new one. In this case the link state is
446 * IEEE80211_NOLINK until we found an interesting cell.
447 * If so the ieee8021_new_net, called by the RX path
448 * will set the state to IEEE80211_LINKED, so we stop
450 * 2- We are linked and the root uses run iwlist scan.
451 * So we switch to IEEE80211_LINKED_SCANNING to remember
452 * that we are still logically linked (not interested in
453 * new network events, despite for updating the net list,
454 * but we are temporarly 'unlinked' as the driver shall
455 * not filter RX frames and the channel is changing.
456 * So the only situation in witch are interested is to check
457 * if the state become LINKED because of the #1 situation
460 if (ieee
->state
== IEEE80211_LINKED
)
462 ieee
->set_chan(ieee
->dev
, ch
);
463 if(channel_map
[ch
] == 1)
464 ieee80211_send_probe_requests(ieee
);
466 /* this prevent excessive time wait when we
467 * need to wait for a syncro scan to end..
469 if (ieee
->state
>= IEEE80211_LINKED
&& ieee
->sync_scan_hurryup
)
472 msleep_interruptible(IEEE80211_SOFTMAC_SCAN_TIME
);
476 if(ieee
->state
< IEEE80211_LINKED
){
477 ieee
->actscanning
= false;
481 ieee
->sync_scan_hurryup
= 0;
482 if(IS_DOT11D_ENABLE(ieee
))
483 DOT11D_ScanComplete(ieee
);
487 EXPORT_SYMBOL(ieee80211_softmac_scan_syncro
);
489 static void ieee80211_softmac_scan_wq(struct work_struct
*work
)
491 struct delayed_work
*dwork
= to_delayed_work(work
);
492 struct ieee80211_device
*ieee
= container_of(dwork
, struct ieee80211_device
, softmac_scan_wq
);
493 static short watchdog
;
494 u8 channel_map
[MAX_CHANNEL_NUMBER
+1];
495 memcpy(channel_map
, GET_DOT11D_INFO(ieee
)->channel_map
, MAX_CHANNEL_NUMBER
+1);
498 down(&ieee
->scan_sem
);
500 ieee
->current_network
.channel
=
501 (ieee
->current_network
.channel
+ 1) % MAX_CHANNEL_NUMBER
;
502 if (watchdog
++ > MAX_CHANNEL_NUMBER
)
504 //if current channel is not in channel map, set to default channel.
505 if (!channel_map
[ieee
->current_network
.channel
]) {
506 ieee
->current_network
.channel
= 6;
507 goto out
; /* no good chans */
510 }while(!channel_map
[ieee
->current_network
.channel
]);
511 if (ieee
->scanning
== 0 )
513 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
514 if(channel_map
[ieee
->current_network
.channel
] == 1)
515 ieee80211_send_probe_requests(ieee
);
518 schedule_delayed_work(&ieee
->softmac_scan_wq
, IEEE80211_SOFTMAC_SCAN_TIME
);
523 if(IS_DOT11D_ENABLE(ieee
))
524 DOT11D_ScanComplete(ieee
);
525 ieee
->actscanning
= false;
533 static void ieee80211_beacons_start(struct ieee80211_device
*ieee
)
536 spin_lock_irqsave(&ieee
->beacon_lock
,flags
);
538 ieee
->beacon_txing
= 1;
539 ieee80211_send_beacon(ieee
);
541 spin_unlock_irqrestore(&ieee
->beacon_lock
, flags
);
544 static void ieee80211_beacons_stop(struct ieee80211_device
*ieee
)
548 spin_lock_irqsave(&ieee
->beacon_lock
, flags
);
550 ieee
->beacon_txing
= 0;
551 del_timer_sync(&ieee
->beacon_timer
);
553 spin_unlock_irqrestore(&ieee
->beacon_lock
, flags
);
558 void ieee80211_stop_send_beacons(struct ieee80211_device
*ieee
)
560 if(ieee
->stop_send_beacons
)
561 ieee
->stop_send_beacons(ieee
->dev
);
562 if (ieee
->softmac_features
& IEEE_SOFTMAC_BEACONS
)
563 ieee80211_beacons_stop(ieee
);
565 EXPORT_SYMBOL(ieee80211_stop_send_beacons
);
567 void ieee80211_start_send_beacons(struct ieee80211_device
*ieee
)
569 if(ieee
->start_send_beacons
)
570 ieee
->start_send_beacons(ieee
->dev
, ieee
->basic_rate
);
571 if(ieee
->softmac_features
& IEEE_SOFTMAC_BEACONS
)
572 ieee80211_beacons_start(ieee
);
574 EXPORT_SYMBOL(ieee80211_start_send_beacons
);
576 static void ieee80211_softmac_stop_scan(struct ieee80211_device
*ieee
)
578 // unsigned long flags;
580 //ieee->sync_scan_hurryup = 1;
582 down(&ieee
->scan_sem
);
583 // spin_lock_irqsave(&ieee->lock, flags);
585 if (ieee
->scanning
== 1) {
588 cancel_delayed_work(&ieee
->softmac_scan_wq
);
591 // spin_unlock_irqrestore(&ieee->lock, flags);
595 void ieee80211_stop_scan(struct ieee80211_device
*ieee
)
597 if (ieee
->softmac_features
& IEEE_SOFTMAC_SCAN
)
598 ieee80211_softmac_stop_scan(ieee
);
600 ieee
->stop_scan(ieee
->dev
);
602 EXPORT_SYMBOL(ieee80211_stop_scan
);
604 /* called with ieee->lock held */
605 static void ieee80211_start_scan(struct ieee80211_device
*ieee
)
607 if (IS_DOT11D_ENABLE(ieee
) )
609 if (IS_COUNTRY_IE_VALID(ieee
))
611 RESET_CIE_WATCHDOG(ieee
);
614 if (ieee
->softmac_features
& IEEE_SOFTMAC_SCAN
){
615 if (ieee
->scanning
== 0) {
617 schedule_delayed_work(&ieee
->softmac_scan_wq
, 0);
620 ieee
->start_scan(ieee
->dev
);
624 /* called with wx_sem held */
625 void ieee80211_start_scan_syncro(struct ieee80211_device
*ieee
)
627 if (IS_DOT11D_ENABLE(ieee
) )
629 if (IS_COUNTRY_IE_VALID(ieee
))
631 RESET_CIE_WATCHDOG(ieee
);
634 ieee
->sync_scan_hurryup
= 0;
635 if (ieee
->softmac_features
& IEEE_SOFTMAC_SCAN
)
636 ieee80211_softmac_scan_syncro(ieee
);
638 ieee
->scan_syncro(ieee
->dev
);
641 EXPORT_SYMBOL(ieee80211_start_scan_syncro
);
643 inline struct sk_buff
*ieee80211_authentication_req(struct ieee80211_network
*beacon
,
644 struct ieee80211_device
*ieee
, int challengelen
)
647 struct ieee80211_authentication
*auth
;
648 int len
= sizeof(struct ieee80211_authentication
) + challengelen
+ ieee
->tx_headroom
;
651 skb
= dev_alloc_skb(len
);
652 if (!skb
) return NULL
;
654 skb_reserve(skb
, ieee
->tx_headroom
);
655 auth
= (struct ieee80211_authentication
*)
656 skb_put(skb
, sizeof(struct ieee80211_authentication
));
659 auth
->header
.frame_ctl
= cpu_to_le16(IEEE80211_STYPE_AUTH
660 | IEEE80211_FCTL_WEP
);
662 auth
->header
.frame_ctl
= cpu_to_le16(IEEE80211_STYPE_AUTH
);
664 auth
->header
.duration_id
= cpu_to_le16(0x013a);
666 memcpy(auth
->header
.addr1
, beacon
->bssid
, ETH_ALEN
);
667 memcpy(auth
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
668 memcpy(auth
->header
.addr3
, beacon
->bssid
, ETH_ALEN
);
670 //auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
671 if(ieee
->auth_mode
== 0)
672 auth
->algorithm
= WLAN_AUTH_OPEN
;
673 else if(ieee
->auth_mode
== 1)
674 auth
->algorithm
= cpu_to_le16(WLAN_AUTH_SHARED_KEY
);
675 else if(ieee
->auth_mode
== 2)
676 auth
->algorithm
= WLAN_AUTH_OPEN
; /* 0x80; */
677 printk("=================>%s():auth->algorithm is %d\n",__func__
,auth
->algorithm
);
678 auth
->transaction
= cpu_to_le16(ieee
->associate_seq
);
679 ieee
->associate_seq
++;
681 auth
->status
= cpu_to_le16(WLAN_STATUS_SUCCESS
);
688 static struct sk_buff
*ieee80211_probe_resp(struct ieee80211_device
*ieee
, u8
*dest
)
692 struct ieee80211_probe_response
*beacon_buf
;
693 struct sk_buff
*skb
= NULL
;
695 int atim_len
, erp_len
;
696 struct ieee80211_crypt_data
*crypt
;
698 char *ssid
= ieee
->current_network
.ssid
;
699 int ssid_len
= ieee
->current_network
.ssid_len
;
700 int rate_len
= ieee
->current_network
.rates_len
+2;
701 int rate_ex_len
= ieee
->current_network
.rates_ex_len
;
702 int wpa_ie_len
= ieee
->wpa_ie_len
;
703 u8 erpinfo_content
= 0;
708 u8 tmp_ht_info_len
=0;
709 PRT_HIGH_THROUGHPUT pHTInfo
= ieee
->pHTInfo
;
710 u8
*tmp_generic_ie_buf
=NULL
;
711 u8 tmp_generic_ie_len
=0;
713 if(rate_ex_len
> 0) rate_ex_len
+=2;
715 if(ieee
->current_network
.capability
& WLAN_CAPABILITY_IBSS
)
720 if(ieee80211_is_54g(&ieee
->current_network
))
726 crypt
= ieee
->crypt
[ieee
->tx_keyidx
];
729 encrypt
= ieee
->host_encrypt
&& crypt
&& crypt
->ops
&&
730 ((0 == strcmp(crypt
->ops
->name
, "WEP") || wpa_ie_len
));
731 /* HT ralated element */
732 tmp_ht_cap_buf
=(u8
*) &(ieee
->pHTInfo
->SelfHTCap
);
733 tmp_ht_cap_len
= sizeof(ieee
->pHTInfo
->SelfHTCap
);
734 tmp_ht_info_buf
=(u8
*) &(ieee
->pHTInfo
->SelfHTInfo
);
735 tmp_ht_info_len
= sizeof(ieee
->pHTInfo
->SelfHTInfo
);
736 HTConstructCapabilityElement(ieee
, tmp_ht_cap_buf
, &tmp_ht_cap_len
,encrypt
);
737 HTConstructInfoElement(ieee
,tmp_ht_info_buf
,&tmp_ht_info_len
, encrypt
);
740 if (pHTInfo
->bRegRT2RTAggregation
)
742 tmp_generic_ie_buf
= ieee
->pHTInfo
->szRT2RTAggBuffer
;
743 tmp_generic_ie_len
= sizeof(ieee
->pHTInfo
->szRT2RTAggBuffer
);
744 HTConstructRT2RTAggElement(ieee
, tmp_generic_ie_buf
, &tmp_generic_ie_len
);
746 // 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);
747 beacon_size
= sizeof(struct ieee80211_probe_response
)+2+
757 // +tmp_generic_ie_len
760 skb
= dev_alloc_skb(beacon_size
);
763 skb_reserve(skb
, ieee
->tx_headroom
);
764 beacon_buf
= (struct ieee80211_probe_response
*) skb_put(skb
, (beacon_size
- ieee
->tx_headroom
));
765 memcpy (beacon_buf
->header
.addr1
, dest
,ETH_ALEN
);
766 memcpy (beacon_buf
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
767 memcpy (beacon_buf
->header
.addr3
, ieee
->current_network
.bssid
, ETH_ALEN
);
769 beacon_buf
->header
.duration_id
= 0; /* FIXME */
770 beacon_buf
->beacon_interval
=
771 cpu_to_le16(ieee
->current_network
.beacon_interval
);
772 beacon_buf
->capability
=
773 cpu_to_le16(ieee
->current_network
.capability
& WLAN_CAPABILITY_IBSS
);
774 beacon_buf
->capability
|=
775 cpu_to_le16(ieee
->current_network
.capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
); /* add short preamble here */
777 if(ieee
->short_slot
&& (ieee
->current_network
.capability
& WLAN_CAPABILITY_SHORT_SLOT
))
778 beacon_buf
->capability
|= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT
);
780 crypt
= ieee
->crypt
[ieee
->tx_keyidx
];
782 beacon_buf
->capability
|= cpu_to_le16(WLAN_CAPABILITY_PRIVACY
);
785 beacon_buf
->header
.frame_ctl
= cpu_to_le16(IEEE80211_STYPE_PROBE_RESP
);
786 beacon_buf
->info_element
[0].id
= MFIE_TYPE_SSID
;
787 beacon_buf
->info_element
[0].len
= ssid_len
;
789 tag
= (u8
*) beacon_buf
->info_element
[0].data
;
791 memcpy(tag
, ssid
, ssid_len
);
795 *(tag
++) = MFIE_TYPE_RATES
;
796 *(tag
++) = rate_len
-2;
797 memcpy(tag
, ieee
->current_network
.rates
, rate_len
-2);
800 *(tag
++) = MFIE_TYPE_DS_SET
;
802 *(tag
++) = ieee
->current_network
.channel
;
805 *(tag
++) = MFIE_TYPE_IBSS_SET
;
808 put_unaligned_le16(ieee
->current_network
.atim_window
,
814 *(tag
++) = MFIE_TYPE_ERP
;
816 *(tag
++) = erpinfo_content
;
819 *(tag
++) = MFIE_TYPE_RATES_EX
;
820 *(tag
++) = rate_ex_len
-2;
821 memcpy(tag
, ieee
->current_network
.rates_ex
, rate_ex_len
-2);
827 if (ieee
->iw_mode
== IW_MODE_ADHOC
)
828 {//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
829 memcpy(&ieee
->wpa_ie
[14], &ieee
->wpa_ie
[8], 4);
831 memcpy(tag
, ieee
->wpa_ie
, ieee
->wpa_ie_len
);
835 //skb->dev = ieee->dev;
840 static struct sk_buff
*ieee80211_assoc_resp(struct ieee80211_device
*ieee
,
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 static struct sk_buff
*ieee80211_auth_resp(struct ieee80211_device
*ieee
,
897 int status
, u8
*dest
)
900 struct ieee80211_authentication
*auth
;
901 int len
= ieee
->tx_headroom
+ sizeof(struct ieee80211_authentication
)+1;
903 skb
= dev_alloc_skb(len
);
908 skb
->len
= sizeof(struct ieee80211_authentication
);
910 auth
= (struct ieee80211_authentication
*)skb
->data
;
912 auth
->status
= cpu_to_le16(status
);
913 auth
->transaction
= cpu_to_le16(2);
914 auth
->algorithm
= cpu_to_le16(WLAN_AUTH_OPEN
);
916 memcpy(auth
->header
.addr3
, ieee
->dev
->dev_addr
, ETH_ALEN
);
917 memcpy(auth
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
918 memcpy(auth
->header
.addr1
, dest
, ETH_ALEN
);
919 auth
->header
.frame_ctl
= cpu_to_le16(IEEE80211_STYPE_AUTH
);
925 static struct sk_buff
*ieee80211_null_func(struct ieee80211_device
*ieee
,
929 struct rtl_80211_hdr_3addr
*hdr
;
931 skb
= dev_alloc_skb(sizeof(struct rtl_80211_hdr_3addr
));
936 hdr
= (struct rtl_80211_hdr_3addr
*)skb_put(skb
,sizeof(struct rtl_80211_hdr_3addr
));
938 memcpy(hdr
->addr1
, ieee
->current_network
.bssid
, ETH_ALEN
);
939 memcpy(hdr
->addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
940 memcpy(hdr
->addr3
, ieee
->current_network
.bssid
, ETH_ALEN
);
942 hdr
->frame_ctl
= cpu_to_le16(IEEE80211_FTYPE_DATA
|
943 IEEE80211_STYPE_NULLFUNC
| IEEE80211_FCTL_TODS
|
944 (pwr
? IEEE80211_FCTL_PM
:0));
952 static void ieee80211_resp_to_assoc_rq(struct ieee80211_device
*ieee
, u8
*dest
)
954 struct sk_buff
*buf
= ieee80211_assoc_resp(ieee
, dest
);
957 softmac_mgmt_xmit(buf
, ieee
);
961 static void ieee80211_resp_to_auth(struct ieee80211_device
*ieee
, int s
,
964 struct sk_buff
*buf
= ieee80211_auth_resp(ieee
, s
, dest
);
967 softmac_mgmt_xmit(buf
, ieee
);
971 static void ieee80211_resp_to_probe(struct ieee80211_device
*ieee
, u8
*dest
)
975 struct sk_buff
*buf
= ieee80211_probe_resp(ieee
, dest
);
977 softmac_mgmt_xmit(buf
, ieee
);
981 inline struct sk_buff
*ieee80211_association_req(struct ieee80211_network
*beacon
,struct ieee80211_device
*ieee
)
984 //unsigned long flags;
986 struct ieee80211_assoc_request_frame
*hdr
;
988 //short info_addr = 0;
990 //u16 suite_count = 0;
991 //u8 suit_select = 0;
992 //unsigned int wpa_len = beacon->wpa_ie_len;
994 u8
*ht_cap_buf
= NULL
;
996 u8
*realtek_ie_buf
=NULL
;
998 int wpa_ie_len
= ieee
->wpa_ie_len
;
999 unsigned int ckip_ie_len
=0;
1000 unsigned int ccxrm_ie_len
=0;
1001 unsigned int cxvernum_ie_len
=0;
1002 struct ieee80211_crypt_data
*crypt
;
1005 unsigned int rate_len
= ieee80211_MFIE_rate_len(ieee
);
1006 unsigned int wmm_info_len
= beacon
->qos_data
.supported
?9:0;
1008 unsigned int turbo_info_len
= beacon
->Turbo_Enable
?9:0;
1013 crypt
= ieee
->crypt
[ieee
->tx_keyidx
];
1014 encrypt
= ieee
->host_encrypt
&& crypt
&& crypt
->ops
&& ((0 == strcmp(crypt
->ops
->name
,"WEP") || wpa_ie_len
));
1016 /* Include High Throuput capability && Realtek proprietary */
1017 if (ieee
->pHTInfo
->bCurrentHTSupport
&&ieee
->pHTInfo
->bEnableHT
)
1019 ht_cap_buf
= (u8
*)&(ieee
->pHTInfo
->SelfHTCap
);
1020 ht_cap_len
= sizeof(ieee
->pHTInfo
->SelfHTCap
);
1021 HTConstructCapabilityElement(ieee
, ht_cap_buf
, &ht_cap_len
, encrypt
);
1022 if (ieee
->pHTInfo
->bCurrentRT2RTAggregation
)
1024 realtek_ie_buf
= ieee
->pHTInfo
->szRT2RTAggBuffer
;
1025 realtek_ie_len
= sizeof( ieee
->pHTInfo
->szRT2RTAggBuffer
);
1026 HTConstructRT2RTAggElement(ieee
, realtek_ie_buf
, &realtek_ie_len
);
1030 if (ieee
->qos_support
) {
1031 wmm_info_len
= beacon
->qos_data
.supported
?9:0;
1035 if (beacon
->bCkipSupported
)
1039 if (beacon
->bCcxRmEnable
)
1043 if (beacon
->BssCcxVerNumber
>= 2)
1044 cxvernum_ie_len
= 5+2;
1047 len
= sizeof(struct ieee80211_assoc_request_frame
)+ 2
1048 + beacon
->ssid_len
/* essid tagged val */
1049 + rate_len
/* rates tagged val */
1058 + ieee
->tx_headroom
;
1060 len
= sizeof(struct ieee80211_assoc_request_frame
)+ 2
1061 + beacon
->ssid_len
/* essid tagged val */
1062 + rate_len
/* rates tagged val */
1070 + ieee
->tx_headroom
;
1073 skb
= dev_alloc_skb(len
);
1078 skb_reserve(skb
, ieee
->tx_headroom
);
1080 hdr
= (struct ieee80211_assoc_request_frame
*)
1081 skb_put(skb
, sizeof(struct ieee80211_assoc_request_frame
)+2);
1084 hdr
->header
.frame_ctl
= IEEE80211_STYPE_ASSOC_REQ
;
1085 hdr
->header
.duration_id
= cpu_to_le16(37);
1086 memcpy(hdr
->header
.addr1
, beacon
->bssid
, ETH_ALEN
);
1087 memcpy(hdr
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
1088 memcpy(hdr
->header
.addr3
, beacon
->bssid
, ETH_ALEN
);
1090 memcpy(ieee
->ap_mac_addr
, beacon
->bssid
, ETH_ALEN
);//for HW security, John
1092 hdr
->capability
= cpu_to_le16(WLAN_CAPABILITY_BSS
);
1093 if (beacon
->capability
& WLAN_CAPABILITY_PRIVACY
)
1094 hdr
->capability
|= cpu_to_le16(WLAN_CAPABILITY_PRIVACY
);
1096 if (beacon
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
1097 hdr
->capability
|= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE
); //add short_preamble here
1099 if(ieee
->short_slot
)
1100 hdr
->capability
|= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT
);
1101 if (wmm_info_len
) //QOS
1102 hdr
->capability
|= cpu_to_le16(WLAN_CAPABILITY_QOS
);
1104 hdr
->listen_interval
= cpu_to_le16(0xa);
1106 hdr
->info_element
[0].id
= MFIE_TYPE_SSID
;
1108 hdr
->info_element
[0].len
= beacon
->ssid_len
;
1109 tag
= skb_put(skb
, beacon
->ssid_len
);
1110 memcpy(tag
, beacon
->ssid
, beacon
->ssid_len
);
1112 tag
= skb_put(skb
, rate_len
);
1114 ieee80211_MFIE_Brate(ieee
, &tag
);
1115 ieee80211_MFIE_Grate(ieee
, &tag
);
1116 // For CCX 1 S13, CKIP. Added by Annie, 2006-08-14.
1117 if (beacon
->bCkipSupported
) {
1118 static u8 AironetIeOui
[] = {0x00, 0x01, 0x66}; // "4500-client"
1119 u8 CcxAironetBuf
[30];
1120 OCTET_STRING osCcxAironetIE
;
1122 memset(CcxAironetBuf
, 0, 30);
1123 osCcxAironetIE
.Octet
= CcxAironetBuf
;
1124 osCcxAironetIE
.Length
= sizeof(CcxAironetBuf
);
1126 // Ref. CCX test plan v3.61, 3.2.3.1 step 13.
1127 // We want to make the device type as "4500-client". 060926, by CCW.
1129 memcpy(osCcxAironetIE
.Octet
, AironetIeOui
, sizeof(AironetIeOui
));
1131 // CCX1 spec V1.13, A01.1 CKIP Negotiation (page23):
1132 // "The CKIP negotiation is started with the associate request from the client to the access point,
1133 // containing an Aironet element with both the MIC and KP bits set."
1134 osCcxAironetIE
.Octet
[IE_CISCO_FLAG_POSITION
] |= (SUPPORT_CKIP_PK
|SUPPORT_CKIP_MIC
) ;
1135 tag
= skb_put(skb
, ckip_ie_len
);
1136 *tag
++ = MFIE_TYPE_AIRONET
;
1137 *tag
++ = osCcxAironetIE
.Length
;
1138 memcpy(tag
, osCcxAironetIE
.Octet
, osCcxAironetIE
.Length
);
1139 tag
+= osCcxAironetIE
.Length
;
1142 if (beacon
->bCcxRmEnable
)
1144 static u8 CcxRmCapBuf
[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
1145 OCTET_STRING osCcxRmCap
;
1147 osCcxRmCap
.Octet
= CcxRmCapBuf
;
1148 osCcxRmCap
.Length
= sizeof(CcxRmCapBuf
);
1149 tag
= skb_put(skb
, ccxrm_ie_len
);
1150 *tag
++ = MFIE_TYPE_GENERIC
;
1151 *tag
++ = osCcxRmCap
.Length
;
1152 memcpy(tag
, osCcxRmCap
.Octet
, osCcxRmCap
.Length
);
1153 tag
+= osCcxRmCap
.Length
;
1156 if (beacon
->BssCcxVerNumber
>= 2) {
1157 u8 CcxVerNumBuf
[] = {0x00, 0x40, 0x96, 0x03, 0x00};
1158 OCTET_STRING osCcxVerNum
;
1159 CcxVerNumBuf
[4] = beacon
->BssCcxVerNumber
;
1160 osCcxVerNum
.Octet
= CcxVerNumBuf
;
1161 osCcxVerNum
.Length
= sizeof(CcxVerNumBuf
);
1162 tag
= skb_put(skb
, cxvernum_ie_len
);
1163 *tag
++ = MFIE_TYPE_GENERIC
;
1164 *tag
++ = osCcxVerNum
.Length
;
1165 memcpy(tag
, osCcxVerNum
.Octet
, osCcxVerNum
.Length
);
1166 tag
+= osCcxVerNum
.Length
;
1169 if (ieee
->pHTInfo
->bCurrentHTSupport
&& ieee
->pHTInfo
->bEnableHT
) {
1170 if (ieee
->pHTInfo
->ePeerHTSpecVer
!= HT_SPEC_VER_EWC
)
1172 tag
= skb_put(skb
, ht_cap_len
);
1173 *tag
++ = MFIE_TYPE_HT_CAP
;
1174 *tag
++ = ht_cap_len
- 2;
1175 memcpy(tag
, ht_cap_buf
, ht_cap_len
- 2);
1176 tag
+= ht_cap_len
-2;
1181 //choose what wpa_supplicant gives to associate.
1182 tag
= skb_put(skb
, wpa_ie_len
);
1184 memcpy(tag
, ieee
->wpa_ie
, ieee
->wpa_ie_len
);
1187 tag
= skb_put(skb
, wmm_info_len
);
1189 ieee80211_WMM_Info(ieee
, &tag
);
1192 tag
= skb_put(skb
, turbo_info_len
);
1193 if (turbo_info_len
) {
1194 ieee80211_TURBO_Info(ieee
, &tag
);
1198 if (ieee
->pHTInfo
->bCurrentHTSupport
&& ieee
->pHTInfo
->bEnableHT
) {
1199 if(ieee
->pHTInfo
->ePeerHTSpecVer
== HT_SPEC_VER_EWC
)
1201 tag
= skb_put(skb
, ht_cap_len
);
1202 *tag
++ = MFIE_TYPE_GENERIC
;
1203 *tag
++ = ht_cap_len
- 2;
1204 memcpy(tag
, ht_cap_buf
, ht_cap_len
- 2);
1205 tag
+= ht_cap_len
-2;
1208 if (ieee
->pHTInfo
->bCurrentRT2RTAggregation
) {
1209 tag
= skb_put(skb
, realtek_ie_len
);
1210 *tag
++ = MFIE_TYPE_GENERIC
;
1211 *tag
++ = realtek_ie_len
- 2;
1212 memcpy(tag
, realtek_ie_buf
, realtek_ie_len
- 2);
1215 // printk("<=====%s(), %p, %p\n", __func__, ieee->dev, ieee->dev->dev_addr);
1216 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
1220 void ieee80211_associate_abort(struct ieee80211_device
*ieee
)
1223 unsigned long flags
;
1224 spin_lock_irqsave(&ieee
->lock
, flags
);
1226 ieee
->associate_seq
++;
1228 /* don't scan, and avoid to have the RX path possibily
1229 * try again to associate. Even do not react to AUTH or
1230 * ASSOC response. Just wait for the retry wq to be scheduled.
1231 * Here we will check if there are good nets to associate
1232 * with, so we retry or just get back to NO_LINK and scanning
1234 if (ieee
->state
== IEEE80211_ASSOCIATING_AUTHENTICATING
){
1235 IEEE80211_DEBUG_MGMT("Authentication failed\n");
1236 ieee
->softmac_stats
.no_auth_rs
++;
1238 IEEE80211_DEBUG_MGMT("Association failed\n");
1239 ieee
->softmac_stats
.no_ass_rs
++;
1242 ieee
->state
= IEEE80211_ASSOCIATING_RETRY
;
1244 schedule_delayed_work(&ieee
->associate_retry_wq
, \
1245 IEEE80211_SOFTMAC_ASSOC_RETRY_TIME
);
1247 spin_unlock_irqrestore(&ieee
->lock
, flags
);
1250 static void ieee80211_associate_abort_cb(unsigned long dev
)
1252 ieee80211_associate_abort((struct ieee80211_device
*) dev
);
1256 static void ieee80211_associate_step1(struct ieee80211_device
*ieee
)
1258 struct ieee80211_network
*beacon
= &ieee
->current_network
;
1259 struct sk_buff
*skb
;
1261 IEEE80211_DEBUG_MGMT("Stopping scan\n");
1263 ieee
->softmac_stats
.tx_auth_rq
++;
1264 skb
=ieee80211_authentication_req(beacon
, ieee
, 0);
1267 ieee80211_associate_abort(ieee
);
1269 ieee
->state
= IEEE80211_ASSOCIATING_AUTHENTICATING
;
1270 IEEE80211_DEBUG_MGMT("Sending authentication request\n");
1271 softmac_mgmt_xmit(skb
, ieee
);
1272 //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
1273 if (!timer_pending(&ieee
->associate_timer
)) {
1274 ieee
->associate_timer
.expires
= jiffies
+ (HZ
/ 2);
1275 add_timer(&ieee
->associate_timer
);
1277 //dev_kfree_skb_any(skb);//edit by thomas
1281 static void ieee80211_auth_challenge(struct ieee80211_device
*ieee
,
1286 struct sk_buff
*skb
;
1287 struct ieee80211_network
*beacon
= &ieee
->current_network
;
1288 // int hlen = sizeof(struct ieee80211_authentication);
1290 ieee
->associate_seq
++;
1291 ieee
->softmac_stats
.tx_auth_rq
++;
1293 skb
= ieee80211_authentication_req(beacon
, ieee
, chlen
+2);
1295 ieee80211_associate_abort(ieee
);
1297 c
= skb_put(skb
, chlen
+2);
1298 *(c
++) = MFIE_TYPE_CHALLENGE
;
1300 memcpy(c
, challenge
, chlen
);
1302 IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
1304 ieee80211_encrypt_fragment(ieee
, skb
, sizeof(struct rtl_80211_hdr_3addr
));
1306 softmac_mgmt_xmit(skb
, ieee
);
1307 mod_timer(&ieee
->associate_timer
, jiffies
+ (HZ
/2));
1308 //dev_kfree_skb_any(skb);//edit by thomas
1313 static void ieee80211_associate_step2(struct ieee80211_device
*ieee
)
1315 struct sk_buff
*skb
;
1316 struct ieee80211_network
*beacon
= &ieee
->current_network
;
1318 del_timer_sync(&ieee
->associate_timer
);
1320 IEEE80211_DEBUG_MGMT("Sending association request\n");
1322 ieee
->softmac_stats
.tx_ass_rq
++;
1323 skb
=ieee80211_association_req(beacon
, ieee
);
1325 ieee80211_associate_abort(ieee
);
1327 softmac_mgmt_xmit(skb
, ieee
);
1328 mod_timer(&ieee
->associate_timer
, jiffies
+ (HZ
/2));
1329 //dev_kfree_skb_any(skb);//edit by thomas
1332 static void ieee80211_associate_complete_wq(struct work_struct
*work
)
1334 struct ieee80211_device
*ieee
= container_of(work
, struct ieee80211_device
, associate_complete_wq
);
1335 printk(KERN_INFO
"Associated successfully\n");
1336 if(ieee80211_is_54g(&ieee
->current_network
) &&
1337 (ieee
->modulation
& IEEE80211_OFDM_MODULATION
)){
1340 printk(KERN_INFO
"Using G rates:%d\n", ieee
->rate
);
1343 printk(KERN_INFO
"Using B rates:%d\n", ieee
->rate
);
1345 if (ieee
->pHTInfo
->bCurrentHTSupport
&&ieee
->pHTInfo
->bEnableHT
)
1347 printk("Successfully associated, ht enabled\n");
1352 printk("Successfully associated, ht not enabled(%d, %d)\n", ieee
->pHTInfo
->bCurrentHTSupport
, ieee
->pHTInfo
->bEnableHT
);
1353 memset(ieee
->dot11HTOperationalRateSet
, 0, 16);
1354 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1356 ieee
->LinkDetectInfo
.SlotNum
= 2 * (1 + ieee
->current_network
.beacon_interval
/500);
1357 // To prevent the immediately calling watch_dog after association.
1358 if (ieee
->LinkDetectInfo
.NumRecvBcnInPeriod
==0||ieee
->LinkDetectInfo
.NumRecvDataInPeriod
==0 )
1360 ieee
->LinkDetectInfo
.NumRecvBcnInPeriod
= 1;
1361 ieee
->LinkDetectInfo
.NumRecvDataInPeriod
= 1;
1363 ieee
->link_change(ieee
->dev
);
1364 if (!ieee
->is_silent_reset
) {
1365 printk("============>normal associate\n");
1366 notify_wx_assoc_event(ieee
);
1368 printk("==================>silent reset associate\n");
1369 ieee
->is_silent_reset
= false;
1372 if (ieee
->data_hard_resume
)
1373 ieee
->data_hard_resume(ieee
->dev
);
1374 netif_carrier_on(ieee
->dev
);
1377 static void ieee80211_associate_complete(struct ieee80211_device
*ieee
)
1380 // struct net_device* dev = ieee->dev;
1381 del_timer_sync(&ieee
->associate_timer
);
1383 ieee
->state
= IEEE80211_LINKED
;
1384 //ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet);
1385 schedule_work(&ieee
->associate_complete_wq
);
1388 static void ieee80211_associate_procedure_wq(struct work_struct
*work
)
1390 struct ieee80211_device
*ieee
= container_of(work
, struct ieee80211_device
, associate_procedure_wq
);
1391 ieee
->sync_scan_hurryup
= 1;
1392 down(&ieee
->wx_sem
);
1394 if (ieee
->data_hard_stop
)
1395 ieee
->data_hard_stop(ieee
->dev
);
1397 ieee80211_stop_scan(ieee
);
1398 printk("===>%s(), chan:%d\n", __func__
, ieee
->current_network
.channel
);
1399 //ieee->set_chan(ieee->dev, ieee->current_network.channel);
1400 HTSetConnectBwMode(ieee
, HT_CHANNEL_WIDTH_20
, HT_EXTCHNL_OFFSET_NO_EXT
);
1402 ieee
->associate_seq
= 1;
1403 ieee80211_associate_step1(ieee
);
1408 inline void ieee80211_softmac_new_net(struct ieee80211_device
*ieee
, struct ieee80211_network
*net
)
1410 u8 tmp_ssid
[IW_ESSID_MAX_SIZE
+1];
1411 int tmp_ssid_len
= 0;
1413 short apset
, ssidset
, ssidbroad
, apmatch
, ssidmatch
;
1415 /* we are interested in new new only if we are not associated
1416 * and we are not associating / authenticating
1418 if (ieee
->state
!= IEEE80211_NOLINK
)
1421 if ((ieee
->iw_mode
== IW_MODE_INFRA
) && !(net
->capability
& WLAN_CAPABILITY_BSS
))
1424 if ((ieee
->iw_mode
== IW_MODE_ADHOC
) && !(net
->capability
& WLAN_CAPABILITY_IBSS
))
1428 if (ieee
->iw_mode
== IW_MODE_INFRA
|| ieee
->iw_mode
== IW_MODE_ADHOC
) {
1429 /* if the user specified the AP MAC, we need also the essid
1430 * This could be obtained by beacons or, if the network does not
1431 * broadcast it, it can be put manually.
1433 apset
= ieee
->wap_set
;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
1434 ssidset
= ieee
->ssid_set
;//ieee->current_network.ssid[0] != '\0';
1435 ssidbroad
= !(net
->ssid_len
== 0 || net
->ssid
[0]== '\0');
1436 apmatch
= (memcmp(ieee
->current_network
.bssid
, net
->bssid
, ETH_ALEN
)==0);
1437 ssidmatch
= (ieee
->current_network
.ssid_len
== net
->ssid_len
)&&\
1438 (!strncmp(ieee
->current_network
.ssid
, net
->ssid
, net
->ssid_len
));
1441 if ( /* if the user set the AP check if match.
1442 * if the network does not broadcast essid we check the user supplyed ANY essid
1443 * if the network does broadcast and the user does not set essid it is OK
1444 * if the network does broadcast and the user did set essid chech if essid match
1446 (apset
&& apmatch
&&
1447 ((ssidset
&& ssidbroad
&& ssidmatch
) || (ssidbroad
&& !ssidset
) || (!ssidbroad
&& ssidset
)) ) ||
1448 /* if the ap is not set, check that the user set the bssid
1449 * and the network does broadcast and that those two bssid matches
1451 (!apset
&& ssidset
&& ssidbroad
&& ssidmatch
)
1453 /* if the essid is hidden replace it with the
1454 * essid provided by the user.
1457 strncpy(tmp_ssid
, ieee
->current_network
.ssid
, IW_ESSID_MAX_SIZE
);
1458 tmp_ssid_len
= ieee
->current_network
.ssid_len
;
1460 memcpy(&ieee
->current_network
, net
, sizeof(struct ieee80211_network
));
1462 strncpy(ieee
->current_network
.ssid
, tmp_ssid
, IW_ESSID_MAX_SIZE
);
1463 ieee
->current_network
.ssid_len
= tmp_ssid_len
;
1464 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
);
1466 //ieee->pHTInfo->IOTAction = 0;
1467 HTResetIOTSetting(ieee
->pHTInfo
);
1468 if (ieee
->iw_mode
== IW_MODE_INFRA
){
1469 /* Join the network for the first time */
1470 ieee
->AsocRetryCount
= 0;
1471 //for HT by amy 080514
1472 if((ieee
->current_network
.qos_data
.supported
== 1) &&
1473 // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT))
1474 ieee
->current_network
.bssht
.bdSupportHT
)
1475 /*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.*/
1477 // ieee->pHTInfo->bCurrentHTSupport = true;
1478 HTResetSelfAndSavePeerSetting(ieee
, &(ieee
->current_network
));
1482 ieee
->pHTInfo
->bCurrentHTSupport
= false;
1485 ieee
->state
= IEEE80211_ASSOCIATING
;
1486 schedule_work(&ieee
->associate_procedure_wq
);
1488 if(ieee80211_is_54g(&ieee
->current_network
) &&
1489 (ieee
->modulation
& IEEE80211_OFDM_MODULATION
)){
1491 ieee
->SetWirelessMode(ieee
->dev
, IEEE_G
);
1492 printk(KERN_INFO
"Using G rates\n");
1495 ieee
->SetWirelessMode(ieee
->dev
, IEEE_B
);
1496 printk(KERN_INFO
"Using B rates\n");
1498 memset(ieee
->dot11HTOperationalRateSet
, 0, 16);
1499 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1500 ieee
->state
= IEEE80211_LINKED
;
1508 void ieee80211_softmac_check_all_nets(struct ieee80211_device
*ieee
)
1510 unsigned long flags
;
1511 struct ieee80211_network
*target
;
1513 spin_lock_irqsave(&ieee
->lock
, flags
);
1515 list_for_each_entry(target
, &ieee
->network_list
, list
) {
1517 /* if the state become different that NOLINK means
1518 * we had found what we are searching for
1521 if (ieee
->state
!= IEEE80211_NOLINK
)
1524 if (ieee
->scan_age
== 0 || time_after(target
->last_scanned
+ ieee
->scan_age
, jiffies
))
1525 ieee80211_softmac_new_net(ieee
, target
);
1528 spin_unlock_irqrestore(&ieee
->lock
, flags
);
1533 static inline u16
auth_parse(struct sk_buff
*skb
, u8
**challenge
, int *chlen
)
1535 struct ieee80211_authentication
*a
;
1537 if (skb
->len
< (sizeof(struct ieee80211_authentication
) - sizeof(struct ieee80211_info_element
))) {
1538 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb
->len
);
1542 a
= (struct ieee80211_authentication
*) skb
->data
;
1543 if (skb
->len
> (sizeof(struct ieee80211_authentication
) + 3)) {
1544 t
= skb
->data
+ sizeof(struct ieee80211_authentication
);
1546 if (*(t
++) == MFIE_TYPE_CHALLENGE
) {
1548 *challenge
= kmemdup(t
, *chlen
, GFP_ATOMIC
);
1554 return le16_to_cpu(a
->status
);
1559 static int auth_rq_parse(struct sk_buff
*skb
, u8
*dest
)
1561 struct ieee80211_authentication
*a
;
1563 if (skb
->len
< (sizeof(struct ieee80211_authentication
) - sizeof(struct ieee80211_info_element
))) {
1564 IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb
->len
);
1567 a
= (struct ieee80211_authentication
*) skb
->data
;
1569 memcpy(dest
,a
->header
.addr2
, ETH_ALEN
);
1571 if (le16_to_cpu(a
->algorithm
) != WLAN_AUTH_OPEN
)
1572 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
1574 return WLAN_STATUS_SUCCESS
;
1577 static short probe_rq_parse(struct ieee80211_device
*ieee
, struct sk_buff
*skb
, u8
*src
)
1584 struct rtl_80211_hdr_3addr
*header
=
1585 (struct rtl_80211_hdr_3addr
*) skb
->data
;
1587 if (skb
->len
< sizeof (struct rtl_80211_hdr_3addr
))
1588 return -1; /* corrupted */
1590 memcpy(src
,header
->addr2
, ETH_ALEN
);
1592 skbend
= (u8
*)skb
->data
+ skb
->len
;
1594 tag
= skb
->data
+ sizeof (struct rtl_80211_hdr_3addr
);
1596 while (tag
+1 < skbend
){
1602 tag
++; /* point to the len field */
1603 tag
= tag
+ *(tag
); /* point to the last data byte of the tag */
1604 tag
++; /* point to the next tag */
1607 //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
1608 if (ssidlen
== 0) return 1;
1610 if (!ssid
) return 1; /* ssid not found in tagged param */
1611 return (!strncmp(ssid
, ieee
->current_network
.ssid
, ssidlen
));
1615 static int assoc_rq_parse(struct sk_buff
*skb
, u8
*dest
)
1617 struct ieee80211_assoc_request_frame
*a
;
1619 if (skb
->len
< (sizeof(struct ieee80211_assoc_request_frame
) -
1620 sizeof(struct ieee80211_info_element
))) {
1622 IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb
->len
);
1626 a
= (struct ieee80211_assoc_request_frame
*) skb
->data
;
1628 memcpy(dest
,a
->header
.addr2
,ETH_ALEN
);
1633 static inline u16
assoc_parse(struct ieee80211_device
*ieee
, struct sk_buff
*skb
, int *aid
)
1635 struct ieee80211_assoc_response_frame
*response_head
;
1638 if (skb
->len
< sizeof(struct ieee80211_assoc_response_frame
)) {
1639 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb
->len
);
1643 response_head
= (struct ieee80211_assoc_response_frame
*) skb
->data
;
1644 *aid
= le16_to_cpu(response_head
->aid
) & 0x3fff;
1646 status_code
= le16_to_cpu(response_head
->status
);
1647 if((status_code
==WLAN_STATUS_ASSOC_DENIED_RATES
|| \
1648 status_code
==WLAN_STATUS_CAPS_UNSUPPORTED
)&&
1649 ((ieee
->mode
== IEEE_G
) &&
1650 (ieee
->current_network
.mode
== IEEE_N_24G
) &&
1651 (ieee
->AsocRetryCount
++ < (RT_ASOC_RETRY_LIMIT
-1)))) {
1652 ieee
->pHTInfo
->IOTAction
|= HT_IOT_ACT_PURE_N_MODE
;
1654 ieee
->AsocRetryCount
= 0;
1657 return le16_to_cpu(response_head
->status
);
1661 ieee80211_rx_probe_rq(struct ieee80211_device
*ieee
, struct sk_buff
*skb
)
1665 //IEEE80211DMESG("Rx probe");
1666 ieee
->softmac_stats
.rx_probe_rq
++;
1667 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1668 if (probe_rq_parse(ieee
, skb
, dest
)) {
1669 //IEEE80211DMESG("Was for me!");
1670 ieee
->softmac_stats
.tx_probe_rs
++;
1671 ieee80211_resp_to_probe(ieee
, dest
);
1676 ieee80211_rx_auth_rq(struct ieee80211_device
*ieee
, struct sk_buff
*skb
)
1680 //IEEE80211DMESG("Rx probe");
1681 ieee
->softmac_stats
.rx_auth_rq
++;
1683 status
= auth_rq_parse(skb
, dest
);
1685 ieee80211_resp_to_auth(ieee
, status
, dest
);
1687 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1692 ieee80211_rx_assoc_rq(struct ieee80211_device
*ieee
, struct sk_buff
*skb
)
1696 //unsigned long flags;
1698 ieee
->softmac_stats
.rx_ass_rq
++;
1699 if (assoc_rq_parse(skb
, dest
) != -1) {
1700 ieee80211_resp_to_assoc_rq(ieee
, dest
);
1703 printk(KERN_INFO
"New client associated: %pM\n", dest
);
1707 static void ieee80211_sta_ps_send_null_frame(struct ieee80211_device
*ieee
,
1711 struct sk_buff
*buf
= ieee80211_null_func(ieee
, pwr
);
1714 softmac_ps_mgmt_xmit(buf
, ieee
);
1717 /* EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame); */
1719 static short ieee80211_sta_ps_sleep(struct ieee80211_device
*ieee
, u32
*time_h
,
1722 int timeout
= ieee
->ps_timeout
;
1724 /*if(ieee->ps == IEEE80211_PS_DISABLED ||
1725 ieee->iw_mode != IW_MODE_INFRA ||
1726 ieee->state != IEEE80211_LINKED)
1730 dtim
= ieee
->current_network
.dtim_data
;
1731 if(!(dtim
& IEEE80211_DTIM_VALID
))
1733 timeout
= ieee
->current_network
.beacon_interval
; //should we use ps_timeout value or beacon_interval
1734 ieee
->current_network
.dtim_data
= IEEE80211_DTIM_INVALID
;
1736 if(dtim
& ((IEEE80211_DTIM_UCAST
| IEEE80211_DTIM_MBCAST
)& ieee
->ps
))
1739 if(!time_after(jiffies
,
1740 dev_trans_start(ieee
->dev
) + msecs_to_jiffies(timeout
)))
1743 if(!time_after(jiffies
,
1744 ieee
->last_rx_ps_time
+ msecs_to_jiffies(timeout
)))
1747 if((ieee
->softmac_features
& IEEE_SOFTMAC_SINGLE_QUEUE
) &&
1748 (ieee
->mgmt_queue_tail
!= ieee
->mgmt_queue_head
))
1752 *time_l
= ieee
->current_network
.last_dtim_sta_time
[0]
1753 + (ieee
->current_network
.beacon_interval
1754 * ieee
->current_network
.dtim_period
) * 1000;
1758 *time_h
= ieee
->current_network
.last_dtim_sta_time
[1];
1759 if(time_l
&& *time_l
< ieee
->current_network
.last_dtim_sta_time
[0])
1768 static inline void ieee80211_sta_ps(struct ieee80211_device
*ieee
)
1774 unsigned long flags
, flags2
;
1776 spin_lock_irqsave(&ieee
->lock
, flags
);
1778 if ((ieee
->ps
== IEEE80211_PS_DISABLED
||
1779 ieee
->iw_mode
!= IW_MODE_INFRA
||
1780 ieee
->state
!= IEEE80211_LINKED
)){
1782 // #warning CHECK_LOCK_HERE
1783 spin_lock_irqsave(&ieee
->mgmt_tx_lock
, flags2
);
1785 ieee80211_sta_wakeup(ieee
, 1);
1787 spin_unlock_irqrestore(&ieee
->mgmt_tx_lock
, flags2
);
1790 sleep
= ieee80211_sta_ps_sleep(ieee
,&th
, &tl
);
1791 /* 2 wake, 1 sleep, 0 do nothing */
1797 if(ieee
->sta_sleep
== 1)
1798 ieee
->enter_sleep_state(ieee
->dev
, th
, tl
);
1800 else if(ieee
->sta_sleep
== 0){
1801 // printk("send null 1\n");
1802 spin_lock_irqsave(&ieee
->mgmt_tx_lock
, flags2
);
1804 if(ieee
->ps_is_queue_empty(ieee
->dev
)){
1807 ieee
->sta_sleep
= 2;
1809 ieee
->ps_request_tx_ack(ieee
->dev
);
1811 ieee80211_sta_ps_send_null_frame(ieee
, 1);
1816 spin_unlock_irqrestore(&ieee
->mgmt_tx_lock
, flags2
);
1821 }else if(sleep
== 2){
1822 //#warning CHECK_LOCK_HERE
1823 spin_lock_irqsave(&ieee
->mgmt_tx_lock
, flags2
);
1825 ieee80211_sta_wakeup(ieee
, 1);
1827 spin_unlock_irqrestore(&ieee
->mgmt_tx_lock
, flags2
);
1831 spin_unlock_irqrestore(&ieee
->lock
, flags
);
1835 void ieee80211_sta_wakeup(struct ieee80211_device
*ieee
, short nl
)
1837 if (ieee
->sta_sleep
== 0) {
1839 printk("Warning: driver is probably failing to report TX ps error\n");
1840 ieee
->ps_request_tx_ack(ieee
->dev
);
1841 ieee80211_sta_ps_send_null_frame(ieee
, 0);
1847 if(ieee
->sta_sleep
== 1)
1848 ieee
->sta_wake_up(ieee
->dev
);
1850 ieee
->sta_sleep
= 0;
1853 ieee
->ps_request_tx_ack(ieee
->dev
);
1854 ieee80211_sta_ps_send_null_frame(ieee
, 0);
1858 void ieee80211_ps_tx_ack(struct ieee80211_device
*ieee
, short success
)
1860 unsigned long flags
, flags2
;
1862 spin_lock_irqsave(&ieee
->lock
, flags
);
1864 if(ieee
->sta_sleep
== 2){
1865 /* Null frame with PS bit set */
1867 ieee
->sta_sleep
= 1;
1868 ieee
->enter_sleep_state(ieee
->dev
,ieee
->ps_th
,ieee
->ps_tl
);
1870 /* if the card report not success we can't be sure the AP
1871 * has not RXed so we can't assume the AP believe us awake
1874 /* 21112005 - tx again null without PS bit if lost */
1877 if ((ieee
->sta_sleep
== 0) && !success
) {
1878 spin_lock_irqsave(&ieee
->mgmt_tx_lock
, flags2
);
1879 ieee80211_sta_ps_send_null_frame(ieee
, 0);
1880 spin_unlock_irqrestore(&ieee
->mgmt_tx_lock
, flags2
);
1883 spin_unlock_irqrestore(&ieee
->lock
, flags
);
1885 EXPORT_SYMBOL(ieee80211_ps_tx_ack
);
1887 static void ieee80211_process_action(struct ieee80211_device
*ieee
,
1888 struct sk_buff
*skb
)
1890 struct rtl_80211_hdr
*header
= (struct rtl_80211_hdr
*)skb
->data
;
1891 u8
*act
= ieee80211_get_payload(header
);
1893 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
1896 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "error to get payload of action frame\n");
1903 if (*act
== ACT_ADDBAREQ
)
1904 ieee80211_rx_ADDBAReq(ieee
, skb
);
1905 else if (*act
== ACT_ADDBARSP
)
1906 ieee80211_rx_ADDBARsp(ieee
, skb
);
1907 else if (*act
== ACT_DELBA
)
1908 ieee80211_rx_DELBA(ieee
, skb
);
1917 static void ieee80211_check_auth_response(struct ieee80211_device
*ieee
,
1918 struct sk_buff
*skb
)
1920 /* default support N mode, disable halfNmode */
1921 bool bSupportNmode
= true, bHalfSupportNmode
= false;
1927 errcode
= auth_parse(skb
, &challenge
, &chlen
);
1929 if (ieee
->open_wep
|| !challenge
) {
1930 ieee
->state
= IEEE80211_ASSOCIATING_AUTHENTICATED
;
1931 ieee
->softmac_stats
.rx_auth_rs_ok
++;
1932 iotAction
= ieee
->pHTInfo
->IOTAction
;
1933 if (!(iotAction
& HT_IOT_ACT_PURE_N_MODE
)) {
1934 if (!ieee
->GetNmodeSupportBySecCfg(ieee
->dev
)) {
1935 /* WEP or TKIP encryption */
1936 if (IsHTHalfNmodeAPs(ieee
)) {
1937 bSupportNmode
= true;
1938 bHalfSupportNmode
= true;
1940 bSupportNmode
= false;
1941 bHalfSupportNmode
= false;
1943 netdev_dbg(ieee
->dev
, "SEC(%d, %d)\n",
1948 /* Dummy wirless mode setting- avoid encryption issue */
1949 if (bSupportNmode
) {
1950 /* N mode setting */
1951 ieee
->SetWirelessMode(ieee
->dev
,
1952 ieee
->current_network
.mode
);
1954 /* b/g mode setting - TODO */
1955 ieee
->SetWirelessMode(ieee
->dev
, IEEE_G
);
1958 if (ieee
->current_network
.mode
== IEEE_N_24G
&&
1959 bHalfSupportNmode
) {
1960 netdev_dbg(ieee
->dev
, "enter half N mode\n");
1961 ieee
->bHalfWirelessN24GMode
= true;
1963 ieee
->bHalfWirelessN24GMode
= false;
1965 ieee80211_associate_step2(ieee
);
1967 ieee80211_auth_challenge(ieee
, challenge
, chlen
);
1970 ieee
->softmac_stats
.rx_auth_rs_err
++;
1971 IEEE80211_DEBUG_MGMT("Auth response status code 0x%x", errcode
);
1972 ieee80211_associate_abort(ieee
);
1977 ieee80211_rx_frame_softmac(struct ieee80211_device
*ieee
, struct sk_buff
*skb
,
1978 struct ieee80211_rx_stats
*rx_stats
, u16 type
,
1981 struct rtl_80211_hdr_3addr
*header
= (struct rtl_80211_hdr_3addr
*) skb
->data
;
1984 struct ieee80211_assoc_response_frame
*assoc_resp
;
1985 // struct ieee80211_info_element *info_element;
1987 if(!ieee
->proto_started
)
1990 if(ieee
->sta_sleep
|| (ieee
->ps
!= IEEE80211_PS_DISABLED
&&
1991 ieee
->iw_mode
== IW_MODE_INFRA
&&
1992 ieee
->state
== IEEE80211_LINKED
))
1994 tasklet_schedule(&ieee
->ps_task
);
1996 if(WLAN_FC_GET_STYPE(header
->frame_ctl
) != IEEE80211_STYPE_PROBE_RESP
&&
1997 WLAN_FC_GET_STYPE(header
->frame_ctl
) != IEEE80211_STYPE_BEACON
)
1998 ieee
->last_rx_ps_time
= jiffies
;
2000 switch (WLAN_FC_GET_STYPE(header
->frame_ctl
)) {
2002 case IEEE80211_STYPE_ASSOC_RESP
:
2003 case IEEE80211_STYPE_REASSOC_RESP
:
2005 IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
2006 WLAN_FC_GET_STYPE(header
->frame_ctl
));
2007 if ((ieee
->softmac_features
& IEEE_SOFTMAC_ASSOCIATE
) &&
2008 ieee
->state
== IEEE80211_ASSOCIATING_AUTHENTICATED
&&
2009 ieee
->iw_mode
== IW_MODE_INFRA
){
2010 struct ieee80211_network network_resp
;
2011 struct ieee80211_network
*network
= &network_resp
;
2013 errcode
= assoc_parse(ieee
, skb
, &aid
);
2015 ieee
->state
=IEEE80211_LINKED
;
2016 ieee
->assoc_id
= aid
;
2017 ieee
->softmac_stats
.rx_ass_ok
++;
2018 /* station support qos */
2019 /* Let the register setting defaultly with Legacy station */
2020 if (ieee
->qos_support
) {
2021 assoc_resp
= (struct ieee80211_assoc_response_frame
*)skb
->data
;
2022 memset(network
, 0, sizeof(*network
));
2023 if (ieee80211_parse_info_param(ieee
,assoc_resp
->info_element
,\
2024 rx_stats
->len
- sizeof(*assoc_resp
),\
2029 { //filling the PeerHTCap. //maybe not necessary as we can get its info from current_network.
2030 memcpy(ieee
->pHTInfo
->PeerHTCapBuf
, network
->bssht
.bdHTCapBuf
, network
->bssht
.bdHTCapLen
);
2031 memcpy(ieee
->pHTInfo
->PeerHTInfoBuf
, network
->bssht
.bdHTInfoBuf
, network
->bssht
.bdHTInfoLen
);
2033 if (ieee
->handle_assoc_response
!= NULL
)
2034 ieee
->handle_assoc_response(ieee
->dev
, (struct ieee80211_assoc_response_frame
*)header
, network
);
2036 ieee80211_associate_complete(ieee
);
2038 /* aid could not been allocated */
2039 ieee
->softmac_stats
.rx_ass_err
++;
2041 "Association response status code 0x%x\n",
2043 IEEE80211_DEBUG_MGMT(
2044 "Association response status code 0x%x\n",
2046 if(ieee
->AsocRetryCount
< RT_ASOC_RETRY_LIMIT
) {
2047 schedule_work(&ieee
->associate_procedure_wq
);
2049 ieee80211_associate_abort(ieee
);
2055 case IEEE80211_STYPE_ASSOC_REQ
:
2056 case IEEE80211_STYPE_REASSOC_REQ
:
2058 if ((ieee
->softmac_features
& IEEE_SOFTMAC_ASSOCIATE
) &&
2059 ieee
->iw_mode
== IW_MODE_MASTER
)
2061 ieee80211_rx_assoc_rq(ieee
, skb
);
2064 case IEEE80211_STYPE_AUTH
:
2066 if (ieee
->softmac_features
& IEEE_SOFTMAC_ASSOCIATE
) {
2067 if (ieee
->state
== IEEE80211_ASSOCIATING_AUTHENTICATING
2068 && ieee
->iw_mode
== IW_MODE_INFRA
) {
2070 IEEE80211_DEBUG_MGMT("Received auth response");
2071 ieee80211_check_auth_response(ieee
, skb
);
2072 } else if (ieee
->iw_mode
== IW_MODE_MASTER
) {
2073 ieee80211_rx_auth_rq(ieee
, skb
);
2078 case IEEE80211_STYPE_PROBE_REQ
:
2080 if ((ieee
->softmac_features
& IEEE_SOFTMAC_PROBERS
) &&
2081 ((ieee
->iw_mode
== IW_MODE_ADHOC
||
2082 ieee
->iw_mode
== IW_MODE_MASTER
) &&
2083 ieee
->state
== IEEE80211_LINKED
)){
2084 ieee80211_rx_probe_rq(ieee
, skb
);
2088 case IEEE80211_STYPE_DISASSOC
:
2089 case IEEE80211_STYPE_DEAUTH
:
2090 /* FIXME for now repeat all the association procedure
2091 * both for disassociation and deauthentication
2093 if ((ieee
->softmac_features
& IEEE_SOFTMAC_ASSOCIATE
) &&
2094 ieee
->state
== IEEE80211_LINKED
&&
2095 ieee
->iw_mode
== IW_MODE_INFRA
){
2097 ieee
->state
= IEEE80211_ASSOCIATING
;
2098 ieee
->softmac_stats
.reassoc
++;
2100 notify_wx_assoc_event(ieee
);
2101 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2102 RemovePeerTS(ieee
, header
->addr2
);
2103 schedule_work(&ieee
->associate_procedure_wq
);
2106 case IEEE80211_STYPE_MANAGE_ACT
:
2107 ieee80211_process_action(ieee
, skb
);
2113 //dev_kfree_skb_any(skb);
2117 /* The following are for a simpler TX queue management.
2118 * Instead of using netif_[stop/wake]_queue, the driver
2119 * will use these two functions (plus a reset one) that
2120 * will internally call the kernel netif_* and take care
2121 * of the ieee802.11 fragmentation.
2122 * So, the driver receives a fragment at a time and might
2123 * call the stop function when it wants, without taking
2124 * care to have enough room to TX an entire packet.
2125 * This might be useful if each fragment needs its own
2126 * descriptor. Thus, just keeping a total free memory > than
2127 * the max fragmentation threshold is not enough. If the
2128 * ieee802.11 stack passed a TXB struct, then you would need
2129 * to keep N free descriptors where
2130 * N = MAX_PACKET_SIZE / MIN_FRAG_THRESHOLD.
2131 * In this way you need just one and the 802.11 stack
2132 * will take care of buffering fragments and pass them to
2133 * to the driver later, when it wakes the queue.
2135 void ieee80211_softmac_xmit(struct ieee80211_txb
*txb
, struct ieee80211_device
*ieee
)
2138 unsigned int queue_index
= txb
->queue_index
;
2139 unsigned long flags
;
2141 cb_desc
*tcb_desc
= NULL
;
2143 spin_lock_irqsave(&ieee
->lock
, flags
);
2145 /* called with 2nd parm 0, no tx mgmt lock required */
2146 ieee80211_sta_wakeup(ieee
, 0);
2148 /* update the tx status */
2149 ieee
->stats
.tx_bytes
+= le16_to_cpu(txb
->payload_size
);
2150 ieee
->stats
.tx_packets
++;
2151 tcb_desc
= (cb_desc
*)(txb
->fragments
[0]->cb
+ MAX_DEV_ADDR_SIZE
);
2152 if (tcb_desc
->bMulticast
) {
2153 ieee
->stats
.multicast
++;
2155 /* if xmit available, just xmit it immediately, else just insert it to the wait queue */
2156 for(i
= 0; i
< txb
->nr_frags
; i
++) {
2157 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2158 if ((skb_queue_len(&ieee
->skb_drv_aggQ
[queue_index
]) != 0) ||
2160 if ((skb_queue_len(&ieee
->skb_waitQ
[queue_index
]) != 0) ||
2162 (!ieee
->check_nic_enough_desc(ieee
->dev
,queue_index
))||\
2163 (ieee
->queue_stop
)) {
2164 /* insert the skb packet to the wait queue */
2165 /* as for the completion function, it does not need
2166 * to check it any more.
2168 //printk("error:no descriptor left@queue_index %d\n", queue_index);
2169 //ieee80211_stop_queue(ieee);
2170 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2171 skb_queue_tail(&ieee
->skb_drv_aggQ
[queue_index
], txb
->fragments
[i
]);
2173 skb_queue_tail(&ieee
->skb_waitQ
[queue_index
], txb
->fragments
[i
]);
2176 ieee
->softmac_data_hard_start_xmit(
2178 ieee
->dev
, ieee
->rate
);
2179 //ieee->stats.tx_packets++;
2180 //ieee->stats.tx_bytes += txb->fragments[i]->len;
2181 //ieee->dev->trans_start = jiffies;
2184 ieee80211_txb_free(txb
);
2187 spin_unlock_irqrestore(&ieee
->lock
, flags
);
2190 EXPORT_SYMBOL(ieee80211_softmac_xmit
);
2192 /* called with ieee->lock acquired */
2193 static void ieee80211_resume_tx(struct ieee80211_device
*ieee
)
2196 for(i
= ieee
->tx_pending
.frag
; i
< ieee
->tx_pending
.txb
->nr_frags
; i
++) {
2198 if (ieee
->queue_stop
){
2199 ieee
->tx_pending
.frag
= i
;
2203 ieee
->softmac_data_hard_start_xmit(
2204 ieee
->tx_pending
.txb
->fragments
[i
],
2205 ieee
->dev
, ieee
->rate
);
2206 //(i+1)<ieee->tx_pending.txb->nr_frags);
2207 ieee
->stats
.tx_packets
++;
2208 netif_trans_update(ieee
->dev
);
2213 ieee80211_txb_free(ieee
->tx_pending
.txb
);
2214 ieee
->tx_pending
.txb
= NULL
;
2218 void ieee80211_reset_queue(struct ieee80211_device
*ieee
)
2220 unsigned long flags
;
2222 spin_lock_irqsave(&ieee
->lock
, flags
);
2223 init_mgmt_queue(ieee
);
2224 if (ieee
->tx_pending
.txb
) {
2225 ieee80211_txb_free(ieee
->tx_pending
.txb
);
2226 ieee
->tx_pending
.txb
= NULL
;
2228 ieee
->queue_stop
= 0;
2229 spin_unlock_irqrestore(&ieee
->lock
, flags
);
2232 EXPORT_SYMBOL(ieee80211_reset_queue
);
2234 void ieee80211_wake_queue(struct ieee80211_device
*ieee
)
2237 unsigned long flags
;
2238 struct sk_buff
*skb
;
2239 struct rtl_80211_hdr_3addr
*header
;
2241 spin_lock_irqsave(&ieee
->lock
, flags
);
2242 if (! ieee
->queue_stop
) goto exit
;
2244 ieee
->queue_stop
= 0;
2246 if (ieee
->softmac_features
& IEEE_SOFTMAC_SINGLE_QUEUE
) {
2247 while (!ieee
->queue_stop
&& (skb
= dequeue_mgmt(ieee
))){
2249 header
= (struct rtl_80211_hdr_3addr
*) skb
->data
;
2251 header
->seq_ctl
= cpu_to_le16(ieee
->seq_ctrl
[0] << 4);
2253 if (ieee
->seq_ctrl
[0] == 0xFFF)
2254 ieee
->seq_ctrl
[0] = 0;
2256 ieee
->seq_ctrl
[0]++;
2258 ieee
->softmac_data_hard_start_xmit(skb
,ieee
->dev
,ieee
->basic_rate
);
2259 //dev_kfree_skb_any(skb);//edit by thomas
2262 if (!ieee
->queue_stop
&& ieee
->tx_pending
.txb
)
2263 ieee80211_resume_tx(ieee
);
2265 if (!ieee
->queue_stop
&& netif_queue_stopped(ieee
->dev
)) {
2266 ieee
->softmac_stats
.swtxawake
++;
2267 netif_wake_queue(ieee
->dev
);
2271 spin_unlock_irqrestore(&ieee
->lock
, flags
);
2273 EXPORT_SYMBOL(ieee80211_wake_queue
);
2275 void ieee80211_stop_queue(struct ieee80211_device
*ieee
)
2277 //unsigned long flags;
2278 //spin_lock_irqsave(&ieee->lock,flags);
2280 if (!netif_queue_stopped(ieee
->dev
)) {
2281 netif_stop_queue(ieee
->dev
);
2282 ieee
->softmac_stats
.swtxstop
++;
2284 ieee
->queue_stop
= 1;
2285 //spin_unlock_irqrestore(&ieee->lock,flags);
2288 EXPORT_SYMBOL(ieee80211_stop_queue
);
2290 /* called in user context only */
2291 void ieee80211_start_master_bss(struct ieee80211_device
*ieee
)
2295 if (ieee
->current_network
.ssid_len
== 0) {
2296 strncpy(ieee
->current_network
.ssid
,
2297 IEEE80211_DEFAULT_TX_ESSID
,
2300 ieee
->current_network
.ssid_len
= strlen(IEEE80211_DEFAULT_TX_ESSID
);
2304 memcpy(ieee
->current_network
.bssid
, ieee
->dev
->dev_addr
, ETH_ALEN
);
2306 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
2307 ieee
->state
= IEEE80211_LINKED
;
2308 ieee
->link_change(ieee
->dev
);
2309 notify_wx_assoc_event(ieee
);
2311 if (ieee
->data_hard_resume
)
2312 ieee
->data_hard_resume(ieee
->dev
);
2314 netif_carrier_on(ieee
->dev
);
2317 static void ieee80211_start_monitor_mode(struct ieee80211_device
*ieee
)
2321 if (ieee
->data_hard_resume
)
2322 ieee
->data_hard_resume(ieee
->dev
);
2324 netif_carrier_on(ieee
->dev
);
2327 static void ieee80211_start_ibss_wq(struct work_struct
*work
)
2330 struct delayed_work
*dwork
= to_delayed_work(work
);
2331 struct ieee80211_device
*ieee
= container_of(dwork
, struct ieee80211_device
, start_ibss_wq
);
2332 /* iwconfig mode ad-hoc will schedule this and return
2333 * on the other hand this will block further iwconfig SET
2334 * operations because of the wx_sem hold.
2335 * Anyway some most set operations set a flag to speed-up
2336 * (abort) this wq (when syncro scanning) before sleeping
2339 if (!ieee
->proto_started
) {
2340 printk("==========oh driver down return\n");
2343 down(&ieee
->wx_sem
);
2345 if (ieee
->current_network
.ssid_len
== 0) {
2346 strcpy(ieee
->current_network
.ssid
, IEEE80211_DEFAULT_TX_ESSID
);
2347 ieee
->current_network
.ssid_len
= strlen(IEEE80211_DEFAULT_TX_ESSID
);
2351 /* check if we have this cell in our network list */
2352 ieee80211_softmac_check_all_nets(ieee
);
2355 // if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK))
2356 if (ieee
->state
== IEEE80211_NOLINK
)
2357 ieee
->current_network
.channel
= 6;
2358 /* if not then the state is not linked. Maybe the user swithced to
2359 * ad-hoc mode just after being in monitor mode, or just after
2360 * being very few time in managed mode (so the card have had no
2361 * time to scan all the chans..) or we have just run up the iface
2362 * after setting ad-hoc mode. So we have to give another try..
2363 * Here, in ibss mode, should be safe to do this without extra care
2364 * (in bss mode we had to make sure no-one tryed to associate when
2365 * we had just checked the ieee->state and we was going to start the
2366 * scan) beacause in ibss mode the ieee80211_new_net function, when
2367 * finds a good net, just set the ieee->state to IEEE80211_LINKED,
2368 * so, at worst, we waste a bit of time to initiate an unneeded syncro
2369 * scan, that will stop at the first round because it sees the state
2372 if (ieee
->state
== IEEE80211_NOLINK
)
2373 ieee80211_start_scan_syncro(ieee
);
2375 /* the network definitively is not here.. create a new cell */
2376 if (ieee
->state
== IEEE80211_NOLINK
) {
2377 printk("creating new IBSS cell\n");
2379 random_ether_addr(ieee
->current_network
.bssid
);
2381 if(ieee
->modulation
& IEEE80211_CCK_MODULATION
){
2383 ieee
->current_network
.rates_len
= 4;
2385 ieee
->current_network
.rates
[0] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_1MB
;
2386 ieee
->current_network
.rates
[1] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_2MB
;
2387 ieee
->current_network
.rates
[2] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_5MB
;
2388 ieee
->current_network
.rates
[3] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_CCK_RATE_11MB
;
2391 ieee
->current_network
.rates_len
= 0;
2393 if(ieee
->modulation
& IEEE80211_OFDM_MODULATION
){
2394 ieee
->current_network
.rates_ex_len
= 8;
2396 ieee
->current_network
.rates_ex
[0] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_6MB
;
2397 ieee
->current_network
.rates_ex
[1] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_9MB
;
2398 ieee
->current_network
.rates_ex
[2] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_12MB
;
2399 ieee
->current_network
.rates_ex
[3] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_18MB
;
2400 ieee
->current_network
.rates_ex
[4] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_24MB
;
2401 ieee
->current_network
.rates_ex
[5] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_36MB
;
2402 ieee
->current_network
.rates_ex
[6] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_48MB
;
2403 ieee
->current_network
.rates_ex
[7] = IEEE80211_BASIC_RATE_MASK
| IEEE80211_OFDM_RATE_54MB
;
2407 ieee
->current_network
.rates_ex_len
= 0;
2411 // By default, WMM function will be disabled in IBSS mode
2412 ieee
->current_network
.QoS_Enable
= 0;
2413 ieee
->SetWirelessMode(ieee
->dev
, IEEE_G
);
2414 ieee
->current_network
.atim_window
= 0;
2415 ieee
->current_network
.capability
= WLAN_CAPABILITY_IBSS
;
2416 if(ieee
->short_slot
)
2417 ieee
->current_network
.capability
|= WLAN_CAPABILITY_SHORT_SLOT
;
2421 ieee
->state
= IEEE80211_LINKED
;
2423 ieee
->set_chan(ieee
->dev
, ieee
->current_network
.channel
);
2424 ieee
->link_change(ieee
->dev
);
2426 notify_wx_assoc_event(ieee
);
2428 ieee80211_start_send_beacons(ieee
);
2430 if (ieee
->data_hard_resume
)
2431 ieee
->data_hard_resume(ieee
->dev
);
2432 netif_carrier_on(ieee
->dev
);
2437 inline void ieee80211_start_ibss(struct ieee80211_device
*ieee
)
2439 schedule_delayed_work(&ieee
->start_ibss_wq
, 150);
2442 /* this is called only in user context, with wx_sem held */
2443 void ieee80211_start_bss(struct ieee80211_device
*ieee
)
2445 unsigned long flags
;
2447 // Ref: 802.11d 11.1.3.3
2448 // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
2450 if (IS_DOT11D_ENABLE(ieee
) && !IS_COUNTRY_IE_VALID(ieee
))
2452 if (! ieee
->bGlobalDomain
)
2457 /* check if we have already found the net we
2458 * are interested in (if any).
2459 * if not (we are disassociated and we are not
2460 * in associating / authenticating phase) start the background scanning.
2462 ieee80211_softmac_check_all_nets(ieee
);
2464 /* ensure no-one start an associating process (thus setting
2465 * the ieee->state to ieee80211_ASSOCIATING) while we
2466 * have just cheked it and we are going to enable scan.
2467 * The ieee80211_new_net function is always called with
2468 * lock held (from both ieee80211_softmac_check_all_nets and
2469 * the rx path), so we cannot be in the middle of such function
2471 spin_lock_irqsave(&ieee
->lock
, flags
);
2473 if (ieee
->state
== IEEE80211_NOLINK
) {
2474 ieee
->actscanning
= true;
2475 ieee80211_start_scan(ieee
);
2477 spin_unlock_irqrestore(&ieee
->lock
, flags
);
2480 /* called only in userspace context */
2481 void ieee80211_disassociate(struct ieee80211_device
*ieee
)
2485 netif_carrier_off(ieee
->dev
);
2486 if (ieee
->softmac_features
& IEEE_SOFTMAC_TX_QUEUE
)
2487 ieee80211_reset_queue(ieee
);
2489 if (ieee
->data_hard_stop
)
2490 ieee
->data_hard_stop(ieee
->dev
);
2491 if(IS_DOT11D_ENABLE(ieee
))
2493 ieee
->state
= IEEE80211_NOLINK
;
2494 ieee
->is_set_key
= false;
2495 ieee
->link_change(ieee
->dev
);
2496 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2497 notify_wx_assoc_event(ieee
);
2500 EXPORT_SYMBOL(ieee80211_disassociate
);
2502 static void ieee80211_associate_retry_wq(struct work_struct
*work
)
2504 struct delayed_work
*dwork
= to_delayed_work(work
);
2505 struct ieee80211_device
*ieee
= container_of(dwork
, struct ieee80211_device
, associate_retry_wq
);
2506 unsigned long flags
;
2508 down(&ieee
->wx_sem
);
2509 if(!ieee
->proto_started
)
2512 if(ieee
->state
!= IEEE80211_ASSOCIATING_RETRY
)
2515 /* until we do not set the state to IEEE80211_NOLINK
2516 * there are no possibility to have someone else trying
2517 * to start an association procedure (we get here with
2518 * ieee->state = IEEE80211_ASSOCIATING).
2519 * When we set the state to IEEE80211_NOLINK it is possible
2520 * that the RX path run an attempt to associate, but
2521 * both ieee80211_softmac_check_all_nets and the
2522 * RX path works with ieee->lock held so there are no
2523 * problems. If we are still disassociated then start a scan.
2524 * the lock here is necessary to ensure no one try to start
2525 * an association procedure when we have just checked the
2526 * state and we are going to start the scan.
2528 ieee
->state
= IEEE80211_NOLINK
;
2530 ieee80211_softmac_check_all_nets(ieee
);
2532 spin_lock_irqsave(&ieee
->lock
, flags
);
2534 if(ieee
->state
== IEEE80211_NOLINK
)
2535 ieee80211_start_scan(ieee
);
2537 spin_unlock_irqrestore(&ieee
->lock
, flags
);
2543 struct sk_buff
*ieee80211_get_beacon_(struct ieee80211_device
*ieee
)
2545 u8 broadcast_addr
[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2547 struct sk_buff
*skb
;
2548 struct ieee80211_probe_response
*b
;
2550 skb
= ieee80211_probe_resp(ieee
, broadcast_addr
);
2555 b
= (struct ieee80211_probe_response
*) skb
->data
;
2556 b
->header
.frame_ctl
= cpu_to_le16(IEEE80211_STYPE_BEACON
);
2562 struct sk_buff
*ieee80211_get_beacon(struct ieee80211_device
*ieee
)
2564 struct sk_buff
*skb
;
2565 struct ieee80211_probe_response
*b
;
2567 skb
= ieee80211_get_beacon_(ieee
);
2571 b
= (struct ieee80211_probe_response
*) skb
->data
;
2572 b
->header
.seq_ctl
= cpu_to_le16(ieee
->seq_ctrl
[0] << 4);
2574 if (ieee
->seq_ctrl
[0] == 0xFFF)
2575 ieee
->seq_ctrl
[0] = 0;
2577 ieee
->seq_ctrl
[0]++;
2581 EXPORT_SYMBOL(ieee80211_get_beacon
);
2583 void ieee80211_softmac_stop_protocol(struct ieee80211_device
*ieee
)
2585 ieee
->sync_scan_hurryup
= 1;
2586 down(&ieee
->wx_sem
);
2587 ieee80211_stop_protocol(ieee
);
2590 EXPORT_SYMBOL(ieee80211_softmac_stop_protocol
);
2592 void ieee80211_stop_protocol(struct ieee80211_device
*ieee
)
2594 if (!ieee
->proto_started
)
2597 ieee
->proto_started
= 0;
2599 ieee80211_stop_send_beacons(ieee
);
2600 del_timer_sync(&ieee
->associate_timer
);
2601 cancel_delayed_work(&ieee
->associate_retry_wq
);
2602 cancel_delayed_work(&ieee
->start_ibss_wq
);
2603 ieee80211_stop_scan(ieee
);
2605 ieee80211_disassociate(ieee
);
2606 RemoveAllTS(ieee
); //added as we disconnect from the previous BSS, Remove all TS
2609 void ieee80211_softmac_start_protocol(struct ieee80211_device
*ieee
)
2611 ieee
->sync_scan_hurryup
= 0;
2612 down(&ieee
->wx_sem
);
2613 ieee80211_start_protocol(ieee
);
2616 EXPORT_SYMBOL(ieee80211_softmac_start_protocol
);
2618 void ieee80211_start_protocol(struct ieee80211_device
*ieee
)
2622 if (ieee
->proto_started
)
2625 ieee
->proto_started
= 1;
2627 if (ieee
->current_network
.channel
== 0) {
2630 if (ch
> MAX_CHANNEL_NUMBER
)
2631 return; /* no channel found */
2632 }while(!GET_DOT11D_INFO(ieee
)->channel_map
[ch
]);
2633 ieee
->current_network
.channel
= ch
;
2636 if (ieee
->current_network
.beacon_interval
== 0)
2637 ieee
->current_network
.beacon_interval
= 100;
2638 // printk("===>%s(), chan:%d\n", __func__, ieee->current_network.channel);
2639 // ieee->set_chan(ieee->dev,ieee->current_network.channel);
2641 for(i
= 0; i
< 17; i
++) {
2642 ieee
->last_rxseq_num
[i
] = -1;
2643 ieee
->last_rxfrag_num
[i
] = -1;
2644 ieee
->last_packet_time
[i
] = 0;
2647 ieee
->init_wmmparam_flag
= 0;//reinitialize AC_xx_PARAM registers.
2650 /* if the user set the MAC of the ad-hoc cell and then
2651 * switch to managed mode, shall we make sure that association
2652 * attempts does not fail just because the user provide the essid
2653 * and the nic is still checking for the AP MAC ??
2655 if (ieee
->iw_mode
== IW_MODE_INFRA
)
2656 ieee80211_start_bss(ieee
);
2658 else if (ieee
->iw_mode
== IW_MODE_ADHOC
)
2659 ieee80211_start_ibss(ieee
);
2661 else if (ieee
->iw_mode
== IW_MODE_MASTER
)
2662 ieee80211_start_master_bss(ieee
);
2664 else if(ieee
->iw_mode
== IW_MODE_MONITOR
)
2665 ieee80211_start_monitor_mode(ieee
);
2669 #define DRV_NAME "Ieee80211"
2670 void ieee80211_softmac_init(struct ieee80211_device
*ieee
)
2673 memset(&ieee
->current_network
, 0, sizeof(struct ieee80211_network
));
2675 ieee
->state
= IEEE80211_NOLINK
;
2676 ieee
->sync_scan_hurryup
= 0;
2677 for(i
= 0; i
< 5; i
++) {
2678 ieee
->seq_ctrl
[i
] = 0;
2680 ieee
->pDot11dInfo
= kzalloc(sizeof(RT_DOT11D_INFO
), GFP_ATOMIC
);
2681 if (!ieee
->pDot11dInfo
)
2682 IEEE80211_DEBUG(IEEE80211_DL_ERR
, "can't alloc memory for DOT11D\n");
2683 //added for AP roaming
2684 ieee
->LinkDetectInfo
.SlotNum
= 2;
2685 ieee
->LinkDetectInfo
.NumRecvBcnInPeriod
=0;
2686 ieee
->LinkDetectInfo
.NumRecvDataInPeriod
=0;
2689 ieee
->queue_stop
= 0;
2691 ieee
->softmac_features
= 0; //so IEEE2100-like driver are happy
2694 ieee
->proto_started
= 0;
2695 ieee
->basic_rate
= IEEE80211_DEFAULT_BASIC_RATE
;
2697 ieee
->ps
= IEEE80211_PS_DISABLED
;
2698 ieee
->sta_sleep
= 0;
2699 ieee
->Regdot11HTOperationalRateSet
[0]= 0xff;//support MCS 0~7
2700 ieee
->Regdot11HTOperationalRateSet
[1]= 0xff;//support MCS 8~15
2701 ieee
->Regdot11HTOperationalRateSet
[4]= 0x01;
2703 ieee
->actscanning
= false;
2704 ieee
->beinretry
= false;
2705 ieee
->is_set_key
= false;
2706 init_mgmt_queue(ieee
);
2708 ieee
->sta_edca_param
[0] = 0x0000A403;
2709 ieee
->sta_edca_param
[1] = 0x0000A427;
2710 ieee
->sta_edca_param
[2] = 0x005E4342;
2711 ieee
->sta_edca_param
[3] = 0x002F3262;
2712 ieee
->aggregation
= true;
2713 ieee
->enable_rx_imm_BA
= true;
2714 ieee
->tx_pending
.txb
= NULL
;
2716 setup_timer(&ieee
->associate_timer
, ieee80211_associate_abort_cb
,
2717 (unsigned long)ieee
);
2719 setup_timer(&ieee
->beacon_timer
, ieee80211_send_beacon_cb
,
2720 (unsigned long)ieee
);
2723 INIT_DELAYED_WORK(&ieee
->start_ibss_wq
, ieee80211_start_ibss_wq
);
2724 INIT_WORK(&ieee
->associate_complete_wq
, ieee80211_associate_complete_wq
);
2725 INIT_WORK(&ieee
->associate_procedure_wq
, ieee80211_associate_procedure_wq
);
2726 INIT_DELAYED_WORK(&ieee
->softmac_scan_wq
, ieee80211_softmac_scan_wq
);
2727 INIT_DELAYED_WORK(&ieee
->associate_retry_wq
, ieee80211_associate_retry_wq
);
2728 INIT_WORK(&ieee
->wx_sync_scan_wq
, ieee80211_wx_sync_scan_wq
);
2731 sema_init(&ieee
->wx_sem
, 1);
2732 sema_init(&ieee
->scan_sem
, 1);
2734 spin_lock_init(&ieee
->mgmt_tx_lock
);
2735 spin_lock_init(&ieee
->beacon_lock
);
2737 tasklet_init(&ieee
->ps_task
,
2738 (void(*)(unsigned long)) ieee80211_sta_ps
,
2739 (unsigned long)ieee
);
2743 void ieee80211_softmac_free(struct ieee80211_device
*ieee
)
2745 down(&ieee
->wx_sem
);
2746 kfree(ieee
->pDot11dInfo
);
2747 ieee
->pDot11dInfo
= NULL
;
2748 del_timer_sync(&ieee
->associate_timer
);
2750 cancel_delayed_work(&ieee
->associate_retry_wq
);
2755 /********************************************************
2756 * Start of WPA code. *
2757 * this is stolen from the ipw2200 driver *
2758 ********************************************************/
2761 static int ieee80211_wpa_enable(struct ieee80211_device
*ieee
, int value
)
2763 /* This is called when wpa_supplicant loads and closes the driver
2765 printk("%s WPA\n",value
? "enabling" : "disabling");
2766 ieee
->wpa_enabled
= value
;
2771 static void ieee80211_wpa_assoc_frame(struct ieee80211_device
*ieee
,
2772 char *wpa_ie
, int wpa_ie_len
)
2774 /* make sure WPA is enabled */
2775 ieee80211_wpa_enable(ieee
, 1);
2777 ieee80211_disassociate(ieee
);
2781 static int ieee80211_wpa_mlme(struct ieee80211_device
*ieee
, int command
, int reason
)
2787 case IEEE_MLME_STA_DEAUTH
:
2791 case IEEE_MLME_STA_DISASSOC
:
2792 ieee80211_disassociate(ieee
);
2796 printk("Unknown MLME request: %d\n", command
);
2804 static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device
*ieee
,
2805 struct ieee_param
*param
, int plen
)
2809 if (param
->u
.wpa_ie
.len
> MAX_WPA_IE_LEN
||
2810 (param
->u
.wpa_ie
.len
&& param
->u
.wpa_ie
.data
== NULL
))
2813 if (param
->u
.wpa_ie
.len
) {
2814 buf
= kmemdup(param
->u
.wpa_ie
.data
, param
->u
.wpa_ie
.len
,
2819 kfree(ieee
->wpa_ie
);
2821 ieee
->wpa_ie_len
= param
->u
.wpa_ie
.len
;
2823 kfree(ieee
->wpa_ie
);
2824 ieee
->wpa_ie
= NULL
;
2825 ieee
->wpa_ie_len
= 0;
2828 ieee80211_wpa_assoc_frame(ieee
, ieee
->wpa_ie
, ieee
->wpa_ie_len
);
2832 #define AUTH_ALG_OPEN_SYSTEM 0x1
2833 #define AUTH_ALG_SHARED_KEY 0x2
2835 static int ieee80211_wpa_set_auth_algs(struct ieee80211_device
*ieee
, int value
)
2838 struct ieee80211_security sec
= {
2839 .flags
= SEC_AUTH_MODE
,
2842 if (value
& AUTH_ALG_SHARED_KEY
) {
2843 sec
.auth_mode
= WLAN_AUTH_SHARED_KEY
;
2845 ieee
->auth_mode
= 1;
2846 } else if (value
& AUTH_ALG_OPEN_SYSTEM
){
2847 sec
.auth_mode
= WLAN_AUTH_OPEN
;
2849 ieee
->auth_mode
= 0;
2851 else if (value
& IW_AUTH_ALG_LEAP
){
2852 sec
.auth_mode
= WLAN_AUTH_LEAP
;
2854 ieee
->auth_mode
= 2;
2858 if (ieee
->set_security
)
2859 ieee
->set_security(ieee
->dev
, &sec
);
2861 // ret = -EOPNOTSUPP;
2866 static int ieee80211_wpa_set_param(struct ieee80211_device
*ieee
, u8 name
, u32 value
)
2869 unsigned long flags
;
2872 case IEEE_PARAM_WPA_ENABLED
:
2873 ret
= ieee80211_wpa_enable(ieee
, value
);
2876 case IEEE_PARAM_TKIP_COUNTERMEASURES
:
2877 ieee
->tkip_countermeasures
=value
;
2880 case IEEE_PARAM_DROP_UNENCRYPTED
: {
2883 * wpa_supplicant calls set_wpa_enabled when the driver
2884 * is loaded and unloaded, regardless of if WPA is being
2885 * used. No other calls are made which can be used to
2886 * determine if encryption will be used or not prior to
2887 * association being expected. If encryption is not being
2888 * used, drop_unencrypted is set to false, else true -- we
2889 * can use this to determine if the CAP_PRIVACY_ON bit should
2892 struct ieee80211_security sec
= {
2893 .flags
= SEC_ENABLED
,
2896 ieee
->drop_unencrypted
= value
;
2897 /* We only change SEC_LEVEL for open mode. Others
2898 * are set by ipw_wpa_set_encryption.
2901 sec
.flags
|= SEC_LEVEL
;
2902 sec
.level
= SEC_LEVEL_0
;
2905 sec
.flags
|= SEC_LEVEL
;
2906 sec
.level
= SEC_LEVEL_1
;
2908 if (ieee
->set_security
)
2909 ieee
->set_security(ieee
->dev
, &sec
);
2913 case IEEE_PARAM_PRIVACY_INVOKED
:
2914 ieee
->privacy_invoked
=value
;
2917 case IEEE_PARAM_AUTH_ALGS
:
2918 ret
= ieee80211_wpa_set_auth_algs(ieee
, value
);
2921 case IEEE_PARAM_IEEE_802_1X
:
2922 ieee
->ieee802_1x
=value
;
2924 case IEEE_PARAM_WPAX_SELECT
:
2925 // added for WPA2 mixed mode
2926 spin_lock_irqsave(&ieee
->wpax_suitlist_lock
, flags
);
2927 ieee
->wpax_type_set
= 1;
2928 ieee
->wpax_type_notify
= value
;
2929 spin_unlock_irqrestore(&ieee
->wpax_suitlist_lock
, flags
);
2933 printk("Unknown WPA param: %d\n",name
);
2940 /* implementation borrowed from hostap driver */
2942 static int ieee80211_wpa_set_encryption(struct ieee80211_device
*ieee
,
2943 struct ieee_param
*param
, int param_len
)
2947 struct ieee80211_crypto_ops
*ops
;
2948 struct ieee80211_crypt_data
**crypt
;
2950 struct ieee80211_security sec
= {
2954 param
->u
.crypt
.err
= 0;
2955 param
->u
.crypt
.alg
[IEEE_CRYPT_ALG_NAME_LEN
- 1] = '\0';
2958 (int) ((char *) param
->u
.crypt
.key
- (char *) param
) +
2959 param
->u
.crypt
.key_len
) {
2960 printk("Len mismatch %d, %d\n", param_len
,
2961 param
->u
.crypt
.key_len
);
2964 if (is_broadcast_ether_addr(param
->sta_addr
)) {
2965 if (param
->u
.crypt
.idx
>= WEP_KEYS
)
2967 crypt
= &ieee
->crypt
[param
->u
.crypt
.idx
];
2972 if (strcmp(param
->u
.crypt
.alg
, "none") == 0) {
2977 sec
.level
= SEC_LEVEL_0
;
2978 sec
.flags
|= SEC_ENABLED
| SEC_LEVEL
;
2979 ieee80211_crypt_delayed_deinit(ieee
, crypt
);
2986 sec
.flags
|= SEC_ENABLED
;
2988 /* IPW HW cannot build TKIP MIC, host decryption still needed. */
2989 if (!(ieee
->host_encrypt
|| ieee
->host_decrypt
) &&
2990 strcmp(param
->u
.crypt
.alg
, "TKIP"))
2991 goto skip_host_crypt
;
2993 ops
= ieee80211_get_crypto_ops(param
->u
.crypt
.alg
);
2994 if (ops
== NULL
&& strcmp(param
->u
.crypt
.alg
, "WEP") == 0) {
2995 request_module("ieee80211_crypt_wep");
2996 ops
= ieee80211_get_crypto_ops(param
->u
.crypt
.alg
);
2997 //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
2998 } else if (ops
== NULL
&& strcmp(param
->u
.crypt
.alg
, "TKIP") == 0) {
2999 request_module("ieee80211_crypt_tkip");
3000 ops
= ieee80211_get_crypto_ops(param
->u
.crypt
.alg
);
3001 } else if (ops
== NULL
&& strcmp(param
->u
.crypt
.alg
, "CCMP") == 0) {
3002 request_module("ieee80211_crypt_ccmp");
3003 ops
= ieee80211_get_crypto_ops(param
->u
.crypt
.alg
);
3006 printk("unknown crypto alg '%s'\n", param
->u
.crypt
.alg
);
3007 param
->u
.crypt
.err
= IEEE_CRYPT_ERR_UNKNOWN_ALG
;
3012 if (*crypt
== NULL
|| (*crypt
)->ops
!= ops
) {
3013 struct ieee80211_crypt_data
*new_crypt
;
3015 ieee80211_crypt_delayed_deinit(ieee
, crypt
);
3017 new_crypt
= kzalloc(sizeof(*new_crypt
), GFP_KERNEL
);
3018 if (new_crypt
== NULL
) {
3022 new_crypt
->ops
= ops
;
3023 if (new_crypt
->ops
&& try_module_get(new_crypt
->ops
->owner
))
3025 new_crypt
->ops
->init(param
->u
.crypt
.idx
);
3027 if (new_crypt
->priv
== NULL
) {
3029 param
->u
.crypt
.err
= IEEE_CRYPT_ERR_CRYPT_INIT_FAILED
;
3037 if (param
->u
.crypt
.key_len
> 0 && (*crypt
)->ops
->set_key
&&
3038 (*crypt
)->ops
->set_key(param
->u
.crypt
.key
,
3039 param
->u
.crypt
.key_len
, param
->u
.crypt
.seq
,
3040 (*crypt
)->priv
) < 0) {
3041 printk("key setting failed\n");
3042 param
->u
.crypt
.err
= IEEE_CRYPT_ERR_KEY_SET_FAILED
;
3048 if (param
->u
.crypt
.set_tx
) {
3049 ieee
->tx_keyidx
= param
->u
.crypt
.idx
;
3050 sec
.active_key
= param
->u
.crypt
.idx
;
3051 sec
.flags
|= SEC_ACTIVE_KEY
;
3053 sec
.flags
&= ~SEC_ACTIVE_KEY
;
3055 if (param
->u
.crypt
.alg
!= NULL
) {
3056 memcpy(sec
.keys
[param
->u
.crypt
.idx
],
3058 param
->u
.crypt
.key_len
);
3059 sec
.key_sizes
[param
->u
.crypt
.idx
] = param
->u
.crypt
.key_len
;
3060 sec
.flags
|= (1 << param
->u
.crypt
.idx
);
3062 if (strcmp(param
->u
.crypt
.alg
, "WEP") == 0) {
3063 sec
.flags
|= SEC_LEVEL
;
3064 sec
.level
= SEC_LEVEL_1
;
3065 } else if (strcmp(param
->u
.crypt
.alg
, "TKIP") == 0) {
3066 sec
.flags
|= SEC_LEVEL
;
3067 sec
.level
= SEC_LEVEL_2
;
3068 } else if (strcmp(param
->u
.crypt
.alg
, "CCMP") == 0) {
3069 sec
.flags
|= SEC_LEVEL
;
3070 sec
.level
= SEC_LEVEL_3
;
3074 if (ieee
->set_security
)
3075 ieee
->set_security(ieee
->dev
, &sec
);
3077 /* Do not reset port if card is in Managed mode since resetting will
3078 * generate new IEEE 802.11 authentication which may end up in looping
3079 * with IEEE 802.1X. If your hardware requires a reset after WEP
3080 * configuration (for example... Prism2), implement the reset_port in
3081 * the callbacks structures used to initialize the 802.11 stack. */
3082 if (ieee
->reset_on_keychange
&&
3083 ieee
->iw_mode
!= IW_MODE_INFRA
&&
3085 ieee
->reset_port(ieee
->dev
)) {
3086 printk("reset_port failed\n");
3087 param
->u
.crypt
.err
= IEEE_CRYPT_ERR_CARD_CONF_FAILED
;
3094 inline struct sk_buff
*ieee80211_disassociate_skb(
3095 struct ieee80211_network
*beacon
,
3096 struct ieee80211_device
*ieee
,
3099 struct sk_buff
*skb
;
3100 struct ieee80211_disassoc
*disass
;
3102 skb
= dev_alloc_skb(sizeof(struct ieee80211_disassoc
));
3106 disass
= (struct ieee80211_disassoc
*) skb_put(skb
,sizeof(struct ieee80211_disassoc
));
3107 disass
->header
.frame_ctl
= cpu_to_le16(IEEE80211_STYPE_DISASSOC
);
3108 disass
->header
.duration_id
= 0;
3110 memcpy(disass
->header
.addr1
, beacon
->bssid
, ETH_ALEN
);
3111 memcpy(disass
->header
.addr2
, ieee
->dev
->dev_addr
, ETH_ALEN
);
3112 memcpy(disass
->header
.addr3
, beacon
->bssid
, ETH_ALEN
);
3114 disass
->reason
= cpu_to_le16(asRsn
);
3121 struct ieee80211_device
*ieee
,
3126 struct ieee80211_network
*beacon
= &ieee
->current_network
;
3127 struct sk_buff
*skb
;
3128 skb
= ieee80211_disassociate_skb(beacon
,ieee
,asRsn
);
3130 softmac_mgmt_xmit(skb
, ieee
);
3131 //dev_kfree_skb_any(skb);//edit by thomas
3134 EXPORT_SYMBOL(SendDisassociation
);
3136 int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device
*ieee
, struct iw_point
*p
)
3138 struct ieee_param
*param
;
3141 down(&ieee
->wx_sem
);
3142 //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
3144 if (p
->length
< sizeof(struct ieee_param
) || !p
->pointer
) {
3149 param
= memdup_user(p
->pointer
, p
->length
);
3150 if (IS_ERR(param
)) {
3151 ret
= PTR_ERR(param
);
3155 switch (param
->cmd
) {
3157 case IEEE_CMD_SET_WPA_PARAM
:
3158 ret
= ieee80211_wpa_set_param(ieee
, param
->u
.wpa_param
.name
,
3159 param
->u
.wpa_param
.value
);
3162 case IEEE_CMD_SET_WPA_IE
:
3163 ret
= ieee80211_wpa_set_wpa_ie(ieee
, param
, p
->length
);
3166 case IEEE_CMD_SET_ENCRYPTION
:
3167 ret
= ieee80211_wpa_set_encryption(ieee
, param
, p
->length
);
3171 ret
= ieee80211_wpa_mlme(ieee
, param
->u
.mlme
.command
,
3172 param
->u
.mlme
.reason_code
);
3176 printk("Unknown WPA supplicant request: %d\n",param
->cmd
);
3181 if (ret
== 0 && copy_to_user(p
->pointer
, param
, p
->length
))
3190 EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl
);
3192 void notify_wx_assoc_event(struct ieee80211_device
*ieee
)
3194 union iwreq_data wrqu
;
3195 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
3196 if (ieee
->state
== IEEE80211_LINKED
)
3197 memcpy(wrqu
.ap_addr
.sa_data
, ieee
->current_network
.bssid
, ETH_ALEN
);
3199 eth_zero_addr(wrqu
.ap_addr
.sa_data
);
3200 wireless_send_event(ieee
->dev
, SIOCGIWAP
, &wrqu
, NULL
);
3202 EXPORT_SYMBOL(notify_wx_assoc_event
);