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