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