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