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 rtllib
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 "rtllib.h"
15
16 #include <linux/random.h>
17 #include <linux/delay.h>
18 #include <linux/uaccess.h>
19 #include <linux/etherdevice.h>
20 #include <linux/ieee80211.h>
21 #include "dot11d.h"
22
23 static void rtllib_sta_wakeup(struct rtllib_device *ieee, short nl);
24
rtllib_is_54g(struct rtllib_network * net)25 static short rtllib_is_54g(struct rtllib_network *net)
26 {
27 return (net->rates_ex_len > 0) || (net->rates_len > 4);
28 }
29
30 /* returns the total length needed for placing the RATE MFIE
31 * tag and the EXTENDED RATE MFIE tag if needed.
32 * It encludes two bytes per tag for the tag itself and its len
33 */
rtllib_MFIE_rate_len(struct rtllib_device * ieee)34 static unsigned int rtllib_MFIE_rate_len(struct rtllib_device *ieee)
35 {
36 unsigned int rate_len = 0;
37
38 rate_len = RTLLIB_CCK_RATE_LEN + 2;
39 rate_len += RTLLIB_OFDM_RATE_LEN + 2;
40
41 return rate_len;
42 }
43
44 /* place the MFIE rate, tag to the memory (double) pointed.
45 * Then it updates the pointer so that
46 * it points after the new MFIE tag added.
47 */
rtllib_MFIE_Brate(struct rtllib_device * ieee,u8 ** tag_p)48 static void rtllib_MFIE_Brate(struct rtllib_device *ieee, u8 **tag_p)
49 {
50 u8 *tag = *tag_p;
51
52 *tag++ = MFIE_TYPE_RATES;
53 *tag++ = 4;
54 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_1MB;
55 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_2MB;
56 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_5MB;
57 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_11MB;
58
59 /* We may add an option for custom rates that specific HW
60 * might support
61 */
62 *tag_p = tag;
63 }
64
rtllib_MFIE_Grate(struct rtllib_device * ieee,u8 ** tag_p)65 static void rtllib_MFIE_Grate(struct rtllib_device *ieee, u8 **tag_p)
66 {
67 u8 *tag = *tag_p;
68
69 *tag++ = MFIE_TYPE_RATES_EX;
70 *tag++ = 8;
71 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_6MB;
72 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_9MB;
73 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_12MB;
74 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_18MB;
75 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_24MB;
76 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_36MB;
77 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_48MB;
78 *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_54MB;
79
80 /* We may add an option for custom rates that specific HW might
81 * support
82 */
83 *tag_p = tag;
84 }
85
rtllib_WMM_Info(struct rtllib_device * ieee,u8 ** tag_p)86 static void rtllib_WMM_Info(struct rtllib_device *ieee, u8 **tag_p)
87 {
88 u8 *tag = *tag_p;
89
90 *tag++ = MFIE_TYPE_GENERIC;
91 *tag++ = 7;
92 *tag++ = 0x00;
93 *tag++ = 0x50;
94 *tag++ = 0xf2;
95 *tag++ = 0x02;
96 *tag++ = 0x00;
97 *tag++ = 0x01;
98 *tag++ = MAX_SP_Len;
99 *tag_p = tag;
100 }
101
rtllib_TURBO_Info(struct rtllib_device * ieee,u8 ** tag_p)102 static void rtllib_TURBO_Info(struct rtllib_device *ieee, u8 **tag_p)
103 {
104 u8 *tag = *tag_p;
105
106 *tag++ = MFIE_TYPE_GENERIC;
107 *tag++ = 7;
108 *tag++ = 0x00;
109 *tag++ = 0xe0;
110 *tag++ = 0x4c;
111 *tag++ = 0x01;
112 *tag++ = 0x02;
113 *tag++ = 0x11;
114 *tag++ = 0x00;
115
116 *tag_p = tag;
117 netdev_alert(ieee->dev, "This is enable turbo mode IE process\n");
118 }
119
enqueue_mgmt(struct rtllib_device * ieee,struct sk_buff * skb)120 static void enqueue_mgmt(struct rtllib_device *ieee, struct sk_buff *skb)
121 {
122 int nh;
123
124 nh = (ieee->mgmt_queue_head + 1) % MGMT_QUEUE_NUM;
125
126 /* if the queue is full but we have newer frames then
127 * just overwrites the oldest.
128 *
129 * if (nh == ieee->mgmt_queue_tail)
130 * return -1;
131 */
132 ieee->mgmt_queue_head = nh;
133 ieee->mgmt_queue_ring[nh] = skb;
134 }
135
init_mgmt_queue(struct rtllib_device * ieee)136 static void init_mgmt_queue(struct rtllib_device *ieee)
137 {
138 ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
139 }
140
MgntQuery_TxRateExcludeCCKRates(struct rtllib_device * ieee)141 u8 MgntQuery_TxRateExcludeCCKRates(struct rtllib_device *ieee)
142 {
143 u16 i;
144 u8 QueryRate = 0;
145 u8 BasicRate;
146
147 for (i = 0; i < ieee->current_network.rates_len; i++) {
148 BasicRate = ieee->current_network.rates[i] & 0x7F;
149 if (!rtllib_is_cck_rate(BasicRate)) {
150 if (QueryRate == 0) {
151 QueryRate = BasicRate;
152 } else {
153 if (BasicRate < QueryRate)
154 QueryRate = BasicRate;
155 }
156 }
157 }
158
159 if (QueryRate == 0) {
160 QueryRate = 12;
161 netdev_info(ieee->dev, "No BasicRate found!!\n");
162 }
163 return QueryRate;
164 }
165
MgntQuery_MgntFrameTxRate(struct rtllib_device * ieee)166 static u8 MgntQuery_MgntFrameTxRate(struct rtllib_device *ieee)
167 {
168 struct rt_hi_throughput *ht_info = ieee->ht_info;
169 u8 rate;
170
171 if (ht_info->iot_action & HT_IOT_ACT_MGNT_USE_CCK_6M)
172 rate = 0x0c;
173 else
174 rate = ieee->basic_rate & 0x7f;
175
176 if (rate == 0) {
177 if (ieee->mode == WIRELESS_MODE_N_24G && !ht_info->bCurSuppCCK)
178 rate = 0x0c;
179 else
180 rate = 0x02;
181 }
182
183 return rate;
184 }
185
softmac_mgmt_xmit(struct sk_buff * skb,struct rtllib_device * ieee)186 inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee)
187 {
188 unsigned long flags;
189 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
190 struct rtllib_hdr_3addr *header =
191 (struct rtllib_hdr_3addr *)skb->data;
192
193 struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8);
194
195 spin_lock_irqsave(&ieee->lock, flags);
196
197 /* called with 2nd param 0, no mgmt lock required */
198 rtllib_sta_wakeup(ieee, 0);
199
200 if (le16_to_cpu(header->frame_ctl) == RTLLIB_STYPE_BEACON)
201 tcb_desc->queue_index = BEACON_QUEUE;
202 else
203 tcb_desc->queue_index = MGNT_QUEUE;
204
205 if (ieee->disable_mgnt_queue)
206 tcb_desc->queue_index = HIGH_QUEUE;
207
208 tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
209 tcb_desc->ratr_index = 7;
210 tcb_desc->tx_dis_rate_fallback = 1;
211 tcb_desc->tx_use_drv_assinged_rate = 1;
212 if (single) {
213 if (ieee->queue_stop) {
214 enqueue_mgmt(ieee, skb);
215 } else {
216 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
217
218 if (ieee->seq_ctrl[0] == 0xFFF)
219 ieee->seq_ctrl[0] = 0;
220 else
221 ieee->seq_ctrl[0]++;
222
223 /* avoid watchdog triggers */
224 ieee->softmac_data_hard_start_xmit(skb, ieee->dev,
225 ieee->basic_rate);
226 }
227
228 spin_unlock_irqrestore(&ieee->lock, flags);
229 } else {
230 spin_unlock_irqrestore(&ieee->lock, flags);
231 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
232
233 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
234
235 if (ieee->seq_ctrl[0] == 0xFFF)
236 ieee->seq_ctrl[0] = 0;
237 else
238 ieee->seq_ctrl[0]++;
239
240 /* check whether the managed packet queued greater than 5 */
241 if (!ieee->check_nic_enough_desc(ieee->dev,
242 tcb_desc->queue_index) ||
243 skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) ||
244 ieee->queue_stop) {
245 /* insert the skb packet to the management queue
246 *
247 * as for the completion function, it does not need
248 * to check it any more.
249 */
250 netdev_info(ieee->dev,
251 "%s():insert to waitqueue, queue_index:%d!\n",
252 __func__, tcb_desc->queue_index);
253 skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index],
254 skb);
255 } else {
256 ieee->softmac_hard_start_xmit(skb, ieee->dev);
257 }
258 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
259 }
260 }
261
262 static inline void
softmac_ps_mgmt_xmit(struct sk_buff * skb,struct rtllib_device * ieee)263 softmac_ps_mgmt_xmit(struct sk_buff *skb,
264 struct rtllib_device *ieee)
265 {
266 short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
267 struct rtllib_hdr_3addr *header =
268 (struct rtllib_hdr_3addr *)skb->data;
269 u16 fc, type, stype;
270 struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8);
271
272 fc = le16_to_cpu(header->frame_ctl);
273 type = WLAN_FC_GET_TYPE(fc);
274 stype = WLAN_FC_GET_STYPE(fc);
275
276 if (stype != RTLLIB_STYPE_PSPOLL)
277 tcb_desc->queue_index = MGNT_QUEUE;
278 else
279 tcb_desc->queue_index = HIGH_QUEUE;
280
281 if (ieee->disable_mgnt_queue)
282 tcb_desc->queue_index = HIGH_QUEUE;
283
284 tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee);
285 tcb_desc->ratr_index = 7;
286 tcb_desc->tx_dis_rate_fallback = 1;
287 tcb_desc->tx_use_drv_assinged_rate = 1;
288 if (single) {
289 if (type != RTLLIB_FTYPE_CTL) {
290 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
291
292 if (ieee->seq_ctrl[0] == 0xFFF)
293 ieee->seq_ctrl[0] = 0;
294 else
295 ieee->seq_ctrl[0]++;
296 }
297 /* avoid watchdog triggers */
298 ieee->softmac_data_hard_start_xmit(skb, ieee->dev,
299 ieee->basic_rate);
300
301 } else {
302 if (type != RTLLIB_FTYPE_CTL) {
303 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
304
305 if (ieee->seq_ctrl[0] == 0xFFF)
306 ieee->seq_ctrl[0] = 0;
307 else
308 ieee->seq_ctrl[0]++;
309 }
310 ieee->softmac_hard_start_xmit(skb, ieee->dev);
311 }
312 }
313
rtllib_probe_req(struct rtllib_device * ieee)314 static inline struct sk_buff *rtllib_probe_req(struct rtllib_device *ieee)
315 {
316 unsigned int len, rate_len;
317 u8 *tag;
318 struct sk_buff *skb;
319 struct rtllib_probe_request *req;
320
321 len = ieee->current_network.ssid_len;
322
323 rate_len = rtllib_MFIE_rate_len(ieee);
324
325 skb = dev_alloc_skb(sizeof(struct rtllib_probe_request) +
326 2 + len + rate_len + ieee->tx_headroom);
327
328 if (!skb)
329 return NULL;
330
331 skb_reserve(skb, ieee->tx_headroom);
332
333 req = skb_put(skb, sizeof(struct rtllib_probe_request));
334 req->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_PROBE_REQ);
335 req->header.duration_id = 0;
336
337 eth_broadcast_addr(req->header.addr1);
338 ether_addr_copy(req->header.addr2, ieee->dev->dev_addr);
339 eth_broadcast_addr(req->header.addr3);
340
341 tag = skb_put(skb, len + 2 + rate_len);
342
343 *tag++ = MFIE_TYPE_SSID;
344 *tag++ = len;
345 memcpy(tag, ieee->current_network.ssid, len);
346 tag += len;
347
348 rtllib_MFIE_Brate(ieee, &tag);
349 rtllib_MFIE_Grate(ieee, &tag);
350
351 return skb;
352 }
353
354 static struct sk_buff *rtllib_get_beacon_(struct rtllib_device *ieee);
355
rtllib_send_beacon(struct rtllib_device * ieee)356 static void rtllib_send_beacon(struct rtllib_device *ieee)
357 {
358 struct sk_buff *skb;
359
360 if (!ieee->ieee_up)
361 return;
362 skb = rtllib_get_beacon_(ieee);
363
364 if (skb) {
365 softmac_mgmt_xmit(skb, ieee);
366 ieee->softmac_stats.tx_beacons++;
367 }
368
369 if (ieee->beacon_txing && ieee->ieee_up)
370 mod_timer(&ieee->beacon_timer, jiffies +
371 (msecs_to_jiffies(ieee->current_network.beacon_interval - 5)));
372 }
373
rtllib_send_beacon_cb(struct timer_list * t)374 static void rtllib_send_beacon_cb(struct timer_list *t)
375 {
376 struct rtllib_device *ieee =
377 from_timer(ieee, t, beacon_timer);
378 unsigned long flags;
379
380 spin_lock_irqsave(&ieee->beacon_lock, flags);
381 rtllib_send_beacon(ieee);
382 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
383 }
384
385 /* Enables network monitor mode, all rx packets will be received. */
rtllib_EnableNetMonitorMode(struct net_device * dev,bool bInitState)386 void rtllib_EnableNetMonitorMode(struct net_device *dev,
387 bool bInitState)
388 {
389 struct rtllib_device *ieee = netdev_priv_rsl(dev);
390
391 netdev_info(dev, "========>Enter Monitor Mode\n");
392
393 ieee->AllowAllDestAddrHandler(dev, true, !bInitState);
394 }
395
396 /* Disables network monitor mode. Only packets destinated to
397 * us will be received.
398 */
rtllib_DisableNetMonitorMode(struct net_device * dev,bool bInitState)399 void rtllib_DisableNetMonitorMode(struct net_device *dev,
400 bool bInitState)
401 {
402 struct rtllib_device *ieee = netdev_priv_rsl(dev);
403
404 netdev_info(dev, "========>Exit Monitor Mode\n");
405
406 ieee->AllowAllDestAddrHandler(dev, false, !bInitState);
407 }
408
409 /* Enables the specialized promiscuous mode required by Intel.
410 * In this mode, Intel intends to hear traffics from/to other STAs in the
411 * same BSS. Therefore we don't have to disable checking BSSID and we only need
412 * to allow all dest. BUT: if we enable checking BSSID then we can't recv
413 * packets from other STA.
414 */
rtllib_EnableIntelPromiscuousMode(struct net_device * dev,bool bInitState)415 void rtllib_EnableIntelPromiscuousMode(struct net_device *dev,
416 bool bInitState)
417 {
418 bool bFilterOutNonAssociatedBSSID = false;
419
420 struct rtllib_device *ieee = netdev_priv_rsl(dev);
421
422 netdev_info(dev, "========>Enter Intel Promiscuous Mode\n");
423
424 ieee->AllowAllDestAddrHandler(dev, true, !bInitState);
425 ieee->SetHwRegHandler(dev, HW_VAR_CECHK_BSSID,
426 (u8 *)&bFilterOutNonAssociatedBSSID);
427
428 ieee->net_promiscuous_md = true;
429 }
430 EXPORT_SYMBOL(rtllib_EnableIntelPromiscuousMode);
431
432 /* Disables the specialized promiscuous mode required by Intel.
433 * See MgntEnableIntelPromiscuousMode for detail.
434 */
rtllib_DisableIntelPromiscuousMode(struct net_device * dev,bool bInitState)435 void rtllib_DisableIntelPromiscuousMode(struct net_device *dev,
436 bool bInitState)
437 {
438 bool bFilterOutNonAssociatedBSSID = true;
439
440 struct rtllib_device *ieee = netdev_priv_rsl(dev);
441
442 netdev_info(dev, "========>Exit Intel Promiscuous Mode\n");
443
444 ieee->AllowAllDestAddrHandler(dev, false, !bInitState);
445 ieee->SetHwRegHandler(dev, HW_VAR_CECHK_BSSID,
446 (u8 *)&bFilterOutNonAssociatedBSSID);
447
448 ieee->net_promiscuous_md = false;
449 }
450 EXPORT_SYMBOL(rtllib_DisableIntelPromiscuousMode);
451
rtllib_send_probe(struct rtllib_device * ieee)452 static void rtllib_send_probe(struct rtllib_device *ieee)
453 {
454 struct sk_buff *skb;
455
456 skb = rtllib_probe_req(ieee);
457 if (skb) {
458 softmac_mgmt_xmit(skb, ieee);
459 ieee->softmac_stats.tx_probe_rq++;
460 }
461 }
462
rtllib_send_probe_requests(struct rtllib_device * ieee)463 static void rtllib_send_probe_requests(struct rtllib_device *ieee)
464 {
465 if (ieee->active_scan && (ieee->softmac_features &
466 IEEE_SOFTMAC_PROBERQ)) {
467 rtllib_send_probe(ieee);
468 rtllib_send_probe(ieee);
469 }
470 }
471
rtllib_update_active_chan_map(struct rtllib_device * ieee)472 static void rtllib_update_active_chan_map(struct rtllib_device *ieee)
473 {
474 memcpy(ieee->active_channel_map, GET_DOT11D_INFO(ieee)->channel_map,
475 MAX_CHANNEL_NUMBER + 1);
476 }
477
478 /* this performs syncro scan blocking the caller until all channels
479 * in the allowed channel map has been checked.
480 */
rtllib_softmac_scan_syncro(struct rtllib_device * ieee)481 static void rtllib_softmac_scan_syncro(struct rtllib_device *ieee)
482 {
483 union iwreq_data wrqu;
484 short ch = 0;
485
486 rtllib_update_active_chan_map(ieee);
487
488 ieee->be_scan_inprogress = true;
489
490 mutex_lock(&ieee->scan_mutex);
491
492 while (1) {
493 do {
494 ch++;
495 if (ch > MAX_CHANNEL_NUMBER)
496 goto out; /* scan completed */
497 } while (!ieee->active_channel_map[ch]);
498
499 /* this function can be called in two situations
500 * 1- We have switched to ad-hoc mode and we are
501 * performing a complete syncro scan before conclude
502 * there are no interesting cell and to create a
503 * new one. In this case the link state is
504 * MAC80211_NOLINK until we found an interesting cell.
505 * If so the ieee8021_new_net, called by the RX path
506 * will set the state to MAC80211_LINKED, so we stop
507 * scanning
508 * 2- We are linked and the root uses run iwlist scan.
509 * So we switch to MAC80211_LINKED_SCANNING to remember
510 * that we are still logically linked (not interested in
511 * new network events, despite for updating the net list,
512 * but we are temporarly 'unlinked' as the driver shall
513 * not filter RX frames and the channel is changing.
514 * So the only situation in which are interested is to check
515 * if the state become LINKED because of the #1 situation
516 */
517
518 if (ieee->link_state == MAC80211_LINKED)
519 goto out;
520 if (ieee->sync_scan_hurryup) {
521 netdev_info(ieee->dev,
522 "============>sync_scan_hurryup out\n");
523 goto out;
524 }
525
526 ieee->set_chan(ieee->dev, ch);
527 if (ieee->active_channel_map[ch] == 1)
528 rtllib_send_probe_requests(ieee);
529
530 /* this prevent excessive time wait when we
531 * need to wait for a syncro scan to end..
532 */
533 msleep_interruptible_rsl(RTLLIB_SOFTMAC_SCAN_TIME);
534 }
535 out:
536 ieee->actscanning = false;
537 ieee->sync_scan_hurryup = 0;
538
539 if (ieee->link_state >= MAC80211_LINKED) {
540 if (IS_DOT11D_ENABLE(ieee))
541 dot11d_scan_complete(ieee);
542 }
543 mutex_unlock(&ieee->scan_mutex);
544
545 ieee->be_scan_inprogress = false;
546
547 memset(&wrqu, 0, sizeof(wrqu));
548 wireless_send_event(ieee->dev, SIOCGIWSCAN, &wrqu, NULL);
549 }
550
rtllib_softmac_scan_wq(void * data)551 static void rtllib_softmac_scan_wq(void *data)
552 {
553 struct rtllib_device *ieee = container_of_dwork_rsl(data,
554 struct rtllib_device, softmac_scan_wq);
555 u8 last_channel = ieee->current_network.channel;
556
557 rtllib_update_active_chan_map(ieee);
558
559 if (!ieee->ieee_up)
560 return;
561 if (rtllib_act_scanning(ieee, true))
562 return;
563
564 mutex_lock(&ieee->scan_mutex);
565
566 if (ieee->rf_power_state == rf_off) {
567 netdev_info(ieee->dev,
568 "======>%s():rf state is rf_off, return\n",
569 __func__);
570 goto out1;
571 }
572
573 do {
574 ieee->current_network.channel =
575 (ieee->current_network.channel + 1) %
576 MAX_CHANNEL_NUMBER;
577 if (ieee->scan_watch_dog++ > MAX_CHANNEL_NUMBER) {
578 if (!ieee->active_channel_map[ieee->current_network.channel])
579 ieee->current_network.channel = 6;
580 goto out; /* no good chans */
581 }
582 } while (!ieee->active_channel_map[ieee->current_network.channel]);
583
584 if (ieee->scanning_continue == 0)
585 goto out;
586
587 ieee->set_chan(ieee->dev, ieee->current_network.channel);
588
589 if (ieee->active_channel_map[ieee->current_network.channel] == 1)
590 rtllib_send_probe_requests(ieee);
591
592 schedule_delayed_work(&ieee->softmac_scan_wq,
593 msecs_to_jiffies(RTLLIB_SOFTMAC_SCAN_TIME));
594
595 mutex_unlock(&ieee->scan_mutex);
596 return;
597
598 out:
599 if (IS_DOT11D_ENABLE(ieee))
600 dot11d_scan_complete(ieee);
601 ieee->current_network.channel = last_channel;
602
603 out1:
604 ieee->actscanning = false;
605 ieee->scan_watch_dog = 0;
606 ieee->scanning_continue = 0;
607 mutex_unlock(&ieee->scan_mutex);
608 }
609
rtllib_beacons_start(struct rtllib_device * ieee)610 static void rtllib_beacons_start(struct rtllib_device *ieee)
611 {
612 unsigned long flags;
613
614 spin_lock_irqsave(&ieee->beacon_lock, flags);
615
616 ieee->beacon_txing = 1;
617 rtllib_send_beacon(ieee);
618
619 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
620 }
621
rtllib_beacons_stop(struct rtllib_device * ieee)622 static void rtllib_beacons_stop(struct rtllib_device *ieee)
623 {
624 unsigned long flags;
625
626 spin_lock_irqsave(&ieee->beacon_lock, flags);
627
628 ieee->beacon_txing = 0;
629
630 spin_unlock_irqrestore(&ieee->beacon_lock, flags);
631 del_timer_sync(&ieee->beacon_timer);
632 }
633
rtllib_stop_send_beacons(struct rtllib_device * ieee)634 void rtllib_stop_send_beacons(struct rtllib_device *ieee)
635 {
636 ieee->stop_send_beacons(ieee->dev);
637 if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
638 rtllib_beacons_stop(ieee);
639 }
640 EXPORT_SYMBOL(rtllib_stop_send_beacons);
641
rtllib_start_send_beacons(struct rtllib_device * ieee)642 void rtllib_start_send_beacons(struct rtllib_device *ieee)
643 {
644 ieee->start_send_beacons(ieee->dev);
645 if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
646 rtllib_beacons_start(ieee);
647 }
648 EXPORT_SYMBOL(rtllib_start_send_beacons);
649
rtllib_softmac_stop_scan(struct rtllib_device * ieee)650 static void rtllib_softmac_stop_scan(struct rtllib_device *ieee)
651 {
652 mutex_lock(&ieee->scan_mutex);
653 ieee->scan_watch_dog = 0;
654 if (ieee->scanning_continue == 1) {
655 ieee->scanning_continue = 0;
656 ieee->actscanning = false;
657 mutex_unlock(&ieee->scan_mutex);
658 cancel_delayed_work_sync(&ieee->softmac_scan_wq);
659 } else {
660 mutex_unlock(&ieee->scan_mutex);
661 }
662 }
663
rtllib_stop_scan(struct rtllib_device * ieee)664 void rtllib_stop_scan(struct rtllib_device *ieee)
665 {
666 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
667 rtllib_softmac_stop_scan(ieee);
668 }
669 EXPORT_SYMBOL(rtllib_stop_scan);
670
rtllib_stop_scan_syncro(struct rtllib_device * ieee)671 void rtllib_stop_scan_syncro(struct rtllib_device *ieee)
672 {
673 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
674 ieee->sync_scan_hurryup = 1;
675 }
676 EXPORT_SYMBOL(rtllib_stop_scan_syncro);
677
rtllib_act_scanning(struct rtllib_device * ieee,bool sync_scan)678 bool rtllib_act_scanning(struct rtllib_device *ieee, bool sync_scan)
679 {
680 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) {
681 if (sync_scan)
682 return ieee->be_scan_inprogress;
683 else
684 return ieee->actscanning || ieee->be_scan_inprogress;
685 } else {
686 return test_bit(STATUS_SCANNING, &ieee->status);
687 }
688 }
689 EXPORT_SYMBOL(rtllib_act_scanning);
690
691 /* called with ieee->lock held */
rtllib_start_scan(struct rtllib_device * ieee)692 static void rtllib_start_scan(struct rtllib_device *ieee)
693 {
694 ieee->rtllib_ips_leave_wq(ieee->dev);
695
696 if (IS_DOT11D_ENABLE(ieee)) {
697 if (IS_COUNTRY_IE_VALID(ieee))
698 RESET_CIE_WATCHDOG(ieee);
699 }
700 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) {
701 if (ieee->scanning_continue == 0) {
702 ieee->actscanning = true;
703 ieee->scanning_continue = 1;
704 schedule_delayed_work(&ieee->softmac_scan_wq, 0);
705 }
706 }
707 }
708
709 /* called with wx_mutex held */
rtllib_start_scan_syncro(struct rtllib_device * ieee)710 void rtllib_start_scan_syncro(struct rtllib_device *ieee)
711 {
712 if (IS_DOT11D_ENABLE(ieee)) {
713 if (IS_COUNTRY_IE_VALID(ieee))
714 RESET_CIE_WATCHDOG(ieee);
715 }
716 ieee->sync_scan_hurryup = 0;
717 if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
718 rtllib_softmac_scan_syncro(ieee);
719 }
720 EXPORT_SYMBOL(rtllib_start_scan_syncro);
721
722 static inline struct sk_buff *
rtllib_authentication_req(struct rtllib_network * beacon,struct rtllib_device * ieee,int challengelen,u8 * daddr)723 rtllib_authentication_req(struct rtllib_network *beacon,
724 struct rtllib_device *ieee,
725 int challengelen, u8 *daddr)
726 {
727 struct sk_buff *skb;
728 struct rtllib_authentication *auth;
729 int len;
730
731 len = sizeof(struct rtllib_authentication) + challengelen +
732 ieee->tx_headroom + 4;
733 skb = dev_alloc_skb(len);
734
735 if (!skb)
736 return NULL;
737
738 skb_reserve(skb, ieee->tx_headroom);
739
740 auth = skb_put(skb, sizeof(struct rtllib_authentication));
741
742 auth->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_AUTH);
743 if (challengelen)
744 auth->header.frame_ctl |= cpu_to_le16(RTLLIB_FCTL_WEP);
745
746 auth->header.duration_id = cpu_to_le16(0x013a);
747 ether_addr_copy(auth->header.addr1, beacon->bssid);
748 ether_addr_copy(auth->header.addr2, ieee->dev->dev_addr);
749 ether_addr_copy(auth->header.addr3, beacon->bssid);
750 if (ieee->auth_mode == 0)
751 auth->algorithm = WLAN_AUTH_OPEN;
752 else if (ieee->auth_mode == 1)
753 auth->algorithm = cpu_to_le16(WLAN_AUTH_SHARED_KEY);
754 else if (ieee->auth_mode == 2)
755 auth->algorithm = WLAN_AUTH_OPEN;
756 auth->transaction = cpu_to_le16(ieee->associate_seq);
757 ieee->associate_seq++;
758
759 auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
760
761 return skb;
762 }
763
rtllib_probe_resp(struct rtllib_device * ieee,const u8 * dest)764 static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee,
765 const u8 *dest)
766 {
767 u8 *tag;
768 int beacon_size;
769 struct rtllib_probe_response *beacon_buf;
770 struct sk_buff *skb = NULL;
771 int encrypt;
772 int atim_len, erp_len;
773 struct lib80211_crypt_data *crypt;
774
775 char *ssid = ieee->current_network.ssid;
776 int ssid_len = ieee->current_network.ssid_len;
777 int rate_len = ieee->current_network.rates_len + 2;
778 int rate_ex_len = ieee->current_network.rates_ex_len;
779 int wpa_ie_len = ieee->wpa_ie_len;
780 u8 erpinfo_content = 0;
781
782 u8 *tmp_ht_cap_buf = NULL;
783 u8 tmp_ht_cap_len = 0;
784 u8 *tmp_ht_info_buf = NULL;
785 u8 tmp_ht_info_len = 0;
786 struct rt_hi_throughput *ht_info = ieee->ht_info;
787 u8 *tmp_generic_ie_buf = NULL;
788 u8 tmp_generic_ie_len = 0;
789
790 if (rate_ex_len > 0)
791 rate_ex_len += 2;
792
793 if (ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
794 atim_len = 4;
795 else
796 atim_len = 0;
797
798 if ((ieee->current_network.mode == WIRELESS_MODE_G) ||
799 (ieee->current_network.mode == WIRELESS_MODE_N_24G &&
800 ieee->ht_info->bCurSuppCCK)) {
801 erp_len = 3;
802 erpinfo_content = 0;
803 if (ieee->current_network.buseprotection)
804 erpinfo_content |= ERP_UseProtection;
805 } else {
806 erp_len = 0;
807 }
808
809 crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
810 encrypt = crypt && crypt->ops &&
811 ((strcmp(crypt->ops->name, "R-WEP") == 0 || wpa_ie_len));
812 if (ieee->ht_info->bCurrentHTSupport) {
813 tmp_ht_cap_buf = (u8 *)&(ieee->ht_info->SelfHTCap);
814 tmp_ht_cap_len = sizeof(ieee->ht_info->SelfHTCap);
815 tmp_ht_info_buf = (u8 *)&(ieee->ht_info->SelfHTInfo);
816 tmp_ht_info_len = sizeof(ieee->ht_info->SelfHTInfo);
817 HTConstructCapabilityElement(ieee, tmp_ht_cap_buf,
818 &tmp_ht_cap_len, encrypt, false);
819 HTConstructInfoElement(ieee, tmp_ht_info_buf, &tmp_ht_info_len,
820 encrypt);
821
822 if (ht_info->reg_rt2rt_aggregation) {
823 tmp_generic_ie_buf = ieee->ht_info->sz_rt2rt_agg_buf;
824 tmp_generic_ie_len =
825 sizeof(ieee->ht_info->sz_rt2rt_agg_buf);
826 HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf,
827 &tmp_generic_ie_len);
828 }
829 }
830
831 beacon_size = sizeof(struct rtllib_probe_response) + 2 +
832 ssid_len + 3 + rate_len + rate_ex_len + atim_len + erp_len
833 + wpa_ie_len + ieee->tx_headroom;
834 skb = dev_alloc_skb(beacon_size);
835 if (!skb)
836 return NULL;
837
838 skb_reserve(skb, ieee->tx_headroom);
839
840 beacon_buf = skb_put(skb, (beacon_size - ieee->tx_headroom));
841 ether_addr_copy(beacon_buf->header.addr1, dest);
842 ether_addr_copy(beacon_buf->header.addr2, ieee->dev->dev_addr);
843 ether_addr_copy(beacon_buf->header.addr3, ieee->current_network.bssid);
844
845 beacon_buf->header.duration_id = 0;
846 beacon_buf->beacon_interval =
847 cpu_to_le16(ieee->current_network.beacon_interval);
848 beacon_buf->capability =
849 cpu_to_le16(ieee->current_network.capability &
850 WLAN_CAPABILITY_IBSS);
851 beacon_buf->capability |=
852 cpu_to_le16(ieee->current_network.capability &
853 WLAN_CAPABILITY_SHORT_PREAMBLE);
854
855 if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
856 beacon_buf->capability |=
857 cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);
858
859 crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
860 if (encrypt)
861 beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
862
863 beacon_buf->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_PROBE_RESP);
864 beacon_buf->info_element[0].id = MFIE_TYPE_SSID;
865 beacon_buf->info_element[0].len = ssid_len;
866
867 tag = (u8 *)beacon_buf->info_element[0].data;
868
869 memcpy(tag, ssid, ssid_len);
870
871 tag += ssid_len;
872
873 *(tag++) = MFIE_TYPE_RATES;
874 *(tag++) = rate_len - 2;
875 memcpy(tag, ieee->current_network.rates, rate_len - 2);
876 tag += rate_len - 2;
877
878 *(tag++) = MFIE_TYPE_DS_SET;
879 *(tag++) = 1;
880 *(tag++) = ieee->current_network.channel;
881
882 if (atim_len) {
883 u16 val16;
884 *(tag++) = MFIE_TYPE_IBSS_SET;
885 *(tag++) = 2;
886 val16 = ieee->current_network.atim_window;
887 memcpy((u8 *)tag, (u8 *)&val16, 2);
888 tag += 2;
889 }
890
891 if (erp_len) {
892 *(tag++) = MFIE_TYPE_ERP;
893 *(tag++) = 1;
894 *(tag++) = erpinfo_content;
895 }
896 if (rate_ex_len) {
897 *(tag++) = MFIE_TYPE_RATES_EX;
898 *(tag++) = rate_ex_len - 2;
899 memcpy(tag, ieee->current_network.rates_ex, rate_ex_len - 2);
900 tag += rate_ex_len - 2;
901 }
902
903 if (wpa_ie_len) {
904 if (ieee->iw_mode == IW_MODE_ADHOC)
905 memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
906 memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
907 tag += ieee->wpa_ie_len;
908 }
909 return skb;
910 }
911
rtllib_null_func(struct rtllib_device * ieee,short pwr)912 static struct sk_buff *rtllib_null_func(struct rtllib_device *ieee, short pwr)
913 {
914 struct sk_buff *skb;
915 struct rtllib_hdr_3addr *hdr;
916
917 skb = dev_alloc_skb(sizeof(struct rtllib_hdr_3addr) + ieee->tx_headroom);
918 if (!skb)
919 return NULL;
920
921 skb_reserve(skb, ieee->tx_headroom);
922
923 hdr = skb_put(skb, sizeof(struct rtllib_hdr_3addr));
924
925 ether_addr_copy(hdr->addr1, ieee->current_network.bssid);
926 ether_addr_copy(hdr->addr2, ieee->dev->dev_addr);
927 ether_addr_copy(hdr->addr3, ieee->current_network.bssid);
928
929 hdr->frame_ctl = cpu_to_le16(RTLLIB_FTYPE_DATA |
930 RTLLIB_STYPE_NULLFUNC | RTLLIB_FCTL_TODS |
931 (pwr ? RTLLIB_FCTL_PM : 0));
932
933 return skb;
934 }
935
rtllib_pspoll_func(struct rtllib_device * ieee)936 static struct sk_buff *rtllib_pspoll_func(struct rtllib_device *ieee)
937 {
938 struct sk_buff *skb;
939 struct rtllib_pspoll_hdr *hdr;
940
941 skb = dev_alloc_skb(sizeof(struct rtllib_pspoll_hdr) + ieee->tx_headroom);
942 if (!skb)
943 return NULL;
944
945 skb_reserve(skb, ieee->tx_headroom);
946
947 hdr = skb_put(skb, sizeof(struct rtllib_pspoll_hdr));
948
949 ether_addr_copy(hdr->bssid, ieee->current_network.bssid);
950 ether_addr_copy(hdr->ta, ieee->dev->dev_addr);
951
952 hdr->aid = cpu_to_le16(ieee->assoc_id | 0xc000);
953 hdr->frame_ctl = cpu_to_le16(RTLLIB_FTYPE_CTL | RTLLIB_STYPE_PSPOLL |
954 RTLLIB_FCTL_PM);
955
956 return skb;
957 }
958
rtllib_resp_to_probe(struct rtllib_device * ieee,u8 * dest)959 static void rtllib_resp_to_probe(struct rtllib_device *ieee, u8 *dest)
960 {
961 struct sk_buff *buf = rtllib_probe_resp(ieee, dest);
962
963 if (buf)
964 softmac_mgmt_xmit(buf, ieee);
965 }
966
SecIsInPMKIDList(struct rtllib_device * ieee,u8 * bssid)967 static inline int SecIsInPMKIDList(struct rtllib_device *ieee, u8 *bssid)
968 {
969 int i = 0;
970
971 do {
972 if ((ieee->PMKIDList[i].bUsed) &&
973 (memcmp(ieee->PMKIDList[i].Bssid, bssid, ETH_ALEN) == 0))
974 break;
975 i++;
976 } while (i < NUM_PMKID_CACHE);
977
978 if (i == NUM_PMKID_CACHE)
979 i = -1;
980 return i;
981 }
982
983 static inline struct sk_buff *
rtllib_association_req(struct rtllib_network * beacon,struct rtllib_device * ieee)984 rtllib_association_req(struct rtllib_network *beacon,
985 struct rtllib_device *ieee)
986 {
987 struct sk_buff *skb;
988 struct rtllib_assoc_request_frame *hdr;
989 u8 *tag, *ies;
990 int i;
991 u8 *ht_cap_buf = NULL;
992 u8 ht_cap_len = 0;
993 u8 *realtek_ie_buf = NULL;
994 u8 realtek_ie_len = 0;
995 int wpa_ie_len = ieee->wpa_ie_len;
996 int wps_ie_len = ieee->wps_ie_len;
997 unsigned int ckip_ie_len = 0;
998 unsigned int ccxrm_ie_len = 0;
999 unsigned int cxvernum_ie_len = 0;
1000 struct lib80211_crypt_data *crypt;
1001 int encrypt;
1002 int PMKCacheIdx;
1003
1004 unsigned int rate_len = (beacon->rates_len ?
1005 (beacon->rates_len + 2) : 0) +
1006 (beacon->rates_ex_len ? (beacon->rates_ex_len) +
1007 2 : 0);
1008
1009 unsigned int wmm_info_len = beacon->qos_data.supported ? 9 : 0;
1010 unsigned int turbo_info_len = beacon->Turbo_Enable ? 9 : 0;
1011
1012 int len = 0;
1013
1014 crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
1015 if (crypt != NULL)
1016 encrypt = crypt && crypt->ops &&
1017 ((strcmp(crypt->ops->name, "R-WEP") == 0 ||
1018 wpa_ie_len));
1019 else
1020 encrypt = 0;
1021
1022 if ((ieee->rtllib_ap_sec_type &&
1023 (ieee->rtllib_ap_sec_type(ieee) & SEC_ALG_TKIP)) ||
1024 ieee->bForcedBgMode) {
1025 ieee->ht_info->enable_ht = 0;
1026 ieee->mode = WIRELESS_MODE_G;
1027 }
1028
1029 if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht) {
1030 ht_cap_buf = (u8 *)&(ieee->ht_info->SelfHTCap);
1031 ht_cap_len = sizeof(ieee->ht_info->SelfHTCap);
1032 HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len,
1033 encrypt, true);
1034 if (ieee->ht_info->current_rt2rt_aggregation) {
1035 realtek_ie_buf = ieee->ht_info->sz_rt2rt_agg_buf;
1036 realtek_ie_len =
1037 sizeof(ieee->ht_info->sz_rt2rt_agg_buf);
1038 HTConstructRT2RTAggElement(ieee, realtek_ie_buf,
1039 &realtek_ie_len);
1040 }
1041 }
1042
1043 if (beacon->bCkipSupported)
1044 ckip_ie_len = 30 + 2;
1045 if (beacon->bCcxRmEnable)
1046 ccxrm_ie_len = 6 + 2;
1047 if (beacon->BssCcxVerNumber >= 2)
1048 cxvernum_ie_len = 5 + 2;
1049
1050 PMKCacheIdx = SecIsInPMKIDList(ieee, ieee->current_network.bssid);
1051 if (PMKCacheIdx >= 0) {
1052 wpa_ie_len += 18;
1053 netdev_info(ieee->dev, "[PMK cache]: WPA2 IE length: %x\n",
1054 wpa_ie_len);
1055 }
1056 len = sizeof(struct rtllib_assoc_request_frame) + 2
1057 + beacon->ssid_len
1058 + rate_len
1059 + wpa_ie_len
1060 + wps_ie_len
1061 + wmm_info_len
1062 + turbo_info_len
1063 + ht_cap_len
1064 + realtek_ie_len
1065 + ckip_ie_len
1066 + ccxrm_ie_len
1067 + cxvernum_ie_len
1068 + ieee->tx_headroom;
1069
1070 skb = dev_alloc_skb(len);
1071
1072 if (!skb)
1073 return NULL;
1074
1075 skb_reserve(skb, ieee->tx_headroom);
1076
1077 hdr = skb_put(skb, sizeof(struct rtllib_assoc_request_frame) + 2);
1078
1079 hdr->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_ASSOC_REQ);
1080 hdr->header.duration_id = cpu_to_le16(37);
1081 ether_addr_copy(hdr->header.addr1, beacon->bssid);
1082 ether_addr_copy(hdr->header.addr2, ieee->dev->dev_addr);
1083 ether_addr_copy(hdr->header.addr3, beacon->bssid);
1084
1085 ether_addr_copy(ieee->ap_mac_addr, beacon->bssid);
1086
1087 hdr->capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
1088 if (beacon->capability & WLAN_CAPABILITY_PRIVACY)
1089 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
1090
1091 if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1092 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
1093
1094 if (beacon->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
1095 hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);
1096
1097 hdr->listen_interval = cpu_to_le16(beacon->listen_interval);
1098
1099 hdr->info_element[0].id = MFIE_TYPE_SSID;
1100
1101 hdr->info_element[0].len = beacon->ssid_len;
1102 skb_put_data(skb, beacon->ssid, beacon->ssid_len);
1103
1104 tag = skb_put(skb, rate_len);
1105
1106 if (beacon->rates_len) {
1107 *tag++ = MFIE_TYPE_RATES;
1108 *tag++ = beacon->rates_len;
1109 for (i = 0; i < beacon->rates_len; i++)
1110 *tag++ = beacon->rates[i];
1111 }
1112
1113 if (beacon->rates_ex_len) {
1114 *tag++ = MFIE_TYPE_RATES_EX;
1115 *tag++ = beacon->rates_ex_len;
1116 for (i = 0; i < beacon->rates_ex_len; i++)
1117 *tag++ = beacon->rates_ex[i];
1118 }
1119
1120 if (beacon->bCkipSupported) {
1121 static const u8 AironetIeOui[] = {0x00, 0x01, 0x66};
1122 u8 CcxAironetBuf[30];
1123 struct octet_string osCcxAironetIE;
1124
1125 memset(CcxAironetBuf, 0, 30);
1126 osCcxAironetIE.Octet = CcxAironetBuf;
1127 osCcxAironetIE.Length = sizeof(CcxAironetBuf);
1128 memcpy(osCcxAironetIE.Octet, AironetIeOui,
1129 sizeof(AironetIeOui));
1130
1131 osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |=
1132 (SUPPORT_CKIP_PK | SUPPORT_CKIP_MIC);
1133 tag = skb_put(skb, ckip_ie_len);
1134 *tag++ = MFIE_TYPE_AIRONET;
1135 *tag++ = osCcxAironetIE.Length;
1136 memcpy(tag, osCcxAironetIE.Octet, osCcxAironetIE.Length);
1137 tag += osCcxAironetIE.Length;
1138 }
1139
1140 if (beacon->bCcxRmEnable) {
1141 static const u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01,
1142 0x00};
1143 struct octet_string osCcxRmCap;
1144
1145 osCcxRmCap.Octet = (u8 *)CcxRmCapBuf;
1146 osCcxRmCap.Length = sizeof(CcxRmCapBuf);
1147 tag = skb_put(skb, ccxrm_ie_len);
1148 *tag++ = MFIE_TYPE_GENERIC;
1149 *tag++ = osCcxRmCap.Length;
1150 memcpy(tag, osCcxRmCap.Octet, osCcxRmCap.Length);
1151 tag += osCcxRmCap.Length;
1152 }
1153
1154 if (beacon->BssCcxVerNumber >= 2) {
1155 u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00};
1156 struct octet_string osCcxVerNum;
1157
1158 CcxVerNumBuf[4] = beacon->BssCcxVerNumber;
1159 osCcxVerNum.Octet = CcxVerNumBuf;
1160 osCcxVerNum.Length = sizeof(CcxVerNumBuf);
1161 tag = skb_put(skb, cxvernum_ie_len);
1162 *tag++ = MFIE_TYPE_GENERIC;
1163 *tag++ = osCcxVerNum.Length;
1164 memcpy(tag, osCcxVerNum.Octet, osCcxVerNum.Length);
1165 tag += osCcxVerNum.Length;
1166 }
1167 if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht) {
1168 if (ieee->ht_info->ePeerHTSpecVer != HT_SPEC_VER_EWC) {
1169 tag = skb_put(skb, ht_cap_len);
1170 *tag++ = MFIE_TYPE_HT_CAP;
1171 *tag++ = ht_cap_len - 2;
1172 memcpy(tag, ht_cap_buf, ht_cap_len - 2);
1173 tag += ht_cap_len - 2;
1174 }
1175 }
1176
1177 if (wpa_ie_len) {
1178 skb_put_data(skb, ieee->wpa_ie, ieee->wpa_ie_len);
1179
1180 if (PMKCacheIdx >= 0) {
1181 tag = skb_put(skb, 18);
1182 *tag = 1;
1183 *(tag + 1) = 0;
1184 memcpy((tag + 2), &ieee->PMKIDList[PMKCacheIdx].PMKID,
1185 16);
1186 }
1187 }
1188 if (wmm_info_len) {
1189 tag = skb_put(skb, wmm_info_len);
1190 rtllib_WMM_Info(ieee, &tag);
1191 }
1192
1193 if (wps_ie_len && ieee->wps_ie)
1194 skb_put_data(skb, ieee->wps_ie, wps_ie_len);
1195
1196 if (turbo_info_len) {
1197 tag = skb_put(skb, turbo_info_len);
1198 rtllib_TURBO_Info(ieee, &tag);
1199 }
1200
1201 if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht) {
1202 if (ieee->ht_info->ePeerHTSpecVer == HT_SPEC_VER_EWC) {
1203 tag = skb_put(skb, ht_cap_len);
1204 *tag++ = MFIE_TYPE_GENERIC;
1205 *tag++ = ht_cap_len - 2;
1206 memcpy(tag, ht_cap_buf, ht_cap_len - 2);
1207 tag += ht_cap_len - 2;
1208 }
1209
1210 if (ieee->ht_info->current_rt2rt_aggregation) {
1211 tag = skb_put(skb, realtek_ie_len);
1212 *tag++ = MFIE_TYPE_GENERIC;
1213 *tag++ = realtek_ie_len - 2;
1214 memcpy(tag, realtek_ie_buf, realtek_ie_len - 2);
1215 }
1216 }
1217
1218 kfree(ieee->assocreq_ies);
1219 ieee->assocreq_ies = NULL;
1220 ies = &(hdr->info_element[0].id);
1221 ieee->assocreq_ies_len = (skb->data + skb->len) - ies;
1222 ieee->assocreq_ies = kmemdup(ies, ieee->assocreq_ies_len, GFP_ATOMIC);
1223 if (!ieee->assocreq_ies)
1224 ieee->assocreq_ies_len = 0;
1225
1226 return skb;
1227 }
1228
rtllib_associate_abort(struct rtllib_device * ieee)1229 static void rtllib_associate_abort(struct rtllib_device *ieee)
1230 {
1231 unsigned long flags;
1232
1233 spin_lock_irqsave(&ieee->lock, flags);
1234
1235 ieee->associate_seq++;
1236
1237 /* don't scan, and avoid to have the RX path possibily
1238 * try again to associate. Even do not react to AUTH or
1239 * ASSOC response. Just wait for the retry wq to be scheduled.
1240 * Here we will check if there are good nets to associate
1241 * with, so we retry or just get back to NO_LINK and scanning
1242 */
1243 if (ieee->link_state == RTLLIB_ASSOCIATING_AUTHENTICATING) {
1244 netdev_dbg(ieee->dev, "Authentication failed\n");
1245 ieee->softmac_stats.no_auth_rs++;
1246 } else {
1247 netdev_dbg(ieee->dev, "Association failed\n");
1248 ieee->softmac_stats.no_ass_rs++;
1249 }
1250
1251 ieee->link_state = RTLLIB_ASSOCIATING_RETRY;
1252
1253 schedule_delayed_work(&ieee->associate_retry_wq,
1254 RTLLIB_SOFTMAC_ASSOC_RETRY_TIME);
1255
1256 spin_unlock_irqrestore(&ieee->lock, flags);
1257 }
1258
rtllib_associate_abort_cb(struct timer_list * t)1259 static void rtllib_associate_abort_cb(struct timer_list *t)
1260 {
1261 struct rtllib_device *dev = from_timer(dev, t, associate_timer);
1262
1263 rtllib_associate_abort(dev);
1264 }
1265
rtllib_associate_step1(struct rtllib_device * ieee,u8 * daddr)1266 static void rtllib_associate_step1(struct rtllib_device *ieee, u8 *daddr)
1267 {
1268 struct rtllib_network *beacon = &ieee->current_network;
1269 struct sk_buff *skb;
1270
1271 netdev_dbg(ieee->dev, "Stopping scan\n");
1272
1273 ieee->softmac_stats.tx_auth_rq++;
1274
1275 skb = rtllib_authentication_req(beacon, ieee, 0, daddr);
1276
1277 if (!skb) {
1278 rtllib_associate_abort(ieee);
1279 } else {
1280 ieee->link_state = RTLLIB_ASSOCIATING_AUTHENTICATING;
1281 netdev_dbg(ieee->dev, "Sending authentication request\n");
1282 softmac_mgmt_xmit(skb, ieee);
1283 if (!timer_pending(&ieee->associate_timer)) {
1284 ieee->associate_timer.expires = jiffies + (HZ / 2);
1285 add_timer(&ieee->associate_timer);
1286 }
1287 }
1288 }
1289
rtllib_auth_challenge(struct rtllib_device * ieee,u8 * challenge,int chlen)1290 static void rtllib_auth_challenge(struct rtllib_device *ieee, u8 *challenge,
1291 int chlen)
1292 {
1293 u8 *c;
1294 struct sk_buff *skb;
1295 struct rtllib_network *beacon = &ieee->current_network;
1296
1297 ieee->associate_seq++;
1298 ieee->softmac_stats.tx_auth_rq++;
1299
1300 skb = rtllib_authentication_req(beacon, ieee, chlen + 2, beacon->bssid);
1301
1302 if (!skb) {
1303 rtllib_associate_abort(ieee);
1304 } else {
1305 c = skb_put(skb, chlen + 2);
1306 *(c++) = MFIE_TYPE_CHALLENGE;
1307 *(c++) = chlen;
1308 memcpy(c, challenge, chlen);
1309
1310 netdev_dbg(ieee->dev,
1311 "Sending authentication challenge response\n");
1312
1313 rtllib_encrypt_fragment(ieee, skb,
1314 sizeof(struct rtllib_hdr_3addr));
1315
1316 softmac_mgmt_xmit(skb, ieee);
1317 mod_timer(&ieee->associate_timer, jiffies + (HZ / 2));
1318 }
1319 kfree(challenge);
1320 }
1321
rtllib_associate_step2(struct rtllib_device * ieee)1322 static void rtllib_associate_step2(struct rtllib_device *ieee)
1323 {
1324 struct sk_buff *skb;
1325 struct rtllib_network *beacon = &ieee->current_network;
1326
1327 del_timer_sync(&ieee->associate_timer);
1328
1329 netdev_dbg(ieee->dev, "Sending association request\n");
1330
1331 ieee->softmac_stats.tx_ass_rq++;
1332 skb = rtllib_association_req(beacon, ieee);
1333 if (!skb) {
1334 rtllib_associate_abort(ieee);
1335 } else {
1336 softmac_mgmt_xmit(skb, ieee);
1337 mod_timer(&ieee->associate_timer, jiffies + (HZ / 2));
1338 }
1339 }
1340
rtllib_associate_complete_wq(void * data)1341 static void rtllib_associate_complete_wq(void *data)
1342 {
1343 struct rtllib_device *ieee = (struct rtllib_device *)
1344 container_of(data,
1345 struct rtllib_device,
1346 associate_complete_wq);
1347 struct rt_pwr_save_ctrl *psc = &ieee->pwr_save_ctrl;
1348
1349 netdev_info(ieee->dev, "Associated successfully with %pM\n",
1350 ieee->current_network.bssid);
1351 if (!ieee->is_silent_reset) {
1352 netdev_info(ieee->dev, "normal associate\n");
1353 notify_wx_assoc_event(ieee);
1354 }
1355
1356 netif_carrier_on(ieee->dev);
1357 ieee->is_roaming = false;
1358 if (rtllib_is_54g(&ieee->current_network)) {
1359 ieee->rate = 108;
1360 netdev_info(ieee->dev, "Using G rates:%d\n", ieee->rate);
1361 } else {
1362 ieee->rate = 22;
1363 ieee->set_wireless_mode(ieee->dev, WIRELESS_MODE_B);
1364 netdev_info(ieee->dev, "Using B rates:%d\n", ieee->rate);
1365 }
1366 if (ieee->ht_info->bCurrentHTSupport && ieee->ht_info->enable_ht) {
1367 netdev_info(ieee->dev, "Successfully associated, ht enabled\n");
1368 HTOnAssocRsp(ieee);
1369 } else {
1370 netdev_info(ieee->dev,
1371 "Successfully associated, ht not enabled(%d, %d)\n",
1372 ieee->ht_info->bCurrentHTSupport,
1373 ieee->ht_info->enable_ht);
1374 memset(ieee->dot11ht_oper_rate_set, 0, 16);
1375 }
1376 ieee->link_detect_info.SlotNum = 2 * (1 +
1377 ieee->current_network.beacon_interval /
1378 500);
1379 if (ieee->link_detect_info.NumRecvBcnInPeriod == 0 ||
1380 ieee->link_detect_info.NumRecvDataInPeriod == 0) {
1381 ieee->link_detect_info.NumRecvBcnInPeriod = 1;
1382 ieee->link_detect_info.NumRecvDataInPeriod = 1;
1383 }
1384 psc->LpsIdleCount = 0;
1385 ieee->link_change(ieee->dev);
1386
1387 if (ieee->is_silent_reset) {
1388 netdev_info(ieee->dev, "silent reset associate\n");
1389 ieee->is_silent_reset = false;
1390 }
1391 }
1392
rtllib_sta_send_associnfo(struct rtllib_device * ieee)1393 static void rtllib_sta_send_associnfo(struct rtllib_device *ieee)
1394 {
1395 }
1396
rtllib_associate_complete(struct rtllib_device * ieee)1397 static void rtllib_associate_complete(struct rtllib_device *ieee)
1398 {
1399 del_timer_sync(&ieee->associate_timer);
1400
1401 ieee->link_state = MAC80211_LINKED;
1402 rtllib_sta_send_associnfo(ieee);
1403
1404 schedule_work(&ieee->associate_complete_wq);
1405 }
1406
rtllib_associate_procedure_wq(void * data)1407 static void rtllib_associate_procedure_wq(void *data)
1408 {
1409 struct rtllib_device *ieee = container_of_dwork_rsl(data,
1410 struct rtllib_device,
1411 associate_procedure_wq);
1412 rtllib_stop_scan_syncro(ieee);
1413 ieee->rtllib_ips_leave(ieee->dev);
1414 mutex_lock(&ieee->wx_mutex);
1415
1416 rtllib_stop_scan(ieee);
1417 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
1418 if (ieee->rf_power_state == rf_off) {
1419 ieee->rtllib_ips_leave_wq(ieee->dev);
1420 mutex_unlock(&ieee->wx_mutex);
1421 return;
1422 }
1423 ieee->associate_seq = 1;
1424
1425 rtllib_associate_step1(ieee, ieee->current_network.bssid);
1426
1427 mutex_unlock(&ieee->wx_mutex);
1428 }
1429
rtllib_softmac_new_net(struct rtllib_device * ieee,struct rtllib_network * net)1430 inline void rtllib_softmac_new_net(struct rtllib_device *ieee,
1431 struct rtllib_network *net)
1432 {
1433 u8 tmp_ssid[IW_ESSID_MAX_SIZE + 1];
1434 int tmp_ssid_len = 0;
1435
1436 short apset, ssidset, ssidbroad, apmatch, ssidmatch;
1437
1438 /* we are interested in new only if we are not associated
1439 * and we are not associating / authenticating
1440 */
1441 if (ieee->link_state != MAC80211_NOLINK)
1442 return;
1443
1444 if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability &
1445 WLAN_CAPABILITY_ESS))
1446 return;
1447
1448 if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability &
1449 WLAN_CAPABILITY_IBSS))
1450 return;
1451
1452 if ((ieee->iw_mode == IW_MODE_ADHOC) &&
1453 (net->channel > ieee->ibss_maxjoin_chal))
1454 return;
1455 if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) {
1456 /* if the user specified the AP MAC, we need also the essid
1457 * This could be obtained by beacons or, if the network does not
1458 * broadcast it, it can be put manually.
1459 */
1460 apset = ieee->wap_set;
1461 ssidset = ieee->ssid_set;
1462 ssidbroad = !(net->ssid_len == 0 || net->ssid[0] == '\0');
1463 apmatch = (memcmp(ieee->current_network.bssid, net->bssid,
1464 ETH_ALEN) == 0);
1465 if (!ssidbroad) {
1466 ssidmatch = (ieee->current_network.ssid_len ==
1467 net->hidden_ssid_len) &&
1468 (!strncmp(ieee->current_network.ssid,
1469 net->hidden_ssid, net->hidden_ssid_len));
1470 if (net->hidden_ssid_len > 0) {
1471 strncpy(net->ssid, net->hidden_ssid,
1472 net->hidden_ssid_len);
1473 net->ssid_len = net->hidden_ssid_len;
1474 ssidbroad = 1;
1475 }
1476 } else {
1477 ssidmatch =
1478 (ieee->current_network.ssid_len == net->ssid_len) &&
1479 (!strncmp(ieee->current_network.ssid, net->ssid,
1480 net->ssid_len));
1481 }
1482
1483 /* if the user set the AP check if match.
1484 * if the network does not broadcast essid we check the
1485 * user supplied ANY essid
1486 * if the network does broadcast and the user does not set
1487 * essid it is OK
1488 * if the network does broadcast and the user did set essid
1489 * check if essid match
1490 * if the ap is not set, check that the user set the bssid
1491 * and the network does broadcast and that those two bssid match
1492 */
1493 if ((apset && apmatch &&
1494 ((ssidset && ssidbroad && ssidmatch) ||
1495 (ssidbroad && !ssidset) || (!ssidbroad && ssidset))) ||
1496 (!apset && ssidset && ssidbroad && ssidmatch) ||
1497 (ieee->is_roaming && ssidset && ssidbroad && ssidmatch)) {
1498 /* Save the essid so that if it is hidden, it is
1499 * replaced with the essid provided by the user.
1500 */
1501 if (!ssidbroad) {
1502 memcpy(tmp_ssid, ieee->current_network.ssid,
1503 ieee->current_network.ssid_len);
1504 tmp_ssid_len = ieee->current_network.ssid_len;
1505 }
1506 memcpy(&ieee->current_network, net,
1507 sizeof(ieee->current_network));
1508 if (!ssidbroad) {
1509 memcpy(ieee->current_network.ssid, tmp_ssid,
1510 tmp_ssid_len);
1511 ieee->current_network.ssid_len = tmp_ssid_len;
1512 }
1513 netdev_info(ieee->dev,
1514 "Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d, mode:%x cur_net.flags:0x%x\n",
1515 ieee->current_network.ssid,
1516 ieee->current_network.channel,
1517 ieee->current_network.qos_data.supported,
1518 ieee->ht_info->enable_ht,
1519 ieee->current_network.bssht.bd_support_ht,
1520 ieee->current_network.mode,
1521 ieee->current_network.flags);
1522
1523 if ((rtllib_act_scanning(ieee, false)) &&
1524 !(ieee->softmac_features & IEEE_SOFTMAC_SCAN))
1525 rtllib_stop_scan_syncro(ieee);
1526
1527 HTResetIOTSetting(ieee->ht_info);
1528 ieee->wmm_acm = 0;
1529 if (ieee->iw_mode == IW_MODE_INFRA) {
1530 /* Join the network for the first time */
1531 ieee->AsocRetryCount = 0;
1532 if ((ieee->current_network.qos_data.supported == 1) &&
1533 ieee->current_network.bssht.bd_support_ht)
1534 HTResetSelfAndSavePeerSetting(ieee,
1535 &(ieee->current_network));
1536 else
1537 ieee->ht_info->bCurrentHTSupport =
1538 false;
1539
1540 ieee->link_state = RTLLIB_ASSOCIATING;
1541 schedule_delayed_work(
1542 &ieee->associate_procedure_wq, 0);
1543 } else {
1544 if (rtllib_is_54g(&ieee->current_network)) {
1545 ieee->rate = 108;
1546 ieee->set_wireless_mode(ieee->dev, WIRELESS_MODE_G);
1547 netdev_info(ieee->dev,
1548 "Using G rates\n");
1549 } else {
1550 ieee->rate = 22;
1551 ieee->set_wireless_mode(ieee->dev, WIRELESS_MODE_B);
1552 netdev_info(ieee->dev,
1553 "Using B rates\n");
1554 }
1555 memset(ieee->dot11ht_oper_rate_set, 0, 16);
1556 ieee->link_state = MAC80211_LINKED;
1557 }
1558 }
1559 }
1560 }
1561
rtllib_softmac_check_all_nets(struct rtllib_device * ieee)1562 static void rtllib_softmac_check_all_nets(struct rtllib_device *ieee)
1563 {
1564 unsigned long flags;
1565 struct rtllib_network *target;
1566
1567 spin_lock_irqsave(&ieee->lock, flags);
1568
1569 list_for_each_entry(target, &ieee->network_list, list) {
1570 /* if the state become different that NOLINK means
1571 * we had found what we are searching for
1572 */
1573
1574 if (ieee->link_state != MAC80211_NOLINK)
1575 break;
1576
1577 if (ieee->scan_age == 0 || time_after(target->last_scanned +
1578 ieee->scan_age, jiffies))
1579 rtllib_softmac_new_net(ieee, target);
1580 }
1581 spin_unlock_irqrestore(&ieee->lock, flags);
1582 }
1583
auth_parse(struct net_device * dev,struct sk_buff * skb,u8 ** challenge,int * chlen)1584 static inline int auth_parse(struct net_device *dev, struct sk_buff *skb,
1585 u8 **challenge, int *chlen)
1586 {
1587 struct rtllib_authentication *a;
1588 u8 *t;
1589
1590 if (skb->len < (sizeof(struct rtllib_authentication) -
1591 sizeof(struct rtllib_info_element))) {
1592 netdev_dbg(dev, "invalid len in auth resp: %d\n", skb->len);
1593 return -EINVAL;
1594 }
1595 *challenge = NULL;
1596 a = (struct rtllib_authentication *)skb->data;
1597 if (skb->len > (sizeof(struct rtllib_authentication) + 3)) {
1598 t = skb->data + sizeof(struct rtllib_authentication);
1599
1600 if (*(t++) == MFIE_TYPE_CHALLENGE) {
1601 *chlen = *(t++);
1602 *challenge = kmemdup(t, *chlen, GFP_ATOMIC);
1603 if (!*challenge)
1604 return -ENOMEM;
1605 }
1606 }
1607
1608 if (a->status) {
1609 netdev_dbg(dev, "auth_parse() failed\n");
1610 return -EINVAL;
1611 }
1612
1613 return 0;
1614 }
1615
probe_rq_parse(struct rtllib_device * ieee,struct sk_buff * skb,u8 * src)1616 static short probe_rq_parse(struct rtllib_device *ieee, struct sk_buff *skb,
1617 u8 *src)
1618 {
1619 u8 *tag;
1620 u8 *skbend;
1621 u8 *ssid = NULL;
1622 u8 ssidlen = 0;
1623 struct rtllib_hdr_3addr *header =
1624 (struct rtllib_hdr_3addr *)skb->data;
1625 bool bssid_match;
1626
1627 if (skb->len < sizeof(struct rtllib_hdr_3addr))
1628 return -1; /* corrupted */
1629
1630 bssid_match =
1631 (!ether_addr_equal(header->addr3, ieee->current_network.bssid)) &&
1632 (!is_broadcast_ether_addr(header->addr3));
1633 if (bssid_match)
1634 return -1;
1635
1636 ether_addr_copy(src, header->addr2);
1637
1638 skbend = (u8 *)skb->data + skb->len;
1639
1640 tag = skb->data + sizeof(struct rtllib_hdr_3addr);
1641
1642 while (tag + 1 < skbend) {
1643 if (*tag == 0) {
1644 ssid = tag + 2;
1645 ssidlen = *(tag + 1);
1646 break;
1647 }
1648 tag++; /* point to the len field */
1649 tag = tag + *(tag); /* point to the last data byte of the tag */
1650 tag++; /* point to the next tag */
1651 }
1652
1653 if (ssidlen == 0)
1654 return 1;
1655
1656 if (!ssid)
1657 return 1; /* ssid not found in tagged param */
1658
1659 return !strncmp(ssid, ieee->current_network.ssid, ssidlen);
1660 }
1661
assoc_parse(struct rtllib_device * ieee,struct sk_buff * skb,int * aid)1662 static inline u16 assoc_parse(struct rtllib_device *ieee, struct sk_buff *skb,
1663 int *aid)
1664 {
1665 struct rtllib_assoc_response_frame *response_head;
1666 u16 status_code;
1667
1668 if (skb->len < sizeof(struct rtllib_assoc_response_frame)) {
1669 netdev_dbg(ieee->dev, "Invalid len in auth resp: %d\n",
1670 skb->len);
1671 return 0xcafe;
1672 }
1673
1674 response_head = (struct rtllib_assoc_response_frame *)skb->data;
1675 *aid = le16_to_cpu(response_head->aid) & 0x3fff;
1676
1677 status_code = le16_to_cpu(response_head->status);
1678 if ((status_code == WLAN_STATUS_ASSOC_DENIED_RATES ||
1679 status_code == WLAN_STATUS_CAPS_UNSUPPORTED) &&
1680 ((ieee->mode == WIRELESS_MODE_G) &&
1681 (ieee->current_network.mode == WIRELESS_MODE_N_24G) &&
1682 (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT - 1)))) {
1683 ieee->ht_info->iot_action |= HT_IOT_ACT_PURE_N_MODE;
1684 } else {
1685 ieee->AsocRetryCount = 0;
1686 }
1687
1688 return le16_to_cpu(response_head->status);
1689 }
1690
rtllib_rx_probe_rq(struct rtllib_device * ieee,struct sk_buff * skb)1691 void rtllib_rx_probe_rq(struct rtllib_device *ieee, struct sk_buff *skb)
1692 {
1693 u8 dest[ETH_ALEN];
1694
1695 ieee->softmac_stats.rx_probe_rq++;
1696 if (probe_rq_parse(ieee, skb, dest) > 0) {
1697 ieee->softmac_stats.tx_probe_rs++;
1698 rtllib_resp_to_probe(ieee, dest);
1699 }
1700 }
1701
rtllib_sta_ps_send_null_frame(struct rtllib_device * ieee,short pwr)1702 void rtllib_sta_ps_send_null_frame(struct rtllib_device *ieee, short pwr)
1703 {
1704 struct sk_buff *buf = rtllib_null_func(ieee, pwr);
1705
1706 if (buf)
1707 softmac_ps_mgmt_xmit(buf, ieee);
1708 }
1709 EXPORT_SYMBOL(rtllib_sta_ps_send_null_frame);
1710
rtllib_sta_ps_send_pspoll_frame(struct rtllib_device * ieee)1711 void rtllib_sta_ps_send_pspoll_frame(struct rtllib_device *ieee)
1712 {
1713 struct sk_buff *buf = rtllib_pspoll_func(ieee);
1714
1715 if (buf)
1716 softmac_ps_mgmt_xmit(buf, ieee);
1717 }
1718
rtllib_sta_ps_sleep(struct rtllib_device * ieee,u64 * time)1719 static short rtllib_sta_ps_sleep(struct rtllib_device *ieee, u64 *time)
1720 {
1721 int timeout;
1722 u8 dtim;
1723 struct rt_pwr_save_ctrl *psc = &ieee->pwr_save_ctrl;
1724
1725 if (ieee->LPSDelayCnt) {
1726 ieee->LPSDelayCnt--;
1727 return 0;
1728 }
1729
1730 dtim = ieee->current_network.dtim_data;
1731 if (!(dtim & RTLLIB_DTIM_VALID))
1732 return 0;
1733 timeout = ieee->current_network.beacon_interval;
1734 ieee->current_network.dtim_data = RTLLIB_DTIM_INVALID;
1735 /* there's no need to nofity AP that I find you buffered
1736 * with broadcast packet
1737 */
1738 if (dtim & (RTLLIB_DTIM_UCAST & ieee->ps))
1739 return 2;
1740
1741 if (!time_after(jiffies,
1742 dev_trans_start(ieee->dev) + msecs_to_jiffies(timeout)))
1743 return 0;
1744 if (!time_after(jiffies,
1745 ieee->last_rx_ps_time + msecs_to_jiffies(timeout)))
1746 return 0;
1747 if ((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) &&
1748 (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
1749 return 0;
1750
1751 if (time) {
1752 if (ieee->bAwakePktSent) {
1753 psc->LPSAwakeIntvl = 1;
1754 } else {
1755 u8 MaxPeriod = 1;
1756
1757 if (psc->LPSAwakeIntvl == 0)
1758 psc->LPSAwakeIntvl = 1;
1759 if (psc->reg_max_lps_awake_intvl == 0)
1760 MaxPeriod = 1;
1761 else if (psc->reg_max_lps_awake_intvl == 0xFF)
1762 MaxPeriod = ieee->current_network.dtim_period;
1763 else
1764 MaxPeriod = psc->reg_max_lps_awake_intvl;
1765 psc->LPSAwakeIntvl = (psc->LPSAwakeIntvl >=
1766 MaxPeriod) ? MaxPeriod :
1767 (psc->LPSAwakeIntvl + 1);
1768 }
1769 {
1770 u8 LPSAwakeIntvl_tmp = 0;
1771 u8 period = ieee->current_network.dtim_period;
1772 u8 count = ieee->current_network.tim.tim_count;
1773
1774 if (count == 0) {
1775 if (psc->LPSAwakeIntvl > period)
1776 LPSAwakeIntvl_tmp = period +
1777 (psc->LPSAwakeIntvl -
1778 period) -
1779 ((psc->LPSAwakeIntvl - period) %
1780 period);
1781 else
1782 LPSAwakeIntvl_tmp = psc->LPSAwakeIntvl;
1783
1784 } else {
1785 if (psc->LPSAwakeIntvl >
1786 ieee->current_network.tim.tim_count)
1787 LPSAwakeIntvl_tmp = count +
1788 (psc->LPSAwakeIntvl - count) -
1789 ((psc->LPSAwakeIntvl - count) % period);
1790 else
1791 LPSAwakeIntvl_tmp = psc->LPSAwakeIntvl;
1792 }
1793
1794 *time = ieee->current_network.last_dtim_sta_time
1795 + msecs_to_jiffies(ieee->current_network.beacon_interval *
1796 LPSAwakeIntvl_tmp);
1797 }
1798 }
1799
1800 return 1;
1801 }
1802
rtllib_sta_ps(struct work_struct * work)1803 static inline void rtllib_sta_ps(struct work_struct *work)
1804 {
1805 struct rtllib_device *ieee;
1806 u64 time;
1807 short sleep;
1808 unsigned long flags, flags2;
1809
1810 ieee = container_of(work, struct rtllib_device, ps_task);
1811
1812 spin_lock_irqsave(&ieee->lock, flags);
1813
1814 if ((ieee->ps == RTLLIB_PS_DISABLED ||
1815 ieee->iw_mode != IW_MODE_INFRA ||
1816 ieee->link_state != MAC80211_LINKED)) {
1817 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1818 rtllib_sta_wakeup(ieee, 1);
1819
1820 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1821 }
1822 sleep = rtllib_sta_ps_sleep(ieee, &time);
1823 /* 2 wake, 1 sleep, 0 do nothing */
1824 if (sleep == 0)
1825 goto out;
1826 if (sleep == 1) {
1827 if (ieee->sta_sleep == LPS_IS_SLEEP) {
1828 ieee->enter_sleep_state(ieee->dev, time);
1829 } else if (ieee->sta_sleep == LPS_IS_WAKE) {
1830 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1831
1832 if (ieee->ps_is_queue_empty(ieee->dev)) {
1833 ieee->sta_sleep = LPS_WAIT_NULL_DATA_SEND;
1834 ieee->ack_tx_to_ieee = 1;
1835 rtllib_sta_ps_send_null_frame(ieee, 1);
1836 ieee->ps_time = time;
1837 }
1838 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1839 }
1840
1841 ieee->bAwakePktSent = false;
1842
1843 } else if (sleep == 2) {
1844 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1845
1846 rtllib_sta_wakeup(ieee, 1);
1847
1848 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1849 }
1850
1851 out:
1852 spin_unlock_irqrestore(&ieee->lock, flags);
1853 }
1854
rtllib_sta_wakeup(struct rtllib_device * ieee,short nl)1855 static void rtllib_sta_wakeup(struct rtllib_device *ieee, short nl)
1856 {
1857 if (ieee->sta_sleep == LPS_IS_WAKE) {
1858 if (nl) {
1859 if (ieee->ht_info->iot_action &
1860 HT_IOT_ACT_NULL_DATA_POWER_SAVING) {
1861 ieee->ack_tx_to_ieee = 1;
1862 rtllib_sta_ps_send_null_frame(ieee, 0);
1863 } else {
1864 ieee->ack_tx_to_ieee = 1;
1865 rtllib_sta_ps_send_pspoll_frame(ieee);
1866 }
1867 }
1868 return;
1869 }
1870
1871 if (ieee->sta_sleep == LPS_IS_SLEEP)
1872 ieee->sta_wake_up(ieee->dev);
1873 if (nl) {
1874 if (ieee->ht_info->iot_action &
1875 HT_IOT_ACT_NULL_DATA_POWER_SAVING) {
1876 ieee->ack_tx_to_ieee = 1;
1877 rtllib_sta_ps_send_null_frame(ieee, 0);
1878 } else {
1879 ieee->ack_tx_to_ieee = 1;
1880 ieee->polling = true;
1881 rtllib_sta_ps_send_pspoll_frame(ieee);
1882 }
1883
1884 } else {
1885 ieee->sta_sleep = LPS_IS_WAKE;
1886 ieee->polling = false;
1887 }
1888 }
1889
rtllib_ps_tx_ack(struct rtllib_device * ieee,short success)1890 void rtllib_ps_tx_ack(struct rtllib_device *ieee, short success)
1891 {
1892 unsigned long flags, flags2;
1893
1894 spin_lock_irqsave(&ieee->lock, flags);
1895
1896 if (ieee->sta_sleep == LPS_WAIT_NULL_DATA_SEND) {
1897 /* Null frame with PS bit set */
1898 if (success) {
1899 ieee->sta_sleep = LPS_IS_SLEEP;
1900 ieee->enter_sleep_state(ieee->dev, ieee->ps_time);
1901 }
1902 /* if the card report not success we can't be sure the AP
1903 * has not RXed so we can't assume the AP believe us awake
1904 */
1905 } else {/* 21112005 - tx again null without PS bit if lost */
1906
1907 if ((ieee->sta_sleep == LPS_IS_WAKE) && !success) {
1908 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
1909 if (ieee->ht_info->iot_action &
1910 HT_IOT_ACT_NULL_DATA_POWER_SAVING)
1911 rtllib_sta_ps_send_null_frame(ieee, 0);
1912 else
1913 rtllib_sta_ps_send_pspoll_frame(ieee);
1914 spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
1915 }
1916 }
1917 spin_unlock_irqrestore(&ieee->lock, flags);
1918 }
1919 EXPORT_SYMBOL(rtllib_ps_tx_ack);
1920
rtllib_process_action(struct rtllib_device * ieee,struct sk_buff * skb)1921 static void rtllib_process_action(struct rtllib_device *ieee,
1922 struct sk_buff *skb)
1923 {
1924 struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *)skb->data;
1925 u8 *act = rtllib_get_payload((struct rtllib_hdr *)header);
1926 u8 category = 0;
1927
1928 if (act == NULL) {
1929 netdev_warn(ieee->dev,
1930 "Error getting payload of action frame\n");
1931 return;
1932 }
1933
1934 category = *act;
1935 act++;
1936 switch (category) {
1937 case ACT_CAT_BA:
1938 switch (*act) {
1939 case ACT_ADDBAREQ:
1940 rtllib_rx_ADDBAReq(ieee, skb);
1941 break;
1942 case ACT_ADDBARSP:
1943 rtllib_rx_ADDBARsp(ieee, skb);
1944 break;
1945 case ACT_DELBA:
1946 rtllib_rx_DELBA(ieee, skb);
1947 break;
1948 }
1949 break;
1950 default:
1951 break;
1952 }
1953 }
1954
1955 static inline int
rtllib_rx_assoc_resp(struct rtllib_device * ieee,struct sk_buff * skb,struct rtllib_rx_stats * rx_stats)1956 rtllib_rx_assoc_resp(struct rtllib_device *ieee, struct sk_buff *skb,
1957 struct rtllib_rx_stats *rx_stats)
1958 {
1959 u16 errcode;
1960 int aid;
1961 u8 *ies;
1962 struct rtllib_assoc_response_frame *assoc_resp;
1963 struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *)skb->data;
1964 u16 frame_ctl = le16_to_cpu(header->frame_ctl);
1965
1966 netdev_dbg(ieee->dev, "received [RE]ASSOCIATION RESPONSE (%d)\n",
1967 WLAN_FC_GET_STYPE(frame_ctl));
1968
1969 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
1970 ieee->link_state == RTLLIB_ASSOCIATING_AUTHENTICATED &&
1971 (ieee->iw_mode == IW_MODE_INFRA)) {
1972 errcode = assoc_parse(ieee, skb, &aid);
1973 if (!errcode) {
1974 struct rtllib_network *network =
1975 kzalloc(sizeof(struct rtllib_network),
1976 GFP_ATOMIC);
1977
1978 if (!network)
1979 return 1;
1980 ieee->link_state = MAC80211_LINKED;
1981 ieee->assoc_id = aid;
1982 ieee->softmac_stats.rx_ass_ok++;
1983 /* station support qos */
1984 /* Let the register setting default with Legacy station */
1985 assoc_resp = (struct rtllib_assoc_response_frame *)skb->data;
1986 if (ieee->current_network.qos_data.supported == 1) {
1987 if (rtllib_parse_info_param(ieee, assoc_resp->info_element,
1988 rx_stats->len - sizeof(*assoc_resp),
1989 network, rx_stats)) {
1990 kfree(network);
1991 return 1;
1992 }
1993 memcpy(ieee->ht_info->PeerHTCapBuf,
1994 network->bssht.bd_ht_cap_buf,
1995 network->bssht.bd_ht_cap_len);
1996 memcpy(ieee->ht_info->PeerHTInfoBuf,
1997 network->bssht.bd_ht_info_buf,
1998 network->bssht.bd_ht_info_len);
1999 ieee->handle_assoc_response(ieee->dev,
2000 (struct rtllib_assoc_response_frame *)header, network);
2001 }
2002 kfree(network);
2003
2004 kfree(ieee->assocresp_ies);
2005 ieee->assocresp_ies = NULL;
2006 ies = &(assoc_resp->info_element[0].id);
2007 ieee->assocresp_ies_len = (skb->data + skb->len) - ies;
2008 ieee->assocresp_ies = kmemdup(ies,
2009 ieee->assocresp_ies_len,
2010 GFP_ATOMIC);
2011 if (!ieee->assocresp_ies)
2012 ieee->assocresp_ies_len = 0;
2013
2014 rtllib_associate_complete(ieee);
2015 } else {
2016 /* aid could not been allocated */
2017 ieee->softmac_stats.rx_ass_err++;
2018 netdev_info(ieee->dev,
2019 "Association response status code 0x%x\n",
2020 errcode);
2021 if (ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT)
2022 schedule_delayed_work(
2023 &ieee->associate_procedure_wq, 0);
2024 else
2025 rtllib_associate_abort(ieee);
2026 }
2027 }
2028 return 0;
2029 }
2030
rtllib_rx_auth_resp(struct rtllib_device * ieee,struct sk_buff * skb)2031 static void rtllib_rx_auth_resp(struct rtllib_device *ieee, struct sk_buff *skb)
2032 {
2033 int errcode;
2034 u8 *challenge;
2035 int chlen = 0;
2036 bool bSupportNmode = true, bHalfSupportNmode = false;
2037
2038 errcode = auth_parse(ieee->dev, skb, &challenge, &chlen);
2039
2040 if (errcode) {
2041 ieee->softmac_stats.rx_auth_rs_err++;
2042 netdev_info(ieee->dev,
2043 "Authentication response status code %d", errcode);
2044 rtllib_associate_abort(ieee);
2045 return;
2046 }
2047
2048 if (ieee->open_wep || !challenge) {
2049 ieee->link_state = RTLLIB_ASSOCIATING_AUTHENTICATED;
2050 ieee->softmac_stats.rx_auth_rs_ok++;
2051 if (!(ieee->ht_info->iot_action & HT_IOT_ACT_PURE_N_MODE)) {
2052 if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) {
2053 if (IsHTHalfNmodeAPs(ieee)) {
2054 bSupportNmode = true;
2055 bHalfSupportNmode = true;
2056 } else {
2057 bSupportNmode = false;
2058 bHalfSupportNmode = false;
2059 }
2060 }
2061 }
2062 /* Dummy wirless mode setting to avoid encryption issue */
2063 if (bSupportNmode) {
2064 ieee->set_wireless_mode(ieee->dev,
2065 ieee->current_network.mode);
2066 } else {
2067 /*TODO*/
2068 ieee->set_wireless_mode(ieee->dev, WIRELESS_MODE_G);
2069 }
2070
2071 if ((ieee->current_network.mode == WIRELESS_MODE_N_24G) &&
2072 bHalfSupportNmode) {
2073 netdev_info(ieee->dev, "======>enter half N mode\n");
2074 ieee->bHalfWirelessN24GMode = true;
2075 } else {
2076 ieee->bHalfWirelessN24GMode = false;
2077 }
2078 rtllib_associate_step2(ieee);
2079 } else {
2080 rtllib_auth_challenge(ieee, challenge, chlen);
2081 }
2082 }
2083
2084 static inline int
rtllib_rx_auth(struct rtllib_device * ieee,struct sk_buff * skb,struct rtllib_rx_stats * rx_stats)2085 rtllib_rx_auth(struct rtllib_device *ieee, struct sk_buff *skb,
2086 struct rtllib_rx_stats *rx_stats)
2087 {
2088 if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) {
2089 if (ieee->link_state == RTLLIB_ASSOCIATING_AUTHENTICATING &&
2090 (ieee->iw_mode == IW_MODE_INFRA)) {
2091 netdev_dbg(ieee->dev,
2092 "Received authentication response");
2093 rtllib_rx_auth_resp(ieee, skb);
2094 }
2095 }
2096 return 0;
2097 }
2098
2099 static inline int
rtllib_rx_deauth(struct rtllib_device * ieee,struct sk_buff * skb)2100 rtllib_rx_deauth(struct rtllib_device *ieee, struct sk_buff *skb)
2101 {
2102 struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *)skb->data;
2103 u16 frame_ctl;
2104
2105 if (memcmp(header->addr3, ieee->current_network.bssid, ETH_ALEN) != 0)
2106 return 0;
2107
2108 /* FIXME for now repeat all the association procedure
2109 * both for disassociation and deauthentication
2110 */
2111 if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
2112 ieee->link_state == MAC80211_LINKED &&
2113 (ieee->iw_mode == IW_MODE_INFRA)) {
2114 frame_ctl = le16_to_cpu(header->frame_ctl);
2115 netdev_info(ieee->dev,
2116 "==========>received disassoc/deauth(%x) frame, reason code:%x\n",
2117 WLAN_FC_GET_STYPE(frame_ctl),
2118 ((struct rtllib_disassoc *)skb->data)->reason);
2119 ieee->link_state = RTLLIB_ASSOCIATING;
2120 ieee->softmac_stats.reassoc++;
2121 ieee->is_roaming = true;
2122 ieee->link_detect_info.bBusyTraffic = false;
2123 rtllib_disassociate(ieee);
2124 RemovePeerTS(ieee, header->addr2);
2125 if (!(ieee->rtllib_ap_sec_type(ieee) &
2126 (SEC_ALG_CCMP | SEC_ALG_TKIP)))
2127 schedule_delayed_work(
2128 &ieee->associate_procedure_wq, 5);
2129 }
2130 return 0;
2131 }
2132
rtllib_rx_frame_softmac(struct rtllib_device * ieee,struct sk_buff * skb,struct rtllib_rx_stats * rx_stats,u16 type,u16 stype)2133 inline int rtllib_rx_frame_softmac(struct rtllib_device *ieee,
2134 struct sk_buff *skb,
2135 struct rtllib_rx_stats *rx_stats, u16 type,
2136 u16 stype)
2137 {
2138 struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *)skb->data;
2139 u16 frame_ctl;
2140
2141 if (!ieee->proto_started)
2142 return 0;
2143
2144 frame_ctl = le16_to_cpu(header->frame_ctl);
2145 switch (WLAN_FC_GET_STYPE(frame_ctl)) {
2146 case RTLLIB_STYPE_ASSOC_RESP:
2147 case RTLLIB_STYPE_REASSOC_RESP:
2148 if (rtllib_rx_assoc_resp(ieee, skb, rx_stats) == 1)
2149 return 1;
2150 break;
2151 case RTLLIB_STYPE_ASSOC_REQ:
2152 case RTLLIB_STYPE_REASSOC_REQ:
2153 break;
2154 case RTLLIB_STYPE_AUTH:
2155 rtllib_rx_auth(ieee, skb, rx_stats);
2156 break;
2157 case RTLLIB_STYPE_DISASSOC:
2158 case RTLLIB_STYPE_DEAUTH:
2159 rtllib_rx_deauth(ieee, skb);
2160 break;
2161 case RTLLIB_STYPE_MANAGE_ACT:
2162 rtllib_process_action(ieee, skb);
2163 break;
2164 default:
2165 return -1;
2166 }
2167 return 0;
2168 }
2169
2170 /* following are for a simpler TX queue management.
2171 * Instead of using netif_[stop/wake]_queue the driver
2172 * will use these two functions (plus a reset one), that
2173 * will internally use the kernel netif_* and takes
2174 * care of the ieee802.11 fragmentation.
2175 * So the driver receives a fragment per time and might
2176 * call the stop function when it wants to not
2177 * have enough room to TX an entire packet.
2178 * This might be useful if each fragment needs it's own
2179 * descriptor, thus just keep a total free memory > than
2180 * the max fragmentation threshold is not enough.. If the
2181 * ieee802.11 stack passed a TXB struct then you need
2182 * to keep N free descriptors where
2183 * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
2184 * In this way you need just one and the 802.11 stack
2185 * will take care of buffering fragments and pass them to
2186 * the driver later, when it wakes the queue.
2187 */
rtllib_softmac_xmit(struct rtllib_txb * txb,struct rtllib_device * ieee)2188 void rtllib_softmac_xmit(struct rtllib_txb *txb, struct rtllib_device *ieee)
2189 {
2190 unsigned int queue_index = txb->queue_index;
2191 unsigned long flags;
2192 int i;
2193 struct cb_desc *tcb_desc = NULL;
2194 unsigned long queue_len = 0;
2195
2196 spin_lock_irqsave(&ieee->lock, flags);
2197
2198 /* called with 2nd parm 0, no tx mgmt lock required */
2199 rtllib_sta_wakeup(ieee, 0);
2200
2201 /* update the tx status */
2202 tcb_desc = (struct cb_desc *)(txb->fragments[0]->cb +
2203 MAX_DEV_ADDR_SIZE);
2204 if (tcb_desc->bMulticast)
2205 ieee->stats.multicast++;
2206
2207 /* if xmit available, just xmit it immediately, else just insert it to
2208 * the wait queue
2209 */
2210 for (i = 0; i < txb->nr_frags; i++) {
2211 queue_len = skb_queue_len(&ieee->skb_waitQ[queue_index]);
2212 if ((queue_len != 0) ||
2213 (!ieee->check_nic_enough_desc(ieee->dev, queue_index)) ||
2214 (ieee->queue_stop)) {
2215 /* insert the skb packet to the wait queue
2216 * as for the completion function, it does not need
2217 * to check it any more.
2218 */
2219 if (queue_len < 200)
2220 skb_queue_tail(&ieee->skb_waitQ[queue_index],
2221 txb->fragments[i]);
2222 else
2223 kfree_skb(txb->fragments[i]);
2224 } else {
2225 ieee->softmac_data_hard_start_xmit(
2226 txb->fragments[i],
2227 ieee->dev, ieee->rate);
2228 }
2229 }
2230
2231 rtllib_txb_free(txb);
2232
2233 spin_unlock_irqrestore(&ieee->lock, flags);
2234 }
2235
rtllib_reset_queue(struct rtllib_device * ieee)2236 void rtllib_reset_queue(struct rtllib_device *ieee)
2237 {
2238 unsigned long flags;
2239
2240 spin_lock_irqsave(&ieee->lock, flags);
2241 init_mgmt_queue(ieee);
2242 if (ieee->tx_pending.txb) {
2243 rtllib_txb_free(ieee->tx_pending.txb);
2244 ieee->tx_pending.txb = NULL;
2245 }
2246 ieee->queue_stop = 0;
2247 spin_unlock_irqrestore(&ieee->lock, flags);
2248 }
2249 EXPORT_SYMBOL(rtllib_reset_queue);
2250
rtllib_stop_all_queues(struct rtllib_device * ieee)2251 void rtllib_stop_all_queues(struct rtllib_device *ieee)
2252 {
2253 unsigned int i;
2254
2255 for (i = 0; i < ieee->dev->num_tx_queues; i++)
2256 txq_trans_cond_update(netdev_get_tx_queue(ieee->dev, i));
2257
2258 netif_tx_stop_all_queues(ieee->dev);
2259 }
2260
rtllib_wake_all_queues(struct rtllib_device * ieee)2261 void rtllib_wake_all_queues(struct rtllib_device *ieee)
2262 {
2263 netif_tx_wake_all_queues(ieee->dev);
2264 }
2265
rtllib_start_monitor_mode(struct rtllib_device * ieee)2266 static void rtllib_start_monitor_mode(struct rtllib_device *ieee)
2267 {
2268 /* reset hardware status */
2269 if (ieee->raw_tx)
2270 netif_carrier_on(ieee->dev);
2271 }
2272
rtllib_start_ibss_wq(void * data)2273 static void rtllib_start_ibss_wq(void *data)
2274 {
2275 struct rtllib_device *ieee = container_of_dwork_rsl(data,
2276 struct rtllib_device, start_ibss_wq);
2277 /* iwconfig mode ad-hoc will schedule this and return
2278 * on the other hand this will block further iwconfig SET
2279 * operations because of the wx_mutex hold.
2280 * Anyway some most set operations set a flag to speed-up
2281 * (abort) this wq (when syncro scanning) before sleeping
2282 * on the mutex
2283 */
2284 if (!ieee->proto_started) {
2285 netdev_info(ieee->dev, "==========oh driver down return\n");
2286 return;
2287 }
2288 mutex_lock(&ieee->wx_mutex);
2289
2290 if (ieee->current_network.ssid_len == 0) {
2291 strscpy(ieee->current_network.ssid, RTLLIB_DEFAULT_TX_ESSID,
2292 sizeof(ieee->current_network.ssid));
2293 ieee->current_network.ssid_len = strlen(RTLLIB_DEFAULT_TX_ESSID);
2294 ieee->ssid_set = 1;
2295 }
2296
2297 ieee->link_state = MAC80211_NOLINK;
2298 ieee->mode = WIRELESS_MODE_G;
2299 /* check if we have this cell in our network list */
2300 rtllib_softmac_check_all_nets(ieee);
2301
2302 /* if not then the state is not linked. Maybe the user switched to
2303 * ad-hoc mode just after being in monitor mode, or just after
2304 * being very few time in managed mode (so the card have had no
2305 * time to scan all the chans..) or we have just run up the iface
2306 * after setting ad-hoc mode. So we have to give another try..
2307 * Here, in ibss mode, should be safe to do this without extra care
2308 * (in bss mode we had to make sure no-one tried to associate when
2309 * we had just checked the ieee->link_state and we was going to start the
2310 * scan) because in ibss mode the rtllib_new_net function, when
2311 * finds a good net, just set the ieee->link_state to MAC80211_LINKED,
2312 * so, at worst, we waste a bit of time to initiate an unneeded syncro
2313 * scan, that will stop at the first round because it sees the state
2314 * associated.
2315 */
2316 if (ieee->link_state == MAC80211_NOLINK)
2317 rtllib_start_scan_syncro(ieee);
2318
2319 /* the network definitively is not here.. create a new cell */
2320 if (ieee->link_state == MAC80211_NOLINK) {
2321 netdev_info(ieee->dev, "creating new IBSS cell\n");
2322 ieee->current_network.channel = ieee->bss_start_channel;
2323 if (!ieee->wap_set)
2324 eth_random_addr(ieee->current_network.bssid);
2325
2326 ieee->current_network.rates_len = 4;
2327 ieee->current_network.rates[0] =
2328 RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_1MB;
2329 ieee->current_network.rates[1] =
2330 RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_2MB;
2331 ieee->current_network.rates[2] =
2332 RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_5MB;
2333 ieee->current_network.rates[3] =
2334 RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_11MB;
2335
2336 ieee->current_network.rates_ex_len = 8;
2337 ieee->current_network.rates_ex[0] =
2338 RTLLIB_OFDM_RATE_6MB;
2339 ieee->current_network.rates_ex[1] =
2340 RTLLIB_OFDM_RATE_9MB;
2341 ieee->current_network.rates_ex[2] =
2342 RTLLIB_OFDM_RATE_12MB;
2343 ieee->current_network.rates_ex[3] =
2344 RTLLIB_OFDM_RATE_18MB;
2345 ieee->current_network.rates_ex[4] =
2346 RTLLIB_OFDM_RATE_24MB;
2347 ieee->current_network.rates_ex[5] =
2348 RTLLIB_OFDM_RATE_36MB;
2349 ieee->current_network.rates_ex[6] =
2350 RTLLIB_OFDM_RATE_48MB;
2351 ieee->current_network.rates_ex[7] =
2352 RTLLIB_OFDM_RATE_54MB;
2353 ieee->rate = 108;
2354
2355 ieee->current_network.qos_data.supported = 0;
2356 ieee->set_wireless_mode(ieee->dev, WIRELESS_MODE_G);
2357 ieee->current_network.mode = ieee->mode;
2358 ieee->current_network.atim_window = 0;
2359 ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
2360 }
2361
2362 netdev_info(ieee->dev, "%s(): ieee->mode = %d\n", __func__, ieee->mode);
2363 if (ieee->mode == WIRELESS_MODE_N_24G)
2364 HTUseDefaultSetting(ieee);
2365 else
2366 ieee->ht_info->bCurrentHTSupport = false;
2367
2368 ieee->SetHwRegHandler(ieee->dev, HW_VAR_MEDIA_STATUS,
2369 (u8 *)(&ieee->link_state));
2370
2371 ieee->link_state = MAC80211_LINKED;
2372 ieee->link_change(ieee->dev);
2373
2374 HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT);
2375 rtllib_start_send_beacons(ieee);
2376
2377 notify_wx_assoc_event(ieee);
2378 netif_carrier_on(ieee->dev);
2379
2380 mutex_unlock(&ieee->wx_mutex);
2381 }
2382
rtllib_start_ibss(struct rtllib_device * ieee)2383 inline void rtllib_start_ibss(struct rtllib_device *ieee)
2384 {
2385 schedule_delayed_work(&ieee->start_ibss_wq, msecs_to_jiffies(150));
2386 }
2387
2388 /* this is called only in user context, with wx_mutex held */
rtllib_start_bss(struct rtllib_device * ieee)2389 static void rtllib_start_bss(struct rtllib_device *ieee)
2390 {
2391 unsigned long flags;
2392
2393 if (IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee)) {
2394 if (!ieee->global_domain)
2395 return;
2396 }
2397 /* check if we have already found the net we
2398 * are interested in (if any).
2399 * if not (we are disassociated and we are not
2400 * in associating / authenticating phase) start the background scanning.
2401 */
2402 rtllib_softmac_check_all_nets(ieee);
2403
2404 /* ensure no-one start an associating process (thus setting
2405 * the ieee->link_state to rtllib_ASSOCIATING) while we
2406 * have just checked it and we are going to enable scan.
2407 * The rtllib_new_net function is always called with
2408 * lock held (from both rtllib_softmac_check_all_nets and
2409 * the rx path), so we cannot be in the middle of such function
2410 */
2411 spin_lock_irqsave(&ieee->lock, flags);
2412
2413 if (ieee->link_state == MAC80211_NOLINK)
2414 rtllib_start_scan(ieee);
2415 spin_unlock_irqrestore(&ieee->lock, flags);
2416 }
2417
rtllib_link_change_wq(void * data)2418 static void rtllib_link_change_wq(void *data)
2419 {
2420 struct rtllib_device *ieee = container_of_dwork_rsl(data,
2421 struct rtllib_device, link_change_wq);
2422 ieee->link_change(ieee->dev);
2423 }
2424 /* called only in userspace context */
rtllib_disassociate(struct rtllib_device * ieee)2425 void rtllib_disassociate(struct rtllib_device *ieee)
2426 {
2427 netif_carrier_off(ieee->dev);
2428 if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
2429 rtllib_reset_queue(ieee);
2430
2431 if (IS_DOT11D_ENABLE(ieee))
2432 dot11d_reset(ieee);
2433 ieee->link_state = MAC80211_NOLINK;
2434 ieee->is_set_key = false;
2435 ieee->wap_set = 0;
2436
2437 schedule_delayed_work(&ieee->link_change_wq, 0);
2438
2439 notify_wx_assoc_event(ieee);
2440 }
2441
rtllib_associate_retry_wq(void * data)2442 static void rtllib_associate_retry_wq(void *data)
2443 {
2444 struct rtllib_device *ieee = container_of_dwork_rsl(data,
2445 struct rtllib_device, associate_retry_wq);
2446 unsigned long flags;
2447
2448 mutex_lock(&ieee->wx_mutex);
2449 if (!ieee->proto_started)
2450 goto exit;
2451
2452 if (ieee->link_state != RTLLIB_ASSOCIATING_RETRY)
2453 goto exit;
2454
2455 /* until we do not set the state to MAC80211_NOLINK
2456 * there are no possibility to have someone else trying
2457 * to start an association procedure (we get here with
2458 * ieee->link_state = RTLLIB_ASSOCIATING).
2459 * When we set the state to MAC80211_NOLINK it is possible
2460 * that the RX path run an attempt to associate, but
2461 * both rtllib_softmac_check_all_nets and the
2462 * RX path works with ieee->lock held so there are no
2463 * problems. If we are still disassociated then start a scan.
2464 * the lock here is necessary to ensure no one try to start
2465 * an association procedure when we have just checked the
2466 * state and we are going to start the scan.
2467 */
2468 ieee->beinretry = true;
2469 ieee->link_state = MAC80211_NOLINK;
2470
2471 rtllib_softmac_check_all_nets(ieee);
2472
2473 spin_lock_irqsave(&ieee->lock, flags);
2474
2475 if (ieee->link_state == MAC80211_NOLINK)
2476 rtllib_start_scan(ieee);
2477 spin_unlock_irqrestore(&ieee->lock, flags);
2478
2479 ieee->beinretry = false;
2480 exit:
2481 mutex_unlock(&ieee->wx_mutex);
2482 }
2483
rtllib_get_beacon_(struct rtllib_device * ieee)2484 static struct sk_buff *rtllib_get_beacon_(struct rtllib_device *ieee)
2485 {
2486 static const u8 broadcast_addr[] = {
2487 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2488 };
2489 struct sk_buff *skb;
2490 struct rtllib_probe_response *b;
2491
2492 skb = rtllib_probe_resp(ieee, broadcast_addr);
2493
2494 if (!skb)
2495 return NULL;
2496
2497 b = (struct rtllib_probe_response *)skb->data;
2498 b->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_BEACON);
2499
2500 return skb;
2501 }
2502
rtllib_get_beacon(struct rtllib_device * ieee)2503 struct sk_buff *rtllib_get_beacon(struct rtllib_device *ieee)
2504 {
2505 struct sk_buff *skb;
2506 struct rtllib_probe_response *b;
2507
2508 skb = rtllib_get_beacon_(ieee);
2509 if (!skb)
2510 return NULL;
2511
2512 b = (struct rtllib_probe_response *)skb->data;
2513 b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2514
2515 if (ieee->seq_ctrl[0] == 0xFFF)
2516 ieee->seq_ctrl[0] = 0;
2517 else
2518 ieee->seq_ctrl[0]++;
2519
2520 return skb;
2521 }
2522 EXPORT_SYMBOL(rtllib_get_beacon);
2523
rtllib_softmac_stop_protocol(struct rtllib_device * ieee,u8 mesh_flag,u8 shutdown)2524 void rtllib_softmac_stop_protocol(struct rtllib_device *ieee, u8 mesh_flag,
2525 u8 shutdown)
2526 {
2527 rtllib_stop_scan_syncro(ieee);
2528 mutex_lock(&ieee->wx_mutex);
2529 rtllib_stop_protocol(ieee, shutdown);
2530 mutex_unlock(&ieee->wx_mutex);
2531 }
2532 EXPORT_SYMBOL(rtllib_softmac_stop_protocol);
2533
rtllib_stop_protocol(struct rtllib_device * ieee,u8 shutdown)2534 void rtllib_stop_protocol(struct rtllib_device *ieee, u8 shutdown)
2535 {
2536 if (!ieee->proto_started)
2537 return;
2538
2539 if (shutdown) {
2540 ieee->proto_started = 0;
2541 ieee->proto_stoppping = 1;
2542 ieee->rtllib_ips_leave(ieee->dev);
2543 }
2544
2545 rtllib_stop_send_beacons(ieee);
2546 del_timer_sync(&ieee->associate_timer);
2547 cancel_delayed_work_sync(&ieee->associate_retry_wq);
2548 cancel_delayed_work_sync(&ieee->start_ibss_wq);
2549 cancel_delayed_work_sync(&ieee->link_change_wq);
2550 rtllib_stop_scan(ieee);
2551
2552 if (ieee->link_state <= RTLLIB_ASSOCIATING_AUTHENTICATED)
2553 ieee->link_state = MAC80211_NOLINK;
2554
2555 if (ieee->link_state == MAC80211_LINKED) {
2556 if (ieee->iw_mode == IW_MODE_INFRA)
2557 SendDisassociation(ieee, 1, WLAN_REASON_DEAUTH_LEAVING);
2558 rtllib_disassociate(ieee);
2559 }
2560
2561 if (shutdown) {
2562 RemoveAllTS(ieee);
2563 ieee->proto_stoppping = 0;
2564 }
2565 kfree(ieee->assocreq_ies);
2566 ieee->assocreq_ies = NULL;
2567 ieee->assocreq_ies_len = 0;
2568 kfree(ieee->assocresp_ies);
2569 ieee->assocresp_ies = NULL;
2570 ieee->assocresp_ies_len = 0;
2571 }
2572
rtllib_softmac_start_protocol(struct rtllib_device * ieee,u8 mesh_flag)2573 void rtllib_softmac_start_protocol(struct rtllib_device *ieee, u8 mesh_flag)
2574 {
2575 mutex_lock(&ieee->wx_mutex);
2576 rtllib_start_protocol(ieee);
2577 mutex_unlock(&ieee->wx_mutex);
2578 }
2579 EXPORT_SYMBOL(rtllib_softmac_start_protocol);
2580
rtllib_start_protocol(struct rtllib_device * ieee)2581 void rtllib_start_protocol(struct rtllib_device *ieee)
2582 {
2583 short ch = 0;
2584 int i = 0;
2585
2586 rtllib_update_active_chan_map(ieee);
2587
2588 if (ieee->proto_started)
2589 return;
2590
2591 ieee->proto_started = 1;
2592
2593 if (ieee->current_network.channel == 0) {
2594 do {
2595 ch++;
2596 if (ch > MAX_CHANNEL_NUMBER)
2597 return; /* no channel found */
2598 } while (!ieee->active_channel_map[ch]);
2599 ieee->current_network.channel = ch;
2600 }
2601
2602 if (ieee->current_network.beacon_interval == 0)
2603 ieee->current_network.beacon_interval = 100;
2604
2605 for (i = 0; i < 17; i++) {
2606 ieee->last_rxseq_num[i] = -1;
2607 ieee->last_rxfrag_num[i] = -1;
2608 ieee->last_packet_time[i] = 0;
2609 }
2610
2611 ieee->wmm_acm = 0;
2612 /* if the user set the MAC of the ad-hoc cell and then
2613 * switch to managed mode, shall we make sure that association
2614 * attempts does not fail just because the user provide the essid
2615 * and the nic is still checking for the AP MAC ??
2616 */
2617 switch (ieee->iw_mode) {
2618 case IW_MODE_INFRA:
2619 rtllib_start_bss(ieee);
2620 break;
2621 case IW_MODE_ADHOC:
2622 rtllib_start_ibss(ieee);
2623 break;
2624 case IW_MODE_MONITOR:
2625 rtllib_start_monitor_mode(ieee);
2626 break;
2627 }
2628 }
2629
rtllib_softmac_init(struct rtllib_device * ieee)2630 int rtllib_softmac_init(struct rtllib_device *ieee)
2631 {
2632 int i;
2633
2634 memset(&ieee->current_network, 0, sizeof(struct rtllib_network));
2635
2636 ieee->link_state = MAC80211_NOLINK;
2637 for (i = 0; i < 5; i++)
2638 ieee->seq_ctrl[i] = 0;
2639 ieee->dot11d_info = kzalloc(sizeof(struct rt_dot11d_info), GFP_ATOMIC);
2640 if (!ieee->dot11d_info)
2641 return -ENOMEM;
2642
2643 ieee->link_detect_info.SlotIndex = 0;
2644 ieee->link_detect_info.SlotNum = 2;
2645 ieee->link_detect_info.NumRecvBcnInPeriod = 0;
2646 ieee->link_detect_info.NumRecvDataInPeriod = 0;
2647 ieee->link_detect_info.NumTxOkInPeriod = 0;
2648 ieee->link_detect_info.NumRxOkInPeriod = 0;
2649 ieee->link_detect_info.NumRxUnicastOkInPeriod = 0;
2650 ieee->bIsAggregateFrame = false;
2651 ieee->assoc_id = 0;
2652 ieee->queue_stop = 0;
2653 ieee->scanning_continue = 0;
2654 ieee->softmac_features = 0;
2655 ieee->wap_set = 0;
2656 ieee->ssid_set = 0;
2657 ieee->proto_started = 0;
2658 ieee->proto_stoppping = 0;
2659 ieee->basic_rate = RTLLIB_DEFAULT_BASIC_RATE;
2660 ieee->rate = 22;
2661 ieee->ps = RTLLIB_PS_DISABLED;
2662 ieee->sta_sleep = LPS_IS_WAKE;
2663
2664 ieee->reg_dot11ht_oper_rate_set[0] = 0xff;
2665 ieee->reg_dot11ht_oper_rate_set[1] = 0xff;
2666 ieee->reg_dot11ht_oper_rate_set[4] = 0x01;
2667
2668 ieee->reg_dot11tx_ht_oper_rate_set[0] = 0xff;
2669 ieee->reg_dot11tx_ht_oper_rate_set[1] = 0xff;
2670 ieee->reg_dot11tx_ht_oper_rate_set[4] = 0x01;
2671
2672 ieee->FirstIe_InScan = false;
2673 ieee->actscanning = false;
2674 ieee->beinretry = false;
2675 ieee->is_set_key = false;
2676 init_mgmt_queue(ieee);
2677
2678 ieee->tx_pending.txb = NULL;
2679
2680 timer_setup(&ieee->associate_timer, rtllib_associate_abort_cb, 0);
2681
2682 timer_setup(&ieee->beacon_timer, rtllib_send_beacon_cb, 0);
2683
2684 INIT_DELAYED_WORK(&ieee->link_change_wq, (void *)rtllib_link_change_wq);
2685 INIT_DELAYED_WORK(&ieee->start_ibss_wq, (void *)rtllib_start_ibss_wq);
2686 INIT_WORK(&ieee->associate_complete_wq, (void *)rtllib_associate_complete_wq);
2687 INIT_DELAYED_WORK(&ieee->associate_procedure_wq, (void *)rtllib_associate_procedure_wq);
2688 INIT_DELAYED_WORK(&ieee->softmac_scan_wq, (void *)rtllib_softmac_scan_wq);
2689 INIT_DELAYED_WORK(&ieee->associate_retry_wq, (void *)rtllib_associate_retry_wq);
2690 INIT_WORK(&ieee->wx_sync_scan_wq, (void *)rtllib_wx_sync_scan_wq);
2691
2692 mutex_init(&ieee->wx_mutex);
2693 mutex_init(&ieee->scan_mutex);
2694 mutex_init(&ieee->ips_mutex);
2695
2696 spin_lock_init(&ieee->mgmt_tx_lock);
2697 spin_lock_init(&ieee->beacon_lock);
2698
2699 INIT_WORK(&ieee->ps_task, rtllib_sta_ps);
2700
2701 return 0;
2702 }
2703
rtllib_softmac_free(struct rtllib_device * ieee)2704 void rtllib_softmac_free(struct rtllib_device *ieee)
2705 {
2706 mutex_lock(&ieee->wx_mutex);
2707 kfree(ieee->dot11d_info);
2708 ieee->dot11d_info = NULL;
2709 del_timer_sync(&ieee->associate_timer);
2710
2711 cancel_delayed_work_sync(&ieee->associate_retry_wq);
2712 cancel_delayed_work_sync(&ieee->associate_procedure_wq);
2713 cancel_delayed_work_sync(&ieee->softmac_scan_wq);
2714 cancel_delayed_work_sync(&ieee->start_ibss_wq);
2715 cancel_delayed_work_sync(&ieee->hw_wakeup_wq);
2716 cancel_delayed_work_sync(&ieee->hw_sleep_wq);
2717 cancel_delayed_work_sync(&ieee->link_change_wq);
2718 cancel_work_sync(&ieee->associate_complete_wq);
2719 cancel_work_sync(&ieee->ips_leave_wq);
2720 cancel_work_sync(&ieee->wx_sync_scan_wq);
2721 cancel_work_sync(&ieee->ps_task);
2722 mutex_unlock(&ieee->wx_mutex);
2723 }
2724
2725 static inline struct sk_buff *
rtllib_disauth_skb(struct rtllib_network * beacon,struct rtllib_device * ieee,u16 asRsn)2726 rtllib_disauth_skb(struct rtllib_network *beacon,
2727 struct rtllib_device *ieee, u16 asRsn)
2728 {
2729 struct sk_buff *skb;
2730 struct rtllib_disauth *disauth;
2731 int len = sizeof(struct rtllib_disauth) + ieee->tx_headroom;
2732
2733 skb = dev_alloc_skb(len);
2734 if (!skb)
2735 return NULL;
2736
2737 skb_reserve(skb, ieee->tx_headroom);
2738
2739 disauth = skb_put(skb, sizeof(struct rtllib_disauth));
2740 disauth->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_DEAUTH);
2741 disauth->header.duration_id = 0;
2742
2743 ether_addr_copy(disauth->header.addr1, beacon->bssid);
2744 ether_addr_copy(disauth->header.addr2, ieee->dev->dev_addr);
2745 ether_addr_copy(disauth->header.addr3, beacon->bssid);
2746
2747 disauth->reason = cpu_to_le16(asRsn);
2748 return skb;
2749 }
2750
2751 static inline struct sk_buff *
rtllib_disassociate_skb(struct rtllib_network * beacon,struct rtllib_device * ieee,u16 asRsn)2752 rtllib_disassociate_skb(struct rtllib_network *beacon,
2753 struct rtllib_device *ieee, u16 asRsn)
2754 {
2755 struct sk_buff *skb;
2756 struct rtllib_disassoc *disass;
2757 int len = sizeof(struct rtllib_disassoc) + ieee->tx_headroom;
2758
2759 skb = dev_alloc_skb(len);
2760
2761 if (!skb)
2762 return NULL;
2763
2764 skb_reserve(skb, ieee->tx_headroom);
2765
2766 disass = skb_put(skb, sizeof(struct rtllib_disassoc));
2767 disass->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_DISASSOC);
2768 disass->header.duration_id = 0;
2769
2770 ether_addr_copy(disass->header.addr1, beacon->bssid);
2771 ether_addr_copy(disass->header.addr2, ieee->dev->dev_addr);
2772 ether_addr_copy(disass->header.addr3, beacon->bssid);
2773
2774 disass->reason = cpu_to_le16(asRsn);
2775 return skb;
2776 }
2777
SendDisassociation(struct rtllib_device * ieee,bool deauth,u16 asRsn)2778 void SendDisassociation(struct rtllib_device *ieee, bool deauth, u16 asRsn)
2779 {
2780 struct rtllib_network *beacon = &ieee->current_network;
2781 struct sk_buff *skb;
2782
2783 if (deauth)
2784 skb = rtllib_disauth_skb(beacon, ieee, asRsn);
2785 else
2786 skb = rtllib_disassociate_skb(beacon, ieee, asRsn);
2787
2788 if (skb)
2789 softmac_mgmt_xmit(skb, ieee);
2790 }
2791
rtllib_ap_sec_type(struct rtllib_device * ieee)2792 u8 rtllib_ap_sec_type(struct rtllib_device *ieee)
2793 {
2794 static u8 ccmp_ie[4] = {0x00, 0x50, 0xf2, 0x04};
2795 static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04};
2796 int wpa_ie_len = ieee->wpa_ie_len;
2797 struct lib80211_crypt_data *crypt;
2798 int encrypt;
2799
2800 crypt = ieee->crypt_info.crypt[ieee->crypt_info.tx_keyidx];
2801 encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY)
2802 || (crypt && crypt->ops && (strcmp(crypt->ops->name, "R-WEP") == 0));
2803
2804 /* simply judge */
2805 if (encrypt && (wpa_ie_len == 0)) {
2806 return SEC_ALG_WEP;
2807 } else if ((wpa_ie_len != 0)) {
2808 if (((ieee->wpa_ie[0] == 0xdd) &&
2809 (!memcmp(&(ieee->wpa_ie[14]), ccmp_ie, 4))) ||
2810 ((ieee->wpa_ie[0] == 0x30) &&
2811 (!memcmp(&ieee->wpa_ie[10], ccmp_rsn_ie, 4))))
2812 return SEC_ALG_CCMP;
2813 else
2814 return SEC_ALG_TKIP;
2815 } else {
2816 return SEC_ALG_NONE;
2817 }
2818 }
2819
rtllib_MgntDisconnectIBSS(struct rtllib_device * rtllib)2820 static void rtllib_MgntDisconnectIBSS(struct rtllib_device *rtllib)
2821 {
2822 u8 OpMode;
2823 u8 i;
2824 bool bFilterOutNonAssociatedBSSID = false;
2825
2826 rtllib->link_state = MAC80211_NOLINK;
2827
2828 for (i = 0; i < 6; i++)
2829 rtllib->current_network.bssid[i] = 0x55;
2830
2831 rtllib->OpMode = RT_OP_MODE_NO_LINK;
2832 rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_BSSID,
2833 rtllib->current_network.bssid);
2834 OpMode = RT_OP_MODE_NO_LINK;
2835 rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_MEDIA_STATUS, &OpMode);
2836 rtllib_stop_send_beacons(rtllib);
2837
2838 bFilterOutNonAssociatedBSSID = false;
2839 rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_CECHK_BSSID,
2840 (u8 *)(&bFilterOutNonAssociatedBSSID));
2841 notify_wx_assoc_event(rtllib);
2842 }
2843
rtllib_MlmeDisassociateRequest(struct rtllib_device * rtllib,u8 * asSta,u8 asRsn)2844 static void rtllib_MlmeDisassociateRequest(struct rtllib_device *rtllib,
2845 u8 *asSta, u8 asRsn)
2846 {
2847 u8 i;
2848 u8 OpMode;
2849
2850 RemovePeerTS(rtllib, asSta);
2851
2852 if (memcmp(rtllib->current_network.bssid, asSta, 6) == 0) {
2853 rtllib->link_state = MAC80211_NOLINK;
2854
2855 for (i = 0; i < 6; i++)
2856 rtllib->current_network.bssid[i] = 0x22;
2857 OpMode = RT_OP_MODE_NO_LINK;
2858 rtllib->OpMode = RT_OP_MODE_NO_LINK;
2859 rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_MEDIA_STATUS,
2860 (u8 *)(&OpMode));
2861 rtllib_disassociate(rtllib);
2862
2863 rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_BSSID,
2864 rtllib->current_network.bssid);
2865 }
2866 }
2867
2868 static void
rtllib_MgntDisconnectAP(struct rtllib_device * rtllib,u8 asRsn)2869 rtllib_MgntDisconnectAP(
2870 struct rtllib_device *rtllib,
2871 u8 asRsn
2872 )
2873 {
2874 bool bFilterOutNonAssociatedBSSID = false;
2875
2876 bFilterOutNonAssociatedBSSID = false;
2877 rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_CECHK_BSSID,
2878 (u8 *)(&bFilterOutNonAssociatedBSSID));
2879 rtllib_MlmeDisassociateRequest(rtllib, rtllib->current_network.bssid,
2880 asRsn);
2881
2882 rtllib->link_state = MAC80211_NOLINK;
2883 }
2884
rtllib_MgntDisconnect(struct rtllib_device * rtllib,u8 asRsn)2885 bool rtllib_MgntDisconnect(struct rtllib_device *rtllib, u8 asRsn)
2886 {
2887 if (rtllib->ps != RTLLIB_PS_DISABLED)
2888 rtllib->sta_wake_up(rtllib->dev);
2889
2890 if (rtllib->link_state == MAC80211_LINKED) {
2891 if (rtllib->iw_mode == IW_MODE_ADHOC)
2892 rtllib_MgntDisconnectIBSS(rtllib);
2893 if (rtllib->iw_mode == IW_MODE_INFRA)
2894 rtllib_MgntDisconnectAP(rtllib, asRsn);
2895 }
2896
2897 return true;
2898 }
2899 EXPORT_SYMBOL(rtllib_MgntDisconnect);
2900
notify_wx_assoc_event(struct rtllib_device * ieee)2901 void notify_wx_assoc_event(struct rtllib_device *ieee)
2902 {
2903 union iwreq_data wrqu;
2904
2905 if (ieee->cannot_notify)
2906 return;
2907
2908 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
2909 if (ieee->link_state == MAC80211_LINKED) {
2910 memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid,
2911 ETH_ALEN);
2912 } else {
2913 netdev_info(ieee->dev, "%s(): Tell user space disconnected\n",
2914 __func__);
2915 eth_zero_addr(wrqu.ap_addr.sa_data);
2916 }
2917 wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
2918 }
2919 EXPORT_SYMBOL(notify_wx_assoc_event);
2920