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