1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#define _RTL871X_MLME_C_
18
19#include <linux/etherdevice.h>
20
21#include "osdep_service.h"
22#include "drv_types.h"
23#include "recv_osdep.h"
24#include "xmit_osdep.h"
25#include "mlme_osdep.h"
26#include "sta_info.h"
27#include "wifi.h"
28#include "wlan_bssdef.h"
29
30static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len);
31
32int r8712_init_mlme_priv(struct _adapter *padapter)
33{
34 sint i;
35 u8 *pbuf;
36 struct wlan_network *pnetwork;
37 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
38
39 memset((u8 *)pmlmepriv, 0, sizeof(struct mlme_priv));
40 pmlmepriv->nic_hdl = (u8 *)padapter;
41 pmlmepriv->pscanned = NULL;
42 pmlmepriv->fw_state = 0;
43 pmlmepriv->cur_network.network.InfrastructureMode =
44 Ndis802_11AutoUnknown;
45
46 pmlmepriv->passive_mode = 1;
47 spin_lock_init(&(pmlmepriv->lock));
48 spin_lock_init(&(pmlmepriv->lock2));
49 _init_queue(&(pmlmepriv->free_bss_pool));
50 _init_queue(&(pmlmepriv->scanned_queue));
51 set_scanned_network_val(pmlmepriv, 0);
52 memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct ndis_802_11_ssid));
53 pbuf = kmalloc_array(MAX_BSS_CNT, sizeof(struct wlan_network),
54 GFP_ATOMIC);
55 if (!pbuf)
56 return -ENOMEM;
57 pmlmepriv->free_bss_buf = pbuf;
58 pnetwork = (struct wlan_network *)pbuf;
59 for (i = 0; i < MAX_BSS_CNT; i++) {
60 INIT_LIST_HEAD(&(pnetwork->list));
61 list_add_tail(&(pnetwork->list),
62 &(pmlmepriv->free_bss_pool.queue));
63 pnetwork++;
64 }
65 pmlmepriv->sitesurveyctrl.last_rx_pkts = 0;
66 pmlmepriv->sitesurveyctrl.last_tx_pkts = 0;
67 pmlmepriv->sitesurveyctrl.traffic_busy = false;
68
69 r8712_init_mlme_timer(padapter);
70 return 0;
71}
72
73struct wlan_network *_r8712_alloc_network(struct mlme_priv *pmlmepriv)
74{
75 unsigned long irqL;
76 struct wlan_network *pnetwork;
77 struct __queue *free_queue = &pmlmepriv->free_bss_pool;
78
79 spin_lock_irqsave(&free_queue->lock, irqL);
80 pnetwork = list_first_entry_or_null(&free_queue->queue,
81 struct wlan_network, list);
82 if (pnetwork) {
83 list_del_init(&pnetwork->list);
84 pnetwork->last_scanned = jiffies;
85 pmlmepriv->num_of_scanned++;
86 }
87 spin_unlock_irqrestore(&free_queue->lock, irqL);
88 return pnetwork;
89}
90
91static void _free_network(struct mlme_priv *pmlmepriv,
92 struct wlan_network *pnetwork)
93{
94 u32 curr_time, delta_time;
95 unsigned long irqL;
96 struct __queue *free_queue = &(pmlmepriv->free_bss_pool);
97
98 if (!pnetwork)
99 return;
100 if (pnetwork->fixed)
101 return;
102 curr_time = jiffies;
103 delta_time = (curr_time - (u32)pnetwork->last_scanned) / HZ;
104 if (delta_time < SCANQUEUE_LIFETIME)
105 return;
106 spin_lock_irqsave(&free_queue->lock, irqL);
107 list_del_init(&pnetwork->list);
108 list_add_tail(&pnetwork->list, &free_queue->queue);
109 pmlmepriv->num_of_scanned--;
110 spin_unlock_irqrestore(&free_queue->lock, irqL);
111}
112
113static void free_network_nolock(struct mlme_priv *pmlmepriv,
114 struct wlan_network *pnetwork)
115{
116 struct __queue *free_queue = &pmlmepriv->free_bss_pool;
117
118 if (!pnetwork)
119 return;
120 if (pnetwork->fixed)
121 return;
122 list_del_init(&pnetwork->list);
123 list_add_tail(&pnetwork->list, &free_queue->queue);
124 pmlmepriv->num_of_scanned--;
125}
126
127
128
129
130
131
132static struct wlan_network *r8712_find_network(struct __queue *scanned_queue,
133 u8 *addr)
134{
135 unsigned long irqL;
136 struct list_head *phead, *plist;
137 struct wlan_network *pnetwork = NULL;
138
139 if (is_zero_ether_addr(addr))
140 return NULL;
141 spin_lock_irqsave(&scanned_queue->lock, irqL);
142 phead = &scanned_queue->queue;
143 plist = phead->next;
144 while (plist != phead) {
145 pnetwork = container_of(plist, struct wlan_network, list);
146 plist = plist->next;
147 if (!memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN))
148 break;
149 }
150 spin_unlock_irqrestore(&scanned_queue->lock, irqL);
151 return pnetwork;
152}
153
154void r8712_free_network_queue(struct _adapter *padapter)
155{
156 unsigned long irqL;
157 struct list_head *phead, *plist;
158 struct wlan_network *pnetwork;
159 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
160 struct __queue *scanned_queue = &pmlmepriv->scanned_queue;
161
162 spin_lock_irqsave(&scanned_queue->lock, irqL);
163 phead = &scanned_queue->queue;
164 plist = phead->next;
165 while (!end_of_queue_search(phead, plist)) {
166 pnetwork = container_of(plist, struct wlan_network, list);
167 plist = plist->next;
168 _free_network(pmlmepriv, pnetwork);
169 }
170 spin_unlock_irqrestore(&scanned_queue->lock, irqL);
171}
172
173sint r8712_if_up(struct _adapter *padapter)
174{
175 sint res;
176
177 if (padapter->driver_stopped || padapter->surprise_removed ||
178 !check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
179 res = false;
180 } else {
181 res = true;
182 }
183 return res;
184}
185
186void r8712_generate_random_ibss(u8 *pibss)
187{
188 u32 curtime = jiffies;
189
190 pibss[0] = 0x02;
191 pibss[1] = 0x11;
192 pibss[2] = 0x87;
193 pibss[3] = (u8)(curtime & 0xff);
194 pibss[4] = (u8)((curtime >> 8) & 0xff);
195 pibss[5] = (u8)((curtime >> 16) & 0xff);
196}
197
198uint r8712_get_wlan_bssid_ex_sz(struct wlan_bssid_ex *bss)
199{
200 return sizeof(*bss) + bss->IELength - MAX_IE_SZ;
201}
202
203u8 *r8712_get_capability_from_ie(u8 *ie)
204{
205 return ie + 8 + 2;
206}
207
208void r8712_free_mlme_priv(struct mlme_priv *pmlmepriv)
209{
210 kfree(pmlmepriv->free_bss_buf);
211}
212
213static struct wlan_network *alloc_network(struct mlme_priv *pmlmepriv)
214{
215 return _r8712_alloc_network(pmlmepriv);
216}
217
218int r8712_is_same_ibss(struct _adapter *adapter, struct wlan_network *pnetwork)
219{
220 int ret = true;
221 struct security_priv *psecuritypriv = &adapter->securitypriv;
222
223 if ((psecuritypriv->PrivacyAlgrthm != _NO_PRIVACY_) &&
224 (pnetwork->network.Privacy == cpu_to_le32(0)))
225 ret = false;
226 else if ((psecuritypriv->PrivacyAlgrthm == _NO_PRIVACY_) &&
227 (pnetwork->network.Privacy == cpu_to_le32(1)))
228 ret = false;
229 else
230 ret = true;
231 return ret;
232
233}
234
235static int is_same_network(struct wlan_bssid_ex *src,
236 struct wlan_bssid_ex *dst)
237{
238 u16 s_cap, d_cap;
239
240 memcpy((u8 *)&s_cap, r8712_get_capability_from_ie(src->IEs), 2);
241 memcpy((u8 *)&d_cap, r8712_get_capability_from_ie(dst->IEs), 2);
242 return (src->Ssid.SsidLength == dst->Ssid.SsidLength) &&
243 (src->Configuration.DSConfig ==
244 dst->Configuration.DSConfig) &&
245 ((!memcmp(src->MacAddress, dst->MacAddress,
246 ETH_ALEN))) &&
247 ((!memcmp(src->Ssid.Ssid,
248 dst->Ssid.Ssid,
249 src->Ssid.SsidLength))) &&
250 ((s_cap & WLAN_CAPABILITY_IBSS) ==
251 (d_cap & WLAN_CAPABILITY_IBSS)) &&
252 ((s_cap & WLAN_CAPABILITY_ESS) ==
253 (d_cap & WLAN_CAPABILITY_ESS));
254
255}
256
257struct wlan_network *r8712_get_oldest_wlan_network(
258 struct __queue *scanned_queue)
259{
260 struct list_head *plist, *phead;
261 struct wlan_network *pwlan = NULL;
262 struct wlan_network *oldest = NULL;
263
264 phead = &scanned_queue->queue;
265 plist = phead->next;
266 while (1) {
267 if (end_of_queue_search(phead, plist))
268 break;
269 pwlan = container_of(plist, struct wlan_network, list);
270 if (!pwlan->fixed) {
271 if (!oldest ||
272 time_after((unsigned long)oldest->last_scanned,
273 (unsigned long)pwlan->last_scanned))
274 oldest = pwlan;
275 }
276 plist = plist->next;
277 }
278 return oldest;
279}
280
281static void update_network(struct wlan_bssid_ex *dst,
282 struct wlan_bssid_ex *src,
283 struct _adapter *padapter)
284{
285 u32 last_evm = 0, tmpVal;
286 struct smooth_rssi_data *sqd = &padapter->recvpriv.signal_qual_data;
287
288 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) &&
289 is_same_network(&(padapter->mlmepriv.cur_network.network), src)) {
290 if (padapter->recvpriv.signal_qual_data.total_num++ >=
291 PHY_LINKQUALITY_SLID_WIN_MAX) {
292 padapter->recvpriv.signal_qual_data.total_num =
293 PHY_LINKQUALITY_SLID_WIN_MAX;
294 last_evm = sqd->elements[sqd->index];
295 padapter->recvpriv.signal_qual_data.total_val -=
296 last_evm;
297 }
298 padapter->recvpriv.signal_qual_data.total_val += src->Rssi;
299
300 sqd->elements[sqd->index++] = src->Rssi;
301 if (padapter->recvpriv.signal_qual_data.index >=
302 PHY_LINKQUALITY_SLID_WIN_MAX)
303 padapter->recvpriv.signal_qual_data.index = 0;
304
305 tmpVal = padapter->recvpriv.signal_qual_data.total_val /
306 padapter->recvpriv.signal_qual_data.total_num;
307 padapter->recvpriv.signal = (u8)tmpVal;
308
309 src->Rssi = padapter->recvpriv.signal;
310 } else {
311 src->Rssi = (src->Rssi + dst->Rssi) / 2;
312 }
313 memcpy((u8 *)dst, (u8 *)src, r8712_get_wlan_bssid_ex_sz(src));
314}
315
316static void update_current_network(struct _adapter *adapter,
317 struct wlan_bssid_ex *pnetwork)
318{
319 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
320
321 if (is_same_network(&(pmlmepriv->cur_network.network), pnetwork)) {
322 update_network(&(pmlmepriv->cur_network.network),
323 pnetwork, adapter);
324 r8712_update_protection(adapter,
325 (pmlmepriv->cur_network.network.IEs) +
326 sizeof(struct NDIS_802_11_FIXED_IEs),
327 pmlmepriv->cur_network.network.IELength);
328 }
329}
330
331
332static void update_scanned_network(struct _adapter *adapter,
333 struct wlan_bssid_ex *target)
334{
335 struct list_head *plist, *phead;
336
337 u32 bssid_ex_sz;
338 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
339 struct __queue *queue = &pmlmepriv->scanned_queue;
340 struct wlan_network *pnetwork = NULL;
341 struct wlan_network *oldest = NULL;
342
343 phead = &queue->queue;
344 plist = phead->next;
345
346 while (1) {
347 if (end_of_queue_search(phead, plist))
348 break;
349
350 pnetwork = container_of(plist, struct wlan_network, list);
351 if (is_same_network(&pnetwork->network, target))
352 break;
353 if ((oldest == ((struct wlan_network *)0)) ||
354 time_after((unsigned long)oldest->last_scanned,
355 (unsigned long)pnetwork->last_scanned))
356 oldest = pnetwork;
357
358 plist = plist->next;
359 }
360
361
362
363
364
365 if (end_of_queue_search(phead, plist)) {
366 if (list_empty(&pmlmepriv->free_bss_pool.queue)) {
367
368 pnetwork = oldest;
369 target->Rssi = (pnetwork->network.Rssi +
370 target->Rssi) / 2;
371 memcpy(&pnetwork->network, target,
372 r8712_get_wlan_bssid_ex_sz(target));
373 pnetwork->last_scanned = jiffies;
374 } else {
375
376
377 pnetwork = alloc_network(pmlmepriv);
378 if (!pnetwork)
379 return;
380 bssid_ex_sz = r8712_get_wlan_bssid_ex_sz(target);
381 target->Length = bssid_ex_sz;
382 memcpy(&pnetwork->network, target, bssid_ex_sz);
383 list_add_tail(&pnetwork->list, &queue->queue);
384 }
385 } else {
386
387
388
389
390
391 update_network(&pnetwork->network, target, adapter);
392 pnetwork->last_scanned = jiffies;
393 }
394}
395
396static void rtl8711_add_network(struct _adapter *adapter,
397 struct wlan_bssid_ex *pnetwork)
398{
399 unsigned long irqL;
400 struct mlme_priv *pmlmepriv = &(((struct _adapter *)adapter)->mlmepriv);
401 struct __queue *queue = &pmlmepriv->scanned_queue;
402
403 spin_lock_irqsave(&queue->lock, irqL);
404 update_current_network(adapter, pnetwork);
405 update_scanned_network(adapter, pnetwork);
406 spin_unlock_irqrestore(&queue->lock, irqL);
407}
408
409
410
411
412
413
414
415
416static int is_desired_network(struct _adapter *adapter,
417 struct wlan_network *pnetwork)
418{
419 u8 wps_ie[512];
420 uint wps_ielen;
421 int bselected = true;
422 struct security_priv *psecuritypriv = &adapter->securitypriv;
423
424 if (psecuritypriv->wps_phase) {
425 if (r8712_get_wps_ie(pnetwork->network.IEs,
426 pnetwork->network.IELength, wps_ie,
427 &wps_ielen))
428 return true;
429 return false;
430 }
431 if ((psecuritypriv->PrivacyAlgrthm != _NO_PRIVACY_) &&
432 (pnetwork->network.Privacy == 0))
433 bselected = false;
434 if (check_fwstate(&adapter->mlmepriv, WIFI_ADHOC_STATE)) {
435 if (pnetwork->network.InfrastructureMode !=
436 adapter->mlmepriv.cur_network.network.
437 InfrastructureMode)
438 bselected = false;
439 }
440 return bselected;
441}
442
443
444void r8712_atimdone_event_callback(struct _adapter *adapter, u8 *pbuf)
445{
446}
447
448void r8712_survey_event_callback(struct _adapter *adapter, u8 *pbuf)
449{
450 unsigned long flags;
451 u32 len;
452 struct wlan_bssid_ex *pnetwork;
453 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
454
455 pnetwork = (struct wlan_bssid_ex *)pbuf;
456#ifdef __BIG_ENDIAN
457
458 pnetwork->Length = le32_to_cpu(pnetwork->Length);
459 pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength);
460 pnetwork->Privacy = le32_to_cpu(pnetwork->Privacy);
461 pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi);
462 pnetwork->NetworkTypeInUse = le32_to_cpu(pnetwork->NetworkTypeInUse);
463 pnetwork->Configuration.ATIMWindow =
464 le32_to_cpu(pnetwork->Configuration.ATIMWindow);
465 pnetwork->Configuration.BeaconPeriod =
466 le32_to_cpu(pnetwork->Configuration.BeaconPeriod);
467 pnetwork->Configuration.DSConfig =
468 le32_to_cpu(pnetwork->Configuration.DSConfig);
469 pnetwork->Configuration.FHConfig.DwellTime =
470 le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime);
471 pnetwork->Configuration.FHConfig.HopPattern =
472 le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern);
473 pnetwork->Configuration.FHConfig.HopSet =
474 le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet);
475 pnetwork->Configuration.FHConfig.Length =
476 le32_to_cpu(pnetwork->Configuration.FHConfig.Length);
477 pnetwork->Configuration.Length =
478 le32_to_cpu(pnetwork->Configuration.Length);
479 pnetwork->InfrastructureMode =
480 le32_to_cpu(pnetwork->InfrastructureMode);
481 pnetwork->IELength = le32_to_cpu(pnetwork->IELength);
482#endif
483 len = r8712_get_wlan_bssid_ex_sz(pnetwork);
484 if (len > sizeof(struct wlan_bssid_ex))
485 return;
486 spin_lock_irqsave(&pmlmepriv->lock2, flags);
487
488 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
489 if (!memcmp(&(pmlmepriv->cur_network.network.MacAddress),
490 pnetwork->MacAddress, ETH_ALEN)) {
491 struct wlan_network *ibss_wlan = NULL;
492
493 memcpy(pmlmepriv->cur_network.network.IEs,
494 pnetwork->IEs, 8);
495 ibss_wlan = r8712_find_network(
496 &pmlmepriv->scanned_queue,
497 pnetwork->MacAddress);
498 if (ibss_wlan) {
499 memcpy(ibss_wlan->network.IEs,
500 pnetwork->IEs, 8);
501 goto exit;
502 }
503 }
504 }
505
506 if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
507 if (pnetwork->Ssid.Ssid[0] != 0) {
508 rtl8711_add_network(adapter, pnetwork);
509 } else {
510 pnetwork->Ssid.SsidLength = 8;
511 memcpy(pnetwork->Ssid.Ssid, "<hidden>", 8);
512 rtl8711_add_network(adapter, pnetwork);
513 }
514 }
515exit:
516 spin_unlock_irqrestore(&pmlmepriv->lock2, flags);
517}
518
519void r8712_surveydone_event_callback(struct _adapter *adapter, u8 *pbuf)
520{
521 unsigned long irqL;
522 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
523
524 spin_lock_irqsave(&pmlmepriv->lock, irqL);
525
526 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
527 del_timer(&pmlmepriv->scan_to_timer);
528
529 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
530 }
531
532 if (pmlmepriv->to_join) {
533 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
534 if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
535 set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
536
537 if (!r8712_select_and_join_from_scan(pmlmepriv)) {
538 mod_timer(&pmlmepriv->assoc_timer, jiffies +
539 msecs_to_jiffies(MAX_JOIN_TIMEOUT));
540 } else {
541 struct wlan_bssid_ex *pdev_network =
542 &(adapter->registrypriv.dev_network);
543 u8 *pibss =
544 adapter->registrypriv.
545 dev_network.MacAddress;
546 pmlmepriv->fw_state ^= _FW_UNDER_SURVEY;
547 memcpy(&pdev_network->Ssid,
548 &pmlmepriv->assoc_ssid,
549 sizeof(struct
550 ndis_802_11_ssid));
551 r8712_update_registrypriv_dev_network
552 (adapter);
553 r8712_generate_random_ibss(pibss);
554 pmlmepriv->fw_state =
555 WIFI_ADHOC_MASTER_STATE;
556 pmlmepriv->to_join = false;
557 }
558 }
559 } else {
560 pmlmepriv->to_join = false;
561 set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
562 if (!r8712_select_and_join_from_scan(pmlmepriv))
563 mod_timer(&pmlmepriv->assoc_timer, jiffies +
564 msecs_to_jiffies(MAX_JOIN_TIMEOUT));
565 else
566 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
567 }
568 }
569 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
570}
571
572
573
574
575void r8712_free_assoc_resources(struct _adapter *adapter)
576{
577 unsigned long irqL;
578 struct wlan_network *pwlan = NULL;
579 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
580 struct sta_priv *pstapriv = &adapter->stapriv;
581 struct wlan_network *tgt_network = &pmlmepriv->cur_network;
582
583 pwlan = r8712_find_network(&pmlmepriv->scanned_queue,
584 tgt_network->network.MacAddress);
585
586 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_AP_STATE)) {
587 struct sta_info *psta;
588
589 psta = r8712_get_stainfo(&adapter->stapriv,
590 tgt_network->network.MacAddress);
591
592 spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL);
593 r8712_free_stainfo(adapter, psta);
594 spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL);
595 }
596
597 if (check_fwstate(pmlmepriv,
598 WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE))
599 r8712_free_all_stainfo(adapter);
600 if (pwlan)
601 pwlan->fixed = false;
602
603 if (((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) &&
604 (adapter->stapriv.asoc_sta_count == 1)))
605 free_network_nolock(pmlmepriv, pwlan);
606}
607
608
609
610
611void r8712_indicate_connect(struct _adapter *padapter)
612{
613 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
614
615 pmlmepriv->to_join = false;
616 set_fwstate(pmlmepriv, _FW_LINKED);
617 padapter->ledpriv.LedControlHandler(padapter, LED_CTL_LINK);
618 r8712_os_indicate_connect(padapter);
619 if (padapter->registrypriv.power_mgnt > PS_MODE_ACTIVE)
620 mod_timer(&pmlmepriv->dhcp_timer,
621 jiffies + msecs_to_jiffies(60000));
622}
623
624
625
626
627
628void r8712_ind_disconnect(struct _adapter *padapter)
629{
630 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
631
632 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
633 _clr_fwstate_(pmlmepriv, _FW_LINKED);
634 padapter->ledpriv.LedControlHandler(padapter, LED_CTL_NO_LINK);
635 r8712_os_indicate_disconnect(padapter);
636 }
637 if (padapter->pwrctrlpriv.pwr_mode !=
638 padapter->registrypriv.power_mgnt) {
639 del_timer(&pmlmepriv->dhcp_timer);
640 r8712_set_ps_mode(padapter, padapter->registrypriv.power_mgnt,
641 padapter->registrypriv.smart_ps);
642 }
643}
644
645
646
647
648
649
650
651
652
653
654
655void r8712_joinbss_event_callback(struct _adapter *adapter, u8 *pbuf)
656{
657 unsigned long irqL = 0, irqL2;
658 struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL;
659 struct sta_priv *pstapriv = &adapter->stapriv;
660 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
661 struct wlan_network *cur_network = &pmlmepriv->cur_network;
662 struct wlan_network *pcur_wlan = NULL, *ptarget_wlan = NULL;
663 unsigned int the_same_macaddr = false;
664 struct wlan_network *pnetwork;
665
666 if (sizeof(struct list_head) == 4 * sizeof(u32)) {
667 pnetwork = kmalloc(sizeof(struct wlan_network), GFP_ATOMIC);
668 if (!pnetwork)
669 return;
670 memcpy((u8 *)pnetwork + 16, (u8 *)pbuf + 8,
671 sizeof(struct wlan_network) - 16);
672 } else {
673 pnetwork = (struct wlan_network *)pbuf;
674 }
675
676#ifdef __BIG_ENDIAN
677
678 pnetwork->join_res = le32_to_cpu(pnetwork->join_res);
679 pnetwork->network_type = le32_to_cpu(pnetwork->network_type);
680 pnetwork->network.Length = le32_to_cpu(pnetwork->network.Length);
681 pnetwork->network.Ssid.SsidLength =
682 le32_to_cpu(pnetwork->network.Ssid.SsidLength);
683 pnetwork->network.Privacy = le32_to_cpu(pnetwork->network.Privacy);
684 pnetwork->network.Rssi = le32_to_cpu(pnetwork->network.Rssi);
685 pnetwork->network.NetworkTypeInUse =
686 le32_to_cpu(pnetwork->network.NetworkTypeInUse);
687 pnetwork->network.Configuration.ATIMWindow =
688 le32_to_cpu(pnetwork->network.Configuration.ATIMWindow);
689 pnetwork->network.Configuration.BeaconPeriod =
690 le32_to_cpu(pnetwork->network.Configuration.BeaconPeriod);
691 pnetwork->network.Configuration.DSConfig =
692 le32_to_cpu(pnetwork->network.Configuration.DSConfig);
693 pnetwork->network.Configuration.FHConfig.DwellTime =
694 le32_to_cpu(pnetwork->network.Configuration.FHConfig.
695 DwellTime);
696 pnetwork->network.Configuration.FHConfig.HopPattern =
697 le32_to_cpu(pnetwork->network.Configuration.
698 FHConfig.HopPattern);
699 pnetwork->network.Configuration.FHConfig.HopSet =
700 le32_to_cpu(pnetwork->network.Configuration.FHConfig.HopSet);
701 pnetwork->network.Configuration.FHConfig.Length =
702 le32_to_cpu(pnetwork->network.Configuration.FHConfig.Length);
703 pnetwork->network.Configuration.Length =
704 le32_to_cpu(pnetwork->network.Configuration.Length);
705 pnetwork->network.InfrastructureMode =
706 le32_to_cpu(pnetwork->network.InfrastructureMode);
707 pnetwork->network.IELength = le32_to_cpu(pnetwork->network.IELength);
708#endif
709
710 the_same_macaddr = !memcmp(pnetwork->network.MacAddress,
711 cur_network->network.MacAddress, ETH_ALEN);
712 pnetwork->network.Length =
713 r8712_get_wlan_bssid_ex_sz(&pnetwork->network);
714 spin_lock_irqsave(&pmlmepriv->lock, irqL);
715 if (pnetwork->network.Length > sizeof(struct wlan_bssid_ex))
716 goto ignore_joinbss_callback;
717 if (pnetwork->join_res > 0) {
718 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
719
720 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
721 if (the_same_macaddr) {
722 ptarget_wlan =
723 r8712_find_network(&pmlmepriv->
724 scanned_queue,
725 cur_network->network.MacAddress);
726 } else {
727 pcur_wlan =
728 r8712_find_network(&pmlmepriv->
729 scanned_queue,
730 cur_network->network.MacAddress);
731 pcur_wlan->fixed = false;
732
733 pcur_sta = r8712_get_stainfo(pstapriv,
734 cur_network->network.MacAddress);
735 spin_lock_irqsave(&pstapriv->
736 sta_hash_lock, irqL2);
737 r8712_free_stainfo(adapter, pcur_sta);
738 spin_unlock_irqrestore(&(pstapriv->
739 sta_hash_lock), irqL2);
740
741 ptarget_wlan =
742 r8712_find_network(&pmlmepriv->
743 scanned_queue,
744 pnetwork->network.
745 MacAddress);
746 if (ptarget_wlan)
747 ptarget_wlan->fixed = true;
748 }
749 } else {
750 ptarget_wlan = r8712_find_network(&pmlmepriv->
751 scanned_queue,
752 pnetwork->network.MacAddress);
753 if (ptarget_wlan)
754 ptarget_wlan->fixed = true;
755 }
756
757 if (ptarget_wlan == NULL) {
758 if (check_fwstate(pmlmepriv,
759 _FW_UNDER_LINKING))
760 pmlmepriv->fw_state ^=
761 _FW_UNDER_LINKING;
762 goto ignore_joinbss_callback;
763 }
764
765
766 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
767 if (the_same_macaddr) {
768 ptarget_sta =
769 r8712_get_stainfo(pstapriv,
770 pnetwork->network.MacAddress);
771 if (ptarget_sta == NULL)
772 ptarget_sta =
773 r8712_alloc_stainfo(pstapriv,
774 pnetwork->network.MacAddress);
775 } else {
776 ptarget_sta =
777 r8712_alloc_stainfo(pstapriv,
778 pnetwork->network.MacAddress);
779 }
780 if (ptarget_sta) {
781 ptarget_sta->aid = pnetwork->join_res;
782 ptarget_sta->qos_option = 1;
783 ptarget_sta->mac_id = 5;
784 if (adapter->securitypriv.
785 AuthAlgrthm == 2) {
786 adapter->securitypriv.
787 binstallGrpkey =
788 false;
789 adapter->securitypriv.
790 busetkipkey =
791 false;
792 adapter->securitypriv.
793 bgrpkey_handshake =
794 false;
795 ptarget_sta->ieee8021x_blocked
796 = true;
797 ptarget_sta->XPrivacy =
798 adapter->securitypriv.
799 PrivacyAlgrthm;
800 memset((u8 *)&ptarget_sta->
801 x_UncstKey,
802 0,
803 sizeof(union Keytype));
804 memset((u8 *)&ptarget_sta->
805 tkiprxmickey,
806 0,
807 sizeof(union Keytype));
808 memset((u8 *)&ptarget_sta->
809 tkiptxmickey,
810 0,
811 sizeof(union Keytype));
812 memset((u8 *)&ptarget_sta->
813 txpn, 0,
814 sizeof(union pn48));
815 memset((u8 *)&ptarget_sta->
816 rxpn, 0,
817 sizeof(union pn48));
818 }
819 } else {
820 if (check_fwstate(pmlmepriv,
821 _FW_UNDER_LINKING))
822 pmlmepriv->fw_state ^=
823 _FW_UNDER_LINKING;
824 goto ignore_joinbss_callback;
825 }
826 }
827
828
829 memcpy(&cur_network->network, &pnetwork->network,
830 pnetwork->network.Length);
831 cur_network->aid = pnetwork->join_res;
832
833 switch (pnetwork->network.InfrastructureMode) {
834 case Ndis802_11Infrastructure:
835 pmlmepriv->fw_state = WIFI_STATION_STATE;
836 break;
837 case Ndis802_11IBSS:
838 pmlmepriv->fw_state = WIFI_ADHOC_STATE;
839 break;
840 default:
841 pmlmepriv->fw_state = WIFI_NULL_STATE;
842 break;
843 }
844 r8712_update_protection(adapter,
845 (cur_network->network.IEs) +
846 sizeof(struct NDIS_802_11_FIXED_IEs),
847 (cur_network->network.IELength));
848
849 update_ht_cap(adapter, cur_network->network.IEs,
850 cur_network->network.IELength);
851
852 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
853 r8712_indicate_connect(adapter);
854 del_timer(&pmlmepriv->assoc_timer);
855 } else {
856 goto ignore_joinbss_callback;
857 }
858 } else {
859 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
860 mod_timer(&pmlmepriv->assoc_timer,
861 jiffies + msecs_to_jiffies(1));
862 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
863 }
864 }
865ignore_joinbss_callback:
866 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
867 if (sizeof(struct list_head) == 4 * sizeof(u32))
868 kfree(pnetwork);
869}
870
871void r8712_stassoc_event_callback(struct _adapter *adapter, u8 *pbuf)
872{
873 unsigned long irqL;
874 struct sta_info *psta;
875 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
876 struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf;
877
878
879 if (!r8712_access_ctrl(&adapter->acl_list, pstassoc->macaddr))
880 return;
881 psta = r8712_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
882 if (psta != NULL) {
883
884
885
886
887 return;
888 }
889
890 psta = r8712_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr);
891 if (psta == NULL)
892 return;
893
894 psta->qos_option = 0;
895 psta->mac_id = le32_to_cpu(pstassoc->cam_id);
896
897
898 if (adapter->securitypriv.AuthAlgrthm == 2)
899 psta->XPrivacy = adapter->securitypriv.PrivacyAlgrthm;
900 psta->ieee8021x_blocked = false;
901 spin_lock_irqsave(&pmlmepriv->lock, irqL);
902 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
903 check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
904 if (adapter->stapriv.asoc_sta_count == 2) {
905
906 r8712_indicate_connect(adapter);
907 }
908 }
909 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
910}
911
912void r8712_stadel_event_callback(struct _adapter *adapter, u8 *pbuf)
913{
914 unsigned long irqL, irqL2;
915 struct sta_info *psta;
916 struct wlan_network *pwlan = NULL;
917 struct wlan_bssid_ex *pdev_network = NULL;
918 u8 *pibss = NULL;
919 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
920 struct stadel_event *pstadel = (struct stadel_event *)pbuf;
921 struct sta_priv *pstapriv = &adapter->stapriv;
922 struct wlan_network *tgt_network = &pmlmepriv->cur_network;
923
924 spin_lock_irqsave(&pmlmepriv->lock, irqL2);
925 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
926 r8712_ind_disconnect(adapter);
927 r8712_free_assoc_resources(adapter);
928 }
929 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE |
930 WIFI_ADHOC_STATE)) {
931 psta = r8712_get_stainfo(&adapter->stapriv, pstadel->macaddr);
932 spin_lock_irqsave(&pstapriv->sta_hash_lock, irqL);
933 r8712_free_stainfo(adapter, psta);
934 spin_unlock_irqrestore(&pstapriv->sta_hash_lock, irqL);
935 if (adapter->stapriv.asoc_sta_count == 1) {
936
937 pwlan = r8712_find_network(&pmlmepriv->scanned_queue,
938 tgt_network->network.MacAddress);
939 if (pwlan) {
940 pwlan->fixed = false;
941 free_network_nolock(pmlmepriv, pwlan);
942 }
943
944 pdev_network = &(adapter->registrypriv.dev_network);
945 pibss = adapter->registrypriv.dev_network.MacAddress;
946 memcpy(pdev_network, &tgt_network->network,
947 r8712_get_wlan_bssid_ex_sz(&tgt_network->
948 network));
949 memcpy(&pdev_network->Ssid,
950 &pmlmepriv->assoc_ssid,
951 sizeof(struct ndis_802_11_ssid));
952 r8712_update_registrypriv_dev_network(adapter);
953 r8712_generate_random_ibss(pibss);
954 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
955 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE);
956 set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
957 }
958 }
959 }
960 spin_unlock_irqrestore(&pmlmepriv->lock, irqL2);
961}
962
963void r8712_cpwm_event_callback(struct _adapter *adapter, u8 *pbuf)
964{
965 struct reportpwrstate_parm *preportpwrstate =
966 (struct reportpwrstate_parm *)pbuf;
967
968 preportpwrstate->state |= (u8)(adapter->pwrctrlpriv.cpwm_tog + 0x80);
969 r8712_cpwm_int_hdl(adapter, preportpwrstate);
970}
971
972
973
974
975
976
977
978
979
980
981void r8712_got_addbareq_event_callback(struct _adapter *adapter, u8 *pbuf)
982{
983 struct ADDBA_Req_Report_parm *pAddbareq_pram =
984 (struct ADDBA_Req_Report_parm *)pbuf;
985 struct sta_info *psta;
986 struct sta_priv *pstapriv = &adapter->stapriv;
987 struct recv_reorder_ctrl *precvreorder_ctrl = NULL;
988
989 psta = r8712_get_stainfo(pstapriv, pAddbareq_pram->MacAddress);
990 if (psta) {
991 precvreorder_ctrl =
992 &psta->recvreorder_ctrl[pAddbareq_pram->tid];
993
994
995
996 precvreorder_ctrl->indicate_seq = 0xffff;
997 }
998}
999
1000void r8712_wpspbc_event_callback(struct _adapter *adapter, u8 *pbuf)
1001{
1002 if (!adapter->securitypriv.wps_hw_pbc_pressed)
1003 adapter->securitypriv.wps_hw_pbc_pressed = true;
1004}
1005
1006void _r8712_sitesurvey_ctrl_handler(struct _adapter *adapter)
1007{
1008 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1009 struct sitesurvey_ctrl *psitesurveyctrl = &pmlmepriv->sitesurveyctrl;
1010 struct registry_priv *pregistrypriv = &adapter->registrypriv;
1011 u64 current_tx_pkts;
1012 uint current_rx_pkts;
1013
1014 current_tx_pkts = (adapter->xmitpriv.tx_pkts) -
1015 (psitesurveyctrl->last_tx_pkts);
1016 current_rx_pkts = (adapter->recvpriv.rx_pkts) -
1017 (psitesurveyctrl->last_rx_pkts);
1018 psitesurveyctrl->last_tx_pkts = adapter->xmitpriv.tx_pkts;
1019 psitesurveyctrl->last_rx_pkts = adapter->recvpriv.rx_pkts;
1020 if ((current_tx_pkts > pregistrypriv->busy_thresh) ||
1021 (current_rx_pkts > pregistrypriv->busy_thresh))
1022 psitesurveyctrl->traffic_busy = true;
1023 else
1024 psitesurveyctrl->traffic_busy = false;
1025}
1026
1027void _r8712_join_timeout_handler(struct _adapter *adapter)
1028{
1029 unsigned long irqL;
1030 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1031
1032 if (adapter->driver_stopped || adapter->surprise_removed)
1033 return;
1034 spin_lock_irqsave(&pmlmepriv->lock, irqL);
1035 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1036 pmlmepriv->to_join = false;
1037 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1038 r8712_os_indicate_disconnect(adapter);
1039 _clr_fwstate_(pmlmepriv, _FW_LINKED);
1040 }
1041 if (adapter->pwrctrlpriv.pwr_mode != adapter->registrypriv.power_mgnt) {
1042 r8712_set_ps_mode(adapter, adapter->registrypriv.power_mgnt,
1043 adapter->registrypriv.smart_ps);
1044 }
1045 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
1046}
1047
1048void r8712_scan_timeout_handler (struct _adapter *adapter)
1049{
1050 unsigned long irqL;
1051 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1052
1053 spin_lock_irqsave(&pmlmepriv->lock, irqL);
1054 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
1055 pmlmepriv->to_join = false;
1056 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
1057}
1058
1059void _r8712_dhcp_timeout_handler (struct _adapter *adapter)
1060{
1061 if (adapter->driver_stopped || adapter->surprise_removed)
1062 return;
1063 if (adapter->pwrctrlpriv.pwr_mode != adapter->registrypriv.power_mgnt)
1064 r8712_set_ps_mode(adapter, adapter->registrypriv.power_mgnt,
1065 adapter->registrypriv.smart_ps);
1066}
1067
1068int r8712_select_and_join_from_scan(struct mlme_priv *pmlmepriv)
1069{
1070 struct list_head *phead;
1071 unsigned char *dst_ssid, *src_ssid;
1072 struct _adapter *adapter;
1073 struct __queue *queue = NULL;
1074 struct wlan_network *pnetwork = NULL;
1075 struct wlan_network *pnetwork_max_rssi = NULL;
1076
1077 adapter = (struct _adapter *)pmlmepriv->nic_hdl;
1078 queue = &pmlmepriv->scanned_queue;
1079 phead = &queue->queue;
1080 pmlmepriv->pscanned = phead->next;
1081 while (1) {
1082 if (end_of_queue_search(phead, pmlmepriv->pscanned)) {
1083 if ((pmlmepriv->assoc_by_rssi) &&
1084 (pnetwork_max_rssi != NULL)) {
1085 pnetwork = pnetwork_max_rssi;
1086 goto ask_for_joinbss;
1087 }
1088 return -EINVAL;
1089 }
1090 pnetwork = container_of(pmlmepriv->pscanned,
1091 struct wlan_network, list);
1092 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1093 if (pmlmepriv->assoc_by_bssid) {
1094 dst_ssid = pnetwork->network.MacAddress;
1095 src_ssid = pmlmepriv->assoc_bssid;
1096 if (!memcmp(dst_ssid, src_ssid, ETH_ALEN)) {
1097 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1098 if (is_same_network(&pmlmepriv->
1099 cur_network.network,
1100 &pnetwork->network)) {
1101 _clr_fwstate_(pmlmepriv,
1102 _FW_UNDER_LINKING);
1103
1104 r8712_indicate_connect(adapter);
1105 return 2;
1106 }
1107 r8712_disassoc_cmd(adapter);
1108 r8712_ind_disconnect(adapter);
1109 r8712_free_assoc_resources(adapter);
1110 }
1111 goto ask_for_joinbss;
1112 }
1113 } else if (pmlmepriv->assoc_ssid.SsidLength == 0) {
1114 goto ask_for_joinbss;
1115 }
1116 dst_ssid = pnetwork->network.Ssid.Ssid;
1117 src_ssid = pmlmepriv->assoc_ssid.Ssid;
1118 if ((pnetwork->network.Ssid.SsidLength ==
1119 pmlmepriv->assoc_ssid.SsidLength) &&
1120 (!memcmp(dst_ssid, src_ssid,
1121 pmlmepriv->assoc_ssid.SsidLength))) {
1122 if (pmlmepriv->assoc_by_rssi) {
1123
1124
1125
1126 if (pnetwork_max_rssi) {
1127 if (pnetwork->network.Rssi >
1128 pnetwork_max_rssi->network.Rssi)
1129 pnetwork_max_rssi = pnetwork;
1130 } else {
1131 pnetwork_max_rssi = pnetwork;
1132 }
1133 } else if (is_desired_network(adapter, pnetwork)) {
1134 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1135 r8712_disassoc_cmd(adapter);
1136 r8712_free_assoc_resources(adapter);
1137 }
1138 goto ask_for_joinbss;
1139 }
1140 }
1141 }
1142
1143ask_for_joinbss:
1144 return r8712_joinbss_cmd(adapter, pnetwork);
1145}
1146
1147int r8712_set_auth(struct _adapter *adapter,
1148 struct security_priv *psecuritypriv)
1149{
1150 struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
1151 struct cmd_obj *pcmd;
1152 struct setauth_parm *psetauthparm;
1153
1154 pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC);
1155 if (!pcmd)
1156 return -ENOMEM;
1157
1158 psetauthparm = kzalloc(sizeof(*psetauthparm), GFP_ATOMIC);
1159 if (!psetauthparm) {
1160 kfree(pcmd);
1161 return -ENOMEM;
1162 }
1163 psetauthparm->mode = (u8)psecuritypriv->AuthAlgrthm;
1164 pcmd->cmdcode = _SetAuth_CMD_;
1165 pcmd->parmbuf = (unsigned char *)psetauthparm;
1166 pcmd->cmdsz = sizeof(struct setauth_parm);
1167 pcmd->rsp = NULL;
1168 pcmd->rspsz = 0;
1169 INIT_LIST_HEAD(&pcmd->list);
1170 r8712_enqueue_cmd(pcmdpriv, pcmd);
1171 return 0;
1172}
1173
1174int r8712_set_key(struct _adapter *adapter,
1175 struct security_priv *psecuritypriv,
1176 sint keyid)
1177{
1178 struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
1179 struct cmd_obj *pcmd;
1180 struct setkey_parm *psetkeyparm;
1181 u8 keylen;
1182 int ret;
1183
1184 pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC);
1185 if (!pcmd)
1186 return -ENOMEM;
1187 psetkeyparm = kzalloc(sizeof(*psetkeyparm), GFP_ATOMIC);
1188 if (!psetkeyparm) {
1189 ret = -ENOMEM;
1190 goto err_free_cmd;
1191 }
1192 if (psecuritypriv->AuthAlgrthm == 2) {
1193 psetkeyparm->algorithm =
1194 (u8)psecuritypriv->XGrpPrivacy;
1195 } else {
1196 psetkeyparm->algorithm =
1197 (u8)psecuritypriv->PrivacyAlgrthm;
1198 }
1199 psetkeyparm->keyid = (u8)keyid;
1200
1201 switch (psetkeyparm->algorithm) {
1202 case _WEP40_:
1203 keylen = 5;
1204 memcpy(psetkeyparm->key,
1205 psecuritypriv->DefKey[keyid].skey, keylen);
1206 break;
1207 case _WEP104_:
1208 keylen = 13;
1209 memcpy(psetkeyparm->key,
1210 psecuritypriv->DefKey[keyid].skey, keylen);
1211 break;
1212 case _TKIP_:
1213 if (keyid < 1 || keyid > 2) {
1214 ret = -EINVAL;
1215 goto err_free_parm;
1216 }
1217 keylen = 16;
1218 memcpy(psetkeyparm->key,
1219 &psecuritypriv->XGrpKey[keyid - 1], keylen);
1220 psetkeyparm->grpkey = 1;
1221 break;
1222 case _AES_:
1223 if (keyid < 1 || keyid > 2) {
1224 ret = -EINVAL;
1225 goto err_free_parm;
1226 }
1227 keylen = 16;
1228 memcpy(psetkeyparm->key,
1229 &psecuritypriv->XGrpKey[keyid - 1], keylen);
1230 psetkeyparm->grpkey = 1;
1231 break;
1232 default:
1233 ret = -EINVAL;
1234 goto err_free_parm;
1235 }
1236 pcmd->cmdcode = _SetKey_CMD_;
1237 pcmd->parmbuf = (u8 *)psetkeyparm;
1238 pcmd->cmdsz = (sizeof(struct setkey_parm));
1239 pcmd->rsp = NULL;
1240 pcmd->rspsz = 0;
1241 INIT_LIST_HEAD(&pcmd->list);
1242 r8712_enqueue_cmd(pcmdpriv, pcmd);
1243 return 0;
1244
1245err_free_parm:
1246 kfree(psetkeyparm);
1247err_free_cmd:
1248 kfree(pcmd);
1249 return ret;
1250}
1251
1252
1253int r8712_restruct_wmm_ie(struct _adapter *adapter, u8 *in_ie, u8 *out_ie,
1254 uint in_len, uint initial_out_len)
1255{
1256 unsigned int ielength = 0;
1257 unsigned int i, j;
1258
1259 i = 12;
1260 while (i < in_len) {
1261 ielength = initial_out_len;
1262 if (in_ie[i] == 0xDD && in_ie[i + 2] == 0x00 &&
1263 in_ie[i + 3] == 0x50 && in_ie[i + 4] == 0xF2 &&
1264 in_ie[i + 5] == 0x02 && i + 5 < in_len) {
1265
1266 for (j = i; j < i + 9; j++) {
1267 out_ie[ielength] = in_ie[j];
1268 ielength++;
1269 }
1270 out_ie[initial_out_len + 1] = 0x07;
1271 out_ie[initial_out_len + 6] = 0x00;
1272 out_ie[initial_out_len + 8] = 0x00;
1273 break;
1274 }
1275 i += (in_ie[i + 1] + 2);
1276 }
1277 return ielength;
1278}
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288static int SecIsInPMKIDList(struct _adapter *Adapter, u8 *bssid)
1289{
1290 struct security_priv *psecuritypriv = &Adapter->securitypriv;
1291 int i = 0;
1292
1293 do {
1294 if (psecuritypriv->PMKIDList[i].bUsed &&
1295 (!memcmp(psecuritypriv->PMKIDList[i].Bssid,
1296 bssid, ETH_ALEN)))
1297 break;
1298 i++;
1299
1300 } while (i < NUM_PMKID_CACHE);
1301
1302 if (i == NUM_PMKID_CACHE) {
1303 i = -1;
1304 } else {
1305 ;
1306
1307
1308 }
1309 return i;
1310}
1311
1312sint r8712_restruct_sec_ie(struct _adapter *adapter, u8 *in_ie,
1313 u8 *out_ie, uint in_len)
1314{
1315 u8 authmode = 0, match;
1316 u8 sec_ie[IW_CUSTOM_MAX], uncst_oui[4], bkup_ie[255];
1317 u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01};
1318 uint ielength, cnt, remove_cnt;
1319 int iEntry;
1320 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1321 struct security_priv *psecuritypriv = &adapter->securitypriv;
1322 uint ndisauthmode = psecuritypriv->ndisauthtype;
1323 uint ndissecuritytype = psecuritypriv->ndisencryptstatus;
1324
1325 if ((ndisauthmode == Ndis802_11AuthModeWPA) ||
1326 (ndisauthmode == Ndis802_11AuthModeWPAPSK)) {
1327 authmode = _WPA_IE_ID_;
1328 uncst_oui[0] = 0x0;
1329 uncst_oui[1] = 0x50;
1330 uncst_oui[2] = 0xf2;
1331 }
1332 if ((ndisauthmode == Ndis802_11AuthModeWPA2) ||
1333 (ndisauthmode == Ndis802_11AuthModeWPA2PSK)) {
1334 authmode = _WPA2_IE_ID_;
1335 uncst_oui[0] = 0x0;
1336 uncst_oui[1] = 0x0f;
1337 uncst_oui[2] = 0xac;
1338 }
1339 switch (ndissecuritytype) {
1340 case Ndis802_11Encryption1Enabled:
1341 case Ndis802_11Encryption1KeyAbsent:
1342 uncst_oui[3] = 0x1;
1343 break;
1344 case Ndis802_11Encryption2Enabled:
1345 case Ndis802_11Encryption2KeyAbsent:
1346 uncst_oui[3] = 0x2;
1347 break;
1348 case Ndis802_11Encryption3Enabled:
1349 case Ndis802_11Encryption3KeyAbsent:
1350 uncst_oui[3] = 0x4;
1351 break;
1352 default:
1353 break;
1354 }
1355
1356 cnt = 12;
1357 match = false;
1358 while (cnt < in_len) {
1359 if (in_ie[cnt] == authmode) {
1360 if ((authmode == _WPA_IE_ID_) &&
1361 (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) {
1362 memcpy(&sec_ie[0], &in_ie[cnt],
1363 in_ie[cnt + 1] + 2);
1364 match = true;
1365 break;
1366 }
1367 if (authmode == _WPA2_IE_ID_) {
1368 memcpy(&sec_ie[0], &in_ie[cnt],
1369 in_ie[cnt + 1] + 2);
1370 match = true;
1371 break;
1372 }
1373 if (((authmode == _WPA_IE_ID_) &&
1374 (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) ||
1375 (authmode == _WPA2_IE_ID_))
1376 memcpy(&bkup_ie[0], &in_ie[cnt],
1377 in_ie[cnt + 1] + 2);
1378 }
1379 cnt += in_ie[cnt + 1] + 2;
1380 }
1381
1382 if (match) {
1383 if (sec_ie[0] == _WPA_IE_ID_) {
1384
1385
1386
1387 while (true) {
1388
1389 if (memcmp(&sec_ie[2], &wpa_oui[0], 4)) {
1390 match = false;
1391 break;
1392 }
1393 if ((sec_ie[6] != 0x01) || (sec_ie[7] != 0x0)) {
1394
1395 match = false;
1396 break;
1397 }
1398 if (!memcmp(&sec_ie[8], &wpa_oui[0], 3)) {
1399
1400
1401
1402 switch (sec_ie[11]) {
1403 case 0x0:
1404 psecuritypriv->XGrpPrivacy =
1405 _NO_PRIVACY_;
1406 break;
1407 case 0x1:
1408 psecuritypriv->XGrpPrivacy =
1409 _WEP40_;
1410 break;
1411 case 0x2:
1412 psecuritypriv->XGrpPrivacy =
1413 _TKIP_;
1414 break;
1415 case 0x3:
1416 case 0x4:
1417 psecuritypriv->XGrpPrivacy =
1418 _AES_;
1419 break;
1420 case 0x5:
1421 psecuritypriv->XGrpPrivacy =
1422 _WEP104_;
1423 break;
1424 }
1425 } else {
1426 match = false;
1427 break;
1428 }
1429 if (sec_ie[12] == 0x01) {
1430
1431 if (memcmp(&sec_ie[14],
1432 &uncst_oui[0], 4)) {
1433 match = false;
1434 break;
1435
1436 }
1437 } else {
1438
1439
1440
1441 cnt = sec_ie[12];
1442 remove_cnt = (cnt - 1) * 4;
1443 sec_ie[12] = 0x01;
1444 memcpy(&sec_ie[14], &uncst_oui[0], 4);
1445
1446 memcpy(&sec_ie[18],
1447 &sec_ie[18 + remove_cnt],
1448 sec_ie[1] - 18 + 2 -
1449 remove_cnt);
1450 sec_ie[1] = sec_ie[1] - remove_cnt;
1451 }
1452 break;
1453 }
1454 }
1455 if (authmode == _WPA2_IE_ID_) {
1456
1457
1458
1459 while (true) {
1460 if ((sec_ie[2] != 0x01) || (sec_ie[3] != 0x0)) {
1461
1462 match = false;
1463 break;
1464 }
1465 if (!memcmp(&sec_ie[4], &uncst_oui[0], 3)) {
1466
1467 switch (sec_ie[7]) {
1468 case 0x1:
1469 psecuritypriv->XGrpPrivacy =
1470 _WEP40_;
1471 break;
1472 case 0x2:
1473 psecuritypriv->XGrpPrivacy =
1474 _TKIP_;
1475 break;
1476 case 0x4:
1477 psecuritypriv->XGrpPrivacy =
1478 _AES_;
1479 break;
1480 case 0x5:
1481 psecuritypriv->XGrpPrivacy =
1482 _WEP104_;
1483 break;
1484 default:
1485 psecuritypriv->XGrpPrivacy =
1486 _NO_PRIVACY_;
1487 break;
1488 }
1489 } else {
1490 match = false;
1491 break;
1492 }
1493 if (sec_ie[8] == 0x01) {
1494
1495 if (memcmp(&sec_ie[10],
1496 &uncst_oui[0], 4)) {
1497 match = false;
1498 break;
1499 }
1500 } else {
1501
1502
1503
1504 cnt = sec_ie[8];
1505 remove_cnt = (cnt - 1) * 4;
1506 sec_ie[8] = 0x01;
1507 memcpy(&sec_ie[10], &uncst_oui[0], 4);
1508
1509 memcpy(&sec_ie[14],
1510 &sec_ie[14 + remove_cnt],
1511 (sec_ie[1] - 14 + 2 -
1512 remove_cnt));
1513 sec_ie[1] = sec_ie[1] - remove_cnt;
1514 }
1515 break;
1516 }
1517 }
1518 }
1519 if ((authmode == _WPA_IE_ID_) || (authmode == _WPA2_IE_ID_)) {
1520
1521 memcpy(out_ie, in_ie, 12);
1522 ielength = 12;
1523
1524 if (match) {
1525 memcpy(&out_ie[ielength], &sec_ie[0], sec_ie[1] + 2);
1526 ielength += sec_ie[1] + 2;
1527 if (authmode == _WPA2_IE_ID_) {
1528
1529 out_ie[ielength - 1] = 0;
1530 out_ie[ielength - 2] = 0;
1531 }
1532 r8712_report_sec_ie(adapter, authmode, sec_ie);
1533 }
1534 } else {
1535
1536 memcpy(out_ie, in_ie, 12);
1537 ielength = 12;
1538 if (psecuritypriv->wps_phase) {
1539 memcpy(out_ie + ielength, psecuritypriv->wps_ie,
1540 psecuritypriv->wps_ie_len);
1541 ielength += psecuritypriv->wps_ie_len;
1542 }
1543 }
1544 iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
1545 if (iEntry < 0)
1546 return ielength;
1547 if (authmode == _WPA2_IE_ID_) {
1548 out_ie[ielength] = 1;
1549 ielength++;
1550 out_ie[ielength] = 0;
1551 ielength++;
1552 memcpy(&out_ie[ielength],
1553 &psecuritypriv->PMKIDList[iEntry].PMKID, 16);
1554 ielength += 16;
1555 out_ie[13] += 18;
1556 }
1557 return ielength;
1558}
1559
1560void r8712_init_registrypriv_dev_network(struct _adapter *adapter)
1561{
1562 struct registry_priv *pregistrypriv = &adapter->registrypriv;
1563 struct eeprom_priv *peepriv = &adapter->eeprompriv;
1564 struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
1565 u8 *myhwaddr = myid(peepriv);
1566
1567 memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN);
1568 memcpy(&pdev_network->Ssid, &pregistrypriv->ssid,
1569 sizeof(struct ndis_802_11_ssid));
1570 pdev_network->Configuration.Length =
1571 sizeof(struct NDIS_802_11_CONFIGURATION);
1572 pdev_network->Configuration.BeaconPeriod = 100;
1573 pdev_network->Configuration.FHConfig.Length = 0;
1574 pdev_network->Configuration.FHConfig.HopPattern = 0;
1575 pdev_network->Configuration.FHConfig.HopSet = 0;
1576 pdev_network->Configuration.FHConfig.DwellTime = 0;
1577}
1578
1579void r8712_update_registrypriv_dev_network(struct _adapter *adapter)
1580{
1581 int sz = 0;
1582 struct registry_priv *pregistrypriv = &adapter->registrypriv;
1583 struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
1584 struct security_priv *psecuritypriv = &adapter->securitypriv;
1585 struct wlan_network *cur_network = &adapter->mlmepriv.cur_network;
1586
1587 pdev_network->Privacy = cpu_to_le32(psecuritypriv->PrivacyAlgrthm
1588 > 0 ? 1 : 0);
1589 pdev_network->Rssi = 0;
1590 switch (pregistrypriv->wireless_mode) {
1591 case WIRELESS_11B:
1592 pdev_network->NetworkTypeInUse = Ndis802_11DS;
1593 break;
1594 case WIRELESS_11G:
1595 case WIRELESS_11BG:
1596 pdev_network->NetworkTypeInUse = Ndis802_11OFDM24;
1597 break;
1598 case WIRELESS_11A:
1599 pdev_network->NetworkTypeInUse = Ndis802_11OFDM5;
1600 break;
1601 default:
1602
1603 break;
1604 }
1605 pdev_network->Configuration.DSConfig = pregistrypriv->channel;
1606 if (cur_network->network.InfrastructureMode == Ndis802_11IBSS)
1607 pdev_network->Configuration.ATIMWindow = 3;
1608 pdev_network->InfrastructureMode = cur_network->network.InfrastructureMode;
1609
1610
1611
1612 sz = r8712_generate_ie(pregistrypriv);
1613 pdev_network->IELength = sz;
1614 pdev_network->Length = r8712_get_wlan_bssid_ex_sz(pdev_network);
1615}
1616
1617
1618void r8712_joinbss_reset(struct _adapter *padapter)
1619{
1620 int i;
1621 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1622 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
1623
1624
1625
1626
1627 phtpriv->ampdu_enable = false;
1628 for (i = 0; i < 16; i++)
1629 phtpriv->baddbareq_issued[i] = false;
1630 if (phtpriv->ht_option) {
1631
1632 r8712_write8(padapter, 0x102500D9, 48);
1633 } else {
1634
1635
1636 r8712_write8(padapter, 0x102500D9, 1);
1637 }
1638}
1639
1640
1641unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie,
1642 u8 *out_ie, uint in_len, uint *pout_len)
1643{
1644 u32 ielen, out_len;
1645 unsigned char *p;
1646 struct rtl_ieee80211_ht_cap ht_capie;
1647 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
1648 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1649 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
1650 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
1651
1652 phtpriv->ht_option = 0;
1653 p = r8712_get_ie(in_ie + 12, _HT_CAPABILITY_IE_, &ielen, in_len - 12);
1654 if (p && (ielen > 0)) {
1655 if (pqospriv->qos_option == 0) {
1656 out_len = *pout_len;
1657 r8712_set_ie(out_ie + out_len, _VENDOR_SPECIFIC_IE_,
1658 _WMM_IE_Length_, WMM_IE, pout_len);
1659 pqospriv->qos_option = 1;
1660 }
1661 out_len = *pout_len;
1662 memset(&ht_capie, 0, sizeof(struct rtl_ieee80211_ht_cap));
1663 ht_capie.cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
1664 IEEE80211_HT_CAP_SGI_20 |
1665 IEEE80211_HT_CAP_SGI_40 |
1666 IEEE80211_HT_CAP_TX_STBC |
1667 IEEE80211_HT_CAP_MAX_AMSDU |
1668 IEEE80211_HT_CAP_DSSSCCK40);
1669 ht_capie.ampdu_params_info = (IEEE80211_HT_AMPDU_PARM_FACTOR &
1670 0x03) | (IEEE80211_HT_AMPDU_PARM_DENSITY & 0x00);
1671 r8712_set_ie(out_ie + out_len, _HT_CAPABILITY_IE_,
1672 sizeof(struct rtl_ieee80211_ht_cap),
1673 (unsigned char *)&ht_capie, pout_len);
1674 phtpriv->ht_option = 1;
1675 }
1676 return phtpriv->ht_option;
1677}
1678
1679
1680static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len)
1681{
1682 u8 *p, max_ampdu_sz;
1683 int i;
1684 uint len;
1685 struct sta_info *bmc_sta, *psta;
1686 struct rtl_ieee80211_ht_cap *pht_capie;
1687 struct recv_reorder_ctrl *preorder_ctrl;
1688 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1689 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
1690 struct registry_priv *pregistrypriv = &padapter->registrypriv;
1691 struct wlan_network *pcur_network = &(pmlmepriv->cur_network);
1692
1693 if (!phtpriv->ht_option)
1694 return;
1695
1696 if (!phtpriv->ampdu_enable &&
1697 (pregistrypriv->ampdu_enable == 1))
1698 phtpriv->ampdu_enable = true;
1699
1700 len = 0;
1701 p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs),
1702 _HT_CAPABILITY_IE_,
1703 &len, ie_len -
1704 sizeof(struct NDIS_802_11_FIXED_IEs));
1705 if (p && len > 0) {
1706 pht_capie = (struct rtl_ieee80211_ht_cap *)(p + 2);
1707 max_ampdu_sz = (pht_capie->ampdu_params_info &
1708 IEEE80211_HT_AMPDU_PARM_FACTOR);
1709
1710 max_ampdu_sz = 1 << (max_ampdu_sz + 3);
1711 phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
1712 }
1713
1714
1715
1716
1717
1718 bmc_sta = r8712_get_bcmc_stainfo(padapter);
1719 if (bmc_sta) {
1720 for (i = 0; i < 16; i++) {
1721 preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
1722 preorder_ctrl->indicate_seq = 0xffff;
1723 preorder_ctrl->wend_b = 0xffff;
1724 }
1725 }
1726 psta = r8712_get_stainfo(&padapter->stapriv,
1727 pcur_network->network.MacAddress);
1728 if (psta) {
1729 for (i = 0; i < 16; i++) {
1730 preorder_ctrl = &psta->recvreorder_ctrl[i];
1731 preorder_ctrl->indicate_seq = 0xffff;
1732 preorder_ctrl->wend_b = 0xffff;
1733 }
1734 }
1735 len = 0;
1736 p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs),
1737 _HT_ADD_INFO_IE_, &len,
1738 ie_len - sizeof(struct NDIS_802_11_FIXED_IEs));
1739}
1740
1741void r8712_issue_addbareq_cmd(struct _adapter *padapter, int priority)
1742{
1743 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1744 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
1745
1746 if ((phtpriv->ht_option == 1) && (phtpriv->ampdu_enable)) {
1747 if (!phtpriv->baddbareq_issued[priority]) {
1748 r8712_addbareq_cmd(padapter, (u8)priority);
1749 phtpriv->baddbareq_issued[priority] = true;
1750 }
1751 }
1752}
1753