• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* IEEE 802.11 SoftMAC layer
2  * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
3  *
4  * Mostly extracted from the rtl8180-sa2400 driver for the
5  * in-kernel generic ieee802.11 stack.
6  *
7  * Few lines might be stolen from other part of the ieee80211
8  * stack. Copyright who own it's copyright
9  *
10  * WPA code stolen from the ipw2200 driver.
11  * Copyright who own it's copyright.
12  *
13  * released under the GPL
14  */
15 
16 
17 #include "ieee80211.h"
18 
19 #include <linux/random.h>
20 #include <linux/delay.h>
21 #include <linux/slab.h>
22 #include <asm/uaccess.h>
23 #include <linux/etherdevice.h>
24 
25 #include "dot11d.h"
26 
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
34 };
35 
ieee80211_is_54g(const struct ieee80211_network * net)36 short ieee80211_is_54g(const struct ieee80211_network *net)
37 {
38 	return (net->rates_ex_len > 0) || (net->rates_len > 4);
39 }
40 
ieee80211_is_shortslot(const struct ieee80211_network * net)41 short ieee80211_is_shortslot(const struct ieee80211_network *net)
42 {
43 	return net->capability & WLAN_CAPABILITY_SHORT_SLOT;
44 }
45 
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
49  */
ieee80211_MFIE_rate_len(struct ieee80211_device * ieee)50 unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
51 {
52 	unsigned int rate_len = 0;
53 
54 	if (ieee->modulation & IEEE80211_CCK_MODULATION)
55 		rate_len = IEEE80211_CCK_RATE_LEN + 2;
56 
57 	if (ieee->modulation & IEEE80211_OFDM_MODULATION)
58 
59 		rate_len += IEEE80211_OFDM_RATE_LEN + 2;
60 
61 	return rate_len;
62 }
63 
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.
67  */
ieee80211_MFIE_Brate(struct ieee80211_device * ieee,u8 ** tag_p)68 void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
69 {
70 	u8 *tag = *tag_p;
71 
72 	if (ieee->modulation & IEEE80211_CCK_MODULATION){
73 		*tag++ = MFIE_TYPE_RATES;
74 		*tag++ = 4;
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;
79 	}
80 
81 	/* We may add an option for custom rates that specific HW might support */
82 	*tag_p = tag;
83 }
84 
ieee80211_MFIE_Grate(struct ieee80211_device * ieee,u8 ** tag_p)85 void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
86 {
87 	u8 *tag = *tag_p;
88 
89 		if (ieee->modulation & IEEE80211_OFDM_MODULATION){
90 
91 		*tag++ = MFIE_TYPE_RATES_EX;
92 		*tag++ = 8;
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;
101 
102 	}
103 
104 	/* We may add an option for custom rates that specific HW might support */
105 	*tag_p = tag;
106 }
107 
108 
ieee80211_WMM_Info(struct ieee80211_device * ieee,u8 ** tag_p)109 void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) {
110 	u8 *tag = *tag_p;
111 
112 	*tag++ = MFIE_TYPE_GENERIC; //0
113 	*tag++ = 7;
114 	*tag++ = 0x00;
115 	*tag++ = 0x50;
116 	*tag++ = 0xf2;
117 	*tag++ = 0x02;//5
118 	*tag++ = 0x00;
119 	*tag++ = 0x01;
120 #ifdef SUPPORT_USPD
121 	if(ieee->current_network.wmm_info & 0x80) {
122 		*tag++ = 0x0f|MAX_SP_Len;
123 	} else {
124 		*tag++ = MAX_SP_Len;
125 	}
126 #else
127 	*tag++ = MAX_SP_Len;
128 #endif
129 	*tag_p = tag;
130 }
131 
132 #ifdef THOMAS_TURBO
ieee80211_TURBO_Info(struct ieee80211_device * ieee,u8 ** tag_p)133 void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
134 	u8 *tag = *tag_p;
135 
136 	*tag++ = MFIE_TYPE_GENERIC; //0
137 	*tag++ = 7;
138 	*tag++ = 0x00;
139 	*tag++ = 0xe0;
140 	*tag++ = 0x4c;
141 	*tag++ = 0x01;//5
142 	*tag++ = 0x02;
143 	*tag++ = 0x11;
144 	*tag++ = 0x00;
145 
146 	*tag_p = tag;
147 	printk(KERN_ALERT "This is enable turbo mode IE process\n");
148 }
149 #endif
150 
enqueue_mgmt(struct ieee80211_device * ieee,struct sk_buff * skb)151 void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
152 {
153 	int nh;
154 	nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
155 
156 /*
157  * if the queue is full but we have newer frames then
158  * just overwrites the oldest.
159  *
160  * if (nh == ieee->mgmt_queue_tail)
161  *		return -1;
162  */
163 	ieee->mgmt_queue_head = nh;
164 	ieee->mgmt_queue_ring[nh] = skb;
165 
166 	//return 0;
167 }
168 
dequeue_mgmt(struct ieee80211_device * ieee)169 struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
170 {
171 	struct sk_buff *ret;
172 
173 	if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
174 		return NULL;
175 
176 	ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
177 
178 	ieee->mgmt_queue_tail =
179 		(ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
180 
181 	return ret;
182 }
183 
init_mgmt_queue(struct ieee80211_device * ieee)184 void init_mgmt_queue(struct ieee80211_device *ieee)
185 {
186 	ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
187 }
188 
MgntQuery_MgntFrameTxRate(struct ieee80211_device * ieee)189 u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee)
190 {
191 	PRT_HIGH_THROUGHPUT      pHTInfo = ieee->pHTInfo;
192 	u8 rate;
193 
194 	// 2008/01/25 MH For broadcom, MGNT frame set as OFDM 6M.
195 	if(pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M)
196 		rate = 0x0c;
197 	else
198 		rate = ieee->basic_rate & 0x7f;
199 
200 	if(rate == 0){
201 		// 2005.01.26, by rcnjko.
202 		if(ieee->mode == IEEE_A||
203 		   ieee->mode== IEEE_N_5G||
204 		   (ieee->mode== IEEE_N_24G&&!pHTInfo->bCurSuppCCK))
205 			rate = 0x0c;
206 		else
207 			rate = 0x02;
208 	}
209 
210 	/*
211 	// Data rate of ProbeReq is already decided. Annie, 2005-03-31
212 	if( pMgntInfo->bScanInProgress || (pMgntInfo->bDualModeScanStep!=0) )
213 	{
214 	if(pMgntInfo->dot11CurrentWirelessMode==WIRELESS_MODE_A)
215 	rate = 0x0c;
216 	else
217 	rate = 0x02;
218 	}
219 	 */
220 	return rate;
221 }
222 
223 
224 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
225 
softmac_mgmt_xmit(struct sk_buff * skb,struct ieee80211_device * ieee)226 inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
227 {
228 	unsigned long flags;
229 	short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
230 	struct ieee80211_hdr_3addr  *header=
231 		(struct ieee80211_hdr_3addr  *) skb->data;
232 
233 	cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8);
234 	spin_lock_irqsave(&ieee->lock, flags);
235 
236 	/* called with 2nd param 0, no mgmt lock required */
237 	ieee80211_sta_wakeup(ieee,0);
238 
239 	tcb_desc->queue_index = MGNT_QUEUE;
240 	tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
241 	tcb_desc->RATRIndex = 7;
242 	tcb_desc->bTxDisableRateFallBack = 1;
243 	tcb_desc->bTxUseDriverAssingedRate = 1;
244 
245 	if(single){
246 		if(ieee->queue_stop){
247 			enqueue_mgmt(ieee,skb);
248 		}else{
249 			header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
250 
251 			if (ieee->seq_ctrl[0] == 0xFFF)
252 				ieee->seq_ctrl[0] = 0;
253 			else
254 				ieee->seq_ctrl[0]++;
255 
256 			/* avoid watchdog triggers */
257 			ieee->dev->trans_start = jiffies;
258 			ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
259 			//dev_kfree_skb_any(skb);//edit by thomas
260 		}
261 
262 		spin_unlock_irqrestore(&ieee->lock, flags);
263 	}else{
264 		spin_unlock_irqrestore(&ieee->lock, flags);
265 		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
266 
267 		header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
268 
269 		if (ieee->seq_ctrl[0] == 0xFFF)
270 			ieee->seq_ctrl[0] = 0;
271 		else
272 			ieee->seq_ctrl[0]++;
273 
274 		/* check whether the managed packet queued greater than 5 */
275 		if(!ieee->check_nic_enough_desc(ieee->dev,tcb_desc->queue_index)||\
276 				(skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)||\
277 				(ieee->queue_stop) ) {
278 			/* insert the skb packet to the management queue */
279 			/* as for the completion function, it does not need
280 			 * to check it any more.
281 			 * */
282 			printk("%s():insert to waitqueue!\n",__FUNCTION__);
283 			skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb);
284 		} else {
285 			//printk("TX packet!\n");
286 			ieee->softmac_hard_start_xmit(skb,ieee->dev);
287 			//dev_kfree_skb_any(skb);//edit by thomas
288 		}
289 		spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
290 	}
291 }
292 
softmac_ps_mgmt_xmit(struct sk_buff * skb,struct ieee80211_device * ieee)293 inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
294 {
295 
296 	short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
297 	struct ieee80211_hdr_3addr  *header =
298 		(struct ieee80211_hdr_3addr  *) skb->data;
299 
300 
301 	if(single){
302 
303 		header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
304 
305 		if (ieee->seq_ctrl[0] == 0xFFF)
306 			ieee->seq_ctrl[0] = 0;
307 		else
308 			ieee->seq_ctrl[0]++;
309 
310 		/* avoid watchdog triggers */
311 		ieee->dev->trans_start = jiffies;
312 		ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
313 
314 	}else{
315 
316 		header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
317 
318 		if (ieee->seq_ctrl[0] == 0xFFF)
319 			ieee->seq_ctrl[0] = 0;
320 		else
321 			ieee->seq_ctrl[0]++;
322 
323 		ieee->softmac_hard_start_xmit(skb,ieee->dev);
324 
325 	}
326 	//dev_kfree_skb_any(skb);//edit by thomas
327 }
328 
ieee80211_probe_req(struct ieee80211_device * ieee)329 inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
330 {
331 	unsigned int len,rate_len;
332 	u8 *tag;
333 	struct sk_buff *skb;
334 	struct ieee80211_probe_request *req;
335 
336 	len = ieee->current_network.ssid_len;
337 
338 	rate_len = ieee80211_MFIE_rate_len(ieee);
339 
340 	skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
341 			    2 + len + rate_len + ieee->tx_headroom);
342 	if (!skb)
343 		return NULL;
344 
345 	skb_reserve(skb, ieee->tx_headroom);
346 
347 	req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
348 	req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
349 	req->header.duration_id = 0; //FIXME: is this OK ?
350 
351 	memset(req->header.addr1, 0xff, ETH_ALEN);
352 	memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
353 	memset(req->header.addr3, 0xff, ETH_ALEN);
354 
355 	tag = (u8 *) skb_put(skb,len+2+rate_len);
356 
357 	*tag++ = MFIE_TYPE_SSID;
358 	*tag++ = len;
359 	memcpy(tag, ieee->current_network.ssid, len);
360 	tag += len;
361 
362 	ieee80211_MFIE_Brate(ieee,&tag);
363 	ieee80211_MFIE_Grate(ieee,&tag);
364 	return skb;
365 }
366 
367 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
ieee80211_send_beacon(struct ieee80211_device * ieee)368 void ieee80211_send_beacon(struct ieee80211_device *ieee)
369 {
370 	struct sk_buff *skb;
371 	if(!ieee->ieee_up)
372 		return;
373 	//unsigned long flags;
374 	skb = ieee80211_get_beacon_(ieee);
375 
376 	if (skb){
377 		softmac_mgmt_xmit(skb, ieee);
378 		ieee->softmac_stats.tx_beacons++;
379 		//dev_kfree_skb_any(skb);//edit by thomas
380 	}
381 //	ieee->beacon_timer.expires = jiffies +
382 //		(MSECS( ieee->current_network.beacon_interval -5));
383 
384 	//spin_lock_irqsave(&ieee->beacon_lock,flags);
385 	if(ieee->beacon_txing && ieee->ieee_up){
386 //		if(!timer_pending(&ieee->beacon_timer))
387 //			add_timer(&ieee->beacon_timer);
388 		mod_timer(&ieee->beacon_timer,jiffies+(MSECS(ieee->current_network.beacon_interval-5)));
389 	}
390 	//spin_unlock_irqrestore(&ieee->beacon_lock,flags);
391 }
392 
393 
ieee80211_send_beacon_cb(unsigned long _ieee)394 void ieee80211_send_beacon_cb(unsigned long _ieee)
395 {
396 	struct ieee80211_device *ieee =
397 		(struct ieee80211_device *) _ieee;
398 	unsigned long flags;
399 
400 	spin_lock_irqsave(&ieee->beacon_lock, flags);
401 	ieee80211_send_beacon(ieee);
402 	spin_unlock_irqrestore(&ieee->beacon_lock, flags);
403 }
404 
405 
ieee80211_send_probe(struct ieee80211_device * ieee)406 void ieee80211_send_probe(struct ieee80211_device *ieee)
407 {
408 	struct sk_buff *skb;
409 
410 	skb = ieee80211_probe_req(ieee);
411 	if (skb){
412 		softmac_mgmt_xmit(skb, ieee);
413 		ieee->softmac_stats.tx_probe_rq++;
414 		//dev_kfree_skb_any(skb);//edit by thomas
415 	}
416 }
417 
ieee80211_send_probe_requests(struct ieee80211_device * ieee)418 void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
419 {
420 	if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){
421 		ieee80211_send_probe(ieee);
422 		ieee80211_send_probe(ieee);
423 	}
424 }
425 
426 /* this performs syncro scan blocking the caller until all channels
427  * in the allowed channel map has been checked.
428  */
ieee80211_softmac_scan_syncro(struct ieee80211_device * ieee)429 void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
430 {
431 	short ch = 0;
432 	u8 channel_map[MAX_CHANNEL_NUMBER+1];
433 	memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
434 	down(&ieee->scan_sem);
435 
436 	while(1)
437 	{
438 
439 		do{
440 			ch++;
441 			if (ch > MAX_CHANNEL_NUMBER)
442 				goto out; /* scan completed */
443 		}while(!channel_map[ch]);
444 
445 		/* this function can be called in two situations
446 		 * 1- We have switched to ad-hoc mode and we are
447 		 *    performing a complete syncro scan before conclude
448 		 *    there are no interesting cell and to create a
449 		 *    new one. In this case the link state is
450 		 *    IEEE80211_NOLINK until we found an interesting cell.
451 		 *    If so the ieee8021_new_net, called by the RX path
452 		 *    will set the state to IEEE80211_LINKED, so we stop
453 		 *    scanning
454 		 * 2- We are linked and the root uses run iwlist scan.
455 		 *    So we switch to IEEE80211_LINKED_SCANNING to remember
456 		 *    that we are still logically linked (not interested in
457 		 *    new network events, despite for updating the net list,
458 		 *    but we are temporarly 'unlinked' as the driver shall
459 		 *    not filter RX frames and the channel is changing.
460 		 * So the only situation in witch are interested is to check
461 		 * if the state become LINKED because of the #1 situation
462 		 */
463 
464 		if (ieee->state == IEEE80211_LINKED)
465 			goto out;
466 		ieee->set_chan(ieee->dev, ch);
467 		if(channel_map[ch] == 1)
468 		ieee80211_send_probe_requests(ieee);
469 
470 		/* this prevent excessive time wait when we
471 		 * need to wait for a syncro scan to end..
472 		 */
473 		if(ieee->state < IEEE80211_LINKED)
474 			;
475 		else
476 		if (ieee->sync_scan_hurryup)
477 			goto out;
478 
479 
480 		msleep_interruptible_rsl(IEEE80211_SOFTMAC_SCAN_TIME);
481 
482 	}
483 out:
484 	if(ieee->state < IEEE80211_LINKED){
485 		ieee->actscanning = false;
486 		up(&ieee->scan_sem);
487 	}
488 	else{
489 	ieee->sync_scan_hurryup = 0;
490 	if(IS_DOT11D_ENABLE(ieee))
491 		DOT11D_ScanComplete(ieee);
492 	up(&ieee->scan_sem);
493 }
494 }
495 
496 
ieee80211_softmac_scan_wq(struct work_struct * work)497 void ieee80211_softmac_scan_wq(struct work_struct *work)
498 {
499 	struct delayed_work *dwork = container_of(work, struct delayed_work, work);
500 	struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
501 	static short watchdog;
502 	u8 channel_map[MAX_CHANNEL_NUMBER+1];
503 	memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
504 	if(!ieee->ieee_up)
505 		return;
506 	down(&ieee->scan_sem);
507 	do{
508 		ieee->current_network.channel =
509 			(ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
510 		if (watchdog++ > MAX_CHANNEL_NUMBER)
511 		{
512 		//if current channel is not in channel map, set to default channel.
513 			if (!channel_map[ieee->current_network.channel]) {
514 				ieee->current_network.channel = 6;
515 				goto out; /* no good chans */
516 			}
517 		}
518 	}while(!channel_map[ieee->current_network.channel]);
519 	if (ieee->scanning == 0 )
520 		goto out;
521 	ieee->set_chan(ieee->dev, ieee->current_network.channel);
522 	if(channel_map[ieee->current_network.channel] == 1)
523 	ieee80211_send_probe_requests(ieee);
524 
525 
526 	queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
527 
528 	up(&ieee->scan_sem);
529 	return;
530 out:
531 	if(IS_DOT11D_ENABLE(ieee))
532 		DOT11D_ScanComplete(ieee);
533 	ieee->actscanning = false;
534 	watchdog = 0;
535 	ieee->scanning = 0;
536 	up(&ieee->scan_sem);
537 }
538 
539 
540 
ieee80211_beacons_start(struct ieee80211_device * ieee)541 void ieee80211_beacons_start(struct ieee80211_device *ieee)
542 {
543 	unsigned long flags;
544 	spin_lock_irqsave(&ieee->beacon_lock,flags);
545 
546 	ieee->beacon_txing = 1;
547 	ieee80211_send_beacon(ieee);
548 
549 	spin_unlock_irqrestore(&ieee->beacon_lock,flags);
550 }
551 
ieee80211_beacons_stop(struct ieee80211_device * ieee)552 void ieee80211_beacons_stop(struct ieee80211_device *ieee)
553 {
554 	unsigned long flags;
555 
556 	spin_lock_irqsave(&ieee->beacon_lock,flags);
557 
558 	ieee->beacon_txing = 0;
559 	del_timer_sync(&ieee->beacon_timer);
560 
561 	spin_unlock_irqrestore(&ieee->beacon_lock,flags);
562 
563 }
564 
565 
ieee80211_stop_send_beacons(struct ieee80211_device * ieee)566 void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
567 {
568 	if(ieee->stop_send_beacons)
569 		ieee->stop_send_beacons(ieee->dev);
570 	if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
571 		ieee80211_beacons_stop(ieee);
572 }
573 
574 
ieee80211_start_send_beacons(struct ieee80211_device * ieee)575 void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
576 {
577 	if(ieee->start_send_beacons)
578 		ieee->start_send_beacons(ieee->dev,ieee->basic_rate);
579 	if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
580 		ieee80211_beacons_start(ieee);
581 }
582 
583 
ieee80211_softmac_stop_scan(struct ieee80211_device * ieee)584 void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
585 {
586 //	unsigned long flags;
587 
588 	//ieee->sync_scan_hurryup = 1;
589 
590 	down(&ieee->scan_sem);
591 //	spin_lock_irqsave(&ieee->lock, flags);
592 
593 	if (ieee->scanning == 1){
594 		ieee->scanning = 0;
595 
596 		cancel_delayed_work(&ieee->softmac_scan_wq);
597 	}
598 
599 //	spin_unlock_irqrestore(&ieee->lock, flags);
600 	up(&ieee->scan_sem);
601 }
602 
ieee80211_stop_scan(struct ieee80211_device * ieee)603 void ieee80211_stop_scan(struct ieee80211_device *ieee)
604 {
605 	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
606 		ieee80211_softmac_stop_scan(ieee);
607 	else
608 		ieee->stop_scan(ieee->dev);
609 }
610 
611 /* called with ieee->lock held */
ieee80211_start_scan(struct ieee80211_device * ieee)612 void ieee80211_start_scan(struct ieee80211_device *ieee)
613 {
614 	if(IS_DOT11D_ENABLE(ieee) )
615 	{
616 		if(IS_COUNTRY_IE_VALID(ieee))
617 		{
618 			RESET_CIE_WATCHDOG(ieee);
619 		}
620 	}
621 	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
622 		if (ieee->scanning == 0){
623 			ieee->scanning = 1;
624 			queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0);
625 		}
626 	}else
627 		ieee->start_scan(ieee->dev);
628 
629 }
630 
631 /* called with wx_sem held */
ieee80211_start_scan_syncro(struct ieee80211_device * ieee)632 void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
633 {
634 	if(IS_DOT11D_ENABLE(ieee) )
635 	{
636 		if(IS_COUNTRY_IE_VALID(ieee))
637 		{
638 			RESET_CIE_WATCHDOG(ieee);
639 		}
640 	}
641 	ieee->sync_scan_hurryup = 0;
642 	if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
643 		ieee80211_softmac_scan_syncro(ieee);
644 	else
645 		ieee->scan_syncro(ieee->dev);
646 
647 }
648 
ieee80211_authentication_req(struct ieee80211_network * beacon,struct ieee80211_device * ieee,int challengelen)649 inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
650 	struct ieee80211_device *ieee, int challengelen)
651 {
652 	struct sk_buff *skb;
653 	struct ieee80211_authentication *auth;
654 	int len = sizeof(struct ieee80211_authentication) + challengelen + ieee->tx_headroom;
655 
656 
657 	skb = dev_alloc_skb(len);
658 	if (!skb) return NULL;
659 
660 	skb_reserve(skb, ieee->tx_headroom);
661 	auth = (struct ieee80211_authentication *)
662 		skb_put(skb, sizeof(struct ieee80211_authentication));
663 
664 	auth->header.frame_ctl = IEEE80211_STYPE_AUTH;
665 	if (challengelen) auth->header.frame_ctl |= IEEE80211_FCTL_WEP;
666 
667 	auth->header.duration_id = 0x013a; //FIXME
668 
669 	memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
670 	memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
671 	memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
672 
673 	//auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
674 	if(ieee->auth_mode == 0)
675 		auth->algorithm = WLAN_AUTH_OPEN;
676 	else if(ieee->auth_mode == 1)
677 		auth->algorithm = WLAN_AUTH_SHARED_KEY;
678 	else if(ieee->auth_mode == 2)
679 		auth->algorithm = WLAN_AUTH_OPEN;//0x80;
680 	printk("=================>%s():auth->algorithm is %d\n",__FUNCTION__,auth->algorithm);
681 	auth->transaction = cpu_to_le16(ieee->associate_seq);
682 	ieee->associate_seq++;
683 
684 	auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
685 
686 	return skb;
687 
688 }
689 
690 
ieee80211_probe_resp(struct ieee80211_device * ieee,u8 * dest)691 static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
692 {
693 	u8 *tag;
694 	int beacon_size;
695 	struct ieee80211_probe_response *beacon_buf;
696 	struct sk_buff *skb = NULL;
697 	int encrypt;
698 	int atim_len,erp_len;
699 	struct ieee80211_crypt_data* crypt;
700 
701 	char *ssid = ieee->current_network.ssid;
702 	int ssid_len = ieee->current_network.ssid_len;
703 	int rate_len = ieee->current_network.rates_len+2;
704 	int rate_ex_len = ieee->current_network.rates_ex_len;
705 	int wpa_ie_len = ieee->wpa_ie_len;
706 	u8 erpinfo_content = 0;
707 
708 	u8* tmp_ht_cap_buf;
709 	u8 tmp_ht_cap_len=0;
710 	u8* tmp_ht_info_buf;
711 	u8 tmp_ht_info_len=0;
712 	PRT_HIGH_THROUGHPUT	pHTInfo = ieee->pHTInfo;
713 	u8* tmp_generic_ie_buf=NULL;
714 	u8 tmp_generic_ie_len=0;
715 
716 	if(rate_ex_len > 0) rate_ex_len+=2;
717 
718 	if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
719 		atim_len = 4;
720 	else
721 		atim_len = 0;
722 
723 	if(ieee80211_is_54g(&ieee->current_network))
724 		erp_len = 3;
725 	else
726 		erp_len = 0;
727 
728 
729 	crypt = ieee->crypt[ieee->tx_keyidx];
730 
731 
732 	encrypt = ieee->host_encrypt && crypt && crypt->ops &&
733 		((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len));
734 	//HT ralated element
735 	tmp_ht_cap_buf =(u8*) &(ieee->pHTInfo->SelfHTCap);
736 	tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap);
737 	tmp_ht_info_buf =(u8*) &(ieee->pHTInfo->SelfHTInfo);
738 	tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo);
739 	HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len,encrypt);
740 	HTConstructInfoElement(ieee,tmp_ht_info_buf,&tmp_ht_info_len, encrypt);
741 
742 
743 	if(pHTInfo->bRegRT2RTAggregation)
744 	{
745 		tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
746 		tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer);
747 		HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len);
748 	}
749 //	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);
750 	beacon_size = sizeof(struct ieee80211_probe_response)+2+
751 		ssid_len
752 		+3 //channel
753 		+rate_len
754 		+rate_ex_len
755 		+atim_len
756 		+erp_len
757 		+wpa_ie_len
758 	//	+tmp_ht_cap_len
759 	//	+tmp_ht_info_len
760 	//	+tmp_generic_ie_len
761 //		+wmm_len+2
762 		+ieee->tx_headroom;
763 	skb = dev_alloc_skb(beacon_size);
764 	if (!skb)
765 		return NULL;
766 	skb_reserve(skb, ieee->tx_headroom);
767 	beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, (beacon_size - ieee->tx_headroom));
768 	memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
769 	memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
770 	memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
771 
772 	beacon_buf->header.duration_id = 0; //FIXME
773 	beacon_buf->beacon_interval =
774 		cpu_to_le16(ieee->current_network.beacon_interval);
775 	beacon_buf->capability =
776 		cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
777 	beacon_buf->capability |=
778 		cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE); //add short preamble here
779 
780 	if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
781 		beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
782 
783 	crypt = ieee->crypt[ieee->tx_keyidx];
784 	if (encrypt)
785 		beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
786 
787 
788 	beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
789 	beacon_buf->info_element[0].id = MFIE_TYPE_SSID;
790 	beacon_buf->info_element[0].len = ssid_len;
791 
792 	tag = (u8*) beacon_buf->info_element[0].data;
793 
794 	memcpy(tag, ssid, ssid_len);
795 
796 	tag += ssid_len;
797 
798 	*(tag++) = MFIE_TYPE_RATES;
799 	*(tag++) = rate_len-2;
800 	memcpy(tag,ieee->current_network.rates,rate_len-2);
801 	tag+=rate_len-2;
802 
803 	*(tag++) = MFIE_TYPE_DS_SET;
804 	*(tag++) = 1;
805 	*(tag++) = ieee->current_network.channel;
806 
807 	if(atim_len){
808 	u16 val16;
809 		*(tag++) = MFIE_TYPE_IBSS_SET;
810 		*(tag++) = 2;
811 		//*((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window);
812 		 val16 = cpu_to_le16(ieee->current_network.atim_window);
813 		memcpy((u8 *)tag, (u8 *)&val16, 2);
814 		tag+=2;
815 	}
816 
817 	if(erp_len){
818 		*(tag++) = MFIE_TYPE_ERP;
819 		*(tag++) = 1;
820 		*(tag++) = erpinfo_content;
821 	}
822 	if(rate_ex_len){
823 		*(tag++) = MFIE_TYPE_RATES_EX;
824 		*(tag++) = rate_ex_len-2;
825 		memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
826 		tag+=rate_ex_len-2;
827 	}
828 
829 	if (wpa_ie_len)
830 	{
831 		if (ieee->iw_mode == IW_MODE_ADHOC)
832 		{//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
833 			memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
834 		}
835 		memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
836 		tag += wpa_ie_len;
837 	}
838 
839 	//skb->dev = ieee->dev;
840 	return skb;
841 }
842 
843 
ieee80211_assoc_resp(struct ieee80211_device * ieee,u8 * dest)844 struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
845 {
846 	struct sk_buff *skb;
847 	u8* tag;
848 
849 	struct ieee80211_crypt_data* crypt;
850 	struct ieee80211_assoc_response_frame *assoc;
851 	short encrypt;
852 
853 	unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
854 	int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len + ieee->tx_headroom;
855 
856 	skb = dev_alloc_skb(len);
857 
858 	if (!skb)
859 		return NULL;
860 
861 	skb_reserve(skb, ieee->tx_headroom);
862 
863 	assoc = (struct ieee80211_assoc_response_frame *)
864 		skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
865 
866 	assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
867 	memcpy(assoc->header.addr1, dest,ETH_ALEN);
868 	memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
869 	memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
870 	assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
871 		WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
872 
873 
874 	if(ieee->short_slot)
875 		assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
876 
877 	if (ieee->host_encrypt)
878 		crypt = ieee->crypt[ieee->tx_keyidx];
879 	else crypt = NULL;
880 
881 	encrypt = ( crypt && crypt->ops);
882 
883 	if (encrypt)
884 		assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
885 
886 	assoc->status = 0;
887 	assoc->aid = cpu_to_le16(ieee->assoc_id);
888 	if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
889 	else ieee->assoc_id++;
890 
891 	tag = (u8*) skb_put(skb, rate_len);
892 
893 	ieee80211_MFIE_Brate(ieee, &tag);
894 	ieee80211_MFIE_Grate(ieee, &tag);
895 
896 	return skb;
897 }
898 
ieee80211_auth_resp(struct ieee80211_device * ieee,int status,u8 * dest)899 struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest)
900 {
901 	struct sk_buff *skb;
902 	struct ieee80211_authentication *auth;
903 	int len = ieee->tx_headroom + sizeof(struct ieee80211_authentication)+1;
904 
905 	skb = dev_alloc_skb(len);
906 
907 	if (!skb)
908 		return NULL;
909 
910 	skb->len = sizeof(struct ieee80211_authentication);
911 
912 	auth = (struct ieee80211_authentication *)skb->data;
913 
914 	auth->status = cpu_to_le16(status);
915 	auth->transaction = cpu_to_le16(2);
916 	auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
917 
918 	memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
919 	memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
920 	memcpy(auth->header.addr1, dest, ETH_ALEN);
921 	auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
922 	return skb;
923 
924 
925 }
926 
ieee80211_null_func(struct ieee80211_device * ieee,short pwr)927 struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
928 {
929 	struct sk_buff *skb;
930 	struct ieee80211_hdr_3addr* hdr;
931 
932 	skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
933 
934 	if (!skb)
935 		return NULL;
936 
937 	hdr = (struct ieee80211_hdr_3addr*)skb_put(skb,sizeof(struct ieee80211_hdr_3addr));
938 
939 	memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
940 	memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
941 	memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
942 
943 	hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
944 		IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
945 		(pwr ? IEEE80211_FCTL_PM:0));
946 
947 	return skb;
948 
949 
950 }
951 
952 
ieee80211_resp_to_assoc_rq(struct ieee80211_device * ieee,u8 * dest)953 void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest)
954 {
955 	struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
956 
957 	if (buf)
958 		softmac_mgmt_xmit(buf, ieee);
959 }
960 
961 
ieee80211_resp_to_auth(struct ieee80211_device * ieee,int s,u8 * dest)962 void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest)
963 {
964 	struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
965 
966 	if (buf)
967 		softmac_mgmt_xmit(buf, ieee);
968 }
969 
970 
ieee80211_resp_to_probe(struct ieee80211_device * ieee,u8 * dest)971 void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
972 {
973 
974 
975 	struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
976 	if (buf)
977 		softmac_mgmt_xmit(buf, ieee);
978 }
979 
980 
ieee80211_association_req(struct ieee80211_network * beacon,struct ieee80211_device * ieee)981 inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
982 {
983 	struct sk_buff *skb;
984 	//unsigned long flags;
985 
986 	struct ieee80211_assoc_request_frame *hdr;
987 	u8 *tag;//,*rsn_ie;
988 	//short info_addr = 0;
989 	//int i;
990 	//u16 suite_count = 0;
991 	//u8 suit_select = 0;
992 	//unsigned int wpa_len = beacon->wpa_ie_len;
993 	//for HT
994 	u8* ht_cap_buf = NULL;
995 	u8 ht_cap_len=0;
996 	u8* realtek_ie_buf=NULL;
997 	u8 realtek_ie_len=0;
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;
1003 	int encrypt;
1004 
1005 	unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
1006 	unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
1007 #ifdef THOMAS_TURBO
1008 	unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
1009 #endif
1010 
1011 	int len = 0;
1012 
1013 	crypt = ieee->crypt[ieee->tx_keyidx];
1014 	encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len));
1015 
1016 	//Include High Throuput capability && Realtek proprietary
1017 	if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1018 	{
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)
1023 		{
1024 			realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer;
1025 			realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer);
1026 			HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len);
1027 
1028 		}
1029 	}
1030 	if(ieee->qos_support){
1031 		wmm_info_len = beacon->qos_data.supported?9:0;
1032 	}
1033 
1034 
1035 	if(beacon->bCkipSupported)
1036 	{
1037 		ckip_ie_len = 30+2;
1038 	}
1039 	if(beacon->bCcxRmEnable)
1040 	{
1041 		ccxrm_ie_len = 6+2;
1042 	}
1043 	if( beacon->BssCcxVerNumber >= 2 )
1044 	{
1045 		cxvernum_ie_len = 5+2;
1046 	}
1047 #ifdef THOMAS_TURBO
1048 	len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1049 		+ beacon->ssid_len//essid tagged val
1050 		+ rate_len//rates tagged val
1051 		+ wpa_ie_len
1052 		+ wmm_info_len
1053 		+ turbo_info_len
1054 		+ ht_cap_len
1055 		+ realtek_ie_len
1056 		+ ckip_ie_len
1057 		+ ccxrm_ie_len
1058 		+ cxvernum_ie_len
1059 		+ ieee->tx_headroom;
1060 #else
1061 	len = sizeof(struct ieee80211_assoc_request_frame)+ 2
1062 		+ beacon->ssid_len//essid tagged val
1063 		+ rate_len//rates tagged val
1064 		+ wpa_ie_len
1065 		+ wmm_info_len
1066 		+ ht_cap_len
1067 		+ realtek_ie_len
1068 		+ ckip_ie_len
1069 		+ ccxrm_ie_len
1070 		+ cxvernum_ie_len
1071 		+ ieee->tx_headroom;
1072 #endif
1073 
1074 	skb = dev_alloc_skb(len);
1075 
1076 	if (!skb)
1077 		return NULL;
1078 
1079 	skb_reserve(skb, ieee->tx_headroom);
1080 
1081 	hdr = (struct ieee80211_assoc_request_frame *)
1082 		skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)+2);
1083 
1084 
1085 	hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
1086 	hdr->header.duration_id= 37; //FIXME
1087 	memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
1088 	memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
1089 	memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
1090 
1091 	memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John
1092 
1093 	hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
1094 	if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
1095 		hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1096 
1097 	if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1098 		hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); //add short_preamble here
1099 
1100 	if(ieee->short_slot)
1101 		hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
1102 	if (wmm_info_len) //QOS
1103 	hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS);
1104 
1105 	hdr->listen_interval = 0xa; //FIXME
1106 
1107 	hdr->info_element[0].id = MFIE_TYPE_SSID;
1108 
1109 	hdr->info_element[0].len = beacon->ssid_len;
1110 	tag = skb_put(skb, beacon->ssid_len);
1111 	memcpy(tag, beacon->ssid, beacon->ssid_len);
1112 
1113 	tag = skb_put(skb, rate_len);
1114 
1115 	ieee80211_MFIE_Brate(ieee, &tag);
1116 	ieee80211_MFIE_Grate(ieee, &tag);
1117 	// For CCX 1 S13, CKIP. Added by Annie, 2006-08-14.
1118 	if( beacon->bCkipSupported )
1119 	{
1120 		static u8	AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client"
1121 		u8	CcxAironetBuf[30];
1122 		OCTET_STRING	osCcxAironetIE;
1123 
1124 		memset(CcxAironetBuf, 0,30);
1125 		osCcxAironetIE.Octet = CcxAironetBuf;
1126 		osCcxAironetIE.Length = sizeof(CcxAironetBuf);
1127 		//
1128 		// Ref. CCX test plan v3.61, 3.2.3.1 step 13.
1129 		// We want to make the device type as "4500-client". 060926, by CCW.
1130 		//
1131 		memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui));
1132 
1133 		// CCX1 spec V1.13, A01.1 CKIP Negotiation (page23):
1134 		// "The CKIP negotiation is started with the associate request from the client to the access point,
1135 		//  containing an Aironet element with both the MIC and KP bits set."
1136 		osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |=  (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ;
1137 		tag = skb_put(skb, ckip_ie_len);
1138 		*tag++ = MFIE_TYPE_AIRONET;
1139 		*tag++ = osCcxAironetIE.Length;
1140 		memcpy(tag,osCcxAironetIE.Octet,osCcxAironetIE.Length);
1141 		tag += osCcxAironetIE.Length;
1142 	}
1143 
1144 	if(beacon->bCcxRmEnable)
1145 	{
1146 		static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00};
1147 		OCTET_STRING osCcxRmCap;
1148 
1149 		osCcxRmCap.Octet = CcxRmCapBuf;
1150 		osCcxRmCap.Length = sizeof(CcxRmCapBuf);
1151 		tag = skb_put(skb,ccxrm_ie_len);
1152 		*tag++ = MFIE_TYPE_GENERIC;
1153 		*tag++ = osCcxRmCap.Length;
1154 		memcpy(tag,osCcxRmCap.Octet,osCcxRmCap.Length);
1155 		tag += osCcxRmCap.Length;
1156 	}
1157 
1158 	if( beacon->BssCcxVerNumber >= 2 )
1159 	{
1160 		u8			CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
1161 		OCTET_STRING	osCcxVerNum;
1162 		CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
1163 		osCcxVerNum.Octet = CcxVerNumBuf;
1164 		osCcxVerNum.Length = sizeof(CcxVerNumBuf);
1165 		tag = skb_put(skb,cxvernum_ie_len);
1166 		*tag++ = MFIE_TYPE_GENERIC;
1167 		*tag++ = osCcxVerNum.Length;
1168 		memcpy(tag,osCcxVerNum.Octet,osCcxVerNum.Length);
1169 		tag += osCcxVerNum.Length;
1170 	}
1171 	//HT cap element
1172 	if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
1173 		if(ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC)
1174 		{
1175 			tag = skb_put(skb, ht_cap_len);
1176 			*tag++ = MFIE_TYPE_HT_CAP;
1177 			*tag++ = ht_cap_len - 2;
1178 			memcpy(tag, ht_cap_buf,ht_cap_len -2);
1179 			tag += ht_cap_len -2;
1180 		}
1181 	}
1182 
1183 
1184 	//choose what wpa_supplicant gives to associate.
1185 	tag = skb_put(skb, wpa_ie_len);
1186 	if (wpa_ie_len){
1187 		memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
1188 	}
1189 
1190 	tag = skb_put(skb,wmm_info_len);
1191 	if(wmm_info_len) {
1192 	  ieee80211_WMM_Info(ieee, &tag);
1193 	}
1194 #ifdef THOMAS_TURBO
1195 	tag = skb_put(skb,turbo_info_len);
1196 	if(turbo_info_len) {
1197 		ieee80211_TURBO_Info(ieee, &tag);
1198 	}
1199 #endif
1200 
1201 	if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){
1202 		if(ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC)
1203 		{
1204 			tag = skb_put(skb, ht_cap_len);
1205 			*tag++ = MFIE_TYPE_GENERIC;
1206 			*tag++ = ht_cap_len - 2;
1207 			memcpy(tag, ht_cap_buf,ht_cap_len - 2);
1208 			tag += ht_cap_len -2;
1209 		}
1210 
1211 		if(ieee->pHTInfo->bCurrentRT2RTAggregation){
1212 			tag = skb_put(skb, realtek_ie_len);
1213 			*tag++ = MFIE_TYPE_GENERIC;
1214 			*tag++ = realtek_ie_len - 2;
1215 			memcpy(tag, realtek_ie_buf,realtek_ie_len -2 );
1216 		}
1217 	}
1218 //	printk("<=====%s(), %p, %p\n", __FUNCTION__, ieee->dev, ieee->dev->dev_addr);
1219 //	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, skb->data, skb->len);
1220 	return skb;
1221 }
1222 
ieee80211_associate_abort(struct ieee80211_device * ieee)1223 void ieee80211_associate_abort(struct ieee80211_device *ieee)
1224 {
1225 
1226 	unsigned long flags;
1227 	spin_lock_irqsave(&ieee->lock, flags);
1228 
1229 	ieee->associate_seq++;
1230 
1231 	/* don't scan, and avoid to have the RX path possibily
1232 	 * try again to associate. Even do not react to AUTH or
1233 	 * ASSOC response. Just wait for the retry wq to be scheduled.
1234 	 * Here we will check if there are good nets to associate
1235 	 * with, so we retry or just get back to NO_LINK and scanning
1236 	 */
1237 	if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
1238 		IEEE80211_DEBUG_MGMT("Authentication failed\n");
1239 		ieee->softmac_stats.no_auth_rs++;
1240 	}else{
1241 		IEEE80211_DEBUG_MGMT("Association failed\n");
1242 		ieee->softmac_stats.no_ass_rs++;
1243 	}
1244 
1245 	ieee->state = IEEE80211_ASSOCIATING_RETRY;
1246 
1247 	queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \
1248 			   IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
1249 
1250 	spin_unlock_irqrestore(&ieee->lock, flags);
1251 }
1252 
ieee80211_associate_abort_cb(unsigned long dev)1253 void ieee80211_associate_abort_cb(unsigned long dev)
1254 {
1255 	ieee80211_associate_abort((struct ieee80211_device *) dev);
1256 }
1257 
1258 
ieee80211_associate_step1(struct ieee80211_device * ieee)1259 void ieee80211_associate_step1(struct ieee80211_device *ieee)
1260 {
1261 	struct ieee80211_network *beacon = &ieee->current_network;
1262 	struct sk_buff *skb;
1263 
1264 	IEEE80211_DEBUG_MGMT("Stopping scan\n");
1265 
1266 	ieee->softmac_stats.tx_auth_rq++;
1267 	skb=ieee80211_authentication_req(beacon, ieee, 0);
1268 
1269 	if (!skb)
1270 		ieee80211_associate_abort(ieee);
1271 	else{
1272 		ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
1273 		IEEE80211_DEBUG_MGMT("Sending authentication request\n");
1274 		//printk(KERN_WARNING "Sending authentication request\n");
1275 		softmac_mgmt_xmit(skb, ieee);
1276 		//BUGON when you try to add_timer twice, using mod_timer may be better, john0709
1277 		if(!timer_pending(&ieee->associate_timer)){
1278 			ieee->associate_timer.expires = jiffies + (HZ / 2);
1279 			add_timer(&ieee->associate_timer);
1280 		}
1281 		//dev_kfree_skb_any(skb);//edit by thomas
1282 	}
1283 }
1284 
ieee80211_auth_challenge(struct ieee80211_device * ieee,u8 * challenge,int chlen)1285 void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
1286 {
1287 	u8 *c;
1288 	struct sk_buff *skb;
1289 	struct ieee80211_network *beacon = &ieee->current_network;
1290 //	int hlen = sizeof(struct ieee80211_authentication);
1291 
1292 	ieee->associate_seq++;
1293 	ieee->softmac_stats.tx_auth_rq++;
1294 
1295 	skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
1296 	if (!skb)
1297 		ieee80211_associate_abort(ieee);
1298 	else{
1299 		c = skb_put(skb, chlen+2);
1300 		*(c++) = MFIE_TYPE_CHALLENGE;
1301 		*(c++) = chlen;
1302 		memcpy(c, challenge, chlen);
1303 
1304 		IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
1305 
1306 		ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr  ));
1307 
1308 		softmac_mgmt_xmit(skb, ieee);
1309 		mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1310 		//dev_kfree_skb_any(skb);//edit by thomas
1311 	}
1312 	kfree(challenge);
1313 }
1314 
ieee80211_associate_step2(struct ieee80211_device * ieee)1315 void ieee80211_associate_step2(struct ieee80211_device *ieee)
1316 {
1317 	struct sk_buff* skb;
1318 	struct ieee80211_network *beacon = &ieee->current_network;
1319 
1320 	del_timer_sync(&ieee->associate_timer);
1321 
1322 	IEEE80211_DEBUG_MGMT("Sending association request\n");
1323 
1324 	ieee->softmac_stats.tx_ass_rq++;
1325 	skb=ieee80211_association_req(beacon, ieee);
1326 	if (!skb)
1327 		ieee80211_associate_abort(ieee);
1328 	else{
1329 		softmac_mgmt_xmit(skb, ieee);
1330 		mod_timer(&ieee->associate_timer, jiffies + (HZ/2));
1331 		//dev_kfree_skb_any(skb);//edit by thomas
1332 	}
1333 }
ieee80211_associate_complete_wq(struct work_struct * work)1334 void ieee80211_associate_complete_wq(struct work_struct *work)
1335 {
1336 	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
1337 	printk(KERN_INFO "Associated successfully\n");
1338 	if(ieee80211_is_54g(&ieee->current_network) &&
1339 		(ieee->modulation & IEEE80211_OFDM_MODULATION)){
1340 
1341 		ieee->rate = 108;
1342 		printk(KERN_INFO"Using G rates:%d\n", ieee->rate);
1343 	}else{
1344 		ieee->rate = 22;
1345 		printk(KERN_INFO"Using B rates:%d\n", ieee->rate);
1346 	}
1347 	if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT)
1348 	{
1349 		printk("Successfully associated, ht enabled\n");
1350 		HTOnAssocRsp(ieee);
1351 	}
1352 	else
1353 	{
1354 		printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
1355 		memset(ieee->dot11HTOperationalRateSet, 0, 16);
1356 		//HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1357 	}
1358 	ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500);
1359 	// To prevent the immediately calling watch_dog after association.
1360 	if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 )
1361 	{
1362 		ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
1363 		ieee->LinkDetectInfo.NumRecvDataInPeriod= 1;
1364 	}
1365 	ieee->link_change(ieee->dev);
1366 	if(ieee->is_silent_reset == 0){
1367 		printk("============>normal associate\n");
1368 	notify_wx_assoc_event(ieee);
1369 	}
1370 	else if(ieee->is_silent_reset == 1)
1371 	{
1372 		printk("==================>silent reset associate\n");
1373 		ieee->is_silent_reset = 0;
1374 	}
1375 
1376 	if (ieee->data_hard_resume)
1377 		ieee->data_hard_resume(ieee->dev);
1378 	netif_carrier_on(ieee->dev);
1379 }
1380 
ieee80211_associate_complete(struct ieee80211_device * ieee)1381 void ieee80211_associate_complete(struct ieee80211_device *ieee)
1382 {
1383 //	int i;
1384 //	struct net_device* dev = ieee->dev;
1385 	del_timer_sync(&ieee->associate_timer);
1386 
1387 	ieee->state = IEEE80211_LINKED;
1388 	//ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet);
1389 	queue_work(ieee->wq, &ieee->associate_complete_wq);
1390 }
1391 
ieee80211_associate_procedure_wq(struct work_struct * work)1392 void ieee80211_associate_procedure_wq(struct work_struct *work)
1393 {
1394 	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
1395 	ieee->sync_scan_hurryup = 1;
1396 	down(&ieee->wx_sem);
1397 
1398 	if (ieee->data_hard_stop)
1399 		ieee->data_hard_stop(ieee->dev);
1400 
1401 	ieee80211_stop_scan(ieee);
1402 	printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);
1403 	//ieee->set_chan(ieee->dev, ieee->current_network.channel);
1404 	HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1405 
1406 	ieee->associate_seq = 1;
1407 	ieee80211_associate_step1(ieee);
1408 
1409 	up(&ieee->wx_sem);
1410 }
1411 
ieee80211_softmac_new_net(struct ieee80211_device * ieee,struct ieee80211_network * net)1412 inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
1413 {
1414 	u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
1415 	int tmp_ssid_len = 0;
1416 
1417 	short apset,ssidset,ssidbroad,apmatch,ssidmatch;
1418 
1419 	/* we are interested in new new only if we are not associated
1420 	 * and we are not associating / authenticating
1421 	 */
1422 	if (ieee->state != IEEE80211_NOLINK)
1423 		return;
1424 
1425 	if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
1426 		return;
1427 
1428 	if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
1429 		return;
1430 
1431 
1432 	if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){
1433 		/* if the user specified the AP MAC, we need also the essid
1434 		 * This could be obtained by beacons or, if the network does not
1435 		 * broadcast it, it can be put manually.
1436 		 */
1437 		apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
1438 		ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
1439 		ssidbroad =  !(net->ssid_len == 0 || net->ssid[0]== '\0');
1440 		apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
1441 		ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\
1442 				(!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
1443 
1444 
1445 		if (	/* if the user set the AP check if match.
1446 			 * if the network does not broadcast essid we check the user supplyed ANY essid
1447 			 * if the network does broadcast and the user does not set essid it is OK
1448 			 * if the network does broadcast and the user did set essid chech if essid match
1449 			 */
1450 			( apset && apmatch &&
1451 				((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
1452 			/* if the ap is not set, check that the user set the bssid
1453 			 * and the network does broadcast and that those two bssid matches
1454 			 */
1455 			(!apset && ssidset && ssidbroad && ssidmatch)
1456 			){
1457 				/* if the essid is hidden replace it with the
1458 				* essid provided by the user.
1459 				*/
1460 				if (!ssidbroad){
1461 					strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
1462 					tmp_ssid_len = ieee->current_network.ssid_len;
1463 				}
1464 				memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
1465 
1466 				if (!ssidbroad){
1467 					strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
1468 					ieee->current_network.ssid_len = tmp_ssid_len;
1469 				}
1470 				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);
1471 
1472 				//ieee->pHTInfo->IOTAction = 0;
1473 				HTResetIOTSetting(ieee->pHTInfo);
1474 				if (ieee->iw_mode == IW_MODE_INFRA){
1475 					/* Join the network for the first time */
1476 					ieee->AsocRetryCount = 0;
1477 					//for HT by amy 080514
1478 					if((ieee->current_network.qos_data.supported == 1) &&
1479 					  // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT))
1480 					   ieee->current_network.bssht.bdSupportHT)
1481 /*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.*/
1482 					{
1483 					//	ieee->pHTInfo->bCurrentHTSupport = true;
1484 						HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network));
1485 					}
1486 					else
1487 					{
1488 						ieee->pHTInfo->bCurrentHTSupport = false;
1489 					}
1490 
1491 					ieee->state = IEEE80211_ASSOCIATING;
1492 					queue_work(ieee->wq, &ieee->associate_procedure_wq);
1493 				}else{
1494 					if(ieee80211_is_54g(&ieee->current_network) &&
1495 						(ieee->modulation & IEEE80211_OFDM_MODULATION)){
1496 						ieee->rate = 108;
1497 						ieee->SetWirelessMode(ieee->dev, IEEE_G);
1498 						printk(KERN_INFO"Using G rates\n");
1499 					}else{
1500 						ieee->rate = 22;
1501 						ieee->SetWirelessMode(ieee->dev, IEEE_B);
1502 						printk(KERN_INFO"Using B rates\n");
1503 					}
1504 					memset(ieee->dot11HTOperationalRateSet, 0, 16);
1505 					//HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1506 					ieee->state = IEEE80211_LINKED;
1507 				}
1508 
1509 		}
1510 	}
1511 
1512 }
1513 
ieee80211_softmac_check_all_nets(struct ieee80211_device * ieee)1514 void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
1515 {
1516 	unsigned long flags;
1517 	struct ieee80211_network *target;
1518 
1519 	spin_lock_irqsave(&ieee->lock, flags);
1520 
1521 	list_for_each_entry(target, &ieee->network_list, list) {
1522 
1523 		/* if the state become different that NOLINK means
1524 		 * we had found what we are searching for
1525 		 */
1526 
1527 		if (ieee->state != IEEE80211_NOLINK)
1528 			break;
1529 
1530 		if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
1531 		ieee80211_softmac_new_net(ieee, target);
1532 	}
1533 
1534 	spin_unlock_irqrestore(&ieee->lock, flags);
1535 
1536 }
1537 
1538 
auth_parse(struct sk_buff * skb,u8 ** challenge,int * chlen)1539 static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen)
1540 {
1541 	struct ieee80211_authentication *a;
1542 	u8 *t;
1543 	if (skb->len <  (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
1544 		IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
1545 		return 0xcafe;
1546 	}
1547 	*challenge = NULL;
1548 	a = (struct ieee80211_authentication*) skb->data;
1549 	if(skb->len > (sizeof(struct ieee80211_authentication) +3)){
1550 		t = skb->data + sizeof(struct ieee80211_authentication);
1551 
1552 		if(*(t++) == MFIE_TYPE_CHALLENGE){
1553 			*chlen = *(t++);
1554 			*challenge = kmemdup(t, *chlen, GFP_ATOMIC);
1555 			if (!*challenge)
1556 				return -ENOMEM;
1557 		}
1558 	}
1559 
1560 	return cpu_to_le16(a->status);
1561 
1562 }
1563 
1564 
auth_rq_parse(struct sk_buff * skb,u8 * dest)1565 int auth_rq_parse(struct sk_buff *skb,u8* dest)
1566 {
1567 	struct ieee80211_authentication *a;
1568 
1569 	if (skb->len <  (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
1570 		IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
1571 		return -1;
1572 	}
1573 	a = (struct ieee80211_authentication*) skb->data;
1574 
1575 	memcpy(dest,a->header.addr2, ETH_ALEN);
1576 
1577 	if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
1578 		return  WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1579 
1580 	return WLAN_STATUS_SUCCESS;
1581 }
1582 
probe_rq_parse(struct ieee80211_device * ieee,struct sk_buff * skb,u8 * src)1583 static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
1584 {
1585 	u8 *tag;
1586 	u8 *skbend;
1587 	u8 *ssid=NULL;
1588 	u8 ssidlen = 0;
1589 
1590 	struct ieee80211_hdr_3addr   *header =
1591 		(struct ieee80211_hdr_3addr   *) skb->data;
1592 
1593 	if (skb->len < sizeof (struct ieee80211_hdr_3addr  ))
1594 		return -1; /* corrupted */
1595 
1596 	memcpy(src,header->addr2, ETH_ALEN);
1597 
1598 	skbend = (u8*)skb->data + skb->len;
1599 
1600 	tag = skb->data + sizeof (struct ieee80211_hdr_3addr  );
1601 
1602 	while (tag+1 < skbend){
1603 		if (*tag == 0){
1604 			ssid = tag+2;
1605 			ssidlen = *(tag+1);
1606 			break;
1607 		}
1608 		tag++; /* point to the len field */
1609 		tag = tag + *(tag); /* point to the last data byte of the tag */
1610 		tag++; /* point to the next tag */
1611 	}
1612 
1613 	//IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
1614 	if (ssidlen == 0) return 1;
1615 
1616 	if (!ssid) return 1; /* ssid not found in tagged param */
1617 	return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
1618 
1619 }
1620 
assoc_rq_parse(struct sk_buff * skb,u8 * dest)1621 int assoc_rq_parse(struct sk_buff *skb,u8* dest)
1622 {
1623 	struct ieee80211_assoc_request_frame *a;
1624 
1625 	if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
1626 		sizeof(struct ieee80211_info_element))) {
1627 
1628 		IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
1629 		return -1;
1630 	}
1631 
1632 	a = (struct ieee80211_assoc_request_frame*) skb->data;
1633 
1634 	memcpy(dest,a->header.addr2,ETH_ALEN);
1635 
1636 	return 0;
1637 }
1638 
assoc_parse(struct ieee80211_device * ieee,struct sk_buff * skb,int * aid)1639 static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid)
1640 {
1641 	struct ieee80211_assoc_response_frame *response_head;
1642 	u16 status_code;
1643 
1644 	if (skb->len <  sizeof(struct ieee80211_assoc_response_frame)){
1645 		IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
1646 		return 0xcafe;
1647 	}
1648 
1649 	response_head = (struct ieee80211_assoc_response_frame*) skb->data;
1650 	*aid = le16_to_cpu(response_head->aid) & 0x3fff;
1651 
1652 	status_code = le16_to_cpu(response_head->status);
1653 	if((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \
1654 	   status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&&
1655 	   ((ieee->mode == IEEE_G) &&
1656 	    (ieee->current_network.mode == IEEE_N_24G) &&
1657 	    (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) {
1658 		 ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
1659 	}else {
1660 		 ieee->AsocRetryCount = 0;
1661 	}
1662 
1663 	return le16_to_cpu(response_head->status);
1664 }
1665 
1666 static inline void
ieee80211_rx_probe_rq(struct ieee80211_device * ieee,struct sk_buff * skb)1667 ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1668 {
1669 	u8 dest[ETH_ALEN];
1670 
1671 	//IEEE80211DMESG("Rx probe");
1672 	ieee->softmac_stats.rx_probe_rq++;
1673 	//DMESG("Dest is "MACSTR, MAC2STR(dest));
1674 	if (probe_rq_parse(ieee, skb, dest)){
1675 		//IEEE80211DMESG("Was for me!");
1676 		ieee->softmac_stats.tx_probe_rs++;
1677 		ieee80211_resp_to_probe(ieee, dest);
1678 	}
1679 }
1680 
1681 static inline void
ieee80211_rx_auth_rq(struct ieee80211_device * ieee,struct sk_buff * skb)1682 ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1683 {
1684 	u8 dest[ETH_ALEN];
1685 	int status;
1686 	//IEEE80211DMESG("Rx probe");
1687 	ieee->softmac_stats.rx_auth_rq++;
1688 
1689 	status = auth_rq_parse(skb, dest);
1690 	if (status != -1) {
1691 		ieee80211_resp_to_auth(ieee, status, dest);
1692 	}
1693 	//DMESG("Dest is "MACSTR, MAC2STR(dest));
1694 
1695 }
1696 
1697 static inline void
ieee80211_rx_assoc_rq(struct ieee80211_device * ieee,struct sk_buff * skb)1698 ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1699 {
1700 
1701 	u8 dest[ETH_ALEN];
1702 	//unsigned long flags;
1703 
1704 	ieee->softmac_stats.rx_ass_rq++;
1705 	if (assoc_rq_parse(skb,dest) != -1){
1706 		ieee80211_resp_to_assoc_rq(ieee, dest);
1707 	}
1708 
1709 	printk(KERN_INFO"New client associated: %pM\n", dest);
1710 	//FIXME
1711 }
1712 
1713 
1714 
ieee80211_sta_ps_send_null_frame(struct ieee80211_device * ieee,short pwr)1715 void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
1716 {
1717 
1718 	struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
1719 
1720 	if (buf)
1721 		softmac_ps_mgmt_xmit(buf, ieee);
1722 
1723 }
1724 
1725 
ieee80211_sta_ps_sleep(struct ieee80211_device * ieee,u32 * time_h,u32 * time_l)1726 short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
1727 {
1728 	int timeout = ieee->ps_timeout;
1729 	u8 dtim;
1730 	/*if(ieee->ps == IEEE80211_PS_DISABLED ||
1731 		ieee->iw_mode != IW_MODE_INFRA ||
1732 		ieee->state != IEEE80211_LINKED)
1733 
1734 		return 0;
1735 	*/
1736 	dtim = ieee->current_network.dtim_data;
1737 	//printk("DTIM\n");
1738 	if(!(dtim & IEEE80211_DTIM_VALID))
1739 		return 0;
1740 	timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
1741 	//printk("VALID\n");
1742 	ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
1743 
1744 	if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
1745 		return 2;
1746 
1747 	if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
1748 		return 0;
1749 
1750 	if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
1751 		return 0;
1752 
1753 	if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
1754 		(ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
1755 		return 0;
1756 
1757 	if(time_l){
1758 		*time_l = ieee->current_network.last_dtim_sta_time[0]
1759 			+ (ieee->current_network.beacon_interval
1760 			* ieee->current_network.dtim_period) * 1000;
1761 	}
1762 
1763 	if(time_h){
1764 		*time_h = ieee->current_network.last_dtim_sta_time[1];
1765 		if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
1766 			*time_h += 1;
1767 	}
1768 
1769 	return 1;
1770 
1771 
1772 }
1773 
ieee80211_sta_ps(struct ieee80211_device * ieee)1774 inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
1775 {
1776 
1777 	u32 th,tl;
1778 	short sleep;
1779 
1780 	unsigned long flags,flags2;
1781 
1782 	spin_lock_irqsave(&ieee->lock, flags);
1783 
1784 	if((ieee->ps == IEEE80211_PS_DISABLED ||
1785 		ieee->iw_mode != IW_MODE_INFRA ||
1786 		ieee->state != IEEE80211_LINKED)){
1787 
1788 	//	#warning CHECK_LOCK_HERE
1789 		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1790 
1791 		ieee80211_sta_wakeup(ieee, 1);
1792 
1793 		spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1794 	}
1795 
1796 	sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
1797 	/* 2 wake, 1 sleep, 0 do nothing */
1798 	if(sleep == 0)
1799 		goto out;
1800 
1801 	if(sleep == 1){
1802 
1803 		if(ieee->sta_sleep == 1)
1804 			ieee->enter_sleep_state(ieee->dev,th,tl);
1805 
1806 		else if(ieee->sta_sleep == 0){
1807 		//	printk("send null 1\n");
1808 			spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1809 
1810 			if(ieee->ps_is_queue_empty(ieee->dev)){
1811 
1812 
1813 				ieee->sta_sleep = 2;
1814 
1815 				ieee->ps_request_tx_ack(ieee->dev);
1816 
1817 				ieee80211_sta_ps_send_null_frame(ieee,1);
1818 
1819 				ieee->ps_th = th;
1820 				ieee->ps_tl = tl;
1821 			}
1822 			spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1823 
1824 		}
1825 
1826 
1827 	}else if(sleep == 2){
1828 //#warning CHECK_LOCK_HERE
1829 		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1830 
1831 		ieee80211_sta_wakeup(ieee,1);
1832 
1833 		spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1834 	}
1835 
1836 out:
1837 	spin_unlock_irqrestore(&ieee->lock, flags);
1838 
1839 }
1840 
ieee80211_sta_wakeup(struct ieee80211_device * ieee,short nl)1841 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
1842 {
1843 	if(ieee->sta_sleep == 0){
1844 		if(nl){
1845 			printk("Warning: driver is probably failing to report TX ps error\n");
1846 			ieee->ps_request_tx_ack(ieee->dev);
1847 			ieee80211_sta_ps_send_null_frame(ieee, 0);
1848 		}
1849 		return;
1850 
1851 	}
1852 
1853 	if(ieee->sta_sleep == 1)
1854 		ieee->sta_wake_up(ieee->dev);
1855 
1856 	ieee->sta_sleep = 0;
1857 
1858 	if(nl){
1859 		ieee->ps_request_tx_ack(ieee->dev);
1860 		ieee80211_sta_ps_send_null_frame(ieee, 0);
1861 	}
1862 }
1863 
ieee80211_ps_tx_ack(struct ieee80211_device * ieee,short success)1864 void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
1865 {
1866 	unsigned long flags,flags2;
1867 
1868 	spin_lock_irqsave(&ieee->lock, flags);
1869 
1870 	if(ieee->sta_sleep == 2){
1871 		/* Null frame with PS bit set */
1872 		if(success){
1873 			ieee->sta_sleep = 1;
1874 			ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
1875 		}
1876 		/* if the card report not success we can't be sure the AP
1877 		 * has not RXed so we can't assume the AP believe us awake
1878 		 */
1879 	}
1880 	/* 21112005 - tx again null without PS bit if lost */
1881 	else {
1882 
1883 		if((ieee->sta_sleep == 0) && !success){
1884 			spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1885 			ieee80211_sta_ps_send_null_frame(ieee, 0);
1886 			spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1887 		}
1888 	}
1889 	spin_unlock_irqrestore(&ieee->lock, flags);
1890 }
ieee80211_process_action(struct ieee80211_device * ieee,struct sk_buff * skb)1891 void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb)
1892 {
1893 	struct ieee80211_hdr* header = (struct ieee80211_hdr*)skb->data;
1894 	u8* act = ieee80211_get_payload(header);
1895 	u8 tmp = 0;
1896 //	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
1897 	if (act == NULL)
1898 	{
1899 		IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
1900 		return;
1901 	}
1902 	tmp = *act;
1903 	act ++;
1904 	switch (tmp)
1905 	{
1906 		case ACT_CAT_BA:
1907 			if (*act == ACT_ADDBAREQ)
1908 			ieee80211_rx_ADDBAReq(ieee, skb);
1909 			else if (*act == ACT_ADDBARSP)
1910 			ieee80211_rx_ADDBARsp(ieee, skb);
1911 			else if (*act == ACT_DELBA)
1912 			ieee80211_rx_DELBA(ieee, skb);
1913 			break;
1914 		default:
1915 //			if (net_ratelimit())
1916 //			IEEE80211_DEBUG(IEEE80211_DL_BA, "unknown action frame(%d)\n", tmp);
1917 			break;
1918 	}
1919 	return;
1920 
1921 }
1922 inline int
ieee80211_rx_frame_softmac(struct ieee80211_device * ieee,struct sk_buff * skb,struct ieee80211_rx_stats * rx_stats,u16 type,u16 stype)1923 ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
1924 			struct ieee80211_rx_stats *rx_stats, u16 type,
1925 			u16 stype)
1926 {
1927 	struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
1928 	u16 errcode;
1929 	u8* challenge;
1930 	int chlen=0;
1931 	int aid;
1932 	struct ieee80211_assoc_response_frame *assoc_resp;
1933 //	struct ieee80211_info_element *info_element;
1934 	bool bSupportNmode = true, bHalfSupportNmode = false; //default support N mode, disable halfNmode
1935 
1936 	if(!ieee->proto_started)
1937 		return 0;
1938 
1939 	if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
1940 		ieee->iw_mode == IW_MODE_INFRA &&
1941 		ieee->state == IEEE80211_LINKED))
1942 
1943 		tasklet_schedule(&ieee->ps_task);
1944 
1945 	if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
1946 		WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
1947 		ieee->last_rx_ps_time = jiffies;
1948 
1949 	switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
1950 
1951 	case IEEE80211_STYPE_ASSOC_RESP:
1952 	case IEEE80211_STYPE_REASSOC_RESP:
1953 
1954 		IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
1955 				WLAN_FC_GET_STYPE(header->frame_ctl));
1956 		if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
1957 			ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
1958 			ieee->iw_mode == IW_MODE_INFRA){
1959 			struct ieee80211_network network_resp;
1960 			struct ieee80211_network *network = &network_resp;
1961 
1962 			if (0 == (errcode=assoc_parse(ieee,skb, &aid))){
1963 				ieee->state=IEEE80211_LINKED;
1964 				ieee->assoc_id = aid;
1965 				ieee->softmac_stats.rx_ass_ok++;
1966 				/* station support qos */
1967 				/* Let the register setting defaultly with Legacy station */
1968 				if(ieee->qos_support) {
1969 					assoc_resp = (struct ieee80211_assoc_response_frame*)skb->data;
1970 					memset(network, 0, sizeof(*network));
1971 					if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\
1972 								rx_stats->len - sizeof(*assoc_resp),\
1973 								network,rx_stats)){
1974 						return 1;
1975 					}
1976 					else
1977 					{	//filling the PeerHTCap. //maybe not necessary as we can get its info from current_network.
1978 						memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
1979 						memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
1980 					}
1981 					if (ieee->handle_assoc_response != NULL)
1982 						ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame*)header, network);
1983 				}
1984 				ieee80211_associate_complete(ieee);
1985 			} else {
1986 				/* aid could not been allocated */
1987 				ieee->softmac_stats.rx_ass_err++;
1988 				printk(
1989 					"Association response status code 0x%x\n",
1990 					errcode);
1991 				IEEE80211_DEBUG_MGMT(
1992 					"Association response status code 0x%x\n",
1993 					errcode);
1994 				if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) {
1995 					queue_work(ieee->wq, &ieee->associate_procedure_wq);
1996 				} else {
1997 					ieee80211_associate_abort(ieee);
1998 				}
1999 			}
2000 		}
2001 		break;
2002 
2003 	case IEEE80211_STYPE_ASSOC_REQ:
2004 	case IEEE80211_STYPE_REASSOC_REQ:
2005 
2006 		if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2007 			ieee->iw_mode == IW_MODE_MASTER)
2008 
2009 			ieee80211_rx_assoc_rq(ieee, skb);
2010 		break;
2011 
2012 	case IEEE80211_STYPE_AUTH:
2013 
2014 		if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){
2015 			if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
2016 			ieee->iw_mode == IW_MODE_INFRA){
2017 
2018 					IEEE80211_DEBUG_MGMT("Received authentication response");
2019 
2020 					if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){
2021 						if(ieee->open_wep || !challenge){
2022 							ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
2023 							ieee->softmac_stats.rx_auth_rs_ok++;
2024 							if(!(ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE))
2025 							{
2026 								if (!ieee->GetNmodeSupportBySecCfg(ieee->dev))
2027 								{
2028 											// WEP or TKIP encryption
2029 									if(IsHTHalfNmodeAPs(ieee))
2030 									{
2031 										bSupportNmode = true;
2032 										bHalfSupportNmode = true;
2033 									}
2034 									else
2035 									{
2036 										bSupportNmode = false;
2037 										bHalfSupportNmode = false;
2038 									}
2039 								printk("==========>to link with AP using SEC(%d, %d)", bSupportNmode, bHalfSupportNmode);
2040 								}
2041 							}
2042 							/* Dummy wirless mode setting to avoid encryption issue */
2043 							if(bSupportNmode) {
2044 								//N mode setting
2045 								ieee->SetWirelessMode(ieee->dev, \
2046 										ieee->current_network.mode);
2047 							}else{
2048 								//b/g mode setting
2049 								/*TODO*/
2050 								ieee->SetWirelessMode(ieee->dev, IEEE_G);
2051 							}
2052 
2053 							if (ieee->current_network.mode == IEEE_N_24G && bHalfSupportNmode == true)
2054 							{
2055 								printk("===============>entern half N mode\n");
2056 								ieee->bHalfWirelessN24GMode = true;
2057 							}
2058 							else
2059 								ieee->bHalfWirelessN24GMode = false;
2060 
2061 							ieee80211_associate_step2(ieee);
2062 						}else{
2063 							ieee80211_auth_challenge(ieee, challenge, chlen);
2064 						}
2065 					}else{
2066 						ieee->softmac_stats.rx_auth_rs_err++;
2067 						IEEE80211_DEBUG_MGMT("Authentication response status code 0x%x",errcode);
2068 						ieee80211_associate_abort(ieee);
2069 					}
2070 
2071 				}else if (ieee->iw_mode == IW_MODE_MASTER){
2072 					ieee80211_rx_auth_rq(ieee, skb);
2073 				}
2074 			}
2075 		break;
2076 
2077 	case IEEE80211_STYPE_PROBE_REQ:
2078 
2079 		if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
2080 			((ieee->iw_mode == IW_MODE_ADHOC ||
2081 			ieee->iw_mode == IW_MODE_MASTER) &&
2082 			ieee->state == IEEE80211_LINKED)){
2083 			ieee80211_rx_probe_rq(ieee, skb);
2084 		}
2085 		break;
2086 
2087 	case IEEE80211_STYPE_DISASSOC:
2088 	case IEEE80211_STYPE_DEAUTH:
2089 		/* FIXME for now repeat all the association procedure
2090 		* both for disassociation and deauthentication
2091 		*/
2092 		if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2093 			ieee->state == IEEE80211_LINKED &&
2094 			ieee->iw_mode == IW_MODE_INFRA){
2095 
2096 			ieee->state = IEEE80211_ASSOCIATING;
2097 			ieee->softmac_stats.reassoc++;
2098 
2099 			notify_wx_assoc_event(ieee);
2100 			//HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2101 			RemovePeerTS(ieee, header->addr2);
2102 			queue_work(ieee->wq, &ieee->associate_procedure_wq);
2103 		}
2104 		break;
2105 	case IEEE80211_STYPE_MANAGE_ACT:
2106 		ieee80211_process_action(ieee,skb);
2107 		break;
2108 	default:
2109 		return -1;
2110 		break;
2111 	}
2112 
2113 	//dev_kfree_skb_any(skb);
2114 	return 0;
2115 }
2116 
2117 /* following are for a simpler TX queue management.
2118  * Instead of using netif_[stop/wake]_queue the driver
2119  * will uses these two function (plus a reset one), that
2120  * will internally uses the kernel netif_* and takes
2121  * care of the ieee802.11 fragmentation.
2122  * So the driver receives a fragment per time and might
2123  * call the stop function when it want without take care
2124  * to have enought room to TX an entire packet.
2125  * This might be useful if each fragment need it's own
2126  * descriptor, thus just keep a total free memory > than
2127  * the max fragmentation treshold is not enought.. If the
2128  * ieee802.11 stack passed a TXB struct then you needed
2129  * to keep N free descriptors where
2130  * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
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.
2134  */
ieee80211_softmac_xmit(struct ieee80211_txb * txb,struct ieee80211_device * ieee)2135 void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
2136 {
2137 
2138 	unsigned int queue_index = txb->queue_index;
2139 	unsigned long flags;
2140 	int  i;
2141 	cb_desc *tcb_desc = NULL;
2142 
2143 	spin_lock_irqsave(&ieee->lock,flags);
2144 
2145 	/* called with 2nd parm 0, no tx mgmt lock required */
2146 	ieee80211_sta_wakeup(ieee,0);
2147 
2148 	/* update the tx status */
2149 	ieee->stats.tx_bytes += 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++;
2154 	}
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) ||
2159 #else
2160 		if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
2161 #endif
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.
2167 			 * */
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]);
2172 #else
2173 			skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
2174 #endif
2175 		}else{
2176 			ieee->softmac_data_hard_start_xmit(
2177 					txb->fragments[i],
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;
2182 		}
2183 	}
2184 	ieee80211_txb_free(txb);
2185 
2186 //exit:
2187 	spin_unlock_irqrestore(&ieee->lock,flags);
2188 
2189 }
2190 
2191 /* called with ieee->lock acquired */
ieee80211_resume_tx(struct ieee80211_device * ieee)2192 void ieee80211_resume_tx(struct ieee80211_device *ieee)
2193 {
2194 	int i;
2195 	for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
2196 
2197 		if (ieee->queue_stop){
2198 			ieee->tx_pending.frag = i;
2199 			return;
2200 		}else{
2201 
2202 			ieee->softmac_data_hard_start_xmit(
2203 				ieee->tx_pending.txb->fragments[i],
2204 				ieee->dev,ieee->rate);
2205 				//(i+1)<ieee->tx_pending.txb->nr_frags);
2206 			ieee->stats.tx_packets++;
2207 			ieee->dev->trans_start = jiffies;
2208 		}
2209 	}
2210 
2211 
2212 	ieee80211_txb_free(ieee->tx_pending.txb);
2213 	ieee->tx_pending.txb = NULL;
2214 }
2215 
2216 
ieee80211_reset_queue(struct ieee80211_device * ieee)2217 void ieee80211_reset_queue(struct ieee80211_device *ieee)
2218 {
2219 	unsigned long flags;
2220 
2221 	spin_lock_irqsave(&ieee->lock,flags);
2222 	init_mgmt_queue(ieee);
2223 	if (ieee->tx_pending.txb){
2224 		ieee80211_txb_free(ieee->tx_pending.txb);
2225 		ieee->tx_pending.txb = NULL;
2226 	}
2227 	ieee->queue_stop = 0;
2228 	spin_unlock_irqrestore(&ieee->lock,flags);
2229 
2230 }
2231 
ieee80211_wake_queue(struct ieee80211_device * ieee)2232 void ieee80211_wake_queue(struct ieee80211_device *ieee)
2233 {
2234 
2235 	unsigned long flags;
2236 	struct sk_buff *skb;
2237 	struct ieee80211_hdr_3addr  *header;
2238 
2239 	spin_lock_irqsave(&ieee->lock,flags);
2240 	if (! ieee->queue_stop) goto exit;
2241 
2242 	ieee->queue_stop = 0;
2243 
2244 	if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){
2245 		while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
2246 
2247 			header = (struct ieee80211_hdr_3addr  *) skb->data;
2248 
2249 			header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2250 
2251 			if (ieee->seq_ctrl[0] == 0xFFF)
2252 				ieee->seq_ctrl[0] = 0;
2253 			else
2254 				ieee->seq_ctrl[0]++;
2255 
2256 			ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
2257 			//dev_kfree_skb_any(skb);//edit by thomas
2258 		}
2259 	}
2260 	if (!ieee->queue_stop && ieee->tx_pending.txb)
2261 		ieee80211_resume_tx(ieee);
2262 
2263 	if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){
2264 		ieee->softmac_stats.swtxawake++;
2265 		netif_wake_queue(ieee->dev);
2266 	}
2267 
2268 exit :
2269 	spin_unlock_irqrestore(&ieee->lock,flags);
2270 }
2271 
2272 
ieee80211_stop_queue(struct ieee80211_device * ieee)2273 void ieee80211_stop_queue(struct ieee80211_device *ieee)
2274 {
2275 	//unsigned long flags;
2276 	//spin_lock_irqsave(&ieee->lock,flags);
2277 
2278 	if (! netif_queue_stopped(ieee->dev)){
2279 		netif_stop_queue(ieee->dev);
2280 		ieee->softmac_stats.swtxstop++;
2281 	}
2282 	ieee->queue_stop = 1;
2283 	//spin_unlock_irqrestore(&ieee->lock,flags);
2284 
2285 }
2286 
2287 
ieee80211_randomize_cell(struct ieee80211_device * ieee)2288 inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
2289 {
2290 
2291 	random_ether_addr(ieee->current_network.bssid);
2292 }
2293 
2294 /* called in user context only */
ieee80211_start_master_bss(struct ieee80211_device * ieee)2295 void ieee80211_start_master_bss(struct ieee80211_device *ieee)
2296 {
2297 	ieee->assoc_id = 1;
2298 
2299 	if (ieee->current_network.ssid_len == 0){
2300 		strncpy(ieee->current_network.ssid,
2301 			IEEE80211_DEFAULT_TX_ESSID,
2302 			IW_ESSID_MAX_SIZE);
2303 
2304 		ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2305 		ieee->ssid_set = 1;
2306 	}
2307 
2308 	memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
2309 
2310 	ieee->set_chan(ieee->dev, ieee->current_network.channel);
2311 	ieee->state = IEEE80211_LINKED;
2312 	ieee->link_change(ieee->dev);
2313 	notify_wx_assoc_event(ieee);
2314 
2315 	if (ieee->data_hard_resume)
2316 		ieee->data_hard_resume(ieee->dev);
2317 
2318 	netif_carrier_on(ieee->dev);
2319 }
2320 
ieee80211_start_monitor_mode(struct ieee80211_device * ieee)2321 void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
2322 {
2323 	if(ieee->raw_tx){
2324 
2325 		if (ieee->data_hard_resume)
2326 			ieee->data_hard_resume(ieee->dev);
2327 
2328 		netif_carrier_on(ieee->dev);
2329 	}
2330 }
ieee80211_start_ibss_wq(struct work_struct * work)2331 void ieee80211_start_ibss_wq(struct work_struct *work)
2332 {
2333 
2334 	struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2335 	struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
2336 	/* iwconfig mode ad-hoc will schedule this and return
2337 	 * on the other hand this will block further iwconfig SET
2338 	 * operations because of the wx_sem hold.
2339 	 * Anyway some most set operations set a flag to speed-up
2340 	 * (abort) this wq (when syncro scanning) before sleeping
2341 	 * on the semaphore
2342 	 */
2343 	if(!ieee->proto_started){
2344 		printk("==========oh driver down return\n");
2345 		return;
2346 	}
2347 	down(&ieee->wx_sem);
2348 
2349 	if (ieee->current_network.ssid_len == 0){
2350 		strcpy(ieee->current_network.ssid,IEEE80211_DEFAULT_TX_ESSID);
2351 		ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2352 		ieee->ssid_set = 1;
2353 	}
2354 
2355 	/* check if we have this cell in our network list */
2356 	ieee80211_softmac_check_all_nets(ieee);
2357 
2358 
2359 //	if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK))
2360 	if (ieee->state == IEEE80211_NOLINK)
2361 		ieee->current_network.channel = 6;
2362 	/* if not then the state is not linked. Maybe the user swithced to
2363 	 * ad-hoc mode just after being in monitor mode, or just after
2364 	 * being very few time in managed mode (so the card have had no
2365 	 * time to scan all the chans..) or we have just run up the iface
2366 	 * after setting ad-hoc mode. So we have to give another try..
2367 	 * Here, in ibss mode, should be safe to do this without extra care
2368 	 * (in bss mode we had to make sure no-one tryed to associate when
2369 	 * we had just checked the ieee->state and we was going to start the
2370 	 * scan) beacause in ibss mode the ieee80211_new_net function, when
2371 	 * finds a good net, just set the ieee->state to IEEE80211_LINKED,
2372 	 * so, at worst, we waste a bit of time to initiate an unneeded syncro
2373 	 * scan, that will stop at the first round because it sees the state
2374 	 * associated.
2375 	 */
2376 	if (ieee->state == IEEE80211_NOLINK)
2377 		ieee80211_start_scan_syncro(ieee);
2378 
2379 	/* the network definitively is not here.. create a new cell */
2380 	if (ieee->state == IEEE80211_NOLINK){
2381 		printk("creating new IBSS cell\n");
2382 		if(!ieee->wap_set)
2383 			ieee80211_randomize_cell(ieee);
2384 
2385 		if(ieee->modulation & IEEE80211_CCK_MODULATION){
2386 
2387 			ieee->current_network.rates_len = 4;
2388 
2389 			ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
2390 			ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
2391 			ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
2392 			ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
2393 
2394 		}else
2395 			ieee->current_network.rates_len = 0;
2396 
2397 		if(ieee->modulation & IEEE80211_OFDM_MODULATION){
2398 			ieee->current_network.rates_ex_len = 8;
2399 
2400 			ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
2401 			ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
2402 			ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
2403 			ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
2404 			ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
2405 			ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
2406 			ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
2407 			ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
2408 
2409 			ieee->rate = 108;
2410 		}else{
2411 			ieee->current_network.rates_ex_len = 0;
2412 			ieee->rate = 22;
2413 		}
2414 
2415 		// By default, WMM function will be disabled in IBSS mode
2416 		ieee->current_network.QoS_Enable = 0;
2417 		ieee->SetWirelessMode(ieee->dev, IEEE_G);
2418 		ieee->current_network.atim_window = 0;
2419 		ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
2420 		if(ieee->short_slot)
2421 			ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
2422 
2423 	}
2424 
2425 	ieee->state = IEEE80211_LINKED;
2426 
2427 	ieee->set_chan(ieee->dev, ieee->current_network.channel);
2428 	ieee->link_change(ieee->dev);
2429 
2430 	notify_wx_assoc_event(ieee);
2431 
2432 	ieee80211_start_send_beacons(ieee);
2433 
2434 	if (ieee->data_hard_resume)
2435 		ieee->data_hard_resume(ieee->dev);
2436 	netif_carrier_on(ieee->dev);
2437 
2438 	up(&ieee->wx_sem);
2439 }
2440 
ieee80211_start_ibss(struct ieee80211_device * ieee)2441 inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
2442 {
2443 	queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150);
2444 }
2445 
2446 /* this is called only in user context, with wx_sem held */
ieee80211_start_bss(struct ieee80211_device * ieee)2447 void ieee80211_start_bss(struct ieee80211_device *ieee)
2448 {
2449 	unsigned long flags;
2450 	//
2451 	// Ref: 802.11d 11.1.3.3
2452 	// STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
2453 	//
2454 	if(IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
2455 	{
2456 		if(! ieee->bGlobalDomain)
2457 		{
2458 			return;
2459 		}
2460 	}
2461 	/* check if we have already found the net we
2462 	 * are interested in (if any).
2463 	 * if not (we are disassociated and we are not
2464 	 * in associating / authenticating phase) start the background scanning.
2465 	 */
2466 	ieee80211_softmac_check_all_nets(ieee);
2467 
2468 	/* ensure no-one start an associating process (thus setting
2469 	 * the ieee->state to ieee80211_ASSOCIATING) while we
2470 	 * have just cheked it and we are going to enable scan.
2471 	 * The ieee80211_new_net function is always called with
2472 	 * lock held (from both ieee80211_softmac_check_all_nets and
2473 	 * the rx path), so we cannot be in the middle of such function
2474 	 */
2475 	spin_lock_irqsave(&ieee->lock, flags);
2476 
2477 	if (ieee->state == IEEE80211_NOLINK){
2478 		ieee->actscanning = true;
2479 		ieee80211_start_scan(ieee);
2480 	}
2481 	spin_unlock_irqrestore(&ieee->lock, flags);
2482 }
2483 
2484 /* called only in userspace context */
ieee80211_disassociate(struct ieee80211_device * ieee)2485 void ieee80211_disassociate(struct ieee80211_device *ieee)
2486 {
2487 
2488 
2489 	netif_carrier_off(ieee->dev);
2490 	if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
2491 			ieee80211_reset_queue(ieee);
2492 
2493 	if (ieee->data_hard_stop)
2494 			ieee->data_hard_stop(ieee->dev);
2495 	if(IS_DOT11D_ENABLE(ieee))
2496 		Dot11d_Reset(ieee);
2497 	ieee->state = IEEE80211_NOLINK;
2498 	ieee->is_set_key = false;
2499 	ieee->link_change(ieee->dev);
2500 	//HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2501 	notify_wx_assoc_event(ieee);
2502 
2503 }
ieee80211_associate_retry_wq(struct work_struct * work)2504 void ieee80211_associate_retry_wq(struct work_struct *work)
2505 {
2506 	struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2507 	struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
2508 	unsigned long flags;
2509 
2510 	down(&ieee->wx_sem);
2511 	if(!ieee->proto_started)
2512 		goto exit;
2513 
2514 	if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
2515 		goto exit;
2516 
2517 	/* until we do not set the state to IEEE80211_NOLINK
2518 	* there are no possibility to have someone else trying
2519 	* to start an association procedure (we get here with
2520 	* ieee->state = IEEE80211_ASSOCIATING).
2521 	* When we set the state to IEEE80211_NOLINK it is possible
2522 	* that the RX path run an attempt to associate, but
2523 	* both ieee80211_softmac_check_all_nets and the
2524 	* RX path works with ieee->lock held so there are no
2525 	* problems. If we are still disassociated then start a scan.
2526 	* the lock here is necessary to ensure no one try to start
2527 	* an association procedure when we have just checked the
2528 	* state and we are going to start the scan.
2529 	*/
2530 	ieee->state = IEEE80211_NOLINK;
2531 
2532 	ieee80211_softmac_check_all_nets(ieee);
2533 
2534 	spin_lock_irqsave(&ieee->lock, flags);
2535 
2536 	if(ieee->state == IEEE80211_NOLINK)
2537 		ieee80211_start_scan(ieee);
2538 
2539 	spin_unlock_irqrestore(&ieee->lock, flags);
2540 
2541 exit:
2542 	up(&ieee->wx_sem);
2543 }
2544 
ieee80211_get_beacon_(struct ieee80211_device * ieee)2545 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
2546 {
2547 	u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
2548 
2549 	struct sk_buff *skb;
2550 	struct ieee80211_probe_response *b;
2551 
2552 	skb = ieee80211_probe_resp(ieee, broadcast_addr);
2553 
2554 	if (!skb)
2555 		return NULL;
2556 
2557 	b = (struct ieee80211_probe_response *) skb->data;
2558 	b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
2559 
2560 	return skb;
2561 
2562 }
2563 
ieee80211_get_beacon(struct ieee80211_device * ieee)2564 struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
2565 {
2566 	struct sk_buff *skb;
2567 	struct ieee80211_probe_response *b;
2568 
2569 	skb = ieee80211_get_beacon_(ieee);
2570 	if(!skb)
2571 		return NULL;
2572 
2573 	b = (struct ieee80211_probe_response *) skb->data;
2574 	b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2575 
2576 	if (ieee->seq_ctrl[0] == 0xFFF)
2577 		ieee->seq_ctrl[0] = 0;
2578 	else
2579 		ieee->seq_ctrl[0]++;
2580 
2581 	return skb;
2582 }
2583 
ieee80211_softmac_stop_protocol(struct ieee80211_device * ieee)2584 void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
2585 {
2586 	ieee->sync_scan_hurryup = 1;
2587 	down(&ieee->wx_sem);
2588 	ieee80211_stop_protocol(ieee);
2589 	up(&ieee->wx_sem);
2590 }
2591 
2592 
ieee80211_stop_protocol(struct ieee80211_device * ieee)2593 void ieee80211_stop_protocol(struct ieee80211_device *ieee)
2594 {
2595 	if (!ieee->proto_started)
2596 		return;
2597 
2598 	ieee->proto_started = 0;
2599 
2600 	ieee80211_stop_send_beacons(ieee);
2601 	del_timer_sync(&ieee->associate_timer);
2602 	cancel_delayed_work(&ieee->associate_retry_wq);
2603 	cancel_delayed_work(&ieee->start_ibss_wq);
2604 	ieee80211_stop_scan(ieee);
2605 
2606 	ieee80211_disassociate(ieee);
2607 	RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
2608 }
2609 
ieee80211_softmac_start_protocol(struct ieee80211_device * ieee)2610 void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
2611 {
2612 	ieee->sync_scan_hurryup = 0;
2613 	down(&ieee->wx_sem);
2614 	ieee80211_start_protocol(ieee);
2615 	up(&ieee->wx_sem);
2616 }
2617 
ieee80211_start_protocol(struct ieee80211_device * ieee)2618 void ieee80211_start_protocol(struct ieee80211_device *ieee)
2619 {
2620 	short ch = 0;
2621 	int i = 0;
2622 	if (ieee->proto_started)
2623 		return;
2624 
2625 	ieee->proto_started = 1;
2626 
2627 	if (ieee->current_network.channel == 0){
2628 		do{
2629 			ch++;
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;
2634 	}
2635 
2636 	if (ieee->current_network.beacon_interval == 0)
2637 		ieee->current_network.beacon_interval = 100;
2638 //	printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel);
2639 //	ieee->set_chan(ieee->dev,ieee->current_network.channel);
2640 
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;
2645 	}
2646 
2647 	ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
2648 
2649 
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 ??
2654 	 */
2655 	if (ieee->iw_mode == IW_MODE_INFRA)
2656 		ieee80211_start_bss(ieee);
2657 
2658 	else if (ieee->iw_mode == IW_MODE_ADHOC)
2659 		ieee80211_start_ibss(ieee);
2660 
2661 	else if (ieee->iw_mode == IW_MODE_MASTER)
2662 		ieee80211_start_master_bss(ieee);
2663 
2664 	else if(ieee->iw_mode == IW_MODE_MONITOR)
2665 		ieee80211_start_monitor_mode(ieee);
2666 }
2667 
2668 
2669 #define DRV_NAME  "Ieee80211"
ieee80211_softmac_init(struct ieee80211_device * ieee)2670 void ieee80211_softmac_init(struct ieee80211_device *ieee)
2671 {
2672 	int i;
2673 	memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
2674 
2675 	ieee->state = IEEE80211_NOLINK;
2676 	ieee->sync_scan_hurryup = 0;
2677 	for(i = 0; i < 5; i++) {
2678 	  ieee->seq_ctrl[i] = 0;
2679 	}
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;
2687 
2688 	ieee->assoc_id = 0;
2689 	ieee->queue_stop = 0;
2690 	ieee->scanning = 0;
2691 	ieee->softmac_features = 0; //so IEEE2100-like driver are happy
2692 	ieee->wap_set = 0;
2693 	ieee->ssid_set = 0;
2694 	ieee->proto_started = 0;
2695 	ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
2696 	ieee->rate = 22;
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;
2702 	//added by amy
2703 	ieee->actscanning = false;
2704 	ieee->beinretry = false;
2705 	ieee->is_set_key = false;
2706 	init_mgmt_queue(ieee);
2707 
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 = 1;
2714 	ieee->tx_pending.txb = NULL;
2715 
2716 	init_timer(&ieee->associate_timer);
2717 	ieee->associate_timer.data = (unsigned long)ieee;
2718 	ieee->associate_timer.function = ieee80211_associate_abort_cb;
2719 
2720 	init_timer(&ieee->beacon_timer);
2721 	ieee->beacon_timer.data = (unsigned long) ieee;
2722 	ieee->beacon_timer.function = ieee80211_send_beacon_cb;
2723 
2724 	ieee->wq = create_workqueue(DRV_NAME);
2725 
2726 	INIT_DELAYED_WORK(&ieee->start_ibss_wq,ieee80211_start_ibss_wq);
2727 	INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
2728 	INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
2729 	INIT_DELAYED_WORK(&ieee->softmac_scan_wq,ieee80211_softmac_scan_wq);
2730 	INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
2731 	INIT_WORK(&ieee->wx_sync_scan_wq,ieee80211_wx_sync_scan_wq);
2732 
2733 
2734 	sema_init(&ieee->wx_sem, 1);
2735 	sema_init(&ieee->scan_sem, 1);
2736 
2737 	spin_lock_init(&ieee->mgmt_tx_lock);
2738 	spin_lock_init(&ieee->beacon_lock);
2739 
2740 	tasklet_init(&ieee->ps_task,
2741 	     (void(*)(unsigned long)) ieee80211_sta_ps,
2742 	     (unsigned long)ieee);
2743 
2744 }
2745 
ieee80211_softmac_free(struct ieee80211_device * ieee)2746 void ieee80211_softmac_free(struct ieee80211_device *ieee)
2747 {
2748 	down(&ieee->wx_sem);
2749 	kfree(ieee->pDot11dInfo);
2750 	ieee->pDot11dInfo = NULL;
2751 	del_timer_sync(&ieee->associate_timer);
2752 
2753 	cancel_delayed_work(&ieee->associate_retry_wq);
2754 	destroy_workqueue(ieee->wq);
2755 
2756 	up(&ieee->wx_sem);
2757 }
2758 
2759 /********************************************************
2760  * Start of WPA code.                                   *
2761  * this is stolen from the ipw2200 driver               *
2762  ********************************************************/
2763 
2764 
ieee80211_wpa_enable(struct ieee80211_device * ieee,int value)2765 static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
2766 {
2767 	/* This is called when wpa_supplicant loads and closes the driver
2768 	 * interface. */
2769 	printk("%s WPA\n",value ? "enabling" : "disabling");
2770 	ieee->wpa_enabled = value;
2771 	return 0;
2772 }
2773 
2774 
ieee80211_wpa_assoc_frame(struct ieee80211_device * ieee,char * wpa_ie,int wpa_ie_len)2775 void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len)
2776 {
2777 	/* make sure WPA is enabled */
2778 	ieee80211_wpa_enable(ieee, 1);
2779 
2780 	ieee80211_disassociate(ieee);
2781 }
2782 
2783 
ieee80211_wpa_mlme(struct ieee80211_device * ieee,int command,int reason)2784 static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
2785 {
2786 
2787 	int ret = 0;
2788 
2789 	switch (command) {
2790 	case IEEE_MLME_STA_DEAUTH:
2791 		// silently ignore
2792 		break;
2793 
2794 	case IEEE_MLME_STA_DISASSOC:
2795 		ieee80211_disassociate(ieee);
2796 		break;
2797 
2798 	default:
2799 		printk("Unknown MLME request: %d\n", command);
2800 		ret = -EOPNOTSUPP;
2801 	}
2802 
2803 	return ret;
2804 }
2805 
2806 
ieee80211_wpa_set_wpa_ie(struct ieee80211_device * ieee,struct ieee_param * param,int plen)2807 static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
2808 			      struct ieee_param *param, int plen)
2809 {
2810 	u8 *buf;
2811 
2812 	if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
2813 	    (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
2814 		return -EINVAL;
2815 
2816 	if (param->u.wpa_ie.len) {
2817 		buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len,
2818 			      GFP_KERNEL);
2819 		if (buf == NULL)
2820 			return -ENOMEM;
2821 
2822 		kfree(ieee->wpa_ie);
2823 		ieee->wpa_ie = buf;
2824 		ieee->wpa_ie_len = param->u.wpa_ie.len;
2825 	} else {
2826 		kfree(ieee->wpa_ie);
2827 		ieee->wpa_ie = NULL;
2828 		ieee->wpa_ie_len = 0;
2829 	}
2830 
2831 	ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
2832 	return 0;
2833 }
2834 
2835 #define AUTH_ALG_OPEN_SYSTEM			0x1
2836 #define AUTH_ALG_SHARED_KEY			0x2
2837 
ieee80211_wpa_set_auth_algs(struct ieee80211_device * ieee,int value)2838 static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
2839 {
2840 
2841 	struct ieee80211_security sec = {
2842 		.flags = SEC_AUTH_MODE,
2843 	};
2844 	int ret = 0;
2845 
2846 	if (value & AUTH_ALG_SHARED_KEY) {
2847 		sec.auth_mode = WLAN_AUTH_SHARED_KEY;
2848 		ieee->open_wep = 0;
2849 		ieee->auth_mode = 1;
2850 	} else if (value & AUTH_ALG_OPEN_SYSTEM){
2851 		sec.auth_mode = WLAN_AUTH_OPEN;
2852 		ieee->open_wep = 1;
2853 		ieee->auth_mode = 0;
2854 	}
2855 	else if (value & IW_AUTH_ALG_LEAP){
2856 		sec.auth_mode = WLAN_AUTH_LEAP;
2857 		ieee->open_wep = 1;
2858 		ieee->auth_mode = 2;
2859 	}
2860 
2861 
2862 	if (ieee->set_security)
2863 		ieee->set_security(ieee->dev, &sec);
2864 	//else
2865 	//	ret = -EOPNOTSUPP;
2866 
2867 	return ret;
2868 }
2869 
ieee80211_wpa_set_param(struct ieee80211_device * ieee,u8 name,u32 value)2870 static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
2871 {
2872 	int ret=0;
2873 	unsigned long flags;
2874 
2875 	switch (name) {
2876 	case IEEE_PARAM_WPA_ENABLED:
2877 		ret = ieee80211_wpa_enable(ieee, value);
2878 		break;
2879 
2880 	case IEEE_PARAM_TKIP_COUNTERMEASURES:
2881 		ieee->tkip_countermeasures=value;
2882 		break;
2883 
2884 	case IEEE_PARAM_DROP_UNENCRYPTED: {
2885 		/* HACK:
2886 		 *
2887 		 * wpa_supplicant calls set_wpa_enabled when the driver
2888 		 * is loaded and unloaded, regardless of if WPA is being
2889 		 * used.  No other calls are made which can be used to
2890 		 * determine if encryption will be used or not prior to
2891 		 * association being expected.  If encryption is not being
2892 		 * used, drop_unencrypted is set to false, else true -- we
2893 		 * can use this to determine if the CAP_PRIVACY_ON bit should
2894 		 * be set.
2895 		 */
2896 		struct ieee80211_security sec = {
2897 			.flags = SEC_ENABLED,
2898 			.enabled = value,
2899 		};
2900 		ieee->drop_unencrypted = value;
2901 		/* We only change SEC_LEVEL for open mode. Others
2902 		 * are set by ipw_wpa_set_encryption.
2903 		 */
2904 		if (!value) {
2905 			sec.flags |= SEC_LEVEL;
2906 			sec.level = SEC_LEVEL_0;
2907 		}
2908 		else {
2909 			sec.flags |= SEC_LEVEL;
2910 			sec.level = SEC_LEVEL_1;
2911 		}
2912 		if (ieee->set_security)
2913 			ieee->set_security(ieee->dev, &sec);
2914 		break;
2915 	}
2916 
2917 	case IEEE_PARAM_PRIVACY_INVOKED:
2918 		ieee->privacy_invoked=value;
2919 		break;
2920 
2921 	case IEEE_PARAM_AUTH_ALGS:
2922 		ret = ieee80211_wpa_set_auth_algs(ieee, value);
2923 		break;
2924 
2925 	case IEEE_PARAM_IEEE_802_1X:
2926 		ieee->ieee802_1x=value;
2927 		break;
2928 	case IEEE_PARAM_WPAX_SELECT:
2929 		// added for WPA2 mixed mode
2930 		spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
2931 		ieee->wpax_type_set = 1;
2932 		ieee->wpax_type_notify = value;
2933 		spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
2934 		break;
2935 
2936 	default:
2937 		printk("Unknown WPA param: %d\n",name);
2938 		ret = -EOPNOTSUPP;
2939 	}
2940 
2941 	return ret;
2942 }
2943 
2944 /* implementation borrowed from hostap driver */
2945 
ieee80211_wpa_set_encryption(struct ieee80211_device * ieee,struct ieee_param * param,int param_len)2946 static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
2947 				  struct ieee_param *param, int param_len)
2948 {
2949 	int ret = 0;
2950 
2951 	struct ieee80211_crypto_ops *ops;
2952 	struct ieee80211_crypt_data **crypt;
2953 
2954 	struct ieee80211_security sec = {
2955 		.flags = 0,
2956 	};
2957 
2958 	param->u.crypt.err = 0;
2959 	param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
2960 
2961 	if (param_len !=
2962 	    (int) ((char *) param->u.crypt.key - (char *) param) +
2963 	    param->u.crypt.key_len) {
2964 		printk("Len mismatch %d, %d\n", param_len,
2965 			       param->u.crypt.key_len);
2966 		return -EINVAL;
2967 	}
2968 	if (is_broadcast_ether_addr(param->sta_addr)) {
2969 		if (param->u.crypt.idx >= WEP_KEYS)
2970 			return -EINVAL;
2971 		crypt = &ieee->crypt[param->u.crypt.idx];
2972 	} else {
2973 		return -EINVAL;
2974 	}
2975 
2976 	if (strcmp(param->u.crypt.alg, "none") == 0) {
2977 		if (crypt) {
2978 			sec.enabled = 0;
2979 			// FIXME FIXME
2980 			//sec.encrypt = 0;
2981 			sec.level = SEC_LEVEL_0;
2982 			sec.flags |= SEC_ENABLED | SEC_LEVEL;
2983 			ieee80211_crypt_delayed_deinit(ieee, crypt);
2984 		}
2985 		goto done;
2986 	}
2987 	sec.enabled = 1;
2988 // FIXME FIXME
2989 //	sec.encrypt = 1;
2990 	sec.flags |= SEC_ENABLED;
2991 
2992 	/* IPW HW cannot build TKIP MIC, host decryption still needed. */
2993 	if (!(ieee->host_encrypt || ieee->host_decrypt) &&
2994 	    strcmp(param->u.crypt.alg, "TKIP"))
2995 		goto skip_host_crypt;
2996 
2997 	ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
2998 	if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
2999 		request_module("ieee80211_crypt_wep");
3000 		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3001 		//set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
3002 	} else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
3003 		request_module("ieee80211_crypt_tkip");
3004 		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3005 	} else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
3006 		request_module("ieee80211_crypt_ccmp");
3007 		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
3008 	}
3009 	if (ops == NULL) {
3010 		printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
3011 		param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
3012 		ret = -EINVAL;
3013 		goto done;
3014 	}
3015 
3016 	if (*crypt == NULL || (*crypt)->ops != ops) {
3017 		struct ieee80211_crypt_data *new_crypt;
3018 
3019 		ieee80211_crypt_delayed_deinit(ieee, crypt);
3020 
3021 		new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL);
3022 		if (new_crypt == NULL) {
3023 			ret = -ENOMEM;
3024 			goto done;
3025 		}
3026 		memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
3027 		new_crypt->ops = ops;
3028 		if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
3029 			new_crypt->priv =
3030 				new_crypt->ops->init(param->u.crypt.idx);
3031 
3032 		if (new_crypt->priv == NULL) {
3033 			kfree(new_crypt);
3034 			param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
3035 			ret = -EINVAL;
3036 			goto done;
3037 		}
3038 
3039 		*crypt = new_crypt;
3040 	}
3041 
3042 	if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
3043 	    (*crypt)->ops->set_key(param->u.crypt.key,
3044 				   param->u.crypt.key_len, param->u.crypt.seq,
3045 				   (*crypt)->priv) < 0) {
3046 		printk("key setting failed\n");
3047 		param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
3048 		ret = -EINVAL;
3049 		goto done;
3050 	}
3051 
3052  skip_host_crypt:
3053 	if (param->u.crypt.set_tx) {
3054 		ieee->tx_keyidx = param->u.crypt.idx;
3055 		sec.active_key = param->u.crypt.idx;
3056 		sec.flags |= SEC_ACTIVE_KEY;
3057 	} else
3058 		sec.flags &= ~SEC_ACTIVE_KEY;
3059 
3060 	if (param->u.crypt.alg != NULL) {
3061 		memcpy(sec.keys[param->u.crypt.idx],
3062 		       param->u.crypt.key,
3063 		       param->u.crypt.key_len);
3064 		sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
3065 		sec.flags |= (1 << param->u.crypt.idx);
3066 
3067 		if (strcmp(param->u.crypt.alg, "WEP") == 0) {
3068 			sec.flags |= SEC_LEVEL;
3069 			sec.level = SEC_LEVEL_1;
3070 		} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
3071 			sec.flags |= SEC_LEVEL;
3072 			sec.level = SEC_LEVEL_2;
3073 		} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
3074 			sec.flags |= SEC_LEVEL;
3075 			sec.level = SEC_LEVEL_3;
3076 		}
3077 	}
3078  done:
3079 	if (ieee->set_security)
3080 		ieee->set_security(ieee->dev, &sec);
3081 
3082 	/* Do not reset port if card is in Managed mode since resetting will
3083 	 * generate new IEEE 802.11 authentication which may end up in looping
3084 	 * with IEEE 802.1X.  If your hardware requires a reset after WEP
3085 	 * configuration (for example... Prism2), implement the reset_port in
3086 	 * the callbacks structures used to initialize the 802.11 stack. */
3087 	if (ieee->reset_on_keychange &&
3088 	    ieee->iw_mode != IW_MODE_INFRA &&
3089 	    ieee->reset_port &&
3090 	    ieee->reset_port(ieee->dev)) {
3091 		printk("reset_port failed\n");
3092 		param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
3093 		return -EINVAL;
3094 	}
3095 
3096 	return ret;
3097 }
3098 
ieee80211_disassociate_skb(struct ieee80211_network * beacon,struct ieee80211_device * ieee,u8 asRsn)3099 inline struct sk_buff *ieee80211_disassociate_skb(
3100 							struct ieee80211_network *beacon,
3101 							struct ieee80211_device *ieee,
3102 							u8	asRsn)
3103 {
3104 	struct sk_buff *skb;
3105 	struct ieee80211_disassoc *disass;
3106 
3107 	skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc));
3108 	if (!skb)
3109 		return NULL;
3110 
3111 	disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc));
3112 	disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
3113 	disass->header.duration_id = 0;
3114 
3115 	memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
3116 	memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
3117 	memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
3118 
3119 	disass->reason = asRsn;
3120 	return skb;
3121 }
3122 
3123 
3124 void
SendDisassociation(struct ieee80211_device * ieee,u8 * asSta,u8 asRsn)3125 SendDisassociation(
3126 		struct ieee80211_device *ieee,
3127 		u8*					asSta,
3128 		u8						asRsn
3129 )
3130 {
3131 		struct ieee80211_network *beacon = &ieee->current_network;
3132 		struct sk_buff *skb;
3133 		skb = ieee80211_disassociate_skb(beacon,ieee,asRsn);
3134 		if (skb){
3135 				softmac_mgmt_xmit(skb, ieee);
3136 				//dev_kfree_skb_any(skb);//edit by thomas
3137 		}
3138 }
3139 
ieee80211_wpa_supplicant_ioctl(struct ieee80211_device * ieee,struct iw_point * p)3140 int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
3141 {
3142 	struct ieee_param *param;
3143 	int ret=0;
3144 
3145 	down(&ieee->wx_sem);
3146 	//IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
3147 
3148 	if (p->length < sizeof(struct ieee_param) || !p->pointer){
3149 		ret = -EINVAL;
3150 		goto out;
3151 	}
3152 
3153 	param = kmalloc(p->length, GFP_KERNEL);
3154 	if (param == NULL){
3155 		ret = -ENOMEM;
3156 		goto out;
3157 	}
3158 	if (copy_from_user(param, p->pointer, p->length)) {
3159 		kfree(param);
3160 		ret = -EFAULT;
3161 		goto out;
3162 	}
3163 
3164 	switch (param->cmd) {
3165 
3166 	case IEEE_CMD_SET_WPA_PARAM:
3167 		ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
3168 					param->u.wpa_param.value);
3169 		break;
3170 
3171 	case IEEE_CMD_SET_WPA_IE:
3172 		ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
3173 		break;
3174 
3175 	case IEEE_CMD_SET_ENCRYPTION:
3176 		ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
3177 		break;
3178 
3179 	case IEEE_CMD_MLME:
3180 		ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
3181 				   param->u.mlme.reason_code);
3182 		break;
3183 
3184 	default:
3185 		printk("Unknown WPA supplicant request: %d\n",param->cmd);
3186 		ret = -EOPNOTSUPP;
3187 		break;
3188 	}
3189 
3190 	if (ret == 0 && copy_to_user(p->pointer, param, p->length))
3191 		ret = -EFAULT;
3192 
3193 	kfree(param);
3194 out:
3195 	up(&ieee->wx_sem);
3196 
3197 	return ret;
3198 }
3199 
notify_wx_assoc_event(struct ieee80211_device * ieee)3200 void notify_wx_assoc_event(struct ieee80211_device *ieee)
3201 {
3202 	union iwreq_data wrqu;
3203 	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3204 	if (ieee->state == IEEE80211_LINKED)
3205 		memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
3206 	else
3207 		memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
3208 	wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
3209 }
3210 
3211 EXPORT_SYMBOL(ieee80211_get_beacon);
3212 EXPORT_SYMBOL(ieee80211_wake_queue);
3213 EXPORT_SYMBOL(ieee80211_stop_queue);
3214 EXPORT_SYMBOL(ieee80211_reset_queue);
3215 EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
3216 EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
3217 EXPORT_SYMBOL(ieee80211_is_shortslot);
3218 EXPORT_SYMBOL(ieee80211_is_54g);
3219 EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
3220 EXPORT_SYMBOL(ieee80211_ps_tx_ack);
3221 EXPORT_SYMBOL(ieee80211_softmac_xmit);
3222 EXPORT_SYMBOL(ieee80211_stop_send_beacons);
3223 EXPORT_SYMBOL(notify_wx_assoc_event);
3224 EXPORT_SYMBOL(SendDisassociation);
3225 EXPORT_SYMBOL(ieee80211_disassociate);
3226 EXPORT_SYMBOL(ieee80211_start_send_beacons);
3227 EXPORT_SYMBOL(ieee80211_stop_scan);
3228 EXPORT_SYMBOL(ieee80211_send_probe_requests);
3229 EXPORT_SYMBOL(ieee80211_softmac_scan_syncro);
3230 EXPORT_SYMBOL(ieee80211_start_scan_syncro);
3231 //EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame);
3232