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 
ieee80211_is_54g(const struct ieee80211_network * net)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 
ieee80211_is_shortslot(const struct ieee80211_network * net)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 pleacing the RATE MFIE
37  * tag and the EXTENDED RATE MFIE tag if needed.
38  * It encludes two bytes per tag for the tag itself and its len
39  */
ieee80211_MFIE_rate_len(struct ieee80211_device * ieee)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 /* pleace the MFIE rate, tag to the memory (double) poined.
54  * Then it updates the pointer so that
55  * it points after the new MFIE tag added.
56  */
ieee80211_MFIE_Brate(struct ieee80211_device * ieee,u8 ** tag_p)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 
ieee80211_MFIE_Grate(struct ieee80211_device * ieee,u8 ** tag_p)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 
ieee80211_WMM_Info(struct ieee80211_device * ieee,u8 ** tag_p)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
ieee80211_TURBO_Info(struct ieee80211_device * ieee,u8 ** tag_p)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 	printk(KERN_ALERT "This is enable turbo mode IE process\n");
135 }
136 #endif
137 
enqueue_mgmt(struct ieee80211_device * ieee,struct sk_buff * skb)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 
dequeue_mgmt(struct ieee80211_device * ieee)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 
init_mgmt_queue(struct ieee80211_device * ieee)172 static void init_mgmt_queue(struct ieee80211_device *ieee)
173 {
174 	ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
175 }
176 
MgntQuery_MgntFrameTxRate(struct ieee80211_device * ieee)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 
softmac_mgmt_xmit(struct sk_buff * skb,struct ieee80211_device * ieee)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
softmac_ps_mgmt_xmit(struct sk_buff * skb,struct ieee80211_device * ieee)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 
ieee80211_probe_req(struct ieee80211_device * ieee)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 
ieee80211_send_beacon(struct ieee80211_device * ieee)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 
ieee80211_send_beacon_cb(struct timer_list * t)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 
ieee80211_send_probe(struct ieee80211_device * ieee)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 
ieee80211_send_probe_requests(struct ieee80211_device * ieee)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  */
ieee80211_softmac_scan_syncro(struct ieee80211_device * ieee)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 temporarly '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 
ieee80211_softmac_scan_wq(struct work_struct * work)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 
ieee80211_beacons_start(struct ieee80211_device * ieee)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 
ieee80211_beacons_stop(struct ieee80211_device * ieee)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 
ieee80211_stop_send_beacons(struct ieee80211_device * ieee)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 
ieee80211_start_send_beacons(struct ieee80211_device * ieee)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 
ieee80211_softmac_stop_scan(struct ieee80211_device * ieee)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 
ieee80211_stop_scan(struct ieee80211_device * ieee)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 */
ieee80211_start_scan(struct ieee80211_device * ieee)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 */
ieee80211_start_scan_syncro(struct ieee80211_device * ieee)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 *
ieee80211_authentication_req(struct ieee80211_network * beacon,struct ieee80211_device * ieee,int challengelen)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 
ieee80211_probe_resp(struct ieee80211_device * ieee,u8 * dest)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 
ieee80211_assoc_resp(struct ieee80211_device * ieee,u8 * dest)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 
ieee80211_auth_resp(struct ieee80211_device * ieee,int status,u8 * dest)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 
ieee80211_null_func(struct ieee80211_device * ieee,short pwr)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 
ieee80211_resp_to_assoc_rq(struct ieee80211_device * ieee,u8 * dest)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 
ieee80211_resp_to_auth(struct ieee80211_device * ieee,int s,u8 * dest)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 
ieee80211_resp_to_probe(struct ieee80211_device * ieee,u8 * dest)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 *
ieee80211_association_req(struct ieee80211_network * beacon,struct ieee80211_device * ieee)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 
ieee80211_associate_abort(struct ieee80211_device * ieee)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 to have the RX path possibily
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 
ieee80211_associate_abort_cb(struct timer_list * t)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 
ieee80211_associate_step1(struct ieee80211_device * ieee)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 
ieee80211_auth_challenge(struct ieee80211_device * ieee,u8 * challenge,int chlen)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 
ieee80211_associate_step2(struct ieee80211_device * ieee)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 }
ieee80211_associate_complete_wq(struct work_struct * work)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 	printk(KERN_INFO "Associated successfully\n");
1274 	if (ieee80211_is_54g(&ieee->current_network) &&
1275 	    (ieee->modulation & IEEE80211_OFDM_MODULATION)) {
1276 		ieee->rate = 108;
1277 		printk(KERN_INFO"Using G rates:%d\n", ieee->rate);
1278 	} else {
1279 		ieee->rate = 22;
1280 		printk(KERN_INFO"Using B rates:%d\n", ieee->rate);
1281 	}
1282 	if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
1283 		printk("Successfully associated, ht enabled\n");
1284 		HTOnAssocRsp(ieee);
1285 	} else {
1286 		printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
1287 		memset(ieee->dot11HTOperationalRateSet, 0, 16);
1288 		//HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1289 	}
1290 	ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval / 500);
1291 	// To prevent the immediately calling watch_dog after association.
1292 	if (ieee->LinkDetectInfo.NumRecvBcnInPeriod == 0 || ieee->LinkDetectInfo.NumRecvDataInPeriod == 0) {
1293 		ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
1294 		ieee->LinkDetectInfo.NumRecvDataInPeriod = 1;
1295 	}
1296 	ieee->link_change(ieee->dev);
1297 	if (!ieee->is_silent_reset) {
1298 		printk("============>normal associate\n");
1299 		notify_wx_assoc_event(ieee);
1300 	} else {
1301 		printk("==================>silent reset associate\n");
1302 		ieee->is_silent_reset = false;
1303 	}
1304 
1305 	if (ieee->data_hard_resume)
1306 		ieee->data_hard_resume(ieee->dev);
1307 	netif_carrier_on(ieee->dev);
1308 }
1309 
ieee80211_associate_complete(struct ieee80211_device * ieee)1310 static void ieee80211_associate_complete(struct ieee80211_device *ieee)
1311 {
1312 //	int i;
1313 //	struct net_device* dev = ieee->dev;
1314 	del_timer_sync(&ieee->associate_timer);
1315 
1316 	ieee->state = IEEE80211_LINKED;
1317 	//ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet);
1318 	schedule_work(&ieee->associate_complete_wq);
1319 }
1320 
ieee80211_associate_procedure_wq(struct work_struct * work)1321 static void ieee80211_associate_procedure_wq(struct work_struct *work)
1322 {
1323 	struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
1324 	ieee->sync_scan_hurryup = 1;
1325 	mutex_lock(&ieee->wx_mutex);
1326 
1327 	if (ieee->data_hard_stop)
1328 		ieee->data_hard_stop(ieee->dev);
1329 
1330 	ieee80211_stop_scan(ieee);
1331 	printk("===>%s(), chan:%d\n", __func__, ieee->current_network.channel);
1332 	//ieee->set_chan(ieee->dev, ieee->current_network.channel);
1333 	HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1334 
1335 	ieee->associate_seq = 1;
1336 	ieee80211_associate_step1(ieee);
1337 
1338 	mutex_unlock(&ieee->wx_mutex);
1339 }
1340 
ieee80211_softmac_new_net(struct ieee80211_device * ieee,struct ieee80211_network * net)1341 inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
1342 {
1343 	u8 tmp_ssid[IW_ESSID_MAX_SIZE + 1];
1344 	int tmp_ssid_len = 0;
1345 
1346 	short apset, ssidset, ssidbroad, apmatch, ssidmatch;
1347 
1348 	/* we are interested in new new only if we are not associated
1349 	 * and we are not associating / authenticating
1350 	 */
1351 	if (ieee->state != IEEE80211_NOLINK)
1352 		return;
1353 
1354 	if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
1355 		return;
1356 
1357 	if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
1358 		return;
1359 
1360 	if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) {
1361 		/* if the user specified the AP MAC, we need also the essid
1362 		 * This could be obtained by beacons or, if the network does not
1363 		 * broadcast it, it can be put manually.
1364 		 */
1365 		apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
1366 		ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
1367 		ssidbroad =  !(net->ssid_len == 0 || net->ssid[0] == '\0');
1368 		apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN) == 0);
1369 		ssidmatch = (ieee->current_network.ssid_len == net->ssid_len) &&
1370 			(!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
1371 
1372 		/* if the user set the AP check if match.
1373 		 * if the network does not broadcast essid we check the user supplyed ANY essid
1374 		 * if the network does broadcast and the user does not set essid it is OK
1375 		 * if the network does broadcast and the user did set essid chech if essid match
1376 		 */
1377 		if ((apset && apmatch &&
1378 		     ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset))) ||
1379 		    /* if the ap is not set, check that the user set the bssid
1380 		     * and the network does broadcast and that those two bssid matches
1381 		     */
1382 		    (!apset && ssidset && ssidbroad && ssidmatch)) {
1383 			/* if the essid is hidden replace it with the
1384 			 * essid provided by the user.
1385 			 */
1386 			if (!ssidbroad) {
1387 				strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
1388 				tmp_ssid_len = ieee->current_network.ssid_len;
1389 			}
1390 			memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
1391 
1392 			strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
1393 			ieee->current_network.ssid_len = tmp_ssid_len;
1394 			printk(KERN_INFO"Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d\n",
1395 			       ieee->current_network.ssid,
1396 			       ieee->current_network.channel,
1397 			       ieee->current_network.qos_data.supported,
1398 			       ieee->pHTInfo->bEnableHT,
1399 			       ieee->current_network.bssht.bdSupportHT);
1400 
1401 			//ieee->pHTInfo->IOTAction = 0;
1402 			HTResetIOTSetting(ieee->pHTInfo);
1403 			if (ieee->iw_mode == IW_MODE_INFRA) {
1404 				/* Join the network for the first time */
1405 				ieee->AsocRetryCount = 0;
1406 				//for HT by amy 080514
1407 				if ((ieee->current_network.qos_data.supported == 1) &&
1408 				    // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT))
1409 				    ieee->current_network.bssht.bdSupportHT) {
1410 /*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.*/
1411 					//	ieee->pHTInfo->bCurrentHTSupport = true;
1412 					HTResetSelfAndSavePeerSetting(ieee, &ieee->current_network);
1413 				} else {
1414 					ieee->pHTInfo->bCurrentHTSupport = false;
1415 				}
1416 
1417 				ieee->state = IEEE80211_ASSOCIATING;
1418 				schedule_work(&ieee->associate_procedure_wq);
1419 			} else {
1420 				if (ieee80211_is_54g(&ieee->current_network) &&
1421 				    (ieee->modulation & IEEE80211_OFDM_MODULATION)) {
1422 					ieee->rate = 108;
1423 					ieee->SetWirelessMode(ieee->dev, IEEE_G);
1424 					printk(KERN_INFO"Using G rates\n");
1425 				} else {
1426 					ieee->rate = 22;
1427 					ieee->SetWirelessMode(ieee->dev, IEEE_B);
1428 					printk(KERN_INFO"Using B rates\n");
1429 				}
1430 				memset(ieee->dot11HTOperationalRateSet, 0, 16);
1431 				//HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1432 				ieee->state = IEEE80211_LINKED;
1433 			}
1434 		}
1435 	}
1436 }
1437 
ieee80211_softmac_check_all_nets(struct ieee80211_device * ieee)1438 void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
1439 {
1440 	unsigned long flags;
1441 	struct ieee80211_network *target;
1442 
1443 	spin_lock_irqsave(&ieee->lock, flags);
1444 
1445 	list_for_each_entry(target, &ieee->network_list, list) {
1446 		/* if the state become different that NOLINK means
1447 		 * we had found what we are searching for
1448 		 */
1449 
1450 		if (ieee->state != IEEE80211_NOLINK)
1451 			break;
1452 
1453 		if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
1454 			ieee80211_softmac_new_net(ieee, target);
1455 	}
1456 
1457 	spin_unlock_irqrestore(&ieee->lock, flags);
1458 }
1459 
auth_parse(struct sk_buff * skb,u8 ** challenge,int * chlen)1460 static inline u16 auth_parse(struct sk_buff *skb, u8 **challenge, int *chlen)
1461 {
1462 	struct ieee80211_authentication *a;
1463 	u8 *t;
1464 	if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
1465 		IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
1466 		return 0xcafe;
1467 	}
1468 	*challenge = NULL;
1469 	a = (struct ieee80211_authentication *)skb->data;
1470 	if (skb->len > (sizeof(struct ieee80211_authentication) + 3)) {
1471 		t = skb->data + sizeof(struct ieee80211_authentication);
1472 
1473 		if (*(t++) == MFIE_TYPE_CHALLENGE) {
1474 			*chlen = *(t++);
1475 			*challenge = kmemdup(t, *chlen, GFP_ATOMIC);
1476 			if (!*challenge)
1477 				return -ENOMEM;
1478 		}
1479 	}
1480 
1481 	return le16_to_cpu(a->status);
1482 }
1483 
auth_rq_parse(struct sk_buff * skb,u8 * dest)1484 static int auth_rq_parse(struct sk_buff *skb, u8 *dest)
1485 {
1486 	struct ieee80211_authentication *a;
1487 
1488 	if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
1489 		IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n", skb->len);
1490 		return -1;
1491 	}
1492 	a = (struct ieee80211_authentication *)skb->data;
1493 
1494 	memcpy(dest, a->header.addr2, ETH_ALEN);
1495 
1496 	if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
1497 		return  WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1498 
1499 	return WLAN_STATUS_SUCCESS;
1500 }
1501 
probe_rq_parse(struct ieee80211_device * ieee,struct sk_buff * skb,u8 * src)1502 static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
1503 {
1504 	u8 *tag;
1505 	u8 *skbend;
1506 	u8 *ssid = NULL;
1507 	u8 ssidlen = 0;
1508 
1509 	struct rtl_80211_hdr_3addr   *header =
1510 		(struct rtl_80211_hdr_3addr   *)skb->data;
1511 
1512 	if (skb->len < sizeof(struct rtl_80211_hdr_3addr))
1513 		return -1; /* corrupted */
1514 
1515 	memcpy(src, header->addr2, ETH_ALEN);
1516 
1517 	skbend = (u8 *)skb->data + skb->len;
1518 
1519 	tag = skb->data + sizeof(struct rtl_80211_hdr_3addr);
1520 
1521 	while (tag + 1 < skbend) {
1522 		if (*tag == 0) {
1523 			ssid = tag + 2;
1524 			ssidlen = *(tag + 1);
1525 			break;
1526 		}
1527 		tag++; /* point to the len field */
1528 		tag = tag + *(tag); /* point to the last data byte of the tag */
1529 		tag++; /* point to the next tag */
1530 	}
1531 
1532 	//IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
1533 	if (ssidlen == 0)
1534 		return 1;
1535 
1536 	if (!ssid)
1537 		return 1; /* ssid not found in tagged param */
1538 
1539 	return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
1540 }
1541 
assoc_rq_parse(struct sk_buff * skb,u8 * dest)1542 static int assoc_rq_parse(struct sk_buff *skb, u8 *dest)
1543 {
1544 	struct ieee80211_assoc_request_frame *a;
1545 
1546 	if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
1547 		sizeof(struct ieee80211_info_element))) {
1548 		IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
1549 		return -1;
1550 	}
1551 
1552 	a = (struct ieee80211_assoc_request_frame *)skb->data;
1553 
1554 	memcpy(dest, a->header.addr2, ETH_ALEN);
1555 
1556 	return 0;
1557 }
1558 
assoc_parse(struct ieee80211_device * ieee,struct sk_buff * skb,int * aid)1559 static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid)
1560 {
1561 	struct ieee80211_assoc_response_frame *response_head;
1562 	u16 status_code;
1563 
1564 	if (skb->len < sizeof(struct ieee80211_assoc_response_frame)) {
1565 		IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
1566 		return 0xcafe;
1567 	}
1568 
1569 	response_head = (struct ieee80211_assoc_response_frame *)skb->data;
1570 	*aid = le16_to_cpu(response_head->aid) & 0x3fff;
1571 
1572 	status_code = le16_to_cpu(response_head->status);
1573 	if ((status_code == WLAN_STATUS_ASSOC_DENIED_RATES ||
1574 	     status_code == WLAN_STATUS_CAPS_UNSUPPORTED) &&
1575 	    ((ieee->mode == IEEE_G) &&
1576 	     (ieee->current_network.mode == IEEE_N_24G) &&
1577 	     (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT - 1)))) {
1578 		ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
1579 	} else {
1580 		ieee->AsocRetryCount = 0;
1581 	}
1582 
1583 	return le16_to_cpu(response_head->status);
1584 }
1585 
1586 static inline void
ieee80211_rx_probe_rq(struct ieee80211_device * ieee,struct sk_buff * skb)1587 ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1588 {
1589 	u8 dest[ETH_ALEN];
1590 
1591 	//IEEE80211DMESG("Rx probe");
1592 	ieee->softmac_stats.rx_probe_rq++;
1593 	//DMESG("Dest is "MACSTR, MAC2STR(dest));
1594 	if (probe_rq_parse(ieee, skb, dest)) {
1595 		//IEEE80211DMESG("Was for me!");
1596 		ieee->softmac_stats.tx_probe_rs++;
1597 		ieee80211_resp_to_probe(ieee, dest);
1598 	}
1599 }
1600 
1601 static inline void
ieee80211_rx_auth_rq(struct ieee80211_device * ieee,struct sk_buff * skb)1602 ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1603 {
1604 	u8 dest[ETH_ALEN];
1605 	int status;
1606 	//IEEE80211DMESG("Rx probe");
1607 	ieee->softmac_stats.rx_auth_rq++;
1608 
1609 	status = auth_rq_parse(skb, dest);
1610 	if (status != -1)
1611 		ieee80211_resp_to_auth(ieee, status, dest);
1612 	//DMESG("Dest is "MACSTR, MAC2STR(dest));
1613 }
1614 
1615 static inline void
ieee80211_rx_assoc_rq(struct ieee80211_device * ieee,struct sk_buff * skb)1616 ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1617 {
1618 	u8 dest[ETH_ALEN];
1619 	//unsigned long flags;
1620 
1621 	ieee->softmac_stats.rx_ass_rq++;
1622 	if (assoc_rq_parse(skb, dest) != -1)
1623 		ieee80211_resp_to_assoc_rq(ieee, dest);
1624 
1625 	printk(KERN_INFO"New client associated: %pM\n", dest);
1626 	//FIXME
1627 }
1628 
ieee80211_sta_ps_send_null_frame(struct ieee80211_device * ieee,short pwr)1629 static void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee,
1630 					     short pwr)
1631 {
1632 	struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
1633 
1634 	if (buf)
1635 		softmac_ps_mgmt_xmit(buf, ieee);
1636 }
1637 /* EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame); */
1638 
ieee80211_sta_ps_sleep(struct ieee80211_device * ieee,u32 * time_h,u32 * time_l)1639 static short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h,
1640 				    u32 *time_l)
1641 {
1642 	int timeout;
1643 	u8 dtim;
1644 	/*if(ieee->ps == IEEE80211_PS_DISABLED ||
1645 		ieee->iw_mode != IW_MODE_INFRA ||
1646 		ieee->state != IEEE80211_LINKED)
1647 
1648 		return 0;
1649 	*/
1650 	dtim = ieee->current_network.dtim_data;
1651 	if (!(dtim & IEEE80211_DTIM_VALID))
1652 		return 0;
1653 	timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
1654 	ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
1655 
1656 	if (dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST) & ieee->ps))
1657 		return 2;
1658 
1659 	if (!time_after(jiffies,
1660 			dev_trans_start(ieee->dev) + msecs_to_jiffies(timeout)))
1661 		return 0;
1662 
1663 	if (!time_after(jiffies,
1664 			ieee->last_rx_ps_time + msecs_to_jiffies(timeout)))
1665 		return 0;
1666 
1667 	if ((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) &&
1668 	    (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
1669 		return 0;
1670 
1671 	if (time_l) {
1672 		*time_l = ieee->current_network.last_dtim_sta_time[0]
1673 			+ (ieee->current_network.beacon_interval
1674 			   * ieee->current_network.dtim_period) * 1000;
1675 	}
1676 
1677 	if (time_h) {
1678 		*time_h = ieee->current_network.last_dtim_sta_time[1];
1679 		if (time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
1680 			*time_h += 1;
1681 	}
1682 
1683 	return 1;
1684 }
1685 
ieee80211_sta_ps(struct ieee80211_device * ieee)1686 static inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
1687 {
1688 	u32 th, tl;
1689 	short sleep;
1690 
1691 	unsigned long flags, flags2;
1692 
1693 	spin_lock_irqsave(&ieee->lock, flags);
1694 
1695 	if ((ieee->ps == IEEE80211_PS_DISABLED ||
1696 	     ieee->iw_mode != IW_MODE_INFRA ||
1697 	     ieee->state != IEEE80211_LINKED)) {
1698 		//	#warning CHECK_LOCK_HERE
1699 		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1700 
1701 		ieee80211_sta_wakeup(ieee, 1);
1702 
1703 		spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1704 	}
1705 
1706 	sleep = ieee80211_sta_ps_sleep(ieee, &th, &tl);
1707 	/* 2 wake, 1 sleep, 0 do nothing */
1708 	if (sleep == 0)
1709 		goto out;
1710 
1711 	if (sleep == 1) {
1712 		if (ieee->sta_sleep == 1) {
1713 			ieee->enter_sleep_state(ieee->dev, th, tl);
1714 		} else if (ieee->sta_sleep == 0) {
1715 		//	printk("send null 1\n");
1716 			spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1717 
1718 			if (ieee->ps_is_queue_empty(ieee->dev)) {
1719 				ieee->sta_sleep = 2;
1720 
1721 				ieee->ps_request_tx_ack(ieee->dev);
1722 
1723 				ieee80211_sta_ps_send_null_frame(ieee, 1);
1724 
1725 				ieee->ps_th = th;
1726 				ieee->ps_tl = tl;
1727 			}
1728 			spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1729 		}
1730 	} else if (sleep == 2) {
1731 //#warning CHECK_LOCK_HERE
1732 		spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1733 
1734 		ieee80211_sta_wakeup(ieee, 1);
1735 
1736 		spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1737 	}
1738 out:
1739 	spin_unlock_irqrestore(&ieee->lock, flags);
1740 }
1741 
ieee80211_sta_wakeup(struct ieee80211_device * ieee,short nl)1742 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
1743 {
1744 	if (ieee->sta_sleep == 0) {
1745 		if (nl) {
1746 			printk("Warning: driver is probably failing to report TX ps error\n");
1747 			ieee->ps_request_tx_ack(ieee->dev);
1748 			ieee80211_sta_ps_send_null_frame(ieee, 0);
1749 		}
1750 		return;
1751 	}
1752 
1753 	if (ieee->sta_sleep == 1)
1754 		ieee->sta_wake_up(ieee->dev);
1755 
1756 	ieee->sta_sleep = 0;
1757 
1758 	if (nl) {
1759 		ieee->ps_request_tx_ack(ieee->dev);
1760 		ieee80211_sta_ps_send_null_frame(ieee, 0);
1761 	}
1762 }
1763 
ieee80211_ps_tx_ack(struct ieee80211_device * ieee,short success)1764 void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
1765 {
1766 	unsigned long flags, flags2;
1767 
1768 	spin_lock_irqsave(&ieee->lock, flags);
1769 
1770 	if (ieee->sta_sleep == 2) {
1771 		/* Null frame with PS bit set */
1772 		if (success) {
1773 			ieee->sta_sleep = 1;
1774 			ieee->enter_sleep_state(ieee->dev, ieee->ps_th, ieee->ps_tl);
1775 		}
1776 		/* if the card report not success we can't be sure the AP
1777 		 * has not RXed so we can't assume the AP believe us awake
1778 		 */
1779 	} else {
1780 		/* 21112005 - tx again null without PS bit if lost */
1781 		if ((ieee->sta_sleep == 0) && !success) {
1782 			spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1783 			ieee80211_sta_ps_send_null_frame(ieee, 0);
1784 			spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1785 		}
1786 	}
1787 	spin_unlock_irqrestore(&ieee->lock, flags);
1788 }
1789 EXPORT_SYMBOL(ieee80211_ps_tx_ack);
1790 
ieee80211_process_action(struct ieee80211_device * ieee,struct sk_buff * skb)1791 static void ieee80211_process_action(struct ieee80211_device *ieee,
1792 				     struct sk_buff *skb)
1793 {
1794 	struct rtl_80211_hdr *header = (struct rtl_80211_hdr *)skb->data;
1795 	u8 *act = ieee80211_get_payload(header);
1796 	u8 tmp = 0;
1797 //	IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
1798 	if (!act) {
1799 		IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
1800 		return;
1801 	}
1802 	tmp = *act;
1803 	act++;
1804 	switch (tmp) {
1805 	case ACT_CAT_BA:
1806 		if (*act == ACT_ADDBAREQ)
1807 			ieee80211_rx_ADDBAReq(ieee, skb);
1808 		else if (*act == ACT_ADDBARSP)
1809 			ieee80211_rx_ADDBARsp(ieee, skb);
1810 		else if (*act == ACT_DELBA)
1811 			ieee80211_rx_DELBA(ieee, skb);
1812 		break;
1813 	default:
1814 		break;
1815 	}
1816 	return;
1817 }
1818 
ieee80211_check_auth_response(struct ieee80211_device * ieee,struct sk_buff * skb)1819 static void ieee80211_check_auth_response(struct ieee80211_device *ieee,
1820 					  struct sk_buff *skb)
1821 {
1822 	/* default support N mode, disable halfNmode */
1823 	bool bSupportNmode = true, bHalfSupportNmode = false;
1824 	u16 errcode;
1825 	u8 *challenge;
1826 	int chlen = 0;
1827 	u32 iotAction;
1828 
1829 	errcode = auth_parse(skb, &challenge, &chlen);
1830 	if (!errcode) {
1831 		if (ieee->open_wep || !challenge) {
1832 			ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
1833 			ieee->softmac_stats.rx_auth_rs_ok++;
1834 			iotAction = ieee->pHTInfo->IOTAction;
1835 			if (!(iotAction & HT_IOT_ACT_PURE_N_MODE)) {
1836 				if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) {
1837 					/* WEP or TKIP encryption */
1838 					if (IsHTHalfNmodeAPs(ieee)) {
1839 						bSupportNmode = true;
1840 						bHalfSupportNmode = true;
1841 					} else {
1842 						bSupportNmode = false;
1843 						bHalfSupportNmode = false;
1844 					}
1845 					netdev_dbg(ieee->dev, "SEC(%d, %d)\n",
1846 							bSupportNmode,
1847 							bHalfSupportNmode);
1848 				}
1849 			}
1850 			/* Dummy wirless mode setting- avoid encryption issue */
1851 			if (bSupportNmode) {
1852 				/* N mode setting */
1853 				ieee->SetWirelessMode(ieee->dev,
1854 						ieee->current_network.mode);
1855 			} else {
1856 				/* b/g mode setting - TODO */
1857 				ieee->SetWirelessMode(ieee->dev, IEEE_G);
1858 			}
1859 
1860 			if (ieee->current_network.mode == IEEE_N_24G &&
1861 					bHalfSupportNmode) {
1862 				netdev_dbg(ieee->dev, "enter half N mode\n");
1863 				ieee->bHalfWirelessN24GMode = true;
1864 			} else {
1865 				ieee->bHalfWirelessN24GMode = false;
1866 			}
1867 			ieee80211_associate_step2(ieee);
1868 		} else {
1869 			ieee80211_auth_challenge(ieee, challenge, chlen);
1870 		}
1871 	} else {
1872 		ieee->softmac_stats.rx_auth_rs_err++;
1873 		IEEE80211_DEBUG_MGMT("Auth response status code 0x%x", errcode);
1874 		ieee80211_associate_abort(ieee);
1875 	}
1876 }
1877 
1878 inline int
ieee80211_rx_frame_softmac(struct ieee80211_device * ieee,struct sk_buff * skb,struct ieee80211_rx_stats * rx_stats,u16 type,u16 stype)1879 ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
1880 			   struct ieee80211_rx_stats *rx_stats, u16 type,
1881 			   u16 stype)
1882 {
1883 	struct rtl_80211_hdr_3addr *header = (struct rtl_80211_hdr_3addr *)skb->data;
1884 	u16 errcode;
1885 	int aid;
1886 	struct ieee80211_assoc_response_frame *assoc_resp;
1887 //	struct ieee80211_info_element *info_element;
1888 
1889 	if (!ieee->proto_started)
1890 		return 0;
1891 
1892 	if (ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
1893 				ieee->iw_mode == IW_MODE_INFRA &&
1894 				ieee->state == IEEE80211_LINKED))
1895 		tasklet_schedule(&ieee->ps_task);
1896 
1897 	if (WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
1898 	    WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
1899 		ieee->last_rx_ps_time = jiffies;
1900 
1901 	switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
1902 	case IEEE80211_STYPE_ASSOC_RESP:
1903 	case IEEE80211_STYPE_REASSOC_RESP:
1904 		IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
1905 				WLAN_FC_GET_STYPE(header->frame_ctl));
1906 		if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
1907 		    ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
1908 		    ieee->iw_mode == IW_MODE_INFRA) {
1909 			struct ieee80211_network network_resp;
1910 			struct ieee80211_network *network = &network_resp;
1911 
1912 			errcode = assoc_parse(ieee, skb, &aid);
1913 			if (!errcode) {
1914 				ieee->state = IEEE80211_LINKED;
1915 				ieee->assoc_id = aid;
1916 				ieee->softmac_stats.rx_ass_ok++;
1917 				/* station support qos */
1918 				/* Let the register setting defaultly with Legacy station */
1919 				if (ieee->qos_support) {
1920 					assoc_resp = (struct ieee80211_assoc_response_frame *)skb->data;
1921 					memset(network, 0, sizeof(*network));
1922 					if (ieee80211_parse_info_param(ieee, assoc_resp->info_element,\
1923 								       rx_stats->len - sizeof(*assoc_resp), \
1924 								       network, rx_stats)) {
1925 						return 1;
1926 					} else {
1927 						//filling the PeerHTCap. //maybe not necessary as we can get its info from current_network.
1928 						memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
1929 						memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
1930 					}
1931 					if (ieee->handle_assoc_response)
1932 						ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame *)header, network);
1933 				}
1934 				ieee80211_associate_complete(ieee);
1935 			} else {
1936 				/* aid could not been allocated */
1937 				ieee->softmac_stats.rx_ass_err++;
1938 				printk("Association response status code 0x%x\n",
1939 				       errcode);
1940 				IEEE80211_DEBUG_MGMT("Association response status code 0x%x\n",
1941 						     errcode);
1942 				if (ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT)
1943 					schedule_work(&ieee->associate_procedure_wq);
1944 				else
1945 					ieee80211_associate_abort(ieee);
1946 			}
1947 		}
1948 		break;
1949 
1950 	case IEEE80211_STYPE_ASSOC_REQ:
1951 	case IEEE80211_STYPE_REASSOC_REQ:
1952 		if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
1953 		    ieee->iw_mode == IW_MODE_MASTER)
1954 			ieee80211_rx_assoc_rq(ieee, skb);
1955 		break;
1956 
1957 	case IEEE80211_STYPE_AUTH:
1958 		if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) {
1959 			if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING
1960 			    && ieee->iw_mode == IW_MODE_INFRA) {
1961 				IEEE80211_DEBUG_MGMT("Received auth response");
1962 				ieee80211_check_auth_response(ieee, skb);
1963 			} else if (ieee->iw_mode == IW_MODE_MASTER) {
1964 				ieee80211_rx_auth_rq(ieee, skb);
1965 			}
1966 		}
1967 		break;
1968 
1969 	case IEEE80211_STYPE_PROBE_REQ:
1970 		if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
1971 		    ((ieee->iw_mode == IW_MODE_ADHOC ||
1972 		      ieee->iw_mode == IW_MODE_MASTER) &&
1973 		     ieee->state == IEEE80211_LINKED)) {
1974 			ieee80211_rx_probe_rq(ieee, skb);
1975 		}
1976 		break;
1977 
1978 	case IEEE80211_STYPE_DISASSOC:
1979 	case IEEE80211_STYPE_DEAUTH:
1980 		/* FIXME for now repeat all the association procedure
1981 		* both for disassociation and deauthentication
1982 		*/
1983 		if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
1984 		    ieee->state == IEEE80211_LINKED &&
1985 		    ieee->iw_mode == IW_MODE_INFRA) {
1986 			ieee->state = IEEE80211_ASSOCIATING;
1987 			ieee->softmac_stats.reassoc++;
1988 
1989 			notify_wx_assoc_event(ieee);
1990 			//HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1991 			RemovePeerTS(ieee, header->addr2);
1992 			schedule_work(&ieee->associate_procedure_wq);
1993 		}
1994 		break;
1995 	case IEEE80211_STYPE_MANAGE_ACT:
1996 		ieee80211_process_action(ieee, skb);
1997 		break;
1998 	default:
1999 		return -1;
2000 	}
2001 
2002 	//dev_kfree_skb_any(skb);
2003 	return 0;
2004 }
2005 
2006 /* The following are for a simpler TX queue management.
2007  * Instead of using netif_[stop/wake]_queue, the driver
2008  * will use these two functions (plus a reset one) that
2009  * will internally call the kernel netif_* and take care
2010  * of the ieee802.11 fragmentation.
2011  * So, the driver receives a fragment at a time and might
2012  * call the stop function when it wants, without taking
2013  * care to have enough room to TX an entire packet.
2014  * This might be useful if each fragment needs its own
2015  * descriptor. Thus, just keeping a total free memory > than
2016  * the max fragmentation threshold is not enough. If the
2017  * ieee802.11 stack passed a TXB struct, then you would need
2018  * to keep N free descriptors where
2019  * N = MAX_PACKET_SIZE / MIN_FRAG_THRESHOLD.
2020  * In this way you need just one and the 802.11 stack
2021  * will take care of buffering fragments and pass them to
2022  * to the driver later, when it wakes the queue.
2023  */
ieee80211_softmac_xmit(struct ieee80211_txb * txb,struct ieee80211_device * ieee)2024 void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
2025 {
2026 	unsigned int queue_index = txb->queue_index;
2027 	unsigned long flags;
2028 	int  i;
2029 	struct cb_desc *tcb_desc = NULL;
2030 
2031 	spin_lock_irqsave(&ieee->lock, flags);
2032 
2033 	/* called with 2nd parm 0, no tx mgmt lock required */
2034 	ieee80211_sta_wakeup(ieee, 0);
2035 
2036 	/* update the tx status */
2037 	ieee->stats.tx_bytes += le16_to_cpu(txb->payload_size);
2038 	ieee->stats.tx_packets++;
2039 	tcb_desc = (struct cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
2040 	if (tcb_desc->bMulticast)
2041 		ieee->stats.multicast++;
2042 
2043 	/* if xmit available, just xmit it immediately, else just insert it to the wait queue */
2044 	for (i = 0; i < txb->nr_frags; i++) {
2045 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2046 		if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) ||
2047 #else
2048 		if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
2049 #endif
2050 		    (!ieee->check_nic_enough_desc(ieee->dev, queue_index)) || \
2051 		    (ieee->queue_stop)) {
2052 			/* insert the skb packet to the wait queue */
2053 			/* as for the completion function, it does not need
2054 			 * to check it any more.
2055 			 * */
2056 			//printk("error:no descriptor left@queue_index %d\n", queue_index);
2057 			//ieee80211_stop_queue(ieee);
2058 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2059 			skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]);
2060 #else
2061 			skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
2062 #endif
2063 		} else {
2064 			ieee->softmac_data_hard_start_xmit(txb->fragments[i],
2065 							   ieee->dev, ieee->rate);
2066 			//ieee->stats.tx_packets++;
2067 			//ieee->stats.tx_bytes += txb->fragments[i]->len;
2068 			//ieee->dev->trans_start = jiffies;
2069 		}
2070 	}
2071 	ieee80211_txb_free(txb);
2072 
2073 //exit:
2074 	spin_unlock_irqrestore(&ieee->lock, flags);
2075 }
2076 EXPORT_SYMBOL(ieee80211_softmac_xmit);
2077 
2078 /* called with ieee->lock acquired */
ieee80211_resume_tx(struct ieee80211_device * ieee)2079 static void ieee80211_resume_tx(struct ieee80211_device *ieee)
2080 {
2081 	int i;
2082 	for (i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
2083 		if (ieee->queue_stop) {
2084 			ieee->tx_pending.frag = i;
2085 			return;
2086 		} else {
2087 			ieee->softmac_data_hard_start_xmit(ieee->tx_pending.txb->fragments[i],
2088 							   ieee->dev, ieee->rate);
2089 			//(i+1)<ieee->tx_pending.txb->nr_frags);
2090 			ieee->stats.tx_packets++;
2091 			netif_trans_update(ieee->dev);
2092 		}
2093 	}
2094 
2095 	ieee80211_txb_free(ieee->tx_pending.txb);
2096 	ieee->tx_pending.txb = NULL;
2097 }
2098 
ieee80211_reset_queue(struct ieee80211_device * ieee)2099 void ieee80211_reset_queue(struct ieee80211_device *ieee)
2100 {
2101 	unsigned long flags;
2102 
2103 	spin_lock_irqsave(&ieee->lock, flags);
2104 	init_mgmt_queue(ieee);
2105 	if (ieee->tx_pending.txb) {
2106 		ieee80211_txb_free(ieee->tx_pending.txb);
2107 		ieee->tx_pending.txb = NULL;
2108 	}
2109 	ieee->queue_stop = 0;
2110 	spin_unlock_irqrestore(&ieee->lock, flags);
2111 }
2112 EXPORT_SYMBOL(ieee80211_reset_queue);
2113 
ieee80211_wake_queue(struct ieee80211_device * ieee)2114 void ieee80211_wake_queue(struct ieee80211_device *ieee)
2115 {
2116 	unsigned long flags;
2117 	struct sk_buff *skb;
2118 	struct rtl_80211_hdr_3addr  *header;
2119 
2120 	spin_lock_irqsave(&ieee->lock, flags);
2121 	if (!ieee->queue_stop)
2122 		goto exit;
2123 
2124 	ieee->queue_stop = 0;
2125 
2126 	if (ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) {
2127 		while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))) {
2128 			header = (struct rtl_80211_hdr_3addr  *)skb->data;
2129 
2130 			header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2131 
2132 			if (ieee->seq_ctrl[0] == 0xFFF)
2133 				ieee->seq_ctrl[0] = 0;
2134 			else
2135 				ieee->seq_ctrl[0]++;
2136 
2137 			ieee->softmac_data_hard_start_xmit(skb, ieee->dev, ieee->basic_rate);
2138 			//dev_kfree_skb_any(skb);//edit by thomas
2139 		}
2140 	}
2141 	if (!ieee->queue_stop && ieee->tx_pending.txb)
2142 		ieee80211_resume_tx(ieee);
2143 
2144 	if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)) {
2145 		ieee->softmac_stats.swtxawake++;
2146 		netif_wake_queue(ieee->dev);
2147 	}
2148 exit:
2149 	spin_unlock_irqrestore(&ieee->lock, flags);
2150 }
2151 EXPORT_SYMBOL(ieee80211_wake_queue);
2152 
ieee80211_stop_queue(struct ieee80211_device * ieee)2153 void ieee80211_stop_queue(struct ieee80211_device *ieee)
2154 {
2155 	//unsigned long flags;
2156 	//spin_lock_irqsave(&ieee->lock,flags);
2157 
2158 	if (!netif_queue_stopped(ieee->dev)) {
2159 		netif_stop_queue(ieee->dev);
2160 		ieee->softmac_stats.swtxstop++;
2161 	}
2162 	ieee->queue_stop = 1;
2163 	//spin_unlock_irqrestore(&ieee->lock,flags);
2164 }
2165 EXPORT_SYMBOL(ieee80211_stop_queue);
2166 
2167 /* called in user context only */
ieee80211_start_master_bss(struct ieee80211_device * ieee)2168 void ieee80211_start_master_bss(struct ieee80211_device *ieee)
2169 {
2170 	ieee->assoc_id = 1;
2171 
2172 	if (ieee->current_network.ssid_len == 0) {
2173 		strncpy(ieee->current_network.ssid,
2174 			IEEE80211_DEFAULT_TX_ESSID,
2175 			IW_ESSID_MAX_SIZE);
2176 
2177 		ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2178 		ieee->ssid_set = 1;
2179 	}
2180 
2181 	memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
2182 
2183 	ieee->set_chan(ieee->dev, ieee->current_network.channel);
2184 	ieee->state = IEEE80211_LINKED;
2185 	ieee->link_change(ieee->dev);
2186 	notify_wx_assoc_event(ieee);
2187 
2188 	if (ieee->data_hard_resume)
2189 		ieee->data_hard_resume(ieee->dev);
2190 
2191 	netif_carrier_on(ieee->dev);
2192 }
2193 
ieee80211_start_monitor_mode(struct ieee80211_device * ieee)2194 static void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
2195 {
2196 	if (ieee->raw_tx) {
2197 		if (ieee->data_hard_resume)
2198 			ieee->data_hard_resume(ieee->dev);
2199 
2200 		netif_carrier_on(ieee->dev);
2201 	}
2202 }
ieee80211_start_ibss_wq(struct work_struct * work)2203 static void ieee80211_start_ibss_wq(struct work_struct *work)
2204 {
2205 	struct delayed_work *dwork = to_delayed_work(work);
2206 	struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
2207 	/* iwconfig mode ad-hoc will schedule this and return
2208 	 * on the other hand this will block further iwconfig SET
2209 	 * operations because of the wx_mutex hold.
2210 	 * Anyway some most set operations set a flag to speed-up
2211 	 * (abort) this wq (when syncro scanning) before sleeping
2212 	 * on the semaphore
2213 	 */
2214 	if (!ieee->proto_started) {
2215 		printk("==========oh driver down return\n");
2216 		return;
2217 	}
2218 	mutex_lock(&ieee->wx_mutex);
2219 
2220 	if (ieee->current_network.ssid_len == 0) {
2221 		strcpy(ieee->current_network.ssid, IEEE80211_DEFAULT_TX_ESSID);
2222 		ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2223 		ieee->ssid_set = 1;
2224 	}
2225 
2226 	/* check if we have this cell in our network list */
2227 	ieee80211_softmac_check_all_nets(ieee);
2228 
2229 //	if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK))
2230 	if (ieee->state == IEEE80211_NOLINK)
2231 		ieee->current_network.channel = 6;
2232 	/* if not then the state is not linked. Maybe the user switched to
2233 	 * ad-hoc mode just after being in monitor mode, or just after
2234 	 * being very few time in managed mode (so the card have had no
2235 	 * time to scan all the chans..) or we have just run up the iface
2236 	 * after setting ad-hoc mode. So we have to give another try..
2237 	 * Here, in ibss mode, should be safe to do this without extra care
2238 	 * (in bss mode we had to make sure no-one tryed to associate when
2239 	 * we had just checked the ieee->state and we was going to start the
2240 	 * scan) beacause in ibss mode the ieee80211_new_net function, when
2241 	 * finds a good net, just set the ieee->state to IEEE80211_LINKED,
2242 	 * so, at worst, we waste a bit of time to initiate an unneeded syncro
2243 	 * scan, that will stop at the first round because it sees the state
2244 	 * associated.
2245 	 */
2246 	if (ieee->state == IEEE80211_NOLINK)
2247 		ieee80211_start_scan_syncro(ieee);
2248 
2249 	/* the network definitively is not here.. create a new cell */
2250 	if (ieee->state == IEEE80211_NOLINK) {
2251 		printk("creating new IBSS cell\n");
2252 		if (!ieee->wap_set)
2253 			eth_random_addr(ieee->current_network.bssid);
2254 
2255 		if (ieee->modulation & IEEE80211_CCK_MODULATION) {
2256 			ieee->current_network.rates_len = 4;
2257 
2258 			ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
2259 			ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
2260 			ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
2261 			ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
2262 		} else {
2263 			ieee->current_network.rates_len = 0;
2264 		}
2265 		if (ieee->modulation & IEEE80211_OFDM_MODULATION) {
2266 			ieee->current_network.rates_ex_len = 8;
2267 
2268 			ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
2269 			ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
2270 			ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
2271 			ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
2272 			ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
2273 			ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
2274 			ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
2275 			ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
2276 
2277 			ieee->rate = 108;
2278 		} else {
2279 			ieee->current_network.rates_ex_len = 0;
2280 			ieee->rate = 22;
2281 		}
2282 
2283 		// By default, WMM function will be disabled in IBSS mode
2284 		ieee->current_network.QoS_Enable = 0;
2285 		ieee->SetWirelessMode(ieee->dev, IEEE_G);
2286 		ieee->current_network.atim_window = 0;
2287 		ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
2288 		if (ieee->short_slot)
2289 			ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
2290 	}
2291 
2292 	ieee->state = IEEE80211_LINKED;
2293 
2294 	ieee->set_chan(ieee->dev, ieee->current_network.channel);
2295 	ieee->link_change(ieee->dev);
2296 
2297 	notify_wx_assoc_event(ieee);
2298 
2299 	ieee80211_start_send_beacons(ieee);
2300 
2301 	if (ieee->data_hard_resume)
2302 		ieee->data_hard_resume(ieee->dev);
2303 	netif_carrier_on(ieee->dev);
2304 
2305 	mutex_unlock(&ieee->wx_mutex);
2306 }
2307 
ieee80211_start_ibss(struct ieee80211_device * ieee)2308 inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
2309 {
2310 	schedule_delayed_work(&ieee->start_ibss_wq, 150);
2311 }
2312 
2313 /* this is called only in user context, with wx_mutex held */
ieee80211_start_bss(struct ieee80211_device * ieee)2314 void ieee80211_start_bss(struct ieee80211_device *ieee)
2315 {
2316 	unsigned long flags;
2317 	//
2318 	// Ref: 802.11d 11.1.3.3
2319 	// STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
2320 	//
2321 	if (IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee)) {
2322 		if (!ieee->bGlobalDomain)
2323 			return;
2324 	}
2325 	/* check if we have already found the net we
2326 	 * are interested in (if any).
2327 	 * if not (we are disassociated and we are not
2328 	 * in associating / authenticating phase) start the background scanning.
2329 	 */
2330 	ieee80211_softmac_check_all_nets(ieee);
2331 
2332 	/* ensure no-one start an associating process (thus setting
2333 	 * the ieee->state to ieee80211_ASSOCIATING) while we
2334 	 * have just cheked it and we are going to enable scan.
2335 	 * The ieee80211_new_net function is always called with
2336 	 * lock held (from both ieee80211_softmac_check_all_nets and
2337 	 * the rx path), so we cannot be in the middle of such function
2338 	 */
2339 	spin_lock_irqsave(&ieee->lock, flags);
2340 
2341 	if (ieee->state == IEEE80211_NOLINK) {
2342 		ieee->actscanning = true;
2343 		ieee80211_start_scan(ieee);
2344 	}
2345 	spin_unlock_irqrestore(&ieee->lock, flags);
2346 }
2347 
2348 /* called only in userspace context */
ieee80211_disassociate(struct ieee80211_device * ieee)2349 void ieee80211_disassociate(struct ieee80211_device *ieee)
2350 {
2351 	netif_carrier_off(ieee->dev);
2352 	if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
2353 		ieee80211_reset_queue(ieee);
2354 
2355 	if (ieee->data_hard_stop)
2356 		ieee->data_hard_stop(ieee->dev);
2357 	if (IS_DOT11D_ENABLE(ieee))
2358 		dot11d_reset(ieee);
2359 	ieee->state = IEEE80211_NOLINK;
2360 	ieee->is_set_key = false;
2361 	ieee->link_change(ieee->dev);
2362 	//HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2363 	notify_wx_assoc_event(ieee);
2364 }
2365 EXPORT_SYMBOL(ieee80211_disassociate);
2366 
ieee80211_associate_retry_wq(struct work_struct * work)2367 static void ieee80211_associate_retry_wq(struct work_struct *work)
2368 {
2369 	struct delayed_work *dwork = to_delayed_work(work);
2370 	struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
2371 	unsigned long flags;
2372 
2373 	mutex_lock(&ieee->wx_mutex);
2374 	if (!ieee->proto_started)
2375 		goto exit;
2376 
2377 	if (ieee->state != IEEE80211_ASSOCIATING_RETRY)
2378 		goto exit;
2379 
2380 	/* until we do not set the state to IEEE80211_NOLINK
2381 	* there are no possibility to have someone else trying
2382 	* to start an association procedure (we get here with
2383 	* ieee->state = IEEE80211_ASSOCIATING).
2384 	* When we set the state to IEEE80211_NOLINK it is possible
2385 	* that the RX path run an attempt to associate, but
2386 	* both ieee80211_softmac_check_all_nets and the
2387 	* RX path works with ieee->lock held so there are no
2388 	* problems. If we are still disassociated then start a scan.
2389 	* the lock here is necessary to ensure no one try to start
2390 	* an association procedure when we have just checked the
2391 	* state and we are going to start the scan.
2392 	*/
2393 	ieee->state = IEEE80211_NOLINK;
2394 
2395 	ieee80211_softmac_check_all_nets(ieee);
2396 
2397 	spin_lock_irqsave(&ieee->lock, flags);
2398 
2399 	if (ieee->state == IEEE80211_NOLINK)
2400 		ieee80211_start_scan(ieee);
2401 
2402 	spin_unlock_irqrestore(&ieee->lock, flags);
2403 
2404 exit:
2405 	mutex_unlock(&ieee->wx_mutex);
2406 }
2407 
ieee80211_get_beacon_(struct ieee80211_device * ieee)2408 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
2409 {
2410 	u8 broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2411 
2412 	struct sk_buff *skb;
2413 	struct ieee80211_probe_response *b;
2414 
2415 	skb = ieee80211_probe_resp(ieee, broadcast_addr);
2416 
2417 	if (!skb)
2418 		return NULL;
2419 
2420 	b = (struct ieee80211_probe_response *)skb->data;
2421 	b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
2422 
2423 	return skb;
2424 }
2425 
ieee80211_get_beacon(struct ieee80211_device * ieee)2426 struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
2427 {
2428 	struct sk_buff *skb;
2429 	struct ieee80211_probe_response *b;
2430 
2431 	skb = ieee80211_get_beacon_(ieee);
2432 	if (!skb)
2433 		return NULL;
2434 
2435 	b = (struct ieee80211_probe_response *)skb->data;
2436 	b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2437 
2438 	if (ieee->seq_ctrl[0] == 0xFFF)
2439 		ieee->seq_ctrl[0] = 0;
2440 	else
2441 		ieee->seq_ctrl[0]++;
2442 
2443 	return skb;
2444 }
2445 EXPORT_SYMBOL(ieee80211_get_beacon);
2446 
ieee80211_softmac_stop_protocol(struct ieee80211_device * ieee)2447 void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
2448 {
2449 	ieee->sync_scan_hurryup = 1;
2450 	mutex_lock(&ieee->wx_mutex);
2451 	ieee80211_stop_protocol(ieee);
2452 	mutex_unlock(&ieee->wx_mutex);
2453 }
2454 EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
2455 
ieee80211_stop_protocol(struct ieee80211_device * ieee)2456 void ieee80211_stop_protocol(struct ieee80211_device *ieee)
2457 {
2458 	if (!ieee->proto_started)
2459 		return;
2460 
2461 	ieee->proto_started = 0;
2462 
2463 	ieee80211_stop_send_beacons(ieee);
2464 	del_timer_sync(&ieee->associate_timer);
2465 	cancel_delayed_work(&ieee->associate_retry_wq);
2466 	cancel_delayed_work(&ieee->start_ibss_wq);
2467 	ieee80211_stop_scan(ieee);
2468 
2469 	ieee80211_disassociate(ieee);
2470 	RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
2471 }
2472 
ieee80211_softmac_start_protocol(struct ieee80211_device * ieee)2473 void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
2474 {
2475 	ieee->sync_scan_hurryup = 0;
2476 	mutex_lock(&ieee->wx_mutex);
2477 	ieee80211_start_protocol(ieee);
2478 	mutex_unlock(&ieee->wx_mutex);
2479 }
2480 EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
2481 
ieee80211_start_protocol(struct ieee80211_device * ieee)2482 void ieee80211_start_protocol(struct ieee80211_device *ieee)
2483 {
2484 	short ch = 0;
2485 	int i = 0;
2486 
2487 	if (ieee->proto_started)
2488 		return;
2489 
2490 	ieee->proto_started = 1;
2491 
2492 	if (ieee->current_network.channel == 0) {
2493 		do {
2494 			ch++;
2495 			if (ch > MAX_CHANNEL_NUMBER)
2496 				return; /* no channel found */
2497 		} while (!GET_DOT11D_INFO(ieee)->channel_map[ch]);
2498 		ieee->current_network.channel = ch;
2499 	}
2500 
2501 	if (ieee->current_network.beacon_interval == 0)
2502 		ieee->current_network.beacon_interval = 100;
2503 //	printk("===>%s(), chan:%d\n", __func__, ieee->current_network.channel);
2504 //	ieee->set_chan(ieee->dev,ieee->current_network.channel);
2505 
2506 	for (i = 0; i < 17; i++) {
2507 		ieee->last_rxseq_num[i] = -1;
2508 		ieee->last_rxfrag_num[i] = -1;
2509 		ieee->last_packet_time[i] = 0;
2510 	}
2511 
2512 	ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
2513 
2514 	/* if the user set the MAC of the ad-hoc cell and then
2515 	 * switch to managed mode, shall we  make sure that association
2516 	 * attempts does not fail just because the user provide the essid
2517 	 * and the nic is still checking for the AP MAC ??
2518 	 */
2519 	if (ieee->iw_mode == IW_MODE_INFRA)
2520 		ieee80211_start_bss(ieee);
2521 
2522 	else if (ieee->iw_mode == IW_MODE_ADHOC)
2523 		ieee80211_start_ibss(ieee);
2524 
2525 	else if (ieee->iw_mode == IW_MODE_MASTER)
2526 		ieee80211_start_master_bss(ieee);
2527 
2528 	else if (ieee->iw_mode == IW_MODE_MONITOR)
2529 		ieee80211_start_monitor_mode(ieee);
2530 }
2531 
2532 #define DRV_NAME  "Ieee80211"
ieee80211_softmac_init(struct ieee80211_device * ieee)2533 void ieee80211_softmac_init(struct ieee80211_device *ieee)
2534 {
2535 	int i;
2536 	memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
2537 
2538 	ieee->state = IEEE80211_NOLINK;
2539 	ieee->sync_scan_hurryup = 0;
2540 	for (i = 0; i < 5; i++)
2541 		ieee->seq_ctrl[i] = 0;
2542 
2543 	ieee->dot11d_info = kzalloc(sizeof(struct rt_dot11d_info), GFP_KERNEL);
2544 	if (!ieee->dot11d_info)
2545 		IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
2546 	//added for  AP roaming
2547 	ieee->LinkDetectInfo.SlotNum = 2;
2548 	ieee->LinkDetectInfo.NumRecvBcnInPeriod = 0;
2549 	ieee->LinkDetectInfo.NumRecvDataInPeriod = 0;
2550 
2551 	ieee->assoc_id = 0;
2552 	ieee->queue_stop = 0;
2553 	ieee->scanning = 0;
2554 	ieee->softmac_features = 0; //so IEEE2100-like driver are happy
2555 	ieee->wap_set = 0;
2556 	ieee->ssid_set = 0;
2557 	ieee->proto_started = 0;
2558 	ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
2559 	ieee->rate = 22;
2560 	ieee->ps = IEEE80211_PS_DISABLED;
2561 	ieee->sta_sleep = 0;
2562 	ieee->Regdot11HTOperationalRateSet[0] = 0xff;//support MCS 0~7
2563 	ieee->Regdot11HTOperationalRateSet[1] = 0xff;//support MCS 8~15
2564 	ieee->Regdot11HTOperationalRateSet[4] = 0x01;
2565 	//added by amy
2566 	ieee->actscanning = false;
2567 	ieee->beinretry = false;
2568 	ieee->is_set_key = false;
2569 	init_mgmt_queue(ieee);
2570 
2571 	ieee->sta_edca_param[0] = 0x0000A403;
2572 	ieee->sta_edca_param[1] = 0x0000A427;
2573 	ieee->sta_edca_param[2] = 0x005E4342;
2574 	ieee->sta_edca_param[3] = 0x002F3262;
2575 	ieee->aggregation = true;
2576 	ieee->enable_rx_imm_BA = true;
2577 	ieee->tx_pending.txb = NULL;
2578 
2579 	timer_setup(&ieee->associate_timer, ieee80211_associate_abort_cb, 0);
2580 
2581 	timer_setup(&ieee->beacon_timer, ieee80211_send_beacon_cb, 0);
2582 
2583 	INIT_DELAYED_WORK(&ieee->start_ibss_wq, ieee80211_start_ibss_wq);
2584 	INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
2585 	INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
2586 	INIT_DELAYED_WORK(&ieee->softmac_scan_wq, ieee80211_softmac_scan_wq);
2587 	INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
2588 	INIT_WORK(&ieee->wx_sync_scan_wq, ieee80211_wx_sync_scan_wq);
2589 
2590 	mutex_init(&ieee->wx_mutex);
2591 	mutex_init(&ieee->scan_mutex);
2592 
2593 	spin_lock_init(&ieee->mgmt_tx_lock);
2594 	spin_lock_init(&ieee->beacon_lock);
2595 
2596 	tasklet_init(&ieee->ps_task,
2597 		     (void(*)(unsigned long)) ieee80211_sta_ps,
2598 		     (unsigned long)ieee);
2599 }
2600 
ieee80211_softmac_free(struct ieee80211_device * ieee)2601 void ieee80211_softmac_free(struct ieee80211_device *ieee)
2602 {
2603 	mutex_lock(&ieee->wx_mutex);
2604 	kfree(ieee->dot11d_info);
2605 	ieee->dot11d_info = NULL;
2606 	del_timer_sync(&ieee->associate_timer);
2607 
2608 	cancel_delayed_work(&ieee->associate_retry_wq);
2609 
2610 	mutex_unlock(&ieee->wx_mutex);
2611 }
2612 
2613 /********************************************************
2614  * Start of WPA code.                                   *
2615  * this is stolen from the ipw2200 driver               *
2616  ********************************************************/
ieee80211_wpa_enable(struct ieee80211_device * ieee,int value)2617 static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
2618 {
2619 	/* This is called when wpa_supplicant loads and closes the driver
2620 	 * interface. */
2621 	printk("%s WPA\n", value ? "enabling" : "disabling");
2622 	ieee->wpa_enabled = value;
2623 	return 0;
2624 }
2625 
ieee80211_wpa_assoc_frame(struct ieee80211_device * ieee,char * wpa_ie,int wpa_ie_len)2626 static void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee,
2627 				      char *wpa_ie, int wpa_ie_len)
2628 {
2629 	/* make sure WPA is enabled */
2630 	ieee80211_wpa_enable(ieee, 1);
2631 
2632 	ieee80211_disassociate(ieee);
2633 }
2634 
ieee80211_wpa_mlme(struct ieee80211_device * ieee,int command,int reason)2635 static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
2636 {
2637 	int ret = 0;
2638 
2639 	switch (command) {
2640 	case IEEE_MLME_STA_DEAUTH:
2641 		// silently ignore
2642 		break;
2643 
2644 	case IEEE_MLME_STA_DISASSOC:
2645 		ieee80211_disassociate(ieee);
2646 		break;
2647 
2648 	default:
2649 		printk("Unknown MLME request: %d\n", command);
2650 		ret = -EOPNOTSUPP;
2651 	}
2652 
2653 	return ret;
2654 }
2655 
ieee80211_wpa_set_wpa_ie(struct ieee80211_device * ieee,struct ieee_param * param,int plen)2656 static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
2657 			      struct ieee_param *param, int plen)
2658 {
2659 	u8 *buf;
2660 
2661 	if (param->u.wpa_ie.len > MAX_WPA_IE_LEN)
2662 		return -EINVAL;
2663 
2664 	if (param->u.wpa_ie.len) {
2665 		buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len,
2666 			      GFP_KERNEL);
2667 		if (!buf)
2668 			return -ENOMEM;
2669 
2670 		kfree(ieee->wpa_ie);
2671 		ieee->wpa_ie = buf;
2672 		ieee->wpa_ie_len = param->u.wpa_ie.len;
2673 	} else {
2674 		kfree(ieee->wpa_ie);
2675 		ieee->wpa_ie = NULL;
2676 		ieee->wpa_ie_len = 0;
2677 	}
2678 
2679 	ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
2680 	return 0;
2681 }
2682 
2683 #define AUTH_ALG_OPEN_SYSTEM			0x1
2684 #define AUTH_ALG_SHARED_KEY			0x2
2685 
ieee80211_wpa_set_auth_algs(struct ieee80211_device * ieee,int value)2686 static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
2687 {
2688 	struct ieee80211_security sec = {
2689 		.flags = SEC_AUTH_MODE,
2690 	};
2691 
2692 	if (value & AUTH_ALG_SHARED_KEY) {
2693 		sec.auth_mode = WLAN_AUTH_SHARED_KEY;
2694 		ieee->open_wep = 0;
2695 		ieee->auth_mode = 1;
2696 	} else if (value & AUTH_ALG_OPEN_SYSTEM) {
2697 		sec.auth_mode = WLAN_AUTH_OPEN;
2698 		ieee->open_wep = 1;
2699 		ieee->auth_mode = 0;
2700 	} else if (value & IW_AUTH_ALG_LEAP) {
2701 		sec.auth_mode = WLAN_AUTH_LEAP;
2702 		ieee->open_wep = 1;
2703 		ieee->auth_mode = 2;
2704 	}
2705 
2706 	if (ieee->set_security)
2707 		ieee->set_security(ieee->dev, &sec);
2708 	//else
2709 	//	ret = -EOPNOTSUPP;
2710 
2711 	return 0;
2712 }
2713 
ieee80211_wpa_set_param(struct ieee80211_device * ieee,u8 name,u32 value)2714 static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
2715 {
2716 	int ret = 0;
2717 	unsigned long flags;
2718 
2719 	switch (name) {
2720 	case IEEE_PARAM_WPA_ENABLED:
2721 		ret = ieee80211_wpa_enable(ieee, value);
2722 		break;
2723 
2724 	case IEEE_PARAM_TKIP_COUNTERMEASURES:
2725 		ieee->tkip_countermeasures = value;
2726 		break;
2727 
2728 	case IEEE_PARAM_DROP_UNENCRYPTED: {
2729 		/* HACK:
2730 		 *
2731 		 * wpa_supplicant calls set_wpa_enabled when the driver
2732 		 * is loaded and unloaded, regardless of if WPA is being
2733 		 * used.  No other calls are made which can be used to
2734 		 * determine if encryption will be used or not prior to
2735 		 * association being expected.  If encryption is not being
2736 		 * used, drop_unencrypted is set to false, else true -- we
2737 		 * can use this to determine if the CAP_PRIVACY_ON bit should
2738 		 * be set.
2739 		 */
2740 		struct ieee80211_security sec = {
2741 			.flags = SEC_ENABLED,
2742 			.enabled = value,
2743 		};
2744 		ieee->drop_unencrypted = value;
2745 		/* We only change SEC_LEVEL for open mode. Others
2746 		 * are set by ipw_wpa_set_encryption.
2747 		 */
2748 		if (!value) {
2749 			sec.flags |= SEC_LEVEL;
2750 			sec.level = SEC_LEVEL_0;
2751 		} else {
2752 			sec.flags |= SEC_LEVEL;
2753 			sec.level = SEC_LEVEL_1;
2754 		}
2755 		if (ieee->set_security)
2756 			ieee->set_security(ieee->dev, &sec);
2757 		break;
2758 	}
2759 
2760 	case IEEE_PARAM_PRIVACY_INVOKED:
2761 		ieee->privacy_invoked = value;
2762 		break;
2763 
2764 	case IEEE_PARAM_AUTH_ALGS:
2765 		ret = ieee80211_wpa_set_auth_algs(ieee, value);
2766 		break;
2767 
2768 	case IEEE_PARAM_IEEE_802_1X:
2769 		ieee->ieee802_1x = value;
2770 		break;
2771 	case IEEE_PARAM_WPAX_SELECT:
2772 		// added for WPA2 mixed mode
2773 		spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags);
2774 		ieee->wpax_type_set = 1;
2775 		ieee->wpax_type_notify = value;
2776 		spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags);
2777 		break;
2778 
2779 	default:
2780 		printk("Unknown WPA param: %d\n", name);
2781 		ret = -EOPNOTSUPP;
2782 	}
2783 
2784 	return ret;
2785 }
2786 
2787 /* implementation borrowed from hostap driver */
ieee80211_wpa_set_encryption(struct ieee80211_device * ieee,struct ieee_param * param,int param_len)2788 static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
2789 				  struct ieee_param *param, int param_len)
2790 {
2791 	int ret = 0;
2792 	const char *module = NULL;
2793 
2794 	struct ieee80211_crypto_ops *ops = NULL;
2795 	struct ieee80211_crypt_data **crypt;
2796 
2797 	struct ieee80211_security sec = {
2798 		.flags = 0,
2799 	};
2800 
2801 	param->u.crypt.err = 0;
2802 	param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
2803 
2804 	if (param_len !=
2805 	    (int)((char *)param->u.crypt.key - (char *)param) +
2806 	    param->u.crypt.key_len) {
2807 		printk("Len mismatch %d, %d\n", param_len,
2808 			       param->u.crypt.key_len);
2809 		return -EINVAL;
2810 	}
2811 	if (is_broadcast_ether_addr(param->sta_addr)) {
2812 		if (param->u.crypt.idx >= WEP_KEYS)
2813 			return -EINVAL;
2814 		crypt = &ieee->crypt[param->u.crypt.idx];
2815 	} else {
2816 		return -EINVAL;
2817 	}
2818 
2819 	if (strcmp(param->u.crypt.alg, "none") == 0) {
2820 		if (crypt) {
2821 			sec.enabled = 0;
2822 			// FIXME FIXME
2823 			//sec.encrypt = 0;
2824 			sec.level = SEC_LEVEL_0;
2825 			sec.flags |= SEC_ENABLED | SEC_LEVEL;
2826 			ieee80211_crypt_delayed_deinit(ieee, crypt);
2827 		}
2828 		goto done;
2829 	}
2830 	sec.enabled = 1;
2831 // FIXME FIXME
2832 //	sec.encrypt = 1;
2833 	sec.flags |= SEC_ENABLED;
2834 
2835 	/* IPW HW cannot build TKIP MIC, host decryption still needed. */
2836 	if (!(ieee->host_encrypt || ieee->host_decrypt) &&
2837 	    strcmp(param->u.crypt.alg, "TKIP"))
2838 		goto skip_host_crypt;
2839 
2840 	//set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
2841 	if (!strcmp(param->u.crypt.alg, "WEP"))
2842 		module = "ieee80211_crypt_wep";
2843 	else if (!strcmp(param->u.crypt.alg, "TKIP"))
2844 		module = "ieee80211_crypt_tkip";
2845 	else if (!strcmp(param->u.crypt.alg, "CCMP"))
2846 		module = "ieee80211_crypt_ccmp";
2847 	if (module)
2848 		ops = try_then_request_module(ieee80211_get_crypto_ops(param->u.crypt.alg),
2849 					      module);
2850 	if (!ops) {
2851 		printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
2852 		param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
2853 		ret = -EINVAL;
2854 		goto done;
2855 	}
2856 
2857 	if (!*crypt || (*crypt)->ops != ops) {
2858 		struct ieee80211_crypt_data *new_crypt;
2859 
2860 		ieee80211_crypt_delayed_deinit(ieee, crypt);
2861 
2862 		new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
2863 		if (!new_crypt) {
2864 			ret = -ENOMEM;
2865 			goto done;
2866 		}
2867 		new_crypt->ops = ops;
2868 		if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
2869 			new_crypt->priv =
2870 				new_crypt->ops->init(param->u.crypt.idx);
2871 
2872 		if (!new_crypt->priv) {
2873 			kfree(new_crypt);
2874 			param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
2875 			ret = -EINVAL;
2876 			goto done;
2877 		}
2878 
2879 		*crypt = new_crypt;
2880 	}
2881 
2882 	if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
2883 	    (*crypt)->ops->set_key(param->u.crypt.key,
2884 				   param->u.crypt.key_len, param->u.crypt.seq,
2885 				   (*crypt)->priv) < 0) {
2886 		printk("key setting failed\n");
2887 		param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
2888 		ret = -EINVAL;
2889 		goto done;
2890 	}
2891 
2892  skip_host_crypt:
2893 	if (param->u.crypt.set_tx) {
2894 		ieee->tx_keyidx = param->u.crypt.idx;
2895 		sec.active_key = param->u.crypt.idx;
2896 		sec.flags |= SEC_ACTIVE_KEY;
2897 	} else {
2898 		sec.flags &= ~SEC_ACTIVE_KEY;
2899 	}
2900 	memcpy(sec.keys[param->u.crypt.idx],
2901 	       param->u.crypt.key,
2902 	       param->u.crypt.key_len);
2903 	sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
2904 	sec.flags |= (1 << param->u.crypt.idx);
2905 
2906 	if (strcmp(param->u.crypt.alg, "WEP") == 0) {
2907 		sec.flags |= SEC_LEVEL;
2908 		sec.level = SEC_LEVEL_1;
2909 	} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
2910 		sec.flags |= SEC_LEVEL;
2911 		sec.level = SEC_LEVEL_2;
2912 	} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
2913 		sec.flags |= SEC_LEVEL;
2914 		sec.level = SEC_LEVEL_3;
2915 	}
2916  done:
2917 	if (ieee->set_security)
2918 		ieee->set_security(ieee->dev, &sec);
2919 
2920 	/* Do not reset port if card is in Managed mode since resetting will
2921 	 * generate new IEEE 802.11 authentication which may end up in looping
2922 	 * with IEEE 802.1X.  If your hardware requires a reset after WEP
2923 	 * configuration (for example... Prism2), implement the reset_port in
2924 	 * the callbacks structures used to initialize the 802.11 stack. */
2925 	if (ieee->reset_on_keychange &&
2926 	    ieee->iw_mode != IW_MODE_INFRA &&
2927 	    ieee->reset_port &&
2928 	    ieee->reset_port(ieee->dev)) {
2929 		printk("reset_port failed\n");
2930 		param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
2931 		return -EINVAL;
2932 	}
2933 
2934 	return ret;
2935 }
2936 
ieee80211_disassociate_skb(struct ieee80211_network * beacon,struct ieee80211_device * ieee,u8 asRsn)2937 static inline struct sk_buff *ieee80211_disassociate_skb(struct ieee80211_network *beacon,
2938 							 struct ieee80211_device *ieee,
2939 							 u8	asRsn)
2940 {
2941 	struct sk_buff *skb;
2942 	struct ieee80211_disassoc *disass;
2943 
2944 	skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc));
2945 	if (!skb)
2946 		return NULL;
2947 
2948 	disass = skb_put(skb, sizeof(struct ieee80211_disassoc));
2949 	disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
2950 	disass->header.duration_id = 0;
2951 
2952 	memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
2953 	memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
2954 	memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
2955 
2956 	disass->reason = cpu_to_le16(asRsn);
2957 	return skb;
2958 }
2959 
2960 void
SendDisassociation(struct ieee80211_device * ieee,u8 * asSta,u8 asRsn)2961 SendDisassociation(struct ieee80211_device *ieee,
2962 		   u8			   *asSta,
2963 		   u8			    asRsn
2964 )
2965 {
2966 	struct ieee80211_network *beacon = &ieee->current_network;
2967 	struct sk_buff *skb;
2968 
2969 	skb = ieee80211_disassociate_skb(beacon, ieee, asRsn);
2970 	if (skb) {
2971 		softmac_mgmt_xmit(skb, ieee);
2972 		//dev_kfree_skb_any(skb);//edit by thomas
2973 	}
2974 }
2975 EXPORT_SYMBOL(SendDisassociation);
2976 
ieee80211_wpa_supplicant_ioctl(struct ieee80211_device * ieee,struct iw_point * p)2977 int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
2978 {
2979 	struct ieee_param *param;
2980 	int ret = 0;
2981 
2982 	mutex_lock(&ieee->wx_mutex);
2983 	//IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
2984 
2985 	if (p->length < sizeof(struct ieee_param) || !p->pointer) {
2986 		ret = -EINVAL;
2987 		goto out;
2988 	}
2989 
2990 	param = memdup_user(p->pointer, p->length);
2991 	if (IS_ERR(param)) {
2992 		ret = PTR_ERR(param);
2993 		goto out;
2994 	}
2995 
2996 	switch (param->cmd) {
2997 	case IEEE_CMD_SET_WPA_PARAM:
2998 		ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
2999 					param->u.wpa_param.value);
3000 		break;
3001 
3002 	case IEEE_CMD_SET_WPA_IE:
3003 		ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
3004 		break;
3005 
3006 	case IEEE_CMD_SET_ENCRYPTION:
3007 		ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
3008 		break;
3009 
3010 	case IEEE_CMD_MLME:
3011 		ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
3012 				   param->u.mlme.reason_code);
3013 		break;
3014 
3015 	default:
3016 		printk("Unknown WPA supplicant request: %d\n", param->cmd);
3017 		ret = -EOPNOTSUPP;
3018 		break;
3019 	}
3020 
3021 	if (ret == 0 && copy_to_user(p->pointer, param, p->length))
3022 		ret = -EFAULT;
3023 
3024 	kfree(param);
3025 out:
3026 	mutex_unlock(&ieee->wx_mutex);
3027 
3028 	return ret;
3029 }
3030 EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
3031 
notify_wx_assoc_event(struct ieee80211_device * ieee)3032 void notify_wx_assoc_event(struct ieee80211_device *ieee)
3033 {
3034 	union iwreq_data wrqu;
3035 
3036 	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3037 	if (ieee->state == IEEE80211_LINKED)
3038 		memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
3039 	else
3040 		eth_zero_addr(wrqu.ap_addr.sa_data);
3041 	wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
3042 }
3043 EXPORT_SYMBOL(notify_wx_assoc_event);
3044