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 pleacing the RATE MFIE
37 * tag and the EXTENDED RATE MFIE tag if needed.
38 * It encludes 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 /* pleace the MFIE rate, tag to the memory (double) poined.
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 printk(KERN_ALERT "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 temporarly '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 del_timer_sync(&ieee->beacon_timer);
532
533 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
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 to have the RX path possibily
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 printk(KERN_INFO "Associated successfully\n");
1274 if (ieee80211_is_54g(&ieee->current_network) &&
1275 (ieee->modulation & IEEE80211_OFDM_MODULATION)) {
1276 ieee->rate = 108;
1277 printk(KERN_INFO"Using G rates:%d\n", ieee->rate);
1278 } else {
1279 ieee->rate = 22;
1280 printk(KERN_INFO"Using B rates:%d\n", ieee->rate);
1281 }
1282 if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) {
1283 printk("Successfully associated, ht enabled\n");
1284 HTOnAssocRsp(ieee);
1285 } else {
1286 printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT);
1287 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1288 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1289 }
1290 ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval / 500);
1291 // To prevent the immediately calling watch_dog after association.
1292 if (ieee->LinkDetectInfo.NumRecvBcnInPeriod == 0 || ieee->LinkDetectInfo.NumRecvDataInPeriod == 0) {
1293 ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1;
1294 ieee->LinkDetectInfo.NumRecvDataInPeriod = 1;
1295 }
1296 ieee->link_change(ieee->dev);
1297 if (!ieee->is_silent_reset) {
1298 printk("============>normal associate\n");
1299 notify_wx_assoc_event(ieee);
1300 } else {
1301 printk("==================>silent reset associate\n");
1302 ieee->is_silent_reset = false;
1303 }
1304
1305 if (ieee->data_hard_resume)
1306 ieee->data_hard_resume(ieee->dev);
1307 netif_carrier_on(ieee->dev);
1308 }
1309
ieee80211_associate_complete(struct ieee80211_device * ieee)1310 static void ieee80211_associate_complete(struct ieee80211_device *ieee)
1311 {
1312 // int i;
1313 // struct net_device* dev = ieee->dev;
1314 del_timer_sync(&ieee->associate_timer);
1315
1316 ieee->state = IEEE80211_LINKED;
1317 //ieee->UpdateHalRATRTableHandler(dev, ieee->dot11HTOperationalRateSet);
1318 schedule_work(&ieee->associate_complete_wq);
1319 }
1320
ieee80211_associate_procedure_wq(struct work_struct * work)1321 static void ieee80211_associate_procedure_wq(struct work_struct *work)
1322 {
1323 struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
1324 ieee->sync_scan_hurryup = 1;
1325 mutex_lock(&ieee->wx_mutex);
1326
1327 if (ieee->data_hard_stop)
1328 ieee->data_hard_stop(ieee->dev);
1329
1330 ieee80211_stop_scan(ieee);
1331 printk("===>%s(), chan:%d\n", __func__, ieee->current_network.channel);
1332 //ieee->set_chan(ieee->dev, ieee->current_network.channel);
1333 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1334
1335 ieee->associate_seq = 1;
1336 ieee80211_associate_step1(ieee);
1337
1338 mutex_unlock(&ieee->wx_mutex);
1339 }
1340
ieee80211_softmac_new_net(struct ieee80211_device * ieee,struct ieee80211_network * net)1341 inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
1342 {
1343 u8 tmp_ssid[IW_ESSID_MAX_SIZE + 1];
1344 int tmp_ssid_len = 0;
1345
1346 short apset, ssidset, ssidbroad, apmatch, ssidmatch;
1347
1348 /* we are interested in new new only if we are not associated
1349 * and we are not associating / authenticating
1350 */
1351 if (ieee->state != IEEE80211_NOLINK)
1352 return;
1353
1354 if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
1355 return;
1356
1357 if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
1358 return;
1359
1360 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) {
1361 /* if the user specified the AP MAC, we need also the essid
1362 * This could be obtained by beacons or, if the network does not
1363 * broadcast it, it can be put manually.
1364 */
1365 apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
1366 ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
1367 ssidbroad = !(net->ssid_len == 0 || net->ssid[0] == '\0');
1368 apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN) == 0);
1369 ssidmatch = (ieee->current_network.ssid_len == net->ssid_len) &&
1370 (!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
1371
1372 /* if the user set the AP check if match.
1373 * if the network does not broadcast essid we check the user supplyed ANY essid
1374 * if the network does broadcast and the user does not set essid it is OK
1375 * if the network does broadcast and the user did set essid chech if essid match
1376 */
1377 if ((apset && apmatch &&
1378 ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset))) ||
1379 /* if the ap is not set, check that the user set the bssid
1380 * and the network does broadcast and that those two bssid matches
1381 */
1382 (!apset && ssidset && ssidbroad && ssidmatch)) {
1383 /* if the essid is hidden replace it with the
1384 * essid provided by the user.
1385 */
1386 if (!ssidbroad) {
1387 strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
1388 tmp_ssid_len = ieee->current_network.ssid_len;
1389 }
1390 memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
1391
1392 strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
1393 ieee->current_network.ssid_len = tmp_ssid_len;
1394 printk(KERN_INFO"Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d\n",
1395 ieee->current_network.ssid,
1396 ieee->current_network.channel,
1397 ieee->current_network.qos_data.supported,
1398 ieee->pHTInfo->bEnableHT,
1399 ieee->current_network.bssht.bdSupportHT);
1400
1401 //ieee->pHTInfo->IOTAction = 0;
1402 HTResetIOTSetting(ieee->pHTInfo);
1403 if (ieee->iw_mode == IW_MODE_INFRA) {
1404 /* Join the network for the first time */
1405 ieee->AsocRetryCount = 0;
1406 //for HT by amy 080514
1407 if ((ieee->current_network.qos_data.supported == 1) &&
1408 // (ieee->pHTInfo->bEnableHT && ieee->current_network.bssht.bdSupportHT))
1409 ieee->current_network.bssht.bdSupportHT) {
1410 /*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.*/
1411 // ieee->pHTInfo->bCurrentHTSupport = true;
1412 HTResetSelfAndSavePeerSetting(ieee, &ieee->current_network);
1413 } else {
1414 ieee->pHTInfo->bCurrentHTSupport = false;
1415 }
1416
1417 ieee->state = IEEE80211_ASSOCIATING;
1418 schedule_work(&ieee->associate_procedure_wq);
1419 } else {
1420 if (ieee80211_is_54g(&ieee->current_network) &&
1421 (ieee->modulation & IEEE80211_OFDM_MODULATION)) {
1422 ieee->rate = 108;
1423 ieee->SetWirelessMode(ieee->dev, IEEE_G);
1424 printk(KERN_INFO"Using G rates\n");
1425 } else {
1426 ieee->rate = 22;
1427 ieee->SetWirelessMode(ieee->dev, IEEE_B);
1428 printk(KERN_INFO"Using B rates\n");
1429 }
1430 memset(ieee->dot11HTOperationalRateSet, 0, 16);
1431 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1432 ieee->state = IEEE80211_LINKED;
1433 }
1434 }
1435 }
1436 }
1437
ieee80211_softmac_check_all_nets(struct ieee80211_device * ieee)1438 void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
1439 {
1440 unsigned long flags;
1441 struct ieee80211_network *target;
1442
1443 spin_lock_irqsave(&ieee->lock, flags);
1444
1445 list_for_each_entry(target, &ieee->network_list, list) {
1446 /* if the state become different that NOLINK means
1447 * we had found what we are searching for
1448 */
1449
1450 if (ieee->state != IEEE80211_NOLINK)
1451 break;
1452
1453 if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
1454 ieee80211_softmac_new_net(ieee, target);
1455 }
1456
1457 spin_unlock_irqrestore(&ieee->lock, flags);
1458 }
1459
auth_parse(struct sk_buff * skb,u8 ** challenge,int * chlen)1460 static inline u16 auth_parse(struct sk_buff *skb, u8 **challenge, int *chlen)
1461 {
1462 struct ieee80211_authentication *a;
1463 u8 *t;
1464 if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
1465 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
1466 return 0xcafe;
1467 }
1468 *challenge = NULL;
1469 a = (struct ieee80211_authentication *)skb->data;
1470 if (skb->len > (sizeof(struct ieee80211_authentication) + 3)) {
1471 t = skb->data + sizeof(struct ieee80211_authentication);
1472
1473 if (*(t++) == MFIE_TYPE_CHALLENGE) {
1474 *chlen = *(t++);
1475 *challenge = kmemdup(t, *chlen, GFP_ATOMIC);
1476 if (!*challenge)
1477 return -ENOMEM;
1478 }
1479 }
1480
1481 return le16_to_cpu(a->status);
1482 }
1483
auth_rq_parse(struct sk_buff * skb,u8 * dest)1484 static int auth_rq_parse(struct sk_buff *skb, u8 *dest)
1485 {
1486 struct ieee80211_authentication *a;
1487
1488 if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
1489 IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n", skb->len);
1490 return -1;
1491 }
1492 a = (struct ieee80211_authentication *)skb->data;
1493
1494 memcpy(dest, a->header.addr2, ETH_ALEN);
1495
1496 if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
1497 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1498
1499 return WLAN_STATUS_SUCCESS;
1500 }
1501
probe_rq_parse(struct ieee80211_device * ieee,struct sk_buff * skb,u8 * src)1502 static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
1503 {
1504 u8 *tag;
1505 u8 *skbend;
1506 u8 *ssid = NULL;
1507 u8 ssidlen = 0;
1508
1509 struct rtl_80211_hdr_3addr *header =
1510 (struct rtl_80211_hdr_3addr *)skb->data;
1511
1512 if (skb->len < sizeof(struct rtl_80211_hdr_3addr))
1513 return -1; /* corrupted */
1514
1515 memcpy(src, header->addr2, ETH_ALEN);
1516
1517 skbend = (u8 *)skb->data + skb->len;
1518
1519 tag = skb->data + sizeof(struct rtl_80211_hdr_3addr);
1520
1521 while (tag + 1 < skbend) {
1522 if (*tag == 0) {
1523 ssid = tag + 2;
1524 ssidlen = *(tag + 1);
1525 break;
1526 }
1527 tag++; /* point to the len field */
1528 tag = tag + *(tag); /* point to the last data byte of the tag */
1529 tag++; /* point to the next tag */
1530 }
1531
1532 //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
1533 if (ssidlen == 0)
1534 return 1;
1535
1536 if (!ssid)
1537 return 1; /* ssid not found in tagged param */
1538
1539 return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
1540 }
1541
assoc_rq_parse(struct sk_buff * skb,u8 * dest)1542 static int assoc_rq_parse(struct sk_buff *skb, u8 *dest)
1543 {
1544 struct ieee80211_assoc_request_frame *a;
1545
1546 if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
1547 sizeof(struct ieee80211_info_element))) {
1548 IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
1549 return -1;
1550 }
1551
1552 a = (struct ieee80211_assoc_request_frame *)skb->data;
1553
1554 memcpy(dest, a->header.addr2, ETH_ALEN);
1555
1556 return 0;
1557 }
1558
assoc_parse(struct ieee80211_device * ieee,struct sk_buff * skb,int * aid)1559 static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid)
1560 {
1561 struct ieee80211_assoc_response_frame *response_head;
1562 u16 status_code;
1563
1564 if (skb->len < sizeof(struct ieee80211_assoc_response_frame)) {
1565 IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
1566 return 0xcafe;
1567 }
1568
1569 response_head = (struct ieee80211_assoc_response_frame *)skb->data;
1570 *aid = le16_to_cpu(response_head->aid) & 0x3fff;
1571
1572 status_code = le16_to_cpu(response_head->status);
1573 if ((status_code == WLAN_STATUS_ASSOC_DENIED_RATES ||
1574 status_code == WLAN_STATUS_CAPS_UNSUPPORTED) &&
1575 ((ieee->mode == IEEE_G) &&
1576 (ieee->current_network.mode == IEEE_N_24G) &&
1577 (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT - 1)))) {
1578 ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE;
1579 } else {
1580 ieee->AsocRetryCount = 0;
1581 }
1582
1583 return le16_to_cpu(response_head->status);
1584 }
1585
1586 static inline void
ieee80211_rx_probe_rq(struct ieee80211_device * ieee,struct sk_buff * skb)1587 ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1588 {
1589 u8 dest[ETH_ALEN];
1590
1591 //IEEE80211DMESG("Rx probe");
1592 ieee->softmac_stats.rx_probe_rq++;
1593 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1594 if (probe_rq_parse(ieee, skb, dest)) {
1595 //IEEE80211DMESG("Was for me!");
1596 ieee->softmac_stats.tx_probe_rs++;
1597 ieee80211_resp_to_probe(ieee, dest);
1598 }
1599 }
1600
1601 static inline void
ieee80211_rx_auth_rq(struct ieee80211_device * ieee,struct sk_buff * skb)1602 ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1603 {
1604 u8 dest[ETH_ALEN];
1605 int status;
1606 //IEEE80211DMESG("Rx probe");
1607 ieee->softmac_stats.rx_auth_rq++;
1608
1609 status = auth_rq_parse(skb, dest);
1610 if (status != -1)
1611 ieee80211_resp_to_auth(ieee, status, dest);
1612 //DMESG("Dest is "MACSTR, MAC2STR(dest));
1613 }
1614
1615 static inline void
ieee80211_rx_assoc_rq(struct ieee80211_device * ieee,struct sk_buff * skb)1616 ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1617 {
1618 u8 dest[ETH_ALEN];
1619 //unsigned long flags;
1620
1621 ieee->softmac_stats.rx_ass_rq++;
1622 if (assoc_rq_parse(skb, dest) != -1)
1623 ieee80211_resp_to_assoc_rq(ieee, dest);
1624
1625 printk(KERN_INFO"New client associated: %pM\n", dest);
1626 //FIXME
1627 }
1628
ieee80211_sta_ps_send_null_frame(struct ieee80211_device * ieee,short pwr)1629 static void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee,
1630 short pwr)
1631 {
1632 struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
1633
1634 if (buf)
1635 softmac_ps_mgmt_xmit(buf, ieee);
1636 }
1637 /* EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame); */
1638
ieee80211_sta_ps_sleep(struct ieee80211_device * ieee,u32 * time_h,u32 * time_l)1639 static short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h,
1640 u32 *time_l)
1641 {
1642 int timeout;
1643 u8 dtim;
1644 /*if(ieee->ps == IEEE80211_PS_DISABLED ||
1645 ieee->iw_mode != IW_MODE_INFRA ||
1646 ieee->state != IEEE80211_LINKED)
1647
1648 return 0;
1649 */
1650 dtim = ieee->current_network.dtim_data;
1651 if (!(dtim & IEEE80211_DTIM_VALID))
1652 return 0;
1653 timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval
1654 ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
1655
1656 if (dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST) & ieee->ps))
1657 return 2;
1658
1659 if (!time_after(jiffies,
1660 dev_trans_start(ieee->dev) + msecs_to_jiffies(timeout)))
1661 return 0;
1662
1663 if (!time_after(jiffies,
1664 ieee->last_rx_ps_time + msecs_to_jiffies(timeout)))
1665 return 0;
1666
1667 if ((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) &&
1668 (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
1669 return 0;
1670
1671 if (time_l) {
1672 *time_l = ieee->current_network.last_dtim_sta_time[0]
1673 + (ieee->current_network.beacon_interval
1674 * ieee->current_network.dtim_period) * 1000;
1675 }
1676
1677 if (time_h) {
1678 *time_h = ieee->current_network.last_dtim_sta_time[1];
1679 if (time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
1680 *time_h += 1;
1681 }
1682
1683 return 1;
1684 }
1685
ieee80211_sta_ps(struct ieee80211_device * ieee)1686 static inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
1687 {
1688 u32 th, tl;
1689 short sleep;
1690
1691 unsigned long flags, flags2;
1692
1693 spin_lock_irqsave(&ieee->lock, flags);
1694
1695 if ((ieee->ps == IEEE80211_PS_DISABLED ||
1696 ieee->iw_mode != IW_MODE_INFRA ||
1697 ieee->state != IEEE80211_LINKED)) {
1698 // #warning CHECK_LOCK_HERE
1699 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1700
1701 ieee80211_sta_wakeup(ieee, 1);
1702
1703 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1704 }
1705
1706 sleep = ieee80211_sta_ps_sleep(ieee, &th, &tl);
1707 /* 2 wake, 1 sleep, 0 do nothing */
1708 if (sleep == 0)
1709 goto out;
1710
1711 if (sleep == 1) {
1712 if (ieee->sta_sleep == 1) {
1713 ieee->enter_sleep_state(ieee->dev, th, tl);
1714 } else if (ieee->sta_sleep == 0) {
1715 // printk("send null 1\n");
1716 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1717
1718 if (ieee->ps_is_queue_empty(ieee->dev)) {
1719 ieee->sta_sleep = 2;
1720
1721 ieee->ps_request_tx_ack(ieee->dev);
1722
1723 ieee80211_sta_ps_send_null_frame(ieee, 1);
1724
1725 ieee->ps_th = th;
1726 ieee->ps_tl = tl;
1727 }
1728 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1729 }
1730 } else if (sleep == 2) {
1731 //#warning CHECK_LOCK_HERE
1732 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1733
1734 ieee80211_sta_wakeup(ieee, 1);
1735
1736 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1737 }
1738 out:
1739 spin_unlock_irqrestore(&ieee->lock, flags);
1740 }
1741
ieee80211_sta_wakeup(struct ieee80211_device * ieee,short nl)1742 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
1743 {
1744 if (ieee->sta_sleep == 0) {
1745 if (nl) {
1746 printk("Warning: driver is probably failing to report TX ps error\n");
1747 ieee->ps_request_tx_ack(ieee->dev);
1748 ieee80211_sta_ps_send_null_frame(ieee, 0);
1749 }
1750 return;
1751 }
1752
1753 if (ieee->sta_sleep == 1)
1754 ieee->sta_wake_up(ieee->dev);
1755
1756 ieee->sta_sleep = 0;
1757
1758 if (nl) {
1759 ieee->ps_request_tx_ack(ieee->dev);
1760 ieee80211_sta_ps_send_null_frame(ieee, 0);
1761 }
1762 }
1763
ieee80211_ps_tx_ack(struct ieee80211_device * ieee,short success)1764 void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
1765 {
1766 unsigned long flags, flags2;
1767
1768 spin_lock_irqsave(&ieee->lock, flags);
1769
1770 if (ieee->sta_sleep == 2) {
1771 /* Null frame with PS bit set */
1772 if (success) {
1773 ieee->sta_sleep = 1;
1774 ieee->enter_sleep_state(ieee->dev, ieee->ps_th, ieee->ps_tl);
1775 }
1776 /* if the card report not success we can't be sure the AP
1777 * has not RXed so we can't assume the AP believe us awake
1778 */
1779 } else {
1780 /* 21112005 - tx again null without PS bit if lost */
1781 if ((ieee->sta_sleep == 0) && !success) {
1782 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1783 ieee80211_sta_ps_send_null_frame(ieee, 0);
1784 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1785 }
1786 }
1787 spin_unlock_irqrestore(&ieee->lock, flags);
1788 }
1789 EXPORT_SYMBOL(ieee80211_ps_tx_ack);
1790
ieee80211_process_action(struct ieee80211_device * ieee,struct sk_buff * skb)1791 static void ieee80211_process_action(struct ieee80211_device *ieee,
1792 struct sk_buff *skb)
1793 {
1794 struct rtl_80211_hdr *header = (struct rtl_80211_hdr *)skb->data;
1795 u8 *act = ieee80211_get_payload(header);
1796 u8 tmp = 0;
1797 // IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len);
1798 if (!act) {
1799 IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n");
1800 return;
1801 }
1802 tmp = *act;
1803 act++;
1804 switch (tmp) {
1805 case ACT_CAT_BA:
1806 if (*act == ACT_ADDBAREQ)
1807 ieee80211_rx_ADDBAReq(ieee, skb);
1808 else if (*act == ACT_ADDBARSP)
1809 ieee80211_rx_ADDBARsp(ieee, skb);
1810 else if (*act == ACT_DELBA)
1811 ieee80211_rx_DELBA(ieee, skb);
1812 break;
1813 default:
1814 break;
1815 }
1816 return;
1817 }
1818
ieee80211_check_auth_response(struct ieee80211_device * ieee,struct sk_buff * skb)1819 static void ieee80211_check_auth_response(struct ieee80211_device *ieee,
1820 struct sk_buff *skb)
1821 {
1822 /* default support N mode, disable halfNmode */
1823 bool bSupportNmode = true, bHalfSupportNmode = false;
1824 u16 errcode;
1825 u8 *challenge;
1826 int chlen = 0;
1827 u32 iotAction;
1828
1829 errcode = auth_parse(skb, &challenge, &chlen);
1830 if (!errcode) {
1831 if (ieee->open_wep || !challenge) {
1832 ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
1833 ieee->softmac_stats.rx_auth_rs_ok++;
1834 iotAction = ieee->pHTInfo->IOTAction;
1835 if (!(iotAction & HT_IOT_ACT_PURE_N_MODE)) {
1836 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) {
1837 /* WEP or TKIP encryption */
1838 if (IsHTHalfNmodeAPs(ieee)) {
1839 bSupportNmode = true;
1840 bHalfSupportNmode = true;
1841 } else {
1842 bSupportNmode = false;
1843 bHalfSupportNmode = false;
1844 }
1845 netdev_dbg(ieee->dev, "SEC(%d, %d)\n",
1846 bSupportNmode,
1847 bHalfSupportNmode);
1848 }
1849 }
1850 /* Dummy wirless mode setting- avoid encryption issue */
1851 if (bSupportNmode) {
1852 /* N mode setting */
1853 ieee->SetWirelessMode(ieee->dev,
1854 ieee->current_network.mode);
1855 } else {
1856 /* b/g mode setting - TODO */
1857 ieee->SetWirelessMode(ieee->dev, IEEE_G);
1858 }
1859
1860 if (ieee->current_network.mode == IEEE_N_24G &&
1861 bHalfSupportNmode) {
1862 netdev_dbg(ieee->dev, "enter half N mode\n");
1863 ieee->bHalfWirelessN24GMode = true;
1864 } else {
1865 ieee->bHalfWirelessN24GMode = false;
1866 }
1867 ieee80211_associate_step2(ieee);
1868 } else {
1869 ieee80211_auth_challenge(ieee, challenge, chlen);
1870 }
1871 } else {
1872 ieee->softmac_stats.rx_auth_rs_err++;
1873 IEEE80211_DEBUG_MGMT("Auth response status code 0x%x", errcode);
1874 ieee80211_associate_abort(ieee);
1875 }
1876 }
1877
1878 inline int
ieee80211_rx_frame_softmac(struct ieee80211_device * ieee,struct sk_buff * skb,struct ieee80211_rx_stats * rx_stats,u16 type,u16 stype)1879 ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
1880 struct ieee80211_rx_stats *rx_stats, u16 type,
1881 u16 stype)
1882 {
1883 struct rtl_80211_hdr_3addr *header = (struct rtl_80211_hdr_3addr *)skb->data;
1884 u16 errcode;
1885 int aid;
1886 struct ieee80211_assoc_response_frame *assoc_resp;
1887 // struct ieee80211_info_element *info_element;
1888
1889 if (!ieee->proto_started)
1890 return 0;
1891
1892 if (ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
1893 ieee->iw_mode == IW_MODE_INFRA &&
1894 ieee->state == IEEE80211_LINKED))
1895 tasklet_schedule(&ieee->ps_task);
1896
1897 if (WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
1898 WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
1899 ieee->last_rx_ps_time = jiffies;
1900
1901 switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
1902 case IEEE80211_STYPE_ASSOC_RESP:
1903 case IEEE80211_STYPE_REASSOC_RESP:
1904 IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
1905 WLAN_FC_GET_STYPE(header->frame_ctl));
1906 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
1907 ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
1908 ieee->iw_mode == IW_MODE_INFRA) {
1909 struct ieee80211_network network_resp;
1910 struct ieee80211_network *network = &network_resp;
1911
1912 errcode = assoc_parse(ieee, skb, &aid);
1913 if (!errcode) {
1914 ieee->state = IEEE80211_LINKED;
1915 ieee->assoc_id = aid;
1916 ieee->softmac_stats.rx_ass_ok++;
1917 /* station support qos */
1918 /* Let the register setting defaultly with Legacy station */
1919 if (ieee->qos_support) {
1920 assoc_resp = (struct ieee80211_assoc_response_frame *)skb->data;
1921 memset(network, 0, sizeof(*network));
1922 if (ieee80211_parse_info_param(ieee, assoc_resp->info_element,\
1923 rx_stats->len - sizeof(*assoc_resp), \
1924 network, rx_stats)) {
1925 return 1;
1926 } else {
1927 //filling the PeerHTCap. //maybe not necessary as we can get its info from current_network.
1928 memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen);
1929 memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen);
1930 }
1931 if (ieee->handle_assoc_response)
1932 ieee->handle_assoc_response(ieee->dev, (struct ieee80211_assoc_response_frame *)header, network);
1933 }
1934 ieee80211_associate_complete(ieee);
1935 } else {
1936 /* aid could not been allocated */
1937 ieee->softmac_stats.rx_ass_err++;
1938 printk("Association response status code 0x%x\n",
1939 errcode);
1940 IEEE80211_DEBUG_MGMT("Association response status code 0x%x\n",
1941 errcode);
1942 if (ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT)
1943 schedule_work(&ieee->associate_procedure_wq);
1944 else
1945 ieee80211_associate_abort(ieee);
1946 }
1947 }
1948 break;
1949
1950 case IEEE80211_STYPE_ASSOC_REQ:
1951 case IEEE80211_STYPE_REASSOC_REQ:
1952 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
1953 ieee->iw_mode == IW_MODE_MASTER)
1954 ieee80211_rx_assoc_rq(ieee, skb);
1955 break;
1956
1957 case IEEE80211_STYPE_AUTH:
1958 if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) {
1959 if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING
1960 && ieee->iw_mode == IW_MODE_INFRA) {
1961 IEEE80211_DEBUG_MGMT("Received auth response");
1962 ieee80211_check_auth_response(ieee, skb);
1963 } else if (ieee->iw_mode == IW_MODE_MASTER) {
1964 ieee80211_rx_auth_rq(ieee, skb);
1965 }
1966 }
1967 break;
1968
1969 case IEEE80211_STYPE_PROBE_REQ:
1970 if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
1971 ((ieee->iw_mode == IW_MODE_ADHOC ||
1972 ieee->iw_mode == IW_MODE_MASTER) &&
1973 ieee->state == IEEE80211_LINKED)) {
1974 ieee80211_rx_probe_rq(ieee, skb);
1975 }
1976 break;
1977
1978 case IEEE80211_STYPE_DISASSOC:
1979 case IEEE80211_STYPE_DEAUTH:
1980 /* FIXME for now repeat all the association procedure
1981 * both for disassociation and deauthentication
1982 */
1983 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
1984 ieee->state == IEEE80211_LINKED &&
1985 ieee->iw_mode == IW_MODE_INFRA) {
1986 ieee->state = IEEE80211_ASSOCIATING;
1987 ieee->softmac_stats.reassoc++;
1988
1989 notify_wx_assoc_event(ieee);
1990 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1991 RemovePeerTS(ieee, header->addr2);
1992 schedule_work(&ieee->associate_procedure_wq);
1993 }
1994 break;
1995 case IEEE80211_STYPE_MANAGE_ACT:
1996 ieee80211_process_action(ieee, skb);
1997 break;
1998 default:
1999 return -1;
2000 }
2001
2002 //dev_kfree_skb_any(skb);
2003 return 0;
2004 }
2005
2006 /* The following are for a simpler TX queue management.
2007 * Instead of using netif_[stop/wake]_queue, the driver
2008 * will use these two functions (plus a reset one) that
2009 * will internally call the kernel netif_* and take care
2010 * of the ieee802.11 fragmentation.
2011 * So, the driver receives a fragment at a time and might
2012 * call the stop function when it wants, without taking
2013 * care to have enough room to TX an entire packet.
2014 * This might be useful if each fragment needs its own
2015 * descriptor. Thus, just keeping a total free memory > than
2016 * the max fragmentation threshold is not enough. If the
2017 * ieee802.11 stack passed a TXB struct, then you would need
2018 * to keep N free descriptors where
2019 * N = MAX_PACKET_SIZE / MIN_FRAG_THRESHOLD.
2020 * In this way you need just one and the 802.11 stack
2021 * will take care of buffering fragments and pass them to
2022 * to the driver later, when it wakes the queue.
2023 */
ieee80211_softmac_xmit(struct ieee80211_txb * txb,struct ieee80211_device * ieee)2024 void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
2025 {
2026 unsigned int queue_index = txb->queue_index;
2027 unsigned long flags;
2028 int i;
2029 struct cb_desc *tcb_desc = NULL;
2030
2031 spin_lock_irqsave(&ieee->lock, flags);
2032
2033 /* called with 2nd parm 0, no tx mgmt lock required */
2034 ieee80211_sta_wakeup(ieee, 0);
2035
2036 /* update the tx status */
2037 ieee->stats.tx_bytes += le16_to_cpu(txb->payload_size);
2038 ieee->stats.tx_packets++;
2039 tcb_desc = (struct cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE);
2040 if (tcb_desc->bMulticast)
2041 ieee->stats.multicast++;
2042
2043 /* if xmit available, just xmit it immediately, else just insert it to the wait queue */
2044 for (i = 0; i < txb->nr_frags; i++) {
2045 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2046 if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) ||
2047 #else
2048 if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) ||
2049 #endif
2050 (!ieee->check_nic_enough_desc(ieee->dev, queue_index)) || \
2051 (ieee->queue_stop)) {
2052 /* insert the skb packet to the wait queue */
2053 /* as for the completion function, it does not need
2054 * to check it any more.
2055 * */
2056 //printk("error:no descriptor left@queue_index %d\n", queue_index);
2057 //ieee80211_stop_queue(ieee);
2058 #ifdef USB_TX_DRIVER_AGGREGATION_ENABLE
2059 skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]);
2060 #else
2061 skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]);
2062 #endif
2063 } else {
2064 ieee->softmac_data_hard_start_xmit(txb->fragments[i],
2065 ieee->dev, ieee->rate);
2066 //ieee->stats.tx_packets++;
2067 //ieee->stats.tx_bytes += txb->fragments[i]->len;
2068 //ieee->dev->trans_start = jiffies;
2069 }
2070 }
2071 ieee80211_txb_free(txb);
2072
2073 //exit:
2074 spin_unlock_irqrestore(&ieee->lock, flags);
2075 }
2076 EXPORT_SYMBOL(ieee80211_softmac_xmit);
2077
2078 /* called with ieee->lock acquired */
ieee80211_resume_tx(struct ieee80211_device * ieee)2079 static void ieee80211_resume_tx(struct ieee80211_device *ieee)
2080 {
2081 int i;
2082 for (i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
2083 if (ieee->queue_stop) {
2084 ieee->tx_pending.frag = i;
2085 return;
2086 } else {
2087 ieee->softmac_data_hard_start_xmit(ieee->tx_pending.txb->fragments[i],
2088 ieee->dev, ieee->rate);
2089 //(i+1)<ieee->tx_pending.txb->nr_frags);
2090 ieee->stats.tx_packets++;
2091 netif_trans_update(ieee->dev);
2092 }
2093 }
2094
2095 ieee80211_txb_free(ieee->tx_pending.txb);
2096 ieee->tx_pending.txb = NULL;
2097 }
2098
ieee80211_reset_queue(struct ieee80211_device * ieee)2099 void ieee80211_reset_queue(struct ieee80211_device *ieee)
2100 {
2101 unsigned long flags;
2102
2103 spin_lock_irqsave(&ieee->lock, flags);
2104 init_mgmt_queue(ieee);
2105 if (ieee->tx_pending.txb) {
2106 ieee80211_txb_free(ieee->tx_pending.txb);
2107 ieee->tx_pending.txb = NULL;
2108 }
2109 ieee->queue_stop = 0;
2110 spin_unlock_irqrestore(&ieee->lock, flags);
2111 }
2112 EXPORT_SYMBOL(ieee80211_reset_queue);
2113
ieee80211_wake_queue(struct ieee80211_device * ieee)2114 void ieee80211_wake_queue(struct ieee80211_device *ieee)
2115 {
2116 unsigned long flags;
2117 struct sk_buff *skb;
2118 struct rtl_80211_hdr_3addr *header;
2119
2120 spin_lock_irqsave(&ieee->lock, flags);
2121 if (!ieee->queue_stop)
2122 goto exit;
2123
2124 ieee->queue_stop = 0;
2125
2126 if (ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) {
2127 while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))) {
2128 header = (struct rtl_80211_hdr_3addr *)skb->data;
2129
2130 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2131
2132 if (ieee->seq_ctrl[0] == 0xFFF)
2133 ieee->seq_ctrl[0] = 0;
2134 else
2135 ieee->seq_ctrl[0]++;
2136
2137 ieee->softmac_data_hard_start_xmit(skb, ieee->dev, ieee->basic_rate);
2138 //dev_kfree_skb_any(skb);//edit by thomas
2139 }
2140 }
2141 if (!ieee->queue_stop && ieee->tx_pending.txb)
2142 ieee80211_resume_tx(ieee);
2143
2144 if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)) {
2145 ieee->softmac_stats.swtxawake++;
2146 netif_wake_queue(ieee->dev);
2147 }
2148 exit:
2149 spin_unlock_irqrestore(&ieee->lock, flags);
2150 }
2151 EXPORT_SYMBOL(ieee80211_wake_queue);
2152
ieee80211_stop_queue(struct ieee80211_device * ieee)2153 void ieee80211_stop_queue(struct ieee80211_device *ieee)
2154 {
2155 //unsigned long flags;
2156 //spin_lock_irqsave(&ieee->lock,flags);
2157
2158 if (!netif_queue_stopped(ieee->dev)) {
2159 netif_stop_queue(ieee->dev);
2160 ieee->softmac_stats.swtxstop++;
2161 }
2162 ieee->queue_stop = 1;
2163 //spin_unlock_irqrestore(&ieee->lock,flags);
2164 }
2165 EXPORT_SYMBOL(ieee80211_stop_queue);
2166
2167 /* called in user context only */
ieee80211_start_master_bss(struct ieee80211_device * ieee)2168 void ieee80211_start_master_bss(struct ieee80211_device *ieee)
2169 {
2170 ieee->assoc_id = 1;
2171
2172 if (ieee->current_network.ssid_len == 0) {
2173 strncpy(ieee->current_network.ssid,
2174 IEEE80211_DEFAULT_TX_ESSID,
2175 IW_ESSID_MAX_SIZE);
2176
2177 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2178 ieee->ssid_set = 1;
2179 }
2180
2181 memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
2182
2183 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2184 ieee->state = IEEE80211_LINKED;
2185 ieee->link_change(ieee->dev);
2186 notify_wx_assoc_event(ieee);
2187
2188 if (ieee->data_hard_resume)
2189 ieee->data_hard_resume(ieee->dev);
2190
2191 netif_carrier_on(ieee->dev);
2192 }
2193
ieee80211_start_monitor_mode(struct ieee80211_device * ieee)2194 static void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
2195 {
2196 if (ieee->raw_tx) {
2197 if (ieee->data_hard_resume)
2198 ieee->data_hard_resume(ieee->dev);
2199
2200 netif_carrier_on(ieee->dev);
2201 }
2202 }
ieee80211_start_ibss_wq(struct work_struct * work)2203 static void ieee80211_start_ibss_wq(struct work_struct *work)
2204 {
2205 struct delayed_work *dwork = to_delayed_work(work);
2206 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
2207 /* iwconfig mode ad-hoc will schedule this and return
2208 * on the other hand this will block further iwconfig SET
2209 * operations because of the wx_mutex hold.
2210 * Anyway some most set operations set a flag to speed-up
2211 * (abort) this wq (when syncro scanning) before sleeping
2212 * on the semaphore
2213 */
2214 if (!ieee->proto_started) {
2215 printk("==========oh driver down return\n");
2216 return;
2217 }
2218 mutex_lock(&ieee->wx_mutex);
2219
2220 if (ieee->current_network.ssid_len == 0) {
2221 strcpy(ieee->current_network.ssid, IEEE80211_DEFAULT_TX_ESSID);
2222 ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
2223 ieee->ssid_set = 1;
2224 }
2225
2226 /* check if we have this cell in our network list */
2227 ieee80211_softmac_check_all_nets(ieee);
2228
2229 // if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK))
2230 if (ieee->state == IEEE80211_NOLINK)
2231 ieee->current_network.channel = 6;
2232 /* if not then the state is not linked. Maybe the user switched to
2233 * ad-hoc mode just after being in monitor mode, or just after
2234 * being very few time in managed mode (so the card have had no
2235 * time to scan all the chans..) or we have just run up the iface
2236 * after setting ad-hoc mode. So we have to give another try..
2237 * Here, in ibss mode, should be safe to do this without extra care
2238 * (in bss mode we had to make sure no-one tryed to associate when
2239 * we had just checked the ieee->state and we was going to start the
2240 * scan) beacause in ibss mode the ieee80211_new_net function, when
2241 * finds a good net, just set the ieee->state to IEEE80211_LINKED,
2242 * so, at worst, we waste a bit of time to initiate an unneeded syncro
2243 * scan, that will stop at the first round because it sees the state
2244 * associated.
2245 */
2246 if (ieee->state == IEEE80211_NOLINK)
2247 ieee80211_start_scan_syncro(ieee);
2248
2249 /* the network definitively is not here.. create a new cell */
2250 if (ieee->state == IEEE80211_NOLINK) {
2251 printk("creating new IBSS cell\n");
2252 if (!ieee->wap_set)
2253 eth_random_addr(ieee->current_network.bssid);
2254
2255 if (ieee->modulation & IEEE80211_CCK_MODULATION) {
2256 ieee->current_network.rates_len = 4;
2257
2258 ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
2259 ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
2260 ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
2261 ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
2262 } else {
2263 ieee->current_network.rates_len = 0;
2264 }
2265 if (ieee->modulation & IEEE80211_OFDM_MODULATION) {
2266 ieee->current_network.rates_ex_len = 8;
2267
2268 ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
2269 ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
2270 ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
2271 ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
2272 ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
2273 ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
2274 ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
2275 ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
2276
2277 ieee->rate = 108;
2278 } else {
2279 ieee->current_network.rates_ex_len = 0;
2280 ieee->rate = 22;
2281 }
2282
2283 // By default, WMM function will be disabled in IBSS mode
2284 ieee->current_network.QoS_Enable = 0;
2285 ieee->SetWirelessMode(ieee->dev, IEEE_G);
2286 ieee->current_network.atim_window = 0;
2287 ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
2288 if (ieee->short_slot)
2289 ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
2290 }
2291
2292 ieee->state = IEEE80211_LINKED;
2293
2294 ieee->set_chan(ieee->dev, ieee->current_network.channel);
2295 ieee->link_change(ieee->dev);
2296
2297 notify_wx_assoc_event(ieee);
2298
2299 ieee80211_start_send_beacons(ieee);
2300
2301 if (ieee->data_hard_resume)
2302 ieee->data_hard_resume(ieee->dev);
2303 netif_carrier_on(ieee->dev);
2304
2305 mutex_unlock(&ieee->wx_mutex);
2306 }
2307
ieee80211_start_ibss(struct ieee80211_device * ieee)2308 inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
2309 {
2310 schedule_delayed_work(&ieee->start_ibss_wq, 150);
2311 }
2312
2313 /* this is called only in user context, with wx_mutex held */
ieee80211_start_bss(struct ieee80211_device * ieee)2314 void ieee80211_start_bss(struct ieee80211_device *ieee)
2315 {
2316 unsigned long flags;
2317 //
2318 // Ref: 802.11d 11.1.3.3
2319 // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
2320 //
2321 if (IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee)) {
2322 if (!ieee->bGlobalDomain)
2323 return;
2324 }
2325 /* check if we have already found the net we
2326 * are interested in (if any).
2327 * if not (we are disassociated and we are not
2328 * in associating / authenticating phase) start the background scanning.
2329 */
2330 ieee80211_softmac_check_all_nets(ieee);
2331
2332 /* ensure no-one start an associating process (thus setting
2333 * the ieee->state to ieee80211_ASSOCIATING) while we
2334 * have just cheked it and we are going to enable scan.
2335 * The ieee80211_new_net function is always called with
2336 * lock held (from both ieee80211_softmac_check_all_nets and
2337 * the rx path), so we cannot be in the middle of such function
2338 */
2339 spin_lock_irqsave(&ieee->lock, flags);
2340
2341 if (ieee->state == IEEE80211_NOLINK) {
2342 ieee->actscanning = true;
2343 ieee80211_start_scan(ieee);
2344 }
2345 spin_unlock_irqrestore(&ieee->lock, flags);
2346 }
2347
2348 /* called only in userspace context */
ieee80211_disassociate(struct ieee80211_device * ieee)2349 void ieee80211_disassociate(struct ieee80211_device *ieee)
2350 {
2351 netif_carrier_off(ieee->dev);
2352 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
2353 ieee80211_reset_queue(ieee);
2354
2355 if (ieee->data_hard_stop)
2356 ieee->data_hard_stop(ieee->dev);
2357 if (IS_DOT11D_ENABLE(ieee))
2358 dot11d_reset(ieee);
2359 ieee->state = IEEE80211_NOLINK;
2360 ieee->is_set_key = false;
2361 ieee->link_change(ieee->dev);
2362 //HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2363 notify_wx_assoc_event(ieee);
2364 }
2365 EXPORT_SYMBOL(ieee80211_disassociate);
2366
ieee80211_associate_retry_wq(struct work_struct * work)2367 static void ieee80211_associate_retry_wq(struct work_struct *work)
2368 {
2369 struct delayed_work *dwork = to_delayed_work(work);
2370 struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
2371 unsigned long flags;
2372
2373 mutex_lock(&ieee->wx_mutex);
2374 if (!ieee->proto_started)
2375 goto exit;
2376
2377 if (ieee->state != IEEE80211_ASSOCIATING_RETRY)
2378 goto exit;
2379
2380 /* until we do not set the state to IEEE80211_NOLINK
2381 * there are no possibility to have someone else trying
2382 * to start an association procedure (we get here with
2383 * ieee->state = IEEE80211_ASSOCIATING).
2384 * When we set the state to IEEE80211_NOLINK it is possible
2385 * that the RX path run an attempt to associate, but
2386 * both ieee80211_softmac_check_all_nets and the
2387 * RX path works with ieee->lock held so there are no
2388 * problems. If we are still disassociated then start a scan.
2389 * the lock here is necessary to ensure no one try to start
2390 * an association procedure when we have just checked the
2391 * state and we are going to start the scan.
2392 */
2393 ieee->state = IEEE80211_NOLINK;
2394
2395 ieee80211_softmac_check_all_nets(ieee);
2396
2397 spin_lock_irqsave(&ieee->lock, flags);
2398
2399 if (ieee->state == IEEE80211_NOLINK)
2400 ieee80211_start_scan(ieee);
2401
2402 spin_unlock_irqrestore(&ieee->lock, flags);
2403
2404 exit:
2405 mutex_unlock(&ieee->wx_mutex);
2406 }
2407
ieee80211_get_beacon_(struct ieee80211_device * ieee)2408 struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
2409 {
2410 u8 broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2411
2412 struct sk_buff *skb;
2413 struct ieee80211_probe_response *b;
2414
2415 skb = ieee80211_probe_resp(ieee, broadcast_addr);
2416
2417 if (!skb)
2418 return NULL;
2419
2420 b = (struct ieee80211_probe_response *)skb->data;
2421 b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
2422
2423 return skb;
2424 }
2425
ieee80211_get_beacon(struct ieee80211_device * ieee)2426 struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
2427 {
2428 struct sk_buff *skb;
2429 struct ieee80211_probe_response *b;
2430
2431 skb = ieee80211_get_beacon_(ieee);
2432 if (!skb)
2433 return NULL;
2434
2435 b = (struct ieee80211_probe_response *)skb->data;
2436 b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2437
2438 if (ieee->seq_ctrl[0] == 0xFFF)
2439 ieee->seq_ctrl[0] = 0;
2440 else
2441 ieee->seq_ctrl[0]++;
2442
2443 return skb;
2444 }
2445 EXPORT_SYMBOL(ieee80211_get_beacon);
2446
ieee80211_softmac_stop_protocol(struct ieee80211_device * ieee)2447 void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
2448 {
2449 ieee->sync_scan_hurryup = 1;
2450 mutex_lock(&ieee->wx_mutex);
2451 ieee80211_stop_protocol(ieee);
2452 mutex_unlock(&ieee->wx_mutex);
2453 }
2454 EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
2455
ieee80211_stop_protocol(struct ieee80211_device * ieee)2456 void ieee80211_stop_protocol(struct ieee80211_device *ieee)
2457 {
2458 if (!ieee->proto_started)
2459 return;
2460
2461 ieee->proto_started = 0;
2462
2463 ieee80211_stop_send_beacons(ieee);
2464 del_timer_sync(&ieee->associate_timer);
2465 cancel_delayed_work(&ieee->associate_retry_wq);
2466 cancel_delayed_work(&ieee->start_ibss_wq);
2467 ieee80211_stop_scan(ieee);
2468
2469 ieee80211_disassociate(ieee);
2470 RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS
2471 }
2472
ieee80211_softmac_start_protocol(struct ieee80211_device * ieee)2473 void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
2474 {
2475 ieee->sync_scan_hurryup = 0;
2476 mutex_lock(&ieee->wx_mutex);
2477 ieee80211_start_protocol(ieee);
2478 mutex_unlock(&ieee->wx_mutex);
2479 }
2480 EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
2481
ieee80211_start_protocol(struct ieee80211_device * ieee)2482 void ieee80211_start_protocol(struct ieee80211_device *ieee)
2483 {
2484 short ch = 0;
2485 int i = 0;
2486
2487 if (ieee->proto_started)
2488 return;
2489
2490 ieee->proto_started = 1;
2491
2492 if (ieee->current_network.channel == 0) {
2493 do {
2494 ch++;
2495 if (ch > MAX_CHANNEL_NUMBER)
2496 return; /* no channel found */
2497 } while (!GET_DOT11D_INFO(ieee)->channel_map[ch]);
2498 ieee->current_network.channel = ch;
2499 }
2500
2501 if (ieee->current_network.beacon_interval == 0)
2502 ieee->current_network.beacon_interval = 100;
2503 // printk("===>%s(), chan:%d\n", __func__, ieee->current_network.channel);
2504 // ieee->set_chan(ieee->dev,ieee->current_network.channel);
2505
2506 for (i = 0; i < 17; i++) {
2507 ieee->last_rxseq_num[i] = -1;
2508 ieee->last_rxfrag_num[i] = -1;
2509 ieee->last_packet_time[i] = 0;
2510 }
2511
2512 ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
2513
2514 /* if the user set the MAC of the ad-hoc cell and then
2515 * switch to managed mode, shall we make sure that association
2516 * attempts does not fail just because the user provide the essid
2517 * and the nic is still checking for the AP MAC ??
2518 */
2519 if (ieee->iw_mode == IW_MODE_INFRA)
2520 ieee80211_start_bss(ieee);
2521
2522 else if (ieee->iw_mode == IW_MODE_ADHOC)
2523 ieee80211_start_ibss(ieee);
2524
2525 else if (ieee->iw_mode == IW_MODE_MASTER)
2526 ieee80211_start_master_bss(ieee);
2527
2528 else if (ieee->iw_mode == IW_MODE_MONITOR)
2529 ieee80211_start_monitor_mode(ieee);
2530 }
2531
2532 #define DRV_NAME "Ieee80211"
ieee80211_softmac_init(struct ieee80211_device * ieee)2533 void ieee80211_softmac_init(struct ieee80211_device *ieee)
2534 {
2535 int i;
2536 memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
2537
2538 ieee->state = IEEE80211_NOLINK;
2539 ieee->sync_scan_hurryup = 0;
2540 for (i = 0; i < 5; i++)
2541 ieee->seq_ctrl[i] = 0;
2542
2543 ieee->dot11d_info = kzalloc(sizeof(struct rt_dot11d_info), GFP_KERNEL);
2544 if (!ieee->dot11d_info)
2545 IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n");
2546 //added for AP roaming
2547 ieee->LinkDetectInfo.SlotNum = 2;
2548 ieee->LinkDetectInfo.NumRecvBcnInPeriod = 0;
2549 ieee->LinkDetectInfo.NumRecvDataInPeriod = 0;
2550
2551 ieee->assoc_id = 0;
2552 ieee->queue_stop = 0;
2553 ieee->scanning = 0;
2554 ieee->softmac_features = 0; //so IEEE2100-like driver are happy
2555 ieee->wap_set = 0;
2556 ieee->ssid_set = 0;
2557 ieee->proto_started = 0;
2558 ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
2559 ieee->rate = 22;
2560 ieee->ps = IEEE80211_PS_DISABLED;
2561 ieee->sta_sleep = 0;
2562 ieee->Regdot11HTOperationalRateSet[0] = 0xff;//support MCS 0~7
2563 ieee->Regdot11HTOperationalRateSet[1] = 0xff;//support MCS 8~15
2564 ieee->Regdot11HTOperationalRateSet[4] = 0x01;
2565 //added by amy
2566 ieee->actscanning = false;
2567 ieee->beinretry = false;
2568 ieee->is_set_key = false;
2569 init_mgmt_queue(ieee);
2570
2571 ieee->sta_edca_param[0] = 0x0000A403;
2572 ieee->sta_edca_param[1] = 0x0000A427;
2573 ieee->sta_edca_param[2] = 0x005E4342;
2574 ieee->sta_edca_param[3] = 0x002F3262;
2575 ieee->aggregation = true;
2576 ieee->enable_rx_imm_BA = true;
2577 ieee->tx_pending.txb = NULL;
2578
2579 timer_setup(&ieee->associate_timer, ieee80211_associate_abort_cb, 0);
2580
2581 timer_setup(&ieee->beacon_timer, ieee80211_send_beacon_cb, 0);
2582
2583 INIT_DELAYED_WORK(&ieee->start_ibss_wq, ieee80211_start_ibss_wq);
2584 INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq);
2585 INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq);
2586 INIT_DELAYED_WORK(&ieee->softmac_scan_wq, ieee80211_softmac_scan_wq);
2587 INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq);
2588 INIT_WORK(&ieee->wx_sync_scan_wq, ieee80211_wx_sync_scan_wq);
2589
2590 mutex_init(&ieee->wx_mutex);
2591 mutex_init(&ieee->scan_mutex);
2592
2593 spin_lock_init(&ieee->mgmt_tx_lock);
2594 spin_lock_init(&ieee->beacon_lock);
2595
2596 tasklet_init(&ieee->ps_task,
2597 (void(*)(unsigned long)) ieee80211_sta_ps,
2598 (unsigned long)ieee);
2599 }
2600
ieee80211_softmac_free(struct ieee80211_device * ieee)2601 void ieee80211_softmac_free(struct ieee80211_device *ieee)
2602 {
2603 mutex_lock(&ieee->wx_mutex);
2604 kfree(ieee->dot11d_info);
2605 ieee->dot11d_info = NULL;
2606 del_timer_sync(&ieee->associate_timer);
2607
2608 cancel_delayed_work(&ieee->associate_retry_wq);
2609
2610 mutex_unlock(&ieee->wx_mutex);
2611 }
2612
2613 /********************************************************
2614 * Start of WPA code. *
2615 * this is stolen from the ipw2200 driver *
2616 ********************************************************/
ieee80211_wpa_enable(struct ieee80211_device * ieee,int value)2617 static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
2618 {
2619 /* This is called when wpa_supplicant loads and closes the driver
2620 * interface. */
2621 printk("%s WPA\n", value ? "enabling" : "disabling");
2622 ieee->wpa_enabled = value;
2623 return 0;
2624 }
2625
ieee80211_wpa_assoc_frame(struct ieee80211_device * ieee,char * wpa_ie,int wpa_ie_len)2626 static void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee,
2627 char *wpa_ie, int wpa_ie_len)
2628 {
2629 /* make sure WPA is enabled */
2630 ieee80211_wpa_enable(ieee, 1);
2631
2632 ieee80211_disassociate(ieee);
2633 }
2634
ieee80211_wpa_mlme(struct ieee80211_device * ieee,int command,int reason)2635 static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
2636 {
2637 int ret = 0;
2638
2639 switch (command) {
2640 case IEEE_MLME_STA_DEAUTH:
2641 // silently ignore
2642 break;
2643
2644 case IEEE_MLME_STA_DISASSOC:
2645 ieee80211_disassociate(ieee);
2646 break;
2647
2648 default:
2649 printk("Unknown MLME request: %d\n", command);
2650 ret = -EOPNOTSUPP;
2651 }
2652
2653 return ret;
2654 }
2655
ieee80211_wpa_set_wpa_ie(struct ieee80211_device * ieee,struct ieee_param * param,int plen)2656 static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
2657 struct ieee_param *param, int plen)
2658 {
2659 u8 *buf;
2660
2661 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN)
2662 return -EINVAL;
2663
2664 if (param->u.wpa_ie.len) {
2665 buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len,
2666 GFP_KERNEL);
2667 if (!buf)
2668 return -ENOMEM;
2669
2670 kfree(ieee->wpa_ie);
2671 ieee->wpa_ie = buf;
2672 ieee->wpa_ie_len = param->u.wpa_ie.len;
2673 } else {
2674 kfree(ieee->wpa_ie);
2675 ieee->wpa_ie = NULL;
2676 ieee->wpa_ie_len = 0;
2677 }
2678
2679 ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
2680 return 0;
2681 }
2682
2683 #define AUTH_ALG_OPEN_SYSTEM 0x1
2684 #define AUTH_ALG_SHARED_KEY 0x2
2685
ieee80211_wpa_set_auth_algs(struct ieee80211_device * ieee,int value)2686 static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
2687 {
2688 struct ieee80211_security sec = {
2689 .flags = SEC_AUTH_MODE,
2690 };
2691
2692 if (value & AUTH_ALG_SHARED_KEY) {
2693 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
2694 ieee->open_wep = 0;
2695 ieee->auth_mode = 1;
2696 } else if (value & AUTH_ALG_OPEN_SYSTEM) {
2697 sec.auth_mode = WLAN_AUTH_OPEN;
2698 ieee->open_wep = 1;
2699 ieee->auth_mode = 0;
2700 } else if (value & IW_AUTH_ALG_LEAP) {
2701 sec.auth_mode = WLAN_AUTH_LEAP;
2702 ieee->open_wep = 1;
2703 ieee->auth_mode = 2;
2704 }
2705
2706 if (ieee->set_security)
2707 ieee->set_security(ieee->dev, &sec);
2708 //else
2709 // ret = -EOPNOTSUPP;
2710
2711 return 0;
2712 }
2713
ieee80211_wpa_set_param(struct ieee80211_device * ieee,u8 name,u32 value)2714 static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
2715 {
2716 int ret = 0;
2717 unsigned long flags;
2718
2719 switch (name) {
2720 case IEEE_PARAM_WPA_ENABLED:
2721 ret = ieee80211_wpa_enable(ieee, value);
2722 break;
2723
2724 case IEEE_PARAM_TKIP_COUNTERMEASURES:
2725 ieee->tkip_countermeasures = value;
2726 break;
2727
2728 case IEEE_PARAM_DROP_UNENCRYPTED: {
2729 /* HACK:
2730 *
2731 * wpa_supplicant calls set_wpa_enabled when the driver
2732 * is loaded and unloaded, regardless of if WPA is being
2733 * used. No other calls are made which can be used to
2734 * determine if encryption will be used or not prior to
2735 * association being expected. If encryption is not being
2736 * used, drop_unencrypted is set to false, else true -- we
2737 * can use this to determine if the CAP_PRIVACY_ON bit should
2738 * be set.
2739 */
2740 struct ieee80211_security sec = {
2741 .flags = SEC_ENABLED,
2742 .enabled = value,
2743 };
2744 ieee->drop_unencrypted = value;
2745 /* We only change SEC_LEVEL for open mode. Others
2746 * are set by ipw_wpa_set_encryption.
2747 */
2748 if (!value) {
2749 sec.flags |= SEC_LEVEL;
2750 sec.level = SEC_LEVEL_0;
2751 } else {
2752 sec.flags |= SEC_LEVEL;
2753 sec.level = SEC_LEVEL_1;
2754 }
2755 if (ieee->set_security)
2756 ieee->set_security(ieee->dev, &sec);
2757 break;
2758 }
2759
2760 case IEEE_PARAM_PRIVACY_INVOKED:
2761 ieee->privacy_invoked = value;
2762 break;
2763
2764 case IEEE_PARAM_AUTH_ALGS:
2765 ret = ieee80211_wpa_set_auth_algs(ieee, value);
2766 break;
2767
2768 case IEEE_PARAM_IEEE_802_1X:
2769 ieee->ieee802_1x = value;
2770 break;
2771 case IEEE_PARAM_WPAX_SELECT:
2772 // added for WPA2 mixed mode
2773 spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags);
2774 ieee->wpax_type_set = 1;
2775 ieee->wpax_type_notify = value;
2776 spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags);
2777 break;
2778
2779 default:
2780 printk("Unknown WPA param: %d\n", name);
2781 ret = -EOPNOTSUPP;
2782 }
2783
2784 return ret;
2785 }
2786
2787 /* implementation borrowed from hostap driver */
ieee80211_wpa_set_encryption(struct ieee80211_device * ieee,struct ieee_param * param,int param_len)2788 static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
2789 struct ieee_param *param, int param_len)
2790 {
2791 int ret = 0;
2792 const char *module = NULL;
2793
2794 struct ieee80211_crypto_ops *ops = NULL;
2795 struct ieee80211_crypt_data **crypt;
2796
2797 struct ieee80211_security sec = {
2798 .flags = 0,
2799 };
2800
2801 param->u.crypt.err = 0;
2802 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
2803
2804 if (param_len !=
2805 (int)((char *)param->u.crypt.key - (char *)param) +
2806 param->u.crypt.key_len) {
2807 printk("Len mismatch %d, %d\n", param_len,
2808 param->u.crypt.key_len);
2809 return -EINVAL;
2810 }
2811 if (is_broadcast_ether_addr(param->sta_addr)) {
2812 if (param->u.crypt.idx >= WEP_KEYS)
2813 return -EINVAL;
2814 crypt = &ieee->crypt[param->u.crypt.idx];
2815 } else {
2816 return -EINVAL;
2817 }
2818
2819 if (strcmp(param->u.crypt.alg, "none") == 0) {
2820 if (crypt) {
2821 sec.enabled = 0;
2822 // FIXME FIXME
2823 //sec.encrypt = 0;
2824 sec.level = SEC_LEVEL_0;
2825 sec.flags |= SEC_ENABLED | SEC_LEVEL;
2826 ieee80211_crypt_delayed_deinit(ieee, crypt);
2827 }
2828 goto done;
2829 }
2830 sec.enabled = 1;
2831 // FIXME FIXME
2832 // sec.encrypt = 1;
2833 sec.flags |= SEC_ENABLED;
2834
2835 /* IPW HW cannot build TKIP MIC, host decryption still needed. */
2836 if (!(ieee->host_encrypt || ieee->host_decrypt) &&
2837 strcmp(param->u.crypt.alg, "TKIP"))
2838 goto skip_host_crypt;
2839
2840 //set WEP40 first, it will be modified according to WEP104 or WEP40 at other place
2841 if (!strcmp(param->u.crypt.alg, "WEP"))
2842 module = "ieee80211_crypt_wep";
2843 else if (!strcmp(param->u.crypt.alg, "TKIP"))
2844 module = "ieee80211_crypt_tkip";
2845 else if (!strcmp(param->u.crypt.alg, "CCMP"))
2846 module = "ieee80211_crypt_ccmp";
2847 if (module)
2848 ops = try_then_request_module(ieee80211_get_crypto_ops(param->u.crypt.alg),
2849 module);
2850 if (!ops) {
2851 printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
2852 param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
2853 ret = -EINVAL;
2854 goto done;
2855 }
2856
2857 if (!*crypt || (*crypt)->ops != ops) {
2858 struct ieee80211_crypt_data *new_crypt;
2859
2860 ieee80211_crypt_delayed_deinit(ieee, crypt);
2861
2862 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
2863 if (!new_crypt) {
2864 ret = -ENOMEM;
2865 goto done;
2866 }
2867 new_crypt->ops = ops;
2868 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
2869 new_crypt->priv =
2870 new_crypt->ops->init(param->u.crypt.idx);
2871
2872 if (!new_crypt->priv) {
2873 kfree(new_crypt);
2874 param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
2875 ret = -EINVAL;
2876 goto done;
2877 }
2878
2879 *crypt = new_crypt;
2880 }
2881
2882 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
2883 (*crypt)->ops->set_key(param->u.crypt.key,
2884 param->u.crypt.key_len, param->u.crypt.seq,
2885 (*crypt)->priv) < 0) {
2886 printk("key setting failed\n");
2887 param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
2888 ret = -EINVAL;
2889 goto done;
2890 }
2891
2892 skip_host_crypt:
2893 if (param->u.crypt.set_tx) {
2894 ieee->tx_keyidx = param->u.crypt.idx;
2895 sec.active_key = param->u.crypt.idx;
2896 sec.flags |= SEC_ACTIVE_KEY;
2897 } else {
2898 sec.flags &= ~SEC_ACTIVE_KEY;
2899 }
2900 memcpy(sec.keys[param->u.crypt.idx],
2901 param->u.crypt.key,
2902 param->u.crypt.key_len);
2903 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
2904 sec.flags |= (1 << param->u.crypt.idx);
2905
2906 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
2907 sec.flags |= SEC_LEVEL;
2908 sec.level = SEC_LEVEL_1;
2909 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
2910 sec.flags |= SEC_LEVEL;
2911 sec.level = SEC_LEVEL_2;
2912 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
2913 sec.flags |= SEC_LEVEL;
2914 sec.level = SEC_LEVEL_3;
2915 }
2916 done:
2917 if (ieee->set_security)
2918 ieee->set_security(ieee->dev, &sec);
2919
2920 /* Do not reset port if card is in Managed mode since resetting will
2921 * generate new IEEE 802.11 authentication which may end up in looping
2922 * with IEEE 802.1X. If your hardware requires a reset after WEP
2923 * configuration (for example... Prism2), implement the reset_port in
2924 * the callbacks structures used to initialize the 802.11 stack. */
2925 if (ieee->reset_on_keychange &&
2926 ieee->iw_mode != IW_MODE_INFRA &&
2927 ieee->reset_port &&
2928 ieee->reset_port(ieee->dev)) {
2929 printk("reset_port failed\n");
2930 param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
2931 return -EINVAL;
2932 }
2933
2934 return ret;
2935 }
2936
ieee80211_disassociate_skb(struct ieee80211_network * beacon,struct ieee80211_device * ieee,u8 asRsn)2937 static inline struct sk_buff *ieee80211_disassociate_skb(struct ieee80211_network *beacon,
2938 struct ieee80211_device *ieee,
2939 u8 asRsn)
2940 {
2941 struct sk_buff *skb;
2942 struct ieee80211_disassoc *disass;
2943
2944 skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc));
2945 if (!skb)
2946 return NULL;
2947
2948 disass = skb_put(skb, sizeof(struct ieee80211_disassoc));
2949 disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
2950 disass->header.duration_id = 0;
2951
2952 memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
2953 memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
2954 memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
2955
2956 disass->reason = cpu_to_le16(asRsn);
2957 return skb;
2958 }
2959
2960 void
SendDisassociation(struct ieee80211_device * ieee,u8 * asSta,u8 asRsn)2961 SendDisassociation(struct ieee80211_device *ieee,
2962 u8 *asSta,
2963 u8 asRsn
2964 )
2965 {
2966 struct ieee80211_network *beacon = &ieee->current_network;
2967 struct sk_buff *skb;
2968
2969 skb = ieee80211_disassociate_skb(beacon, ieee, asRsn);
2970 if (skb) {
2971 softmac_mgmt_xmit(skb, ieee);
2972 //dev_kfree_skb_any(skb);//edit by thomas
2973 }
2974 }
2975 EXPORT_SYMBOL(SendDisassociation);
2976
ieee80211_wpa_supplicant_ioctl(struct ieee80211_device * ieee,struct iw_point * p)2977 int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
2978 {
2979 struct ieee_param *param;
2980 int ret = 0;
2981
2982 mutex_lock(&ieee->wx_mutex);
2983 //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
2984
2985 if (p->length < sizeof(struct ieee_param) || !p->pointer) {
2986 ret = -EINVAL;
2987 goto out;
2988 }
2989
2990 param = memdup_user(p->pointer, p->length);
2991 if (IS_ERR(param)) {
2992 ret = PTR_ERR(param);
2993 goto out;
2994 }
2995
2996 switch (param->cmd) {
2997 case IEEE_CMD_SET_WPA_PARAM:
2998 ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
2999 param->u.wpa_param.value);
3000 break;
3001
3002 case IEEE_CMD_SET_WPA_IE:
3003 ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
3004 break;
3005
3006 case IEEE_CMD_SET_ENCRYPTION:
3007 ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
3008 break;
3009
3010 case IEEE_CMD_MLME:
3011 ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
3012 param->u.mlme.reason_code);
3013 break;
3014
3015 default:
3016 printk("Unknown WPA supplicant request: %d\n", param->cmd);
3017 ret = -EOPNOTSUPP;
3018 break;
3019 }
3020
3021 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
3022 ret = -EFAULT;
3023
3024 kfree(param);
3025 out:
3026 mutex_unlock(&ieee->wx_mutex);
3027
3028 return ret;
3029 }
3030 EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
3031
notify_wx_assoc_event(struct ieee80211_device * ieee)3032 void notify_wx_assoc_event(struct ieee80211_device *ieee)
3033 {
3034 union iwreq_data wrqu;
3035
3036 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3037 if (ieee->state == IEEE80211_LINKED)
3038 memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
3039 else
3040 eth_zero_addr(wrqu.ap_addr.sa_data);
3041 wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
3042 }
3043 EXPORT_SYMBOL(notify_wx_assoc_event);
3044