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