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