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