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