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