1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3 * rtl871x_mlme.c
4 *
5 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
6 * Linux device driver for RTL8192SU
7 *
8 * Modifications for inclusion into the Linux staging tree are
9 * Copyright(c) 2010 Larry Finger. All rights reserved.
10 *
11 * Contact information:
12 * WLAN FAE <wlanfae@realtek.com>
13 * Larry Finger <Larry.Finger@lwfinger.net>
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
30 static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len);
31
r8712_init_mlme_priv(struct _adapter * padapter)32 int 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 /* Maybe someday we should rename this variable to "active_mode"(Jeff)*/
46 pmlmepriv->passive_mode = 1; /* 1: active, 0: passive. */
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 /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
69 r8712_init_mlme_timer(padapter);
70 return 0;
71 }
72
_r8712_alloc_network(struct mlme_priv * pmlmepriv)73 struct 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
_free_network(struct mlme_priv * pmlmepriv,struct wlan_network * pnetwork)91 static 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
free_network_nolock(struct mlme_priv * pmlmepriv,struct wlan_network * pnetwork)113 static 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 /* return the wlan_network with the matching addr
129 * Shall be called under atomic context...
130 * to avoid possible racing condition...
131 */
r8712_find_network(struct __queue * scanned_queue,u8 * addr)132 static 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
r8712_free_network_queue(struct _adapter * padapter)154 void 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
r8712_if_up(struct _adapter * padapter)173 sint 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
r8712_generate_random_ibss(u8 * pibss)186 void r8712_generate_random_ibss(u8 *pibss)
187 {
188 u32 curtime = jiffies;
189
190 pibss[0] = 0x02; /*in ad-hoc mode bit1 must set to 1 */
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
r8712_get_wlan_bssid_ex_sz(struct wlan_bssid_ex * bss)198 uint r8712_get_wlan_bssid_ex_sz(struct wlan_bssid_ex *bss)
199 {
200 return sizeof(*bss) + bss->IELength - MAX_IE_SZ;
201 }
202
r8712_get_capability_from_ie(u8 * ie)203 u8 *r8712_get_capability_from_ie(u8 *ie)
204 {
205 return ie + 8 + 2;
206 }
207
r8712_free_mlme_priv(struct mlme_priv * pmlmepriv)208 void r8712_free_mlme_priv(struct mlme_priv *pmlmepriv)
209 {
210 kfree(pmlmepriv->free_bss_buf);
211 }
212
alloc_network(struct mlme_priv * pmlmepriv)213 static struct wlan_network *alloc_network(struct mlme_priv *pmlmepriv)
214 {
215 return _r8712_alloc_network(pmlmepriv);
216 }
217
r8712_is_same_ibss(struct _adapter * adapter,struct wlan_network * pnetwork)218 int 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
is_same_network(struct wlan_bssid_ex * src,struct wlan_bssid_ex * dst)235 static 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
r8712_get_oldest_wlan_network(struct __queue * scanned_queue)257 struct 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
update_network(struct wlan_bssid_ex * dst,struct wlan_bssid_ex * src,struct _adapter * padapter)281 static 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 /* <1> Showed on UI for user, in percentage. */
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
update_current_network(struct _adapter * adapter,struct wlan_bssid_ex * pnetwork)316 static 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 /* Caller must hold pmlmepriv->lock first */
update_scanned_network(struct _adapter * adapter,struct wlan_bssid_ex * target)332 static 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 /* If we didn't find a match, then get a new network slot to initialize
363 * with this beacon's information
364 */
365 if (end_of_queue_search(phead, plist)) {
366 if (list_empty(&pmlmepriv->free_bss_pool.queue)) {
367 /* If there are no more slots, expire the oldest */
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 /* Otherwise just pull from the free list */
376 /* update scan_time */
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 /* we have an entry and we are going to update it. But
387 * this entry may be already expired. In this case we
388 * do the same as we found a new net and call the new_net
389 * handler
390 */
391 update_network(&pnetwork->network, target, adapter);
392 pnetwork->last_scanned = jiffies;
393 }
394 }
395
rtl8711_add_network(struct _adapter * adapter,struct wlan_bssid_ex * pnetwork)396 static 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 /*select the desired network based on the capability of the (i)bss.
410 * check items: (1) security
411 * (2) network_type
412 * (3) WMM
413 * (4) HT
414 * (5) others
415 */
is_desired_network(struct _adapter * adapter,struct wlan_network * pnetwork)416 static 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 /* TODO: Perry : For Power Management */
r8712_atimdone_event_callback(struct _adapter * adapter,u8 * pbuf)444 void r8712_atimdone_event_callback(struct _adapter *adapter, u8 *pbuf)
445 {
446 }
447
r8712_survey_event_callback(struct _adapter * adapter,u8 * pbuf)448 void 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 /* endian_convert */
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 /* update IBSS_network 's timestamp */
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 /* lock pmlmepriv->lock when you accessing network_q */
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 }
515 exit:
516 spin_unlock_irqrestore(&pmlmepriv->lock2, flags);
517 }
518
r8712_surveydone_event_callback(struct _adapter * adapter,u8 * pbuf)519 void 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 *r8712_free_assoc_resources: the caller has to lock pmlmepriv->lock
574 */
r8712_free_assoc_resources(struct _adapter * adapter)575 void 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 * r8712_indicate_connect: the caller has to lock pmlmepriv->lock
610 */
r8712_indicate_connect(struct _adapter * padapter)611 void 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 * r8712_ind_disconnect: the caller has to lock pmlmepriv->lock
627 */
r8712_ind_disconnect(struct _adapter * padapter)628 void 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 /*Notes:
646 *pnetwork : returns from r8712_joinbss_event_callback
647 *ptarget_wlan: found from scanned_queue
648 *if join_res > 0, for (fw_state==WIFI_STATION_STATE), we check if
649 * "ptarget_sta" & "ptarget_wlan" exist.
650 *if join_res > 0, for (fw_state==WIFI_ADHOC_STATE), we only check
651 * if "ptarget_wlan" exist.
652 *if join_res > 0, update "cur_network->network" from
653 * "pnetwork->network" if (ptarget_wlan !=NULL).
654 */
r8712_joinbss_event_callback(struct _adapter * adapter,u8 * pbuf)655 void 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 /* endian_convert */
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 /*s1. find ptarget_wlan*/
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) {
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 /*s2. find ptarget_sta & update ptarget_sta*/
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)
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) /*update 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 /*s3. update cur_network & indicate connect*/
829 memcpy(&cur_network->network, &pnetwork->network,
830 pnetwork->network.Length);
831 cur_network->aid = pnetwork->join_res;
832 /*update fw_state will clr _FW_UNDER_LINKING*/
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 /*TODO: update HT_Capability*/
849 update_ht_cap(adapter, cur_network->network.IEs,
850 cur_network->network.IELength);
851 /*indicate connect*/
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 }
865 ignore_joinbss_callback:
866 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
867 if (sizeof(struct list_head) == 4 * sizeof(u32))
868 kfree(pnetwork);
869 }
870
r8712_stassoc_event_callback(struct _adapter * adapter,u8 * pbuf)871 void 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 /* to do: */
879 if (!r8712_access_ctrl(&adapter->acl_list, pstassoc->macaddr))
880 return;
881 psta = r8712_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
882 if (psta) {
883 /*the sta have been in sta_info_queue => do nothing
884 *(between drv has received this event before and
885 * fw have not yet to set key to CAM_ENTRY)
886 */
887 return;
888 }
889
890 psta = r8712_alloc_stainfo(&adapter->stapriv, pstassoc->macaddr);
891 if (!psta)
892 return;
893 /* to do : init sta_info variable */
894 psta->qos_option = 0;
895 psta->mac_id = le32_to_cpu(pstassoc->cam_id);
896 /* psta->aid = (uint)pstassoc->cam_id; */
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 /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
906 r8712_indicate_connect(adapter);
907 }
908 }
909 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
910 }
911
r8712_stadel_event_callback(struct _adapter * adapter,u8 * pbuf)912 void 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 /*a sta + bc/mc_stainfo (not Ibss_stainfo) */
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 /*re-create ibss*/
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
r8712_cpwm_event_callback(struct _adapter * adapter,u8 * pbuf)963 void 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 /* When the Netgear 3500 AP is with WPA2PSK-AES mode, it will send
973 * the ADDBA req frame with start seq control = 0 to wifi client after
974 * the WPA handshake and the seqence number of following data packet
975 * will be 0. In this case, the Rx reorder sequence is not longer than 0
976 * and the WiFi client will drop the data with seq number 0.
977 * So, the 8712 firmware has to inform driver with receiving the
978 * ADDBA-Req frame so that the driver can reset the
979 * sequence value of Rx reorder control.
980 */
r8712_got_addbareq_event_callback(struct _adapter * adapter,u8 * pbuf)981 void 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 /* set the indicate_seq to 0xffff so that the rx reorder
994 * can store any following data packet.
995 */
996 precvreorder_ctrl->indicate_seq = 0xffff;
997 }
998 }
999
r8712_wpspbc_event_callback(struct _adapter * adapter,u8 * pbuf)1000 void 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
_r8712_sitesurvey_ctrl_handler(struct _adapter * adapter)1006 void _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
_r8712_join_timeout_handler(struct _adapter * adapter)1027 void _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
r8712_scan_timeout_handler(struct _adapter * adapter)1048 void 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; /* scan fail, so clear to_join flag */
1056 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
1057 }
1058
_r8712_dhcp_timeout_handler(struct _adapter * adapter)1059 void _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
r8712_select_and_join_from_scan(struct mlme_priv * pmlmepriv)1068 int 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 && pnetwork_max_rssi) {
1084 pnetwork = pnetwork_max_rssi;
1085 goto ask_for_joinbss;
1086 }
1087 return -EINVAL;
1088 }
1089 pnetwork = container_of(pmlmepriv->pscanned,
1090 struct wlan_network, list);
1091 pmlmepriv->pscanned = pmlmepriv->pscanned->next;
1092 if (pmlmepriv->assoc_by_bssid) {
1093 dst_ssid = pnetwork->network.MacAddress;
1094 src_ssid = pmlmepriv->assoc_bssid;
1095 if (!memcmp(dst_ssid, src_ssid, ETH_ALEN)) {
1096 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1097 if (is_same_network(&pmlmepriv->
1098 cur_network.network,
1099 &pnetwork->network)) {
1100 _clr_fwstate_(pmlmepriv,
1101 _FW_UNDER_LINKING);
1102 /*r8712_indicate_connect again*/
1103 r8712_indicate_connect(adapter);
1104 return 2;
1105 }
1106 r8712_disassoc_cmd(adapter);
1107 r8712_ind_disconnect(adapter);
1108 r8712_free_assoc_resources(adapter);
1109 }
1110 goto ask_for_joinbss;
1111 }
1112 } else if (pmlmepriv->assoc_ssid.SsidLength == 0) {
1113 goto ask_for_joinbss;
1114 }
1115 dst_ssid = pnetwork->network.Ssid.Ssid;
1116 src_ssid = pmlmepriv->assoc_ssid.Ssid;
1117 if ((pnetwork->network.Ssid.SsidLength ==
1118 pmlmepriv->assoc_ssid.SsidLength) &&
1119 (!memcmp(dst_ssid, src_ssid,
1120 pmlmepriv->assoc_ssid.SsidLength))) {
1121 if (pmlmepriv->assoc_by_rssi) {
1122 /* if the ssid is the same, select the bss
1123 * which has the max rssi
1124 */
1125 if (pnetwork_max_rssi) {
1126 if (pnetwork->network.Rssi >
1127 pnetwork_max_rssi->network.Rssi)
1128 pnetwork_max_rssi = pnetwork;
1129 } else {
1130 pnetwork_max_rssi = pnetwork;
1131 }
1132 } else if (is_desired_network(adapter, pnetwork)) {
1133 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1134 r8712_disassoc_cmd(adapter);
1135 r8712_free_assoc_resources(adapter);
1136 }
1137 goto ask_for_joinbss;
1138 }
1139 }
1140 }
1141
1142 ask_for_joinbss:
1143 return r8712_joinbss_cmd(adapter, pnetwork);
1144 }
1145
r8712_set_auth(struct _adapter * adapter,struct security_priv * psecuritypriv)1146 int r8712_set_auth(struct _adapter *adapter,
1147 struct security_priv *psecuritypriv)
1148 {
1149 struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
1150 struct cmd_obj *pcmd;
1151 struct setauth_parm *psetauthparm;
1152
1153 pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC);
1154 if (!pcmd)
1155 return -ENOMEM;
1156
1157 psetauthparm = kzalloc(sizeof(*psetauthparm), GFP_ATOMIC);
1158 if (!psetauthparm) {
1159 kfree(pcmd);
1160 return -ENOMEM;
1161 }
1162 psetauthparm->mode = (u8)psecuritypriv->AuthAlgrthm;
1163 pcmd->cmdcode = _SetAuth_CMD_;
1164 pcmd->parmbuf = (unsigned char *)psetauthparm;
1165 pcmd->cmdsz = sizeof(struct setauth_parm);
1166 pcmd->rsp = NULL;
1167 pcmd->rspsz = 0;
1168 INIT_LIST_HEAD(&pcmd->list);
1169 r8712_enqueue_cmd(pcmdpriv, pcmd);
1170 return 0;
1171 }
1172
r8712_set_key(struct _adapter * adapter,struct security_priv * psecuritypriv,sint keyid)1173 int r8712_set_key(struct _adapter *adapter,
1174 struct security_priv *psecuritypriv,
1175 sint keyid)
1176 {
1177 struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
1178 struct cmd_obj *pcmd;
1179 struct setkey_parm *psetkeyparm;
1180 u8 keylen;
1181 int ret;
1182
1183 pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC);
1184 if (!pcmd)
1185 return -ENOMEM;
1186 psetkeyparm = kzalloc(sizeof(*psetkeyparm), GFP_ATOMIC);
1187 if (!psetkeyparm) {
1188 ret = -ENOMEM;
1189 goto err_free_cmd;
1190 }
1191 if (psecuritypriv->AuthAlgrthm == 2) { /* 802.1X */
1192 psetkeyparm->algorithm =
1193 (u8)psecuritypriv->XGrpPrivacy;
1194 } else { /* WEP */
1195 psetkeyparm->algorithm =
1196 (u8)psecuritypriv->PrivacyAlgrthm;
1197 }
1198 psetkeyparm->keyid = (u8)keyid;
1199
1200 switch (psetkeyparm->algorithm) {
1201 case _WEP40_:
1202 keylen = 5;
1203 memcpy(psetkeyparm->key,
1204 psecuritypriv->DefKey[keyid].skey, keylen);
1205 break;
1206 case _WEP104_:
1207 keylen = 13;
1208 memcpy(psetkeyparm->key,
1209 psecuritypriv->DefKey[keyid].skey, keylen);
1210 break;
1211 case _TKIP_:
1212 if (keyid < 1 || keyid > 2) {
1213 ret = -EINVAL;
1214 goto err_free_parm;
1215 }
1216 keylen = 16;
1217 memcpy(psetkeyparm->key,
1218 &psecuritypriv->XGrpKey[keyid - 1], keylen);
1219 psetkeyparm->grpkey = 1;
1220 break;
1221 case _AES_:
1222 if (keyid < 1 || keyid > 2) {
1223 ret = -EINVAL;
1224 goto err_free_parm;
1225 }
1226 keylen = 16;
1227 memcpy(psetkeyparm->key,
1228 &psecuritypriv->XGrpKey[keyid - 1], keylen);
1229 psetkeyparm->grpkey = 1;
1230 break;
1231 default:
1232 ret = -EINVAL;
1233 goto err_free_parm;
1234 }
1235 pcmd->cmdcode = _SetKey_CMD_;
1236 pcmd->parmbuf = (u8 *)psetkeyparm;
1237 pcmd->cmdsz = (sizeof(struct setkey_parm));
1238 pcmd->rsp = NULL;
1239 pcmd->rspsz = 0;
1240 INIT_LIST_HEAD(&pcmd->list);
1241 r8712_enqueue_cmd(pcmdpriv, pcmd);
1242 return 0;
1243
1244 err_free_parm:
1245 kfree(psetkeyparm);
1246 err_free_cmd:
1247 kfree(pcmd);
1248 return ret;
1249 }
1250
1251 /* adjust IEs for r8712_joinbss_cmd in WMM */
r8712_restruct_wmm_ie(struct _adapter * adapter,u8 * in_ie,u8 * out_ie,uint in_len,uint initial_out_len)1252 int r8712_restruct_wmm_ie(struct _adapter *adapter, u8 *in_ie, u8 *out_ie,
1253 uint in_len, uint initial_out_len)
1254 {
1255 unsigned int ielength = 0;
1256 unsigned int i, j;
1257
1258 i = 12; /* after the fixed IE */
1259 while (i < in_len) {
1260 ielength = initial_out_len;
1261 if (in_ie[i] == 0xDD && in_ie[i + 2] == 0x00 &&
1262 in_ie[i + 3] == 0x50 && in_ie[i + 4] == 0xF2 &&
1263 in_ie[i + 5] == 0x02 && i + 5 < in_len) {
1264 /*WMM element ID and OUI*/
1265 for (j = i; j < i + 9; j++) {
1266 out_ie[ielength] = in_ie[j];
1267 ielength++;
1268 }
1269 out_ie[initial_out_len + 1] = 0x07;
1270 out_ie[initial_out_len + 6] = 0x00;
1271 out_ie[initial_out_len + 8] = 0x00;
1272 break;
1273 }
1274 i += (in_ie[i + 1] + 2); /* to the next IE element */
1275 }
1276 return ielength;
1277 }
1278
1279 /*
1280 * Ported from 8185: IsInPreAuthKeyList().
1281 *
1282 * Search by BSSID,
1283 * Return Value:
1284 * -1 :if there is no pre-auth key in the table
1285 * >=0 :if there is pre-auth key, and return the entry id
1286 */
SecIsInPMKIDList(struct _adapter * Adapter,u8 * bssid)1287 static int SecIsInPMKIDList(struct _adapter *Adapter, u8 *bssid)
1288 {
1289 struct security_priv *psecuritypriv = &Adapter->securitypriv;
1290 int i = 0;
1291
1292 do {
1293 if (psecuritypriv->PMKIDList[i].bUsed &&
1294 (!memcmp(psecuritypriv->PMKIDList[i].Bssid,
1295 bssid, ETH_ALEN)))
1296 break;
1297 i++;
1298
1299 } while (i < NUM_PMKID_CACHE);
1300
1301 if (i == NUM_PMKID_CACHE) {
1302 i = -1; /* Could not find. */
1303 } else {
1304 ; /* There is one Pre-Authentication Key for the
1305 * specific BSSID.
1306 */
1307 }
1308 return i;
1309 }
1310
r8712_restruct_sec_ie(struct _adapter * adapter,u8 * in_ie,u8 * out_ie,uint in_len)1311 sint r8712_restruct_sec_ie(struct _adapter *adapter, u8 *in_ie,
1312 u8 *out_ie, uint in_len)
1313 {
1314 u8 authmode = 0, match;
1315 u8 sec_ie[IW_CUSTOM_MAX], uncst_oui[4], bkup_ie[255];
1316 u8 wpa_oui[4] = {0x0, 0x50, 0xf2, 0x01};
1317 uint ielength, cnt, remove_cnt;
1318 int iEntry;
1319 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1320 struct security_priv *psecuritypriv = &adapter->securitypriv;
1321 uint ndisauthmode = psecuritypriv->ndisauthtype;
1322 uint ndissecuritytype = psecuritypriv->ndisencryptstatus;
1323
1324 if ((ndisauthmode == Ndis802_11AuthModeWPA) ||
1325 (ndisauthmode == Ndis802_11AuthModeWPAPSK)) {
1326 authmode = _WPA_IE_ID_;
1327 uncst_oui[0] = 0x0;
1328 uncst_oui[1] = 0x50;
1329 uncst_oui[2] = 0xf2;
1330 }
1331 if ((ndisauthmode == Ndis802_11AuthModeWPA2) ||
1332 (ndisauthmode == Ndis802_11AuthModeWPA2PSK)) {
1333 authmode = _WPA2_IE_ID_;
1334 uncst_oui[0] = 0x0;
1335 uncst_oui[1] = 0x0f;
1336 uncst_oui[2] = 0xac;
1337 }
1338 switch (ndissecuritytype) {
1339 case Ndis802_11Encryption1Enabled:
1340 case Ndis802_11Encryption1KeyAbsent:
1341 uncst_oui[3] = 0x1;
1342 break;
1343 case Ndis802_11Encryption2Enabled:
1344 case Ndis802_11Encryption2KeyAbsent:
1345 uncst_oui[3] = 0x2;
1346 break;
1347 case Ndis802_11Encryption3Enabled:
1348 case Ndis802_11Encryption3KeyAbsent:
1349 uncst_oui[3] = 0x4;
1350 break;
1351 default:
1352 break;
1353 }
1354 /*Search required WPA or WPA2 IE and copy to sec_ie[] */
1355 cnt = 12;
1356 match = false;
1357 while (cnt < in_len) {
1358 if (in_ie[cnt] == authmode) {
1359 if ((authmode == _WPA_IE_ID_) &&
1360 (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) {
1361 memcpy(&sec_ie[0], &in_ie[cnt],
1362 in_ie[cnt + 1] + 2);
1363 match = true;
1364 break;
1365 }
1366 if (authmode == _WPA2_IE_ID_) {
1367 memcpy(&sec_ie[0], &in_ie[cnt],
1368 in_ie[cnt + 1] + 2);
1369 match = true;
1370 break;
1371 }
1372 if (((authmode == _WPA_IE_ID_) &&
1373 (!memcmp(&in_ie[cnt + 2], &wpa_oui[0], 4))) ||
1374 (authmode == _WPA2_IE_ID_))
1375 memcpy(&bkup_ie[0], &in_ie[cnt],
1376 in_ie[cnt + 1] + 2);
1377 }
1378 cnt += in_ie[cnt + 1] + 2; /*get next*/
1379 }
1380 /*restruct WPA IE or WPA2 IE in sec_ie[] */
1381 if (match) {
1382 if (sec_ie[0] == _WPA_IE_ID_) {
1383 /* parsing SSN IE to select required encryption
1384 * algorithm, and set the bc/mc encryption algorithm
1385 */
1386 while (true) {
1387 /*check wpa_oui tag*/
1388 if (memcmp(&sec_ie[2], &wpa_oui[0], 4)) {
1389 match = false;
1390 break;
1391 }
1392 if ((sec_ie[6] != 0x01) || (sec_ie[7] != 0x0)) {
1393 /*IE Ver error*/
1394 match = false;
1395 break;
1396 }
1397 if (!memcmp(&sec_ie[8], &wpa_oui[0], 3)) {
1398 /* get bc/mc encryption type (group
1399 * key type)
1400 */
1401 switch (sec_ie[11]) {
1402 case 0x0: /*none*/
1403 psecuritypriv->XGrpPrivacy =
1404 _NO_PRIVACY_;
1405 break;
1406 case 0x1: /*WEP_40*/
1407 psecuritypriv->XGrpPrivacy =
1408 _WEP40_;
1409 break;
1410 case 0x2: /*TKIP*/
1411 psecuritypriv->XGrpPrivacy =
1412 _TKIP_;
1413 break;
1414 case 0x3: /*AESCCMP*/
1415 case 0x4:
1416 psecuritypriv->XGrpPrivacy =
1417 _AES_;
1418 break;
1419 case 0x5: /*WEP_104*/
1420 psecuritypriv->XGrpPrivacy =
1421 _WEP104_;
1422 break;
1423 }
1424 } else {
1425 match = false;
1426 break;
1427 }
1428 if (sec_ie[12] == 0x01) {
1429 /*check the unicast encryption type*/
1430 if (memcmp(&sec_ie[14],
1431 &uncst_oui[0], 4)) {
1432 match = false;
1433 break;
1434
1435 } /*else the uncst_oui is match*/
1436 } else { /*mixed mode, unicast_enc_type > 1*/
1437 /*select the uncst_oui and remove
1438 * the other uncst_oui
1439 */
1440 cnt = sec_ie[12];
1441 remove_cnt = (cnt - 1) * 4;
1442 sec_ie[12] = 0x01;
1443 memcpy(&sec_ie[14], &uncst_oui[0], 4);
1444 /*remove the other unicast suit*/
1445 memcpy(&sec_ie[18],
1446 &sec_ie[18 + remove_cnt],
1447 sec_ie[1] - 18 + 2 -
1448 remove_cnt);
1449 sec_ie[1] = sec_ie[1] - remove_cnt;
1450 }
1451 break;
1452 }
1453 }
1454 if (authmode == _WPA2_IE_ID_) {
1455 /* parsing RSN IE to select required encryption
1456 * algorithm, and set the bc/mc encryption algorithm
1457 */
1458 while (true) {
1459 if ((sec_ie[2] != 0x01) || (sec_ie[3] != 0x0)) {
1460 /*IE Ver error*/
1461 match = false;
1462 break;
1463 }
1464 if (!memcmp(&sec_ie[4], &uncst_oui[0], 3)) {
1465 /*get bc/mc encryption type*/
1466 switch (sec_ie[7]) {
1467 case 0x1: /*WEP_40*/
1468 psecuritypriv->XGrpPrivacy =
1469 _WEP40_;
1470 break;
1471 case 0x2: /*TKIP*/
1472 psecuritypriv->XGrpPrivacy =
1473 _TKIP_;
1474 break;
1475 case 0x4: /*AESWRAP*/
1476 psecuritypriv->XGrpPrivacy =
1477 _AES_;
1478 break;
1479 case 0x5: /*WEP_104*/
1480 psecuritypriv->XGrpPrivacy =
1481 _WEP104_;
1482 break;
1483 default: /*one*/
1484 psecuritypriv->XGrpPrivacy =
1485 _NO_PRIVACY_;
1486 break;
1487 }
1488 } else {
1489 match = false;
1490 break;
1491 }
1492 if (sec_ie[8] == 0x01) {
1493 /*check the unicast encryption type*/
1494 if (memcmp(&sec_ie[10],
1495 &uncst_oui[0], 4)) {
1496 match = false;
1497 break;
1498 } /*else the uncst_oui is match*/
1499 } else { /*mixed mode, unicast_enc_type > 1*/
1500 /*select the uncst_oui and remove the
1501 * other uncst_oui
1502 */
1503 cnt = sec_ie[8];
1504 remove_cnt = (cnt - 1) * 4;
1505 sec_ie[8] = 0x01;
1506 memcpy(&sec_ie[10], &uncst_oui[0], 4);
1507 /*remove the other unicast suit*/
1508 memcpy(&sec_ie[14],
1509 &sec_ie[14 + remove_cnt],
1510 (sec_ie[1] - 14 + 2 -
1511 remove_cnt));
1512 sec_ie[1] = sec_ie[1] - remove_cnt;
1513 }
1514 break;
1515 }
1516 }
1517 }
1518 if ((authmode == _WPA_IE_ID_) || (authmode == _WPA2_IE_ID_)) {
1519 /*copy fixed ie*/
1520 memcpy(out_ie, in_ie, 12);
1521 ielength = 12;
1522 /*copy RSN or SSN*/
1523 if (match) {
1524 memcpy(&out_ie[ielength], &sec_ie[0], sec_ie[1] + 2);
1525 ielength += sec_ie[1] + 2;
1526 if (authmode == _WPA2_IE_ID_) {
1527 /*the Pre-Authentication bit should be zero*/
1528 out_ie[ielength - 1] = 0;
1529 out_ie[ielength - 2] = 0;
1530 }
1531 r8712_report_sec_ie(adapter, authmode, sec_ie);
1532 }
1533 } else {
1534 /*copy fixed ie only*/
1535 memcpy(out_ie, in_ie, 12);
1536 ielength = 12;
1537 if (psecuritypriv->wps_phase) {
1538 memcpy(out_ie + ielength, psecuritypriv->wps_ie,
1539 psecuritypriv->wps_ie_len);
1540 ielength += psecuritypriv->wps_ie_len;
1541 }
1542 }
1543 iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
1544 if (iEntry < 0)
1545 return ielength;
1546 if (authmode == _WPA2_IE_ID_) {
1547 out_ie[ielength] = 1;
1548 ielength++;
1549 out_ie[ielength] = 0; /*PMKID count = 0x0100*/
1550 ielength++;
1551 memcpy(&out_ie[ielength],
1552 &psecuritypriv->PMKIDList[iEntry].PMKID, 16);
1553 ielength += 16;
1554 out_ie[13] += 18;/*PMKID length = 2+16*/
1555 }
1556 return ielength;
1557 }
1558
r8712_init_registrypriv_dev_network(struct _adapter * adapter)1559 void r8712_init_registrypriv_dev_network(struct _adapter *adapter)
1560 {
1561 struct registry_priv *pregistrypriv = &adapter->registrypriv;
1562 struct eeprom_priv *peepriv = &adapter->eeprompriv;
1563 struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
1564 u8 *myhwaddr = myid(peepriv);
1565
1566 memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN);
1567 memcpy(&pdev_network->Ssid, &pregistrypriv->ssid,
1568 sizeof(struct ndis_802_11_ssid));
1569 pdev_network->Configuration.Length =
1570 sizeof(struct NDIS_802_11_CONFIGURATION);
1571 pdev_network->Configuration.BeaconPeriod = 100;
1572 pdev_network->Configuration.FHConfig.Length = 0;
1573 pdev_network->Configuration.FHConfig.HopPattern = 0;
1574 pdev_network->Configuration.FHConfig.HopSet = 0;
1575 pdev_network->Configuration.FHConfig.DwellTime = 0;
1576 }
1577
r8712_update_registrypriv_dev_network(struct _adapter * adapter)1578 void r8712_update_registrypriv_dev_network(struct _adapter *adapter)
1579 {
1580 int sz = 0;
1581 struct registry_priv *pregistrypriv = &adapter->registrypriv;
1582 struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
1583 struct security_priv *psecuritypriv = &adapter->securitypriv;
1584 struct wlan_network *cur_network = &adapter->mlmepriv.cur_network;
1585
1586 pdev_network->Privacy = cpu_to_le32(psecuritypriv->PrivacyAlgrthm
1587 > 0 ? 1 : 0); /* adhoc no 802.1x */
1588 pdev_network->Rssi = 0;
1589 switch (pregistrypriv->wireless_mode) {
1590 case WIRELESS_11B:
1591 pdev_network->NetworkTypeInUse = Ndis802_11DS;
1592 break;
1593 case WIRELESS_11G:
1594 case WIRELESS_11BG:
1595 pdev_network->NetworkTypeInUse = Ndis802_11OFDM24;
1596 break;
1597 case WIRELESS_11A:
1598 pdev_network->NetworkTypeInUse = Ndis802_11OFDM5;
1599 break;
1600 default:
1601 /* TODO */
1602 break;
1603 }
1604 pdev_network->Configuration.DSConfig = pregistrypriv->channel;
1605 if (cur_network->network.InfrastructureMode == Ndis802_11IBSS)
1606 pdev_network->Configuration.ATIMWindow = 3;
1607 pdev_network->InfrastructureMode = cur_network->network.InfrastructureMode;
1608 /* 1. Supported rates
1609 * 2. IE
1610 */
1611 sz = r8712_generate_ie(pregistrypriv);
1612 pdev_network->IELength = sz;
1613 pdev_network->Length = r8712_get_wlan_bssid_ex_sz(pdev_network);
1614 }
1615
1616 /*the function is at passive_level*/
r8712_joinbss_reset(struct _adapter * padapter)1617 void r8712_joinbss_reset(struct _adapter *padapter)
1618 {
1619 int i;
1620 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1621 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
1622
1623 /* todo: if you want to do something io/reg/hw setting before join_bss,
1624 * please add code here
1625 */
1626 phtpriv->ampdu_enable = false;/*reset to disabled*/
1627 for (i = 0; i < 16; i++)
1628 phtpriv->baddbareq_issued[i] = false;/*reset it*/
1629 if (phtpriv->ht_option) {
1630 /* validate usb rx aggregation */
1631 r8712_write8(padapter, 0x102500D9, 48);/*TH = 48 pages, 6k*/
1632 } else {
1633 /* invalidate usb rx aggregation */
1634 /* TH=1 => means that invalidate usb rx aggregation */
1635 r8712_write8(padapter, 0x102500D9, 1);
1636 }
1637 }
1638
1639 /*the function is >= passive_level*/
r8712_restructure_ht_ie(struct _adapter * padapter,u8 * in_ie,u8 * out_ie,uint in_len,uint * pout_len)1640 unsigned int r8712_restructure_ht_ie(struct _adapter *padapter, u8 *in_ie,
1641 u8 *out_ie, uint in_len, uint *pout_len)
1642 {
1643 u32 ielen, out_len;
1644 unsigned char *p;
1645 struct rtl_ieee80211_ht_cap ht_capie;
1646 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
1647 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1648 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
1649 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
1650
1651 phtpriv->ht_option = 0;
1652 p = r8712_get_ie(in_ie + 12, _HT_CAPABILITY_IE_, &ielen, in_len - 12);
1653 if (p && (ielen > 0)) {
1654 if (pqospriv->qos_option == 0) {
1655 out_len = *pout_len;
1656 r8712_set_ie(out_ie + out_len, _VENDOR_SPECIFIC_IE_,
1657 _WMM_IE_Length_, WMM_IE, pout_len);
1658 pqospriv->qos_option = 1;
1659 }
1660 out_len = *pout_len;
1661 memset(&ht_capie, 0, sizeof(struct rtl_ieee80211_ht_cap));
1662 ht_capie.cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
1663 IEEE80211_HT_CAP_SGI_20 |
1664 IEEE80211_HT_CAP_SGI_40 |
1665 IEEE80211_HT_CAP_TX_STBC |
1666 IEEE80211_HT_CAP_MAX_AMSDU |
1667 IEEE80211_HT_CAP_DSSSCCK40);
1668 ht_capie.ampdu_params_info = (IEEE80211_HT_AMPDU_PARM_FACTOR &
1669 0x03) | (IEEE80211_HT_AMPDU_PARM_DENSITY & 0x00);
1670 r8712_set_ie(out_ie + out_len, _HT_CAPABILITY_IE_,
1671 sizeof(struct rtl_ieee80211_ht_cap),
1672 (unsigned char *)&ht_capie, pout_len);
1673 phtpriv->ht_option = 1;
1674 }
1675 return phtpriv->ht_option;
1676 }
1677
1678 /* the function is > passive_level (in critical_section) */
update_ht_cap(struct _adapter * padapter,u8 * pie,uint ie_len)1679 static void update_ht_cap(struct _adapter *padapter, u8 *pie, uint ie_len)
1680 {
1681 u8 *p, max_ampdu_sz;
1682 int i;
1683 uint len;
1684 struct sta_info *bmc_sta, *psta;
1685 struct rtl_ieee80211_ht_cap *pht_capie;
1686 struct recv_reorder_ctrl *preorder_ctrl;
1687 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1688 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
1689 struct registry_priv *pregistrypriv = &padapter->registrypriv;
1690 struct wlan_network *pcur_network = &(pmlmepriv->cur_network);
1691
1692 if (!phtpriv->ht_option)
1693 return;
1694 /* maybe needs check if ap supports rx ampdu. */
1695 if (!phtpriv->ampdu_enable &&
1696 (pregistrypriv->ampdu_enable == 1))
1697 phtpriv->ampdu_enable = true;
1698 /*check Max Rx A-MPDU Size*/
1699 len = 0;
1700 p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs),
1701 _HT_CAPABILITY_IE_,
1702 &len, ie_len -
1703 sizeof(struct NDIS_802_11_FIXED_IEs));
1704 if (p && len > 0) {
1705 pht_capie = (struct rtl_ieee80211_ht_cap *)(p + 2);
1706 max_ampdu_sz = (pht_capie->ampdu_params_info &
1707 IEEE80211_HT_AMPDU_PARM_FACTOR);
1708 /* max_ampdu_sz (kbytes); */
1709 max_ampdu_sz = 1 << (max_ampdu_sz + 3);
1710 phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
1711 }
1712 /* for A-MPDU Rx reordering buffer control for bmc_sta & sta_info
1713 * if A-MPDU Rx is enabled, resetting rx_ordering_ctrl
1714 * wstart_b(indicate_seq) to default value=0xffff
1715 * todo: check if AP can send A-MPDU packets
1716 */
1717 bmc_sta = r8712_get_bcmc_stainfo(padapter);
1718 if (bmc_sta) {
1719 for (i = 0; i < 16; i++) {
1720 preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
1721 preorder_ctrl->indicate_seq = 0xffff;
1722 preorder_ctrl->wend_b = 0xffff;
1723 }
1724 }
1725 psta = r8712_get_stainfo(&padapter->stapriv,
1726 pcur_network->network.MacAddress);
1727 if (psta) {
1728 for (i = 0; i < 16; i++) {
1729 preorder_ctrl = &psta->recvreorder_ctrl[i];
1730 preorder_ctrl->indicate_seq = 0xffff;
1731 preorder_ctrl->wend_b = 0xffff;
1732 }
1733 }
1734 len = 0;
1735 p = r8712_get_ie(pie + sizeof(struct NDIS_802_11_FIXED_IEs),
1736 _HT_ADD_INFO_IE_, &len,
1737 ie_len - sizeof(struct NDIS_802_11_FIXED_IEs));
1738 }
1739
r8712_issue_addbareq_cmd(struct _adapter * padapter,int priority)1740 void r8712_issue_addbareq_cmd(struct _adapter *padapter, int priority)
1741 {
1742 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1743 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
1744
1745 if ((phtpriv->ht_option == 1) && (phtpriv->ampdu_enable)) {
1746 if (!phtpriv->baddbareq_issued[priority]) {
1747 r8712_addbareq_cmd(padapter, (u8)priority);
1748 phtpriv->baddbareq_issued[priority] = true;
1749 }
1750 }
1751 }
1752