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