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