This source file includes following definitions.
- ieee80211_is_54g
- ieee80211_is_shortslot
- ieee80211_MFIE_rate_len
- ieee80211_MFIE_Brate
- ieee80211_MFIE_Grate
- ieee80211_WMM_Info
- ieee80211_TURBO_Info
- enqueue_mgmt
- dequeue_mgmt
- init_mgmt_queue
- MgntQuery_MgntFrameTxRate
- softmac_mgmt_xmit
- softmac_ps_mgmt_xmit
- ieee80211_probe_req
- ieee80211_send_beacon
- ieee80211_send_beacon_cb
- ieee80211_send_probe
- ieee80211_send_probe_requests
- ieee80211_softmac_scan_syncro
- ieee80211_softmac_scan_wq
- ieee80211_beacons_start
- ieee80211_beacons_stop
- ieee80211_stop_send_beacons
- ieee80211_start_send_beacons
- ieee80211_softmac_stop_scan
- ieee80211_stop_scan
- ieee80211_start_scan
- ieee80211_start_scan_syncro
- ieee80211_authentication_req
- ieee80211_probe_resp
- ieee80211_assoc_resp
- ieee80211_auth_resp
- ieee80211_null_func
- ieee80211_resp_to_assoc_rq
- ieee80211_resp_to_auth
- ieee80211_resp_to_probe
- ieee80211_association_req
- ieee80211_associate_abort
- ieee80211_associate_abort_cb
- ieee80211_associate_step1
- ieee80211_auth_challenge
- ieee80211_associate_step2
- ieee80211_associate_complete_wq
- ieee80211_associate_complete
- ieee80211_associate_procedure_wq
- ieee80211_softmac_new_net
- ieee80211_softmac_check_all_nets
- auth_parse
- auth_rq_parse
- probe_rq_parse
- assoc_rq_parse
- assoc_parse
- ieee80211_rx_probe_rq
- ieee80211_rx_auth_rq
- ieee80211_rx_assoc_rq
- ieee80211_sta_ps_send_null_frame
- ieee80211_sta_ps_sleep
- ieee80211_sta_ps
- ieee80211_sta_wakeup
- ieee80211_ps_tx_ack
- ieee80211_process_action
- ieee80211_check_auth_response
- ieee80211_rx_frame_softmac
- ieee80211_softmac_xmit
- ieee80211_resume_tx
- ieee80211_reset_queue
- ieee80211_wake_queue
- ieee80211_stop_queue
- ieee80211_start_master_bss
- ieee80211_start_monitor_mode
- ieee80211_start_ibss_wq
- ieee80211_start_ibss
- ieee80211_start_bss
- ieee80211_disassociate
- ieee80211_associate_retry_wq
- ieee80211_get_beacon_
- ieee80211_get_beacon
- ieee80211_softmac_stop_protocol
- ieee80211_stop_protocol
- ieee80211_softmac_start_protocol
- ieee80211_start_protocol
- ieee80211_softmac_init
- ieee80211_softmac_free
- ieee80211_wpa_enable
- ieee80211_wpa_assoc_frame
- ieee80211_wpa_mlme
- ieee80211_wpa_set_wpa_ie
- ieee80211_wpa_set_auth_algs
- ieee80211_wpa_set_param
- ieee80211_wpa_set_encryption
- ieee80211_disassociate_skb
- SendDisassociation
- ieee80211_wpa_supplicant_ioctl
- notify_wx_assoc_event
1
2
3
4
5
6
7
8
9
10
11
12
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
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
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
37
38
39
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
54
55
56
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
71 *tag_p = tag;
72 }
73
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
92 *tag_p = tag;
93 }
94
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;
100 *tag++ = 7;
101 *tag++ = 0x00;
102 *tag++ = 0x50;
103 *tag++ = 0xf2;
104 *tag++ = 0x02;
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
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;
124 *tag++ = 7;
125 *tag++ = 0x00;
126 *tag++ = 0xe0;
127 *tag++ = 0x4c;
128 *tag++ = 0x01;
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
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
146
147
148
149
150
151 ieee->mgmt_queue_head = nh;
152 ieee->mgmt_queue_ring[nh] = skb;
153
154
155 }
156
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
172 static void init_mgmt_queue(struct ieee80211_device *ieee)
173 {
174 ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
175 }
176
177 static u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee)
178 {
179 PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo;
180 u8 rate;
181
182
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
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
200
201
202
203
204
205
206
207 return rate;
208 }
209
210 void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
211
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
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
244 netif_trans_update(ieee->dev);
245 ieee->softmac_data_hard_start_xmit(skb, ieee->dev, ieee->basic_rate);
246
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
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
266
267
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
274 }
275 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
276 }
277 }
278
279 static inline void
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
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
308 }
309
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;
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
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
357 skb = ieee80211_get_beacon_(ieee);
358
359 if (skb) {
360 softmac_mgmt_xmit(skb, ieee);
361 ieee->softmac_stats.tx_beacons++;
362
363 }
364
365
366
367
368 if (ieee->beacon_txing && ieee->ieee_up) {
369
370
371 mod_timer(&ieee->beacon_timer,
372 jiffies + msecs_to_jiffies(ieee->current_network.beacon_interval - 5));
373 }
374
375 }
376
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
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
397 }
398 }
399
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
409
410
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;
424 } while (!channel_map[ch]);
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
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
452
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
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
488 if (!channel_map[ieee->current_network.channel]) {
489 ieee->current_network.channel = 6;
490 goto out;
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
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
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
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
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
554 static void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
555 {
556
557
558
559
560 mutex_lock(&ieee->scan_mutex);
561
562
563 if (ieee->scanning == 1) {
564 ieee->scanning = 0;
565
566 cancel_delayed_work(&ieee->softmac_scan_wq);
567 }
568
569
570 mutex_unlock(&ieee->scan_mutex);
571 }
572
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
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
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 *
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
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;
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
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
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
713 beacon_size = sizeof(struct ieee80211_probe_response) + 2
714 + ssid_len
715 + 3
716 + rate_len
717 + rate_ex_len
718 + atim_len
719 + erp_len
720 + wpa_ie_len
721
722
723
724
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;
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);
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
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
799 return skb;
800 }
801
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
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
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
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
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
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 *
935 ieee80211_association_req(struct ieee80211_network *beacon,
936 struct ieee80211_device *ieee)
937 {
938 struct sk_buff *skb;
939
940
941 struct ieee80211_assoc_request_frame *hdr;
942 u8 *tag;
943
944
945
946
947
948
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
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
997 + rate_len
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
1010 + rate_len
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);
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);
1043
1044 if (ieee->short_slot)
1045 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
1046 if (wmm_info_len)
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
1061 if (beacon->bCkipSupported) {
1062 static u8 AironetIeOui[] = {0x00, 0x01, 0x66};
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
1071
1072
1073 memcpy(osCcxAironetIE.octet, AironetIeOui, sizeof(AironetIeOui));
1074
1075
1076
1077
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
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
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
1154
1155 return skb;
1156 }
1157
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
1166
1167
1168
1169
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
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
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
1211 if (!timer_pending(&ieee->associate_timer)) {
1212 ieee->associate_timer.expires = jiffies + (HZ / 2);
1213 add_timer(&ieee->associate_timer);
1214 }
1215
1216 }
1217 }
1218
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
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
1247 }
1248 kfree(challenge);
1249 }
1250
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
1268 }
1269 }
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
1289 }
1290 ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval / 500);
1291
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
1310 static void ieee80211_associate_complete(struct ieee80211_device *ieee)
1311 {
1312
1313
1314 del_timer_sync(&ieee->associate_timer);
1315
1316 ieee->state = IEEE80211_LINKED;
1317
1318 schedule_work(&ieee->associate_complete_wq);
1319 }
1320
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
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
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
1349
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
1362
1363
1364
1365 apset = ieee->wap_set;
1366 ssidset = ieee->ssid_set;
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
1373
1374
1375
1376
1377 if ((apset && apmatch &&
1378 ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset))) ||
1379
1380
1381
1382 (!apset && ssidset && ssidbroad && ssidmatch)) {
1383
1384
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
1402 HTResetIOTSetting(ieee->pHTInfo);
1403 if (ieee->iw_mode == IW_MODE_INFRA) {
1404
1405 ieee->AsocRetryCount = 0;
1406
1407 if ((ieee->current_network.qos_data.supported == 1) &&
1408
1409 ieee->current_network.bssht.bdSupportHT) {
1410
1411
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
1432 ieee->state = IEEE80211_LINKED;
1433 }
1434 }
1435 }
1436 }
1437
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
1447
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
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
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
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;
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++;
1528 tag = tag + *(tag);
1529 tag++;
1530 }
1531
1532
1533 if (ssidlen == 0)
1534 return 1;
1535
1536 if (!ssid)
1537 return 1;
1538
1539 return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
1540 }
1541
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
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
1587 ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1588 {
1589 u8 dest[ETH_ALEN];
1590
1591
1592 ieee->softmac_stats.rx_probe_rq++;
1593
1594 if (probe_rq_parse(ieee, skb, dest)) {
1595
1596 ieee->softmac_stats.tx_probe_rs++;
1597 ieee80211_resp_to_probe(ieee, dest);
1598 }
1599 }
1600
1601 static inline void
1602 ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1603 {
1604 u8 dest[ETH_ALEN];
1605 int status;
1606
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
1613 }
1614
1615 static inline void
1616 ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
1617 {
1618 u8 dest[ETH_ALEN];
1619
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
1627 }
1628
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
1638
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
1645
1646
1647
1648
1649
1650 dtim = ieee->current_network.dtim_data;
1651 if (!(dtim & IEEE80211_DTIM_VALID))
1652 return 0;
1653 timeout = ieee->current_network.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
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
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
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
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
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
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
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
1772 if (success) {
1773 ieee->sta_sleep = 1;
1774 ieee->enter_sleep_state(ieee->dev, ieee->ps_th, ieee->ps_tl);
1775 }
1776
1777
1778
1779 } else {
1780
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
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
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
1819 static void ieee80211_check_auth_response(struct ieee80211_device *ieee,
1820 struct sk_buff *skb)
1821 {
1822
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
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
1851 if (bSupportNmode) {
1852
1853 ieee->SetWirelessMode(ieee->dev,
1854 ieee->current_network.mode);
1855 } else {
1856
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
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
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
1918
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
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
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
1981
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
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
2003 return 0;
2004 }
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
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
2034 ieee80211_sta_wakeup(ieee, 0);
2035
2036
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
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
2053
2054
2055
2056
2057
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
2067
2068
2069 }
2070 }
2071 ieee80211_txb_free(txb);
2072
2073
2074 spin_unlock_irqrestore(&ieee->lock, flags);
2075 }
2076 EXPORT_SYMBOL(ieee80211_softmac_xmit);
2077
2078
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
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
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
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
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
2153 void ieee80211_stop_queue(struct ieee80211_device *ieee)
2154 {
2155
2156
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
2164 }
2165 EXPORT_SYMBOL(ieee80211_stop_queue);
2166
2167
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
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 }
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
2208
2209
2210
2211
2212
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
2227 ieee80211_softmac_check_all_nets(ieee);
2228
2229
2230 if (ieee->state == IEEE80211_NOLINK)
2231 ieee->current_network.channel = 6;
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246 if (ieee->state == IEEE80211_NOLINK)
2247 ieee80211_start_scan_syncro(ieee);
2248
2249
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
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
2308 inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
2309 {
2310 schedule_delayed_work(&ieee->start_ibss_wq, 150);
2311 }
2312
2313
2314 void ieee80211_start_bss(struct ieee80211_device *ieee)
2315 {
2316 unsigned long flags;
2317
2318
2319
2320
2321 if (IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee)) {
2322 if (!ieee->bGlobalDomain)
2323 return;
2324 }
2325
2326
2327
2328
2329
2330 ieee80211_softmac_check_all_nets(ieee);
2331
2332
2333
2334
2335
2336
2337
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
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
2363 notify_wx_assoc_event(ieee);
2364 }
2365 EXPORT_SYMBOL(ieee80211_disassociate);
2366
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
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
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
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
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
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
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);
2471 }
2472
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
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;
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
2504
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;
2513
2514
2515
2516
2517
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"
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
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;
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;
2563 ieee->Regdot11HTOperationalRateSet[1] = 0xff;
2564 ieee->Regdot11HTOperationalRateSet[4] = 0x01;
2565
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
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
2615
2616
2617 static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
2618 {
2619
2620
2621 printk("%s WPA\n", value ? "enabling" : "disabling");
2622 ieee->wpa_enabled = value;
2623 return 0;
2624 }
2625
2626 static void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee,
2627 char *wpa_ie, int wpa_ie_len)
2628 {
2629
2630 ieee80211_wpa_enable(ieee, 1);
2631
2632 ieee80211_disassociate(ieee);
2633 }
2634
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
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
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
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
2709
2710
2711 return 0;
2712 }
2713
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
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740 struct ieee80211_security sec = {
2741 .flags = SEC_ENABLED,
2742 .enabled = value,
2743 };
2744 ieee->drop_unencrypted = value;
2745
2746
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
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
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
2823
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
2832
2833 sec.flags |= SEC_ENABLED;
2834
2835
2836 if (!(ieee->host_encrypt || ieee->host_decrypt) &&
2837 strcmp(param->u.crypt.alg, "TKIP"))
2838 goto skip_host_crypt;
2839
2840
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
2921
2922
2923
2924
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
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
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
2973 }
2974 }
2975 EXPORT_SYMBOL(SendDisassociation);
2976
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
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
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);