1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 ******************************************************************************/
15 #define _RTW_MLME_C_
16
17 #include <osdep_service.h>
18 #include <drv_types.h>
19 #include <recv_osdep.h>
20 #include <xmit_osdep.h>
21 #include <hal_intf.h>
22 #include <mlme_osdep.h>
23 #include <sta_info.h>
24 #include <linux/ieee80211.h>
25 #include <wifi.h>
26 #include <wlan_bssdef.h>
27 #include <rtw_sreset.h>
28
29 static struct wlan_network *
30 rtw_select_candidate_from_queue(struct mlme_priv *pmlmepriv);
31 static int rtw_do_join(struct rtw_adapter *padapter);
32
rtw_init_mlme_timer(struct rtw_adapter * padapter)33 static void rtw_init_mlme_timer(struct rtw_adapter *padapter)
34 {
35 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
36
37 setup_timer(&pmlmepriv->assoc_timer, rtw23a_join_to_handler,
38 (unsigned long)padapter);
39
40 setup_timer(&pmlmepriv->scan_to_timer, rtw_scan_timeout_handler23a,
41 (unsigned long)padapter);
42
43 setup_timer(&pmlmepriv->dynamic_chk_timer,
44 rtw_dynamic_check_timer_handler, (unsigned long)padapter);
45
46 setup_timer(&pmlmepriv->set_scan_deny_timer,
47 rtw_set_scan_deny_timer_hdl, (unsigned long)padapter);
48 }
49
rtw_init_mlme_priv23a(struct rtw_adapter * padapter)50 int rtw_init_mlme_priv23a(struct rtw_adapter *padapter)
51 {
52 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
53
54 pmlmepriv->nic_hdl = padapter;
55
56 pmlmepriv->fw_state = 0;
57 pmlmepriv->cur_network.network.ifmode = NL80211_IFTYPE_UNSPECIFIED;
58 /* 1: active, 0: pasive. Maybe someday we should rename this
59 varable to "active_mode" (Jeff) */
60 pmlmepriv->scan_mode = SCAN_ACTIVE;
61
62 spin_lock_init(&pmlmepriv->lock);
63 _rtw_init_queue23a(&pmlmepriv->scanned_queue);
64
65 memset(&pmlmepriv->assoc_ssid, 0, sizeof(struct cfg80211_ssid));
66
67 rtw_clear_scan_deny(padapter);
68
69 rtw_init_mlme_timer(padapter);
70 return _SUCCESS;
71 }
72
73 #ifdef CONFIG_8723AU_AP_MODE
rtw_free_mlme_ie_data(u8 ** ppie,u32 * plen)74 static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen)
75 {
76 if (*ppie) {
77 kfree(*ppie);
78 *plen = 0;
79 *ppie = NULL;
80 }
81 }
82 #endif
83
rtw23a_free_mlme_priv_ie_data(struct mlme_priv * pmlmepriv)84 void rtw23a_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv)
85 {
86 #ifdef CONFIG_8723AU_AP_MODE
87 kfree(pmlmepriv->assoc_req);
88 kfree(pmlmepriv->assoc_rsp);
89 rtw_free_mlme_ie_data(&pmlmepriv->wps_probe_req_ie,
90 &pmlmepriv->wps_probe_req_ie_len);
91 #endif
92 }
93
rtw_free_mlme_priv23a(struct mlme_priv * pmlmepriv)94 void rtw_free_mlme_priv23a(struct mlme_priv *pmlmepriv)
95 {
96 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
97 "rtw_free_mlme_priv23a\n");
98
99 rtw23a_free_mlme_priv_ie_data(pmlmepriv);
100 }
101
rtw_alloc_network(struct mlme_priv * pmlmepriv,gfp_t gfp)102 struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv, gfp_t gfp)
103 {
104 struct wlan_network *pnetwork;
105
106 pnetwork = kzalloc(sizeof(struct wlan_network), gfp);
107 if (pnetwork) {
108 INIT_LIST_HEAD(&pnetwork->list);
109 pnetwork->network_type = 0;
110 pnetwork->fixed = false;
111 pnetwork->last_scanned = jiffies;
112 pnetwork->join_res = 0;
113 }
114
115 return pnetwork;
116 }
117
_rtw_free_network23a(struct mlme_priv * pmlmepriv,struct wlan_network * pnetwork)118 static void _rtw_free_network23a(struct mlme_priv *pmlmepriv,
119 struct wlan_network *pnetwork)
120 {
121 if (!pnetwork)
122 return;
123
124 if (pnetwork->fixed == true)
125 return;
126
127 list_del_init(&pnetwork->list);
128
129 kfree(pnetwork);
130 }
131
132 /*
133 return the wlan_network with the matching addr
134
135 Shall be called under atomic context... to avoid possible racing condition...
136 */
137 struct wlan_network *
rtw_find_network23a(struct rtw_queue * scanned_queue,u8 * addr)138 rtw_find_network23a(struct rtw_queue *scanned_queue, u8 *addr)
139 {
140 struct list_head *phead, *plist;
141 struct wlan_network *pnetwork = NULL;
142
143 if (is_zero_ether_addr(addr)) {
144 pnetwork = NULL;
145 goto exit;
146 }
147
148 /* spin_lock_bh(&scanned_queue->lock); */
149
150 phead = get_list_head(scanned_queue);
151 plist = phead->next;
152
153 while (plist != phead) {
154 pnetwork = container_of(plist, struct wlan_network, list);
155
156 if (ether_addr_equal(addr, pnetwork->network.MacAddress))
157 break;
158
159 plist = plist->next;
160 }
161
162 if (plist == phead)
163 pnetwork = NULL;
164
165 /* spin_unlock_bh(&scanned_queue->lock); */
166
167 exit:
168
169 return pnetwork;
170 }
171
rtw_free_network_queue23a(struct rtw_adapter * padapter)172 void rtw_free_network_queue23a(struct rtw_adapter *padapter)
173 {
174 struct list_head *phead, *plist, *ptmp;
175 struct wlan_network *pnetwork;
176 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
177 struct rtw_queue *scanned_queue = &pmlmepriv->scanned_queue;
178
179 spin_lock_bh(&scanned_queue->lock);
180
181 phead = get_list_head(scanned_queue);
182
183 list_for_each_safe(plist, ptmp, phead) {
184 pnetwork = container_of(plist, struct wlan_network, list);
185
186 _rtw_free_network23a(pmlmepriv, pnetwork);
187 }
188
189 spin_unlock_bh(&scanned_queue->lock);
190 }
191
rtw_if_up23a(struct rtw_adapter * padapter)192 int rtw_if_up23a(struct rtw_adapter *padapter)
193 {
194 int res;
195
196 if (padapter->bDriverStopped || padapter->bSurpriseRemoved ||
197 !check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
198 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
199 "rtw_if_up23a:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n",
200 padapter->bDriverStopped, padapter->bSurpriseRemoved);
201 res = false;
202 } else
203 res = true;
204
205 return res;
206 }
207
rtw_generate_random_ibss23a(u8 * pibss)208 void rtw_generate_random_ibss23a(u8 *pibss)
209 {
210 unsigned long curtime = jiffies;
211
212 pibss[0] = 0x02; /* in ad-hoc mode bit1 must set to 1 */
213 pibss[1] = 0x11;
214 pibss[2] = 0x87;
215 pibss[3] = curtime & 0xff;/* p[0]; */
216 pibss[4] = (curtime >> 8) & 0xff;/* p[1]; */
217 pibss[5] = (curtime >> 16) & 0xff;/* p[2]; */
218 }
219
rtw_set_roaming(struct rtw_adapter * adapter,u8 to_roaming)220 void rtw_set_roaming(struct rtw_adapter *adapter, u8 to_roaming)
221 {
222 if (to_roaming == 0)
223 adapter->mlmepriv.to_join = false;
224 adapter->mlmepriv.to_roaming = to_roaming;
225 }
226
_rtw_roaming(struct rtw_adapter * padapter,struct wlan_network * tgt_network)227 static void _rtw_roaming(struct rtw_adapter *padapter,
228 struct wlan_network *tgt_network)
229 {
230 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
231 struct wlan_network *pnetwork;
232 int do_join_r;
233
234 if (tgt_network)
235 pnetwork = tgt_network;
236 else
237 pnetwork = &pmlmepriv->cur_network;
238
239 if (padapter->mlmepriv.to_roaming > 0) {
240 DBG_8723A("roaming from %s(%pM), length:%d\n",
241 pnetwork->network.Ssid.ssid,
242 pnetwork->network.MacAddress,
243 pnetwork->network.Ssid.ssid_len);
244 memcpy(&pmlmepriv->assoc_ssid, &pnetwork->network.Ssid,
245 sizeof(struct cfg80211_ssid));
246
247 pmlmepriv->assoc_by_bssid = false;
248
249 while (1) {
250 do_join_r = rtw_do_join(padapter);
251 if (do_join_r == _SUCCESS)
252 break;
253 else {
254 DBG_8723A("roaming do_join return %d\n",
255 do_join_r);
256 pmlmepriv->to_roaming--;
257
258 if (padapter->mlmepriv.to_roaming > 0)
259 continue;
260 else {
261 DBG_8723A("%s(%d) -to roaming fail, "
262 "indicate_disconnect\n",
263 __func__, __LINE__);
264 rtw_indicate_disconnect23a(padapter);
265 break;
266 }
267 }
268 }
269 }
270 }
271
rtw23a_roaming(struct rtw_adapter * padapter,struct wlan_network * tgt_network)272 void rtw23a_roaming(struct rtw_adapter *padapter,
273 struct wlan_network *tgt_network)
274 {
275 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
276
277 spin_lock_bh(&pmlmepriv->lock);
278 _rtw_roaming(padapter, tgt_network);
279 spin_unlock_bh(&pmlmepriv->lock);
280 }
281
rtw_free_network_nolock(struct mlme_priv * pmlmepriv,struct wlan_network * pnetwork)282 static void rtw_free_network_nolock(struct mlme_priv *pmlmepriv,
283 struct wlan_network *pnetwork)
284 {
285 _rtw_free_network23a(pmlmepriv, pnetwork);
286 }
287
rtw_is_same_ibss23a(struct rtw_adapter * adapter,struct wlan_network * pnetwork)288 bool rtw_is_same_ibss23a(struct rtw_adapter *adapter,
289 struct wlan_network *pnetwork)
290 {
291 int ret;
292 struct security_priv *psecuritypriv = &adapter->securitypriv;
293
294 if (psecuritypriv->dot11PrivacyAlgrthm != 0 &&
295 pnetwork->network.Privacy == 0)
296 ret = false;
297 else if (psecuritypriv->dot11PrivacyAlgrthm == 0 &&
298 pnetwork->network.Privacy == 1)
299 ret = false;
300 else
301 ret = true;
302
303 return ret;
304 }
305
306 inline int is_same_ess(struct wlan_bssid_ex *a, struct wlan_bssid_ex *b);
is_same_ess(struct wlan_bssid_ex * a,struct wlan_bssid_ex * b)307 inline int is_same_ess(struct wlan_bssid_ex *a, struct wlan_bssid_ex *b)
308 {
309 return (a->Ssid.ssid_len == b->Ssid.ssid_len) &&
310 !memcmp(a->Ssid.ssid, b->Ssid.ssid, a->Ssid.ssid_len);
311 }
312
is_same_network23a(struct wlan_bssid_ex * src,struct wlan_bssid_ex * dst)313 int is_same_network23a(struct wlan_bssid_ex *src, struct wlan_bssid_ex *dst)
314 {
315 u16 s_cap, d_cap;
316
317 s_cap = src->capability;
318 d_cap = dst->capability;
319
320 return ((src->Ssid.ssid_len == dst->Ssid.ssid_len) &&
321 /* (src->DSConfig == dst->DSConfig) && */
322 ether_addr_equal(src->MacAddress, dst->MacAddress) &&
323 !memcmp(src->Ssid.ssid, dst->Ssid.ssid, src->Ssid.ssid_len) &&
324 (s_cap & WLAN_CAPABILITY_IBSS) ==
325 (d_cap & WLAN_CAPABILITY_IBSS) &&
326 (s_cap & WLAN_CAPABILITY_ESS) == (d_cap & WLAN_CAPABILITY_ESS));
327 }
328
329 struct wlan_network *
rtw_get_oldest_wlan_network23a(struct rtw_queue * scanned_queue)330 rtw_get_oldest_wlan_network23a(struct rtw_queue *scanned_queue)
331 {
332 struct list_head *plist, *phead;
333 struct wlan_network *pwlan;
334 struct wlan_network *oldest = NULL;
335
336 phead = get_list_head(scanned_queue);
337
338 list_for_each(plist, phead) {
339 pwlan = container_of(plist, struct wlan_network, list);
340
341 if (pwlan->fixed != true) {
342 if (!oldest || time_after(oldest->last_scanned,
343 pwlan->last_scanned))
344 oldest = pwlan;
345 }
346 }
347
348 return oldest;
349 }
350
update_network23a(struct wlan_bssid_ex * dst,struct wlan_bssid_ex * src,struct rtw_adapter * padapter,bool update_ie)351 void update_network23a(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src,
352 struct rtw_adapter *padapter, bool update_ie)
353 {
354 u8 ss_ori = dst->SignalStrength;
355 u8 sq_ori = dst->SignalQuality;
356 long rssi_ori = dst->Rssi;
357
358 u8 ss_smp = src->SignalStrength;
359 u8 sq_smp = src->SignalQuality;
360 long rssi_smp = src->Rssi;
361
362 u8 ss_final;
363 u8 sq_final;
364 long rssi_final;
365
366 DBG_8723A("%s %s(%pM, ch%u) ss_ori:%3u, sq_ori:%3u, rssi_ori:%3ld, "
367 "ss_smp:%3u, sq_smp:%3u, rssi_smp:%3ld\n",
368 __func__, src->Ssid.ssid, src->MacAddress,
369 src->DSConfig, ss_ori, sq_ori, rssi_ori,
370 ss_smp, sq_smp, rssi_smp
371 );
372
373 /* The rule below is 1/5 for sample value, 4/5 for history value */
374 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) &&
375 is_same_network23a(&padapter->mlmepriv.cur_network.network, src)) {
376 /* Take the recvpriv's value for the connected AP*/
377 ss_final = padapter->recvpriv.signal_strength;
378 sq_final = padapter->recvpriv.signal_qual;
379 /* the rssi value here is undecorated, and will be
380 used for antenna diversity */
381 if (sq_smp != 101) /* from the right channel */
382 rssi_final = (src->Rssi+dst->Rssi*4)/5;
383 else
384 rssi_final = rssi_ori;
385 } else {
386 if (sq_smp != 101) { /* from the right channel */
387 ss_final = ((u32)src->SignalStrength +
388 (u32)dst->SignalStrength * 4) / 5;
389 sq_final = ((u32)src->SignalQuality +
390 (u32)dst->SignalQuality * 4) / 5;
391 rssi_final = src->Rssi+dst->Rssi * 4 / 5;
392 } else {
393 /* bss info not receiving from the right channel, use
394 the original RX signal infos */
395 ss_final = dst->SignalStrength;
396 sq_final = dst->SignalQuality;
397 rssi_final = dst->Rssi;
398 }
399
400 }
401
402 if (update_ie)
403 memcpy(dst, src, get_wlan_bssid_ex_sz(src));
404
405 dst->SignalStrength = ss_final;
406 dst->SignalQuality = sq_final;
407 dst->Rssi = rssi_final;
408
409 DBG_8723A("%s %s(%pM), SignalStrength:%u, SignalQuality:%u, "
410 "RawRSSI:%ld\n", __func__, dst->Ssid.ssid, dst->MacAddress,
411 dst->SignalStrength, dst->SignalQuality, dst->Rssi);
412 }
413
update_current_network(struct rtw_adapter * adapter,struct wlan_bssid_ex * pnetwork)414 static void update_current_network(struct rtw_adapter *adapter,
415 struct wlan_bssid_ex *pnetwork)
416 {
417 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
418
419 if (check_fwstate(pmlmepriv, _FW_LINKED) &&
420 is_same_network23a(&pmlmepriv->cur_network.network, pnetwork)) {
421 update_network23a(&pmlmepriv->cur_network.network,
422 pnetwork, adapter, true);
423
424 rtw_update_protection23a(adapter,
425 pmlmepriv->cur_network.network.IEs,
426 pmlmepriv->cur_network.network.IELength);
427 }
428 }
429
430 /*
431
432 Caller must hold pmlmepriv->lock first.
433
434 */
rtw_update_scanned_network(struct rtw_adapter * adapter,struct wlan_bssid_ex * target)435 static void rtw_update_scanned_network(struct rtw_adapter *adapter,
436 struct wlan_bssid_ex *target)
437 {
438 struct list_head *plist, *phead;
439 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
440 struct wlan_network *pnetwork = NULL;
441 struct wlan_network *oldest = NULL;
442 struct rtw_queue *queue = &pmlmepriv->scanned_queue;
443 u32 bssid_ex_sz;
444 int found = 0;
445
446 spin_lock_bh(&queue->lock);
447 phead = get_list_head(queue);
448
449 list_for_each(plist, phead) {
450 pnetwork = container_of(plist, struct wlan_network, list);
451
452 if (is_same_network23a(&pnetwork->network, target)) {
453 found = 1;
454 break;
455 }
456 if (!oldest || time_after(oldest->last_scanned,
457 pnetwork->last_scanned))
458 oldest = pnetwork;
459 }
460
461 /* If we didn't find a match, then get a new network slot to initialize
462 * with this beacon's information */
463 if (!found) {
464 pnetwork = rtw_alloc_network(pmlmepriv, GFP_ATOMIC);
465 if (!pnetwork) {
466 if (!oldest) {
467 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
468 "something wrong here\n");
469 goto exit;
470 }
471 pnetwork = oldest;
472 } else
473 list_add_tail(&pnetwork->list, &queue->queue);
474
475 bssid_ex_sz = get_wlan_bssid_ex_sz(target);
476 target->Length = bssid_ex_sz;
477 memcpy(&pnetwork->network, target, bssid_ex_sz);
478
479 /* variable initialize */
480 pnetwork->fixed = false;
481 pnetwork->last_scanned = jiffies;
482
483 pnetwork->network_type = 0;
484 pnetwork->join_res = 0;
485
486 /* bss info not receiving from the right channel */
487 if (pnetwork->network.SignalQuality == 101)
488 pnetwork->network.SignalQuality = 0;
489 } else {
490 /*
491 * we have an entry and we are going to update it. But
492 * this entry may be already expired. In this case we
493 * do the same as we found a new net and call the
494 * new_net handler
495 */
496 bool update_ie = true;
497
498 pnetwork->last_scanned = jiffies;
499
500 /* target.reserved == 1, means that scanned network is
501 * a bcn frame. */
502 if (pnetwork->network.IELength > target->IELength &&
503 target->reserved == 1)
504 update_ie = false;
505
506 update_network23a(&pnetwork->network, target, adapter,
507 update_ie);
508 }
509
510 exit:
511 spin_unlock_bh(&queue->lock);
512 }
513
rtw_add_network(struct rtw_adapter * adapter,struct wlan_bssid_ex * pnetwork)514 static void rtw_add_network(struct rtw_adapter *adapter,
515 struct wlan_bssid_ex *pnetwork)
516 {
517 update_current_network(adapter, pnetwork);
518 rtw_update_scanned_network(adapter, pnetwork);
519 }
520
521 /* select the desired network based on the capability of the (i)bss. */
522 /* check items: (1) security */
523 /* (2) network_type */
524 /* (3) WMM */
525 /* (4) HT */
526 /* (5) others */
rtw_is_desired_network(struct rtw_adapter * adapter,struct wlan_network * pnetwork)527 static int rtw_is_desired_network(struct rtw_adapter *adapter,
528 struct wlan_network *pnetwork)
529 {
530 struct security_priv *psecuritypriv = &adapter->securitypriv;
531 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
532 u32 desired_encmode;
533 u32 privacy;
534 int bselected = true;
535
536 desired_encmode = psecuritypriv->ndisencryptstatus;
537 privacy = pnetwork->network.Privacy;
538
539 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
540 if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
541 WLAN_OUI_TYPE_MICROSOFT_WPA,
542 pnetwork->network.IEs,
543 pnetwork->network.IELength))
544 return true;
545 else
546 return false;
547 }
548 if (adapter->registrypriv.wifi_spec == 1) {
549 /* for correct flow of 8021X to do.... */
550 if (desired_encmode == Ndis802_11EncryptionDisabled &&
551 privacy != 0)
552 bselected = false;
553 }
554
555 if (desired_encmode != Ndis802_11EncryptionDisabled && privacy == 0) {
556 DBG_8723A("desired_encmode: %d, privacy: %d\n",
557 desired_encmode, privacy);
558 bselected = false;
559 }
560
561 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
562 if (pnetwork->network.ifmode !=
563 pmlmepriv->cur_network.network.ifmode)
564 bselected = false;
565 }
566
567 return bselected;
568 }
569
rtw_survey_event_cb23a(struct rtw_adapter * adapter,const u8 * pbuf)570 void rtw_survey_event_cb23a(struct rtw_adapter *adapter, const u8 *pbuf)
571 {
572 u32 len;
573 struct wlan_bssid_ex *pnetwork;
574 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
575 struct survey_event *survey = (struct survey_event *)pbuf;
576
577 pnetwork = survey->bss;
578
579 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
580 "rtw_survey_event_cb23a, ssid=%s\n", pnetwork->Ssid.ssid);
581
582 len = get_wlan_bssid_ex_sz(pnetwork);
583 if (len > (sizeof(struct wlan_bssid_ex))) {
584 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
585 "****rtw_survey_event_cb23a: return a wrong bss ***\n");
586 return;
587 }
588
589 spin_lock_bh(&pmlmepriv->lock);
590
591 /* update IBSS_network 's timestamp */
592 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
593 if (ether_addr_equal(pmlmepriv->cur_network.network.MacAddress,
594 pnetwork->MacAddress)) {
595 struct wlan_network *ibss_wlan;
596
597 pmlmepriv->cur_network.network.beacon_interval =
598 pnetwork->beacon_interval;
599 pmlmepriv->cur_network.network.capability =
600 pnetwork->capability;
601 pmlmepriv->cur_network.network.tsf = pnetwork->tsf;
602 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
603 ibss_wlan = rtw_find_network23a(
604 &pmlmepriv->scanned_queue,
605 pnetwork->MacAddress);
606 if (ibss_wlan) {
607 pmlmepriv->cur_network.network.beacon_interval =
608 ibss_wlan->network.beacon_interval;
609 pmlmepriv->cur_network.network.capability =
610 ibss_wlan->network.capability;
611 pmlmepriv->cur_network.network.tsf =
612 ibss_wlan->network.tsf;
613 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
614 goto exit;
615 }
616 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
617 }
618 }
619
620 /* lock pmlmepriv->lock when you accessing network_q */
621 if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
622 if (pnetwork->Ssid.ssid[0] == 0)
623 pnetwork->Ssid.ssid_len = 0;
624
625 rtw_add_network(adapter, pnetwork);
626 }
627
628 exit:
629
630 spin_unlock_bh(&pmlmepriv->lock);
631
632 kfree(survey->bss);
633 survey->bss = NULL;
634 }
635
636 void
rtw_surveydone_event_callback23a(struct rtw_adapter * adapter,const u8 * pbuf)637 rtw_surveydone_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf)
638 {
639 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
640 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
641 int ret;
642
643 spin_lock_bh(&pmlmepriv->lock);
644
645 if (pmlmepriv->wps_probe_req_ie) {
646 pmlmepriv->wps_probe_req_ie_len = 0;
647 kfree(pmlmepriv->wps_probe_req_ie);
648 pmlmepriv->wps_probe_req_ie = NULL;
649 }
650
651 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
652 "rtw_surveydone_event_callback23a: fw_state:%x\n",
653 get_fwstate(pmlmepriv));
654
655 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
656 del_timer_sync(&pmlmepriv->scan_to_timer);
657
658 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
659 } else {
660 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
661 "nic status =%x, survey done event comes too late!\n",
662 get_fwstate(pmlmepriv));
663 }
664
665 rtw_set_signal_stat_timer(&adapter->recvpriv);
666
667 if (pmlmepriv->to_join == true) {
668 set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
669 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
670 ret = rtw_select_and_join_from_scanned_queue23a(
671 pmlmepriv);
672 if (ret != _SUCCESS)
673 rtw_do_join_adhoc(adapter);
674 } else {
675 pmlmepriv->to_join = false;
676 ret = rtw_select_and_join_from_scanned_queue23a(
677 pmlmepriv);
678 if (ret != _SUCCESS) {
679 DBG_8723A("try_to_join, but select scanning "
680 "queue fail, to_roaming:%d\n",
681 adapter->mlmepriv.to_roaming);
682 if (adapter->mlmepriv.to_roaming) {
683 if (--pmlmepriv->to_roaming == 0 ||
684 rtw_sitesurvey_cmd23a(
685 adapter,
686 &pmlmepriv->assoc_ssid, 1,
687 NULL, 0) != _SUCCESS) {
688 rtw_set_roaming(adapter, 0);
689 rtw_free_assoc_resources23a(
690 adapter, 1);
691 rtw_indicate_disconnect23a(
692 adapter);
693 } else
694 pmlmepriv->to_join = true;
695 }
696 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
697 }
698 }
699 }
700
701 spin_unlock_bh(&pmlmepriv->lock);
702
703 rtw_os_xmit_schedule23a(adapter);
704
705 if (pmlmeext->sitesurvey_res.bss_cnt == 0)
706 rtw_sreset_reset(adapter);
707
708 rtw_cfg80211_surveydone_event_callback(adapter);
709 }
710
free_scanqueue(struct mlme_priv * pmlmepriv)711 static void free_scanqueue(struct mlme_priv *pmlmepriv)
712 {
713 struct wlan_network *pnetwork;
714 struct rtw_queue *scan_queue = &pmlmepriv->scanned_queue;
715 struct list_head *plist, *phead, *ptemp;
716
717 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, "+free_scanqueue\n");
718 spin_lock_bh(&scan_queue->lock);
719
720 phead = get_list_head(scan_queue);
721
722 list_for_each_safe(plist, ptemp, phead) {
723 pnetwork = container_of(plist, struct wlan_network, list);
724 pnetwork->fixed = false;
725 _rtw_free_network23a(pmlmepriv, pnetwork);
726 }
727
728 spin_unlock_bh(&scan_queue->lock);
729 }
730
731 /*
732 *rtw_free_assoc_resources23a: the caller has to lock pmlmepriv->lock
733 */
rtw_free_assoc_resources23a(struct rtw_adapter * adapter,int lock_scanned_queue)734 void rtw_free_assoc_resources23a(struct rtw_adapter *adapter,
735 int lock_scanned_queue)
736 {
737 struct wlan_network *pwlan;
738 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
739 struct sta_priv *pstapriv = &adapter->stapriv;
740 struct wlan_network *tgt_network = &pmlmepriv->cur_network;
741 struct sta_info *psta;
742
743 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
744 "+rtw_free_assoc_resources23a\n");
745 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
746 "tgt_network->network.MacAddress=%pM ssid=%s\n",
747 tgt_network->network.MacAddress,
748 tgt_network->network.Ssid.ssid);
749
750 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_AP_STATE)) {
751 psta = rtw_get_stainfo23a(&adapter->stapriv,
752 tgt_network->network.MacAddress);
753
754 spin_lock_bh(&pstapriv->sta_hash_lock);
755 rtw_free_stainfo23a(adapter, psta);
756 spin_unlock_bh(&pstapriv->sta_hash_lock);
757 }
758
759 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE |
760 WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)) {
761 rtw_free_all_stainfo23a(adapter);
762
763 psta = rtw_get_bcmc_stainfo23a(adapter);
764 spin_lock_bh(&pstapriv->sta_hash_lock);
765 rtw_free_stainfo23a(adapter, psta);
766 spin_unlock_bh(&pstapriv->sta_hash_lock);
767
768 rtw_init_bcmc_stainfo23a(adapter);
769 }
770
771 if (lock_scanned_queue)
772 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
773
774 pwlan = rtw_find_network23a(&pmlmepriv->scanned_queue,
775 tgt_network->network.MacAddress);
776 if (pwlan)
777 pwlan->fixed = false;
778 else
779 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
780 "rtw_free_assoc_resources23a : pwlan== NULL\n");
781
782 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) &&
783 adapter->stapriv.asoc_sta_count == 1)
784 rtw_free_network_nolock(pmlmepriv, pwlan);
785
786 if (lock_scanned_queue)
787 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
788
789 pmlmepriv->key_mask = 0;
790 }
791
792 /*
793 *rtw_indicate_connect23a: the caller has to lock pmlmepriv->lock
794 */
rtw_indicate_connect23a(struct rtw_adapter * padapter)795 void rtw_indicate_connect23a(struct rtw_adapter *padapter)
796 {
797 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
798
799 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
800 "+rtw_indicate_connect23a\n");
801
802 pmlmepriv->to_join = false;
803
804 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
805 set_fwstate(pmlmepriv, _FW_LINKED);
806
807 rtw_cfg80211_indicate_connect(padapter);
808
809 netif_carrier_on(padapter->pnetdev);
810
811 if (padapter->pid[2] != 0)
812 kill_pid(find_vpid(padapter->pid[2]), SIGALRM, 1);
813 }
814
815 rtw_set_roaming(padapter, 0);
816
817 rtw_set_scan_deny(padapter, 3000);
818
819 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
820 "-rtw_indicate_connect23a: fw_state=0x%08x\n",
821 get_fwstate(pmlmepriv));
822 }
823
824 /*
825 *rtw_indicate_disconnect23a: the caller has to lock pmlmepriv->lock
826 */
rtw_indicate_disconnect23a(struct rtw_adapter * padapter)827 void rtw_indicate_disconnect23a(struct rtw_adapter *padapter)
828 {
829 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
830
831 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
832 "+rtw_indicate_disconnect23a\n");
833
834 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING|WIFI_UNDER_WPS);
835
836 /* DBG_8723A("clear wps when %s\n", __func__); */
837
838 if (padapter->mlmepriv.to_roaming > 0)
839 _clr_fwstate_(pmlmepriv, _FW_LINKED);
840
841 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) ||
842 padapter->mlmepriv.to_roaming <= 0) {
843 rtw_os_indicate_disconnect23a(padapter);
844
845 /* set ips_deny_time to avoid enter IPS before LPS leave */
846 padapter->pwrctrlpriv.ips_deny_time =
847 jiffies + msecs_to_jiffies(3000);
848
849 _clr_fwstate_(pmlmepriv, _FW_LINKED);
850
851 rtw_clear_scan_deny(padapter);
852 }
853
854 rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_DISCONNECT, 1);
855 }
856
rtw_scan_abort23a(struct rtw_adapter * adapter)857 void rtw_scan_abort23a(struct rtw_adapter *adapter)
858 {
859 unsigned long start;
860 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
861 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
862
863 start = jiffies;
864 pmlmeext->scan_abort = true;
865 while (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) &&
866 jiffies_to_msecs(jiffies - start) <= 200) {
867 if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
868 break;
869
870 DBG_8723A("%s(%s): fw_state = _FW_UNDER_SURVEY!\n",
871 __func__, adapter->pnetdev->name);
872 msleep(20);
873 }
874
875 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
876 if (!adapter->bDriverStopped && !adapter->bSurpriseRemoved)
877 DBG_8723A("%s(%s): waiting for scan_abort time out!\n",
878 __func__, adapter->pnetdev->name);
879 rtw_cfg80211_indicate_scan_done(wdev_to_priv(adapter->rtw_wdev),
880 true);
881 }
882 pmlmeext->scan_abort = false;
883 }
884
885 static struct sta_info *
rtw_joinbss_update_stainfo(struct rtw_adapter * padapter,struct wlan_network * pnetwork)886 rtw_joinbss_update_stainfo(struct rtw_adapter *padapter,
887 struct wlan_network *pnetwork)
888 {
889 int i;
890 struct sta_info *bmc_sta, *psta;
891 struct recv_reorder_ctrl *preorder_ctrl;
892 struct sta_priv *pstapriv = &padapter->stapriv;
893
894 psta = rtw_get_stainfo23a(pstapriv, pnetwork->network.MacAddress);
895 if (!psta)
896 psta = rtw_alloc_stainfo23a(pstapriv,
897 pnetwork->network.MacAddress,
898 GFP_ATOMIC);
899
900 if (psta) { /* update ptarget_sta */
901 DBG_8723A("%s\n", __func__);
902
903 psta->aid = pnetwork->join_res;
904 psta->mac_id = 0;
905
906 /* sta mode */
907 rtl8723a_SetHalODMVar(padapter, HAL_ODM_STA_INFO, psta, true);
908
909 /* security related */
910 if (padapter->securitypriv.dot11AuthAlgrthm ==
911 dot11AuthAlgrthm_8021X) {
912 padapter->securitypriv.binstallGrpkey = 0;
913 padapter->securitypriv.busetkipkey = 0;
914
915 psta->ieee8021x_blocked = true;
916 psta->dot118021XPrivacy =
917 padapter->securitypriv.dot11PrivacyAlgrthm;
918
919 memset(&psta->dot118021x_UncstKey, 0,
920 sizeof (union Keytype));
921
922 memset(&psta->dot11tkiprxmickey, 0,
923 sizeof (union Keytype));
924 memset(&psta->dot11tkiptxmickey, 0,
925 sizeof (union Keytype));
926
927 memset(&psta->dot11txpn, 0, sizeof (union pn48));
928 memset(&psta->dot11rxpn, 0, sizeof (union pn48));
929 }
930
931 /* Commented by Albert 2012/07/21 */
932 /* When doing the WPS, the wps_ie_len won't equal to 0 */
933 /* And the Wi-Fi driver shouldn't allow the data packet
934 to be transmitted. */
935 if (padapter->securitypriv.wps_ie_len != 0) {
936 psta->ieee8021x_blocked = true;
937 padapter->securitypriv.wps_ie_len = 0;
938 }
939
940 /* for A-MPDU Rx reordering buffer control for bmc_sta &
941 * sta_info */
942 /* if A-MPDU Rx is enabled, resetting
943 rx_ordering_ctrl wstart_b(indicate_seq) to default
944 value = 0xffff */
945 /* todo: check if AP can send A-MPDU packets */
946 for (i = 0; i < 16 ; i++) {
947 /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
948 preorder_ctrl = &psta->recvreorder_ctrl[i];
949 preorder_ctrl->enable = false;
950 preorder_ctrl->indicate_seq = 0xffff;
951 preorder_ctrl->wend_b = 0xffff;
952 /* max_ampdu_sz; ex. 32(kbytes) -> wsize_b = 32 */
953 preorder_ctrl->wsize_b = 64;
954 }
955
956 bmc_sta = rtw_get_bcmc_stainfo23a(padapter);
957 if (bmc_sta) {
958 for (i = 0; i < 16 ; i++) {
959 preorder_ctrl = &bmc_sta->recvreorder_ctrl[i];
960 preorder_ctrl->enable = false;
961 preorder_ctrl->indicate_seq = 0xffff;
962 preorder_ctrl->wend_b = 0xffff;
963 /* max_ampdu_sz; ex. 32(kbytes) ->
964 wsize_b = 32 */
965 preorder_ctrl->wsize_b = 64;
966 }
967 }
968
969 /* misc. */
970 update_sta_info23a(padapter, psta);
971
972 }
973
974 return psta;
975 }
976
977 /* pnetwork : returns from rtw23a_joinbss_event_cb */
978 /* ptarget_wlan: found from scanned_queue */
979 static void
rtw_joinbss_update_network23a(struct rtw_adapter * padapter,struct wlan_network * ptarget_wlan,struct wlan_network * pnetwork)980 rtw_joinbss_update_network23a(struct rtw_adapter *padapter,
981 struct wlan_network *ptarget_wlan,
982 struct wlan_network *pnetwork)
983 {
984 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
985 struct wlan_network *cur_network = &pmlmepriv->cur_network;
986
987 DBG_8723A("%s\n", __func__);
988
989 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
990 "fw_state:%x, BSSID:%pM\n",
991 get_fwstate(pmlmepriv),
992 pnetwork->network.MacAddress);
993
994 /* why not use ptarget_wlan?? */
995 memcpy(&cur_network->network, &pnetwork->network,
996 pnetwork->network.Length);
997 /* some IEs in pnetwork is wrong, so we should use ptarget_wlan IEs */
998 cur_network->network.IELength = ptarget_wlan->network.IELength;
999 memcpy(&cur_network->network.IEs[0], &ptarget_wlan->network.IEs[0],
1000 MAX_IE_SZ);
1001
1002 cur_network->network.capability = ptarget_wlan->network.capability;
1003 cur_network->network.beacon_interval =
1004 ptarget_wlan->network.beacon_interval;
1005 cur_network->network.tsf = ptarget_wlan->network.tsf;
1006
1007 rtw_set_signal_stat_timer(&padapter->recvpriv);
1008 padapter->recvpriv.signal_strength =
1009 ptarget_wlan->network.SignalStrength;
1010 padapter->recvpriv.signal_qual = ptarget_wlan->network.SignalQuality;
1011 /*
1012 * the ptarget_wlan->network.Rssi is raw data, we use
1013 * ptarget_wlan->network.SignalStrength instead (has scaled)
1014 */
1015 DBG_8723A("%s signal_strength:%3u, signal_qual:%3u\n",
1016 __func__, padapter->recvpriv.signal_strength,
1017 padapter->recvpriv.signal_qual);
1018 rtw_set_signal_stat_timer(&padapter->recvpriv);
1019
1020 /* update fw_state will clr _FW_UNDER_LINKING here indirectly */
1021 switch (pnetwork->network.ifmode) {
1022 case NL80211_IFTYPE_P2P_CLIENT:
1023 case NL80211_IFTYPE_STATION:
1024 if (pmlmepriv->fw_state & WIFI_UNDER_WPS)
1025 pmlmepriv->fw_state = WIFI_STATION_STATE|WIFI_UNDER_WPS;
1026 else
1027 pmlmepriv->fw_state = WIFI_STATION_STATE;
1028 break;
1029 case NL80211_IFTYPE_ADHOC:
1030 pmlmepriv->fw_state = WIFI_ADHOC_STATE;
1031 break;
1032 default:
1033 pmlmepriv->fw_state = WIFI_NULL_STATE;
1034 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1035 "Invalid network_mode\n");
1036 break;
1037 }
1038
1039 rtw_update_protection23a(padapter, cur_network->network.IEs,
1040 cur_network->network.IELength);
1041
1042 rtw_update_ht_cap23a(padapter, cur_network->network.IEs,
1043 cur_network->network.IELength);
1044 }
1045
1046 /*
1047 * Notes:
1048 * the function could be > passive_level (the same context as Rx tasklet)
1049 * pnetwork : returns from rtw23a_joinbss_event_cb
1050 * ptarget_wlan: found from scanned_queue
1051 * if join_res > 0, for (fw_state==WIFI_STATION_STATE),
1052 * we check if "ptarget_sta" & "ptarget_wlan" exist.
1053 * if join_res > 0, for (fw_state==WIFI_ADHOC_STATE),
1054 * we only check if "ptarget_wlan" exist.
1055 * if join_res > 0, update "cur_network->network" from "pnetwork->network"
1056 * if (ptarget_wlan !=NULL).
1057 */
1058
rtw_joinbss_event_prehandle23a(struct rtw_adapter * adapter,u8 * pbuf)1059 void rtw_joinbss_event_prehandle23a(struct rtw_adapter *adapter, u8 *pbuf)
1060 {
1061 struct sta_info *ptarget_sta, *pcur_sta;
1062 struct sta_priv *pstapriv = &adapter->stapriv;
1063 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1064 struct wlan_network *pnetwork = (struct wlan_network *)pbuf;
1065 struct wlan_network *cur_network = &pmlmepriv->cur_network;
1066 struct wlan_network *pcur_wlan, *ptarget_wlan = NULL;
1067 bool the_same_macaddr;
1068
1069 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1070 "joinbss event call back received with res=%d\n",
1071 pnetwork->join_res);
1072
1073 if (pmlmepriv->assoc_ssid.ssid_len == 0) {
1074 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1075 "@@@@@ joinbss event call back for Any SSid\n");
1076 } else {
1077 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1078 "@@@@@ rtw23a_joinbss_event_cb for SSid:%s\n",
1079 pmlmepriv->assoc_ssid.ssid);
1080 }
1081
1082 if (ether_addr_equal(pnetwork->network.MacAddress,
1083 cur_network->network.MacAddress))
1084 the_same_macaddr = true;
1085 else
1086 the_same_macaddr = false;
1087
1088 pnetwork->network.Length = get_wlan_bssid_ex_sz(&pnetwork->network);
1089 if (pnetwork->network.Length > sizeof(struct wlan_bssid_ex)) {
1090 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1091 "***joinbss_evt_callback return a wrong bss ***\n");
1092 return;
1093 }
1094
1095 spin_lock_bh(&pmlmepriv->lock);
1096
1097 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1098 "rtw23a_joinbss_event_cb !! _enter_critical\n");
1099
1100 if (pnetwork->join_res > 0) {
1101 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1102 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
1103 /* s1. find ptarget_wlan */
1104 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1105 if (the_same_macaddr) {
1106 ptarget_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
1107 } else {
1108 pcur_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
1109 if (pcur_wlan)
1110 pcur_wlan->fixed = false;
1111
1112 pcur_sta = rtw_get_stainfo23a(pstapriv, cur_network->network.MacAddress);
1113 if (pcur_sta) {
1114 spin_lock_bh(&pstapriv->sta_hash_lock);
1115 rtw_free_stainfo23a(adapter,
1116 pcur_sta);
1117 spin_unlock_bh(&pstapriv->sta_hash_lock);
1118 }
1119
1120 ptarget_wlan = rtw_find_network23a(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress);
1121 if (check_fwstate(pmlmepriv,
1122 WIFI_STATION_STATE)) {
1123 if (ptarget_wlan)
1124 ptarget_wlan->fixed =
1125 true;
1126 }
1127 }
1128
1129 } else {
1130 ptarget_wlan = rtw_find_network23a(
1131 &pmlmepriv->scanned_queue,
1132 pnetwork->network.MacAddress);
1133 if (check_fwstate(pmlmepriv,
1134 WIFI_STATION_STATE)) {
1135 if (ptarget_wlan)
1136 ptarget_wlan->fixed = true;
1137 }
1138 }
1139
1140 /* s2. update cur_network */
1141 if (ptarget_wlan)
1142 rtw_joinbss_update_network23a(adapter,
1143 ptarget_wlan,
1144 pnetwork);
1145 else {
1146 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1147 "Can't find ptarget_wlan when joinbss_event callback\n");
1148 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1149 goto ignore_joinbss_callback;
1150 }
1151
1152 /* s3. find ptarget_sta & update ptarget_sta after
1153 update cur_network only for station mode */
1154 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
1155 ptarget_sta = rtw_joinbss_update_stainfo(
1156 adapter, pnetwork);
1157 if (!ptarget_sta) {
1158 RT_TRACE(_module_rtl871x_mlme_c_,
1159 _drv_err_,
1160 "Can't update stainfo when joinbss_event callback\n");
1161 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1162 goto ignore_joinbss_callback;
1163 }
1164 }
1165
1166 /* s4. indicate connect */
1167 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
1168 rtw_indicate_connect23a(adapter);
1169 else {
1170 /* adhoc mode will rtw_indicate_connect23a
1171 when rtw_stassoc_event_callback23a */
1172 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1173 "adhoc mode, fw_state:%x\n",
1174 get_fwstate(pmlmepriv));
1175 }
1176
1177 /* s5. Cancle assoc_timer */
1178 del_timer_sync(&pmlmepriv->assoc_timer);
1179
1180 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
1181 "Cancle assoc_timer\n");
1182 } else {
1183 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1184 "rtw23a_joinbss_event_cb err: fw_state:%x\n",
1185 get_fwstate(pmlmepriv));
1186 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1187 goto ignore_joinbss_callback;
1188 }
1189 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1190 } else if (pnetwork->join_res == -4) {
1191 rtw_reset_securitypriv23a(adapter);
1192 mod_timer(&pmlmepriv->assoc_timer,
1193 jiffies + msecs_to_jiffies(1));
1194
1195 /* rtw_free_assoc_resources23a(adapter, 1); */
1196
1197 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
1198 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1199 "fail! clear _FW_UNDER_LINKING ^^^fw_state=%x\n",
1200 get_fwstate(pmlmepriv));
1201 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1202 }
1203 } else {
1204 /* if join_res < 0 (join fails), then try again */
1205 mod_timer(&pmlmepriv->assoc_timer,
1206 jiffies + msecs_to_jiffies(1));
1207 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1208 }
1209
1210 ignore_joinbss_callback:
1211
1212 spin_unlock_bh(&pmlmepriv->lock);
1213 }
1214
rtw23a_joinbss_event_cb(struct rtw_adapter * adapter,const u8 * pbuf)1215 void rtw23a_joinbss_event_cb(struct rtw_adapter *adapter, const u8 *pbuf)
1216 {
1217 struct wlan_network *pnetwork = (struct wlan_network *)pbuf;
1218
1219 mlmeext_joinbss_event_callback23a(adapter, pnetwork->join_res);
1220
1221 rtw_os_xmit_schedule23a(adapter);
1222 }
1223
rtw_stassoc_event_callback23a(struct rtw_adapter * adapter,const u8 * pbuf)1224 void rtw_stassoc_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf)
1225 {
1226 struct sta_info *psta;
1227 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1228 struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf;
1229 struct wlan_network *cur_network = &pmlmepriv->cur_network;
1230 struct wlan_network *ptarget_wlan;
1231
1232 if (rtw_access_ctrl23a(adapter, pstassoc->macaddr) == false)
1233 return;
1234
1235 #ifdef CONFIG_8723AU_AP_MODE
1236 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1237 psta = rtw_get_stainfo23a(&adapter->stapriv, pstassoc->macaddr);
1238 if (psta) {
1239 /* bss_cap_update_on_sta_join23a(adapter, psta); */
1240 /* sta_info_update23a(adapter, psta); */
1241 ap_sta_info_defer_update23a(adapter, psta);
1242 }
1243 return;
1244 }
1245 #endif
1246 /* for AD-HOC mode */
1247 psta = rtw_get_stainfo23a(&adapter->stapriv, pstassoc->macaddr);
1248 if (psta != NULL) {
1249 /* the sta have been in sta_info_queue => do nothing */
1250 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1251 "Error: rtw_stassoc_event_callback23a: sta has been in sta_hash_queue\n");
1252 /* between drv has received this event before and
1253 fw have not yet to set key to CAM_ENTRY) */
1254 return;
1255 }
1256
1257 psta = rtw_alloc_stainfo23a(&adapter->stapriv, pstassoc->macaddr,
1258 GFP_KERNEL);
1259 if (!psta) {
1260 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1261 "Can't alloc sta_info when rtw_stassoc_event_callback23a\n");
1262 return;
1263 }
1264
1265 /* to do : init sta_info variable */
1266 psta->qos_option = 0;
1267 psta->mac_id = (uint)pstassoc->cam_id;
1268 /* psta->aid = (uint)pstassoc->cam_id; */
1269 DBG_8723A("%s\n", __func__);
1270 /* for ad-hoc mode */
1271 rtl8723a_SetHalODMVar(adapter, HAL_ODM_STA_INFO, psta, true);
1272
1273 if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
1274 psta->dot118021XPrivacy =
1275 adapter->securitypriv.dot11PrivacyAlgrthm;
1276
1277 psta->ieee8021x_blocked = false;
1278
1279 spin_lock_bh(&pmlmepriv->lock);
1280
1281 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
1282 check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1283 if (adapter->stapriv.asoc_sta_count == 2) {
1284 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1285 ptarget_wlan =
1286 rtw_find_network23a(&pmlmepriv->scanned_queue,
1287 cur_network->network.MacAddress);
1288 if (ptarget_wlan)
1289 ptarget_wlan->fixed = true;
1290 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1291 /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
1292 rtw_indicate_connect23a(adapter);
1293 }
1294 }
1295
1296 spin_unlock_bh(&pmlmepriv->lock);
1297
1298 mlmeext_sta_add_event_callback23a(adapter, psta);
1299 }
1300
rtw_stadel_event_callback23a(struct rtw_adapter * adapter,const u8 * pbuf)1301 void rtw_stadel_event_callback23a(struct rtw_adapter *adapter, const u8 *pbuf)
1302 {
1303 int mac_id;
1304 struct sta_info *psta;
1305 struct wlan_network *pwlan;
1306 struct wlan_bssid_ex *pdev_network;
1307 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1308 struct stadel_event *pstadel = (struct stadel_event *)pbuf;
1309 struct sta_priv *pstapriv = &adapter->stapriv;
1310 struct wlan_network *tgt_network = &pmlmepriv->cur_network;
1311
1312 psta = rtw_get_stainfo23a(&adapter->stapriv, pstadel->macaddr);
1313 if (psta)
1314 mac_id = psta->mac_id;
1315 else
1316 mac_id = pstadel->mac_id;
1317
1318 DBG_8723A("%s(mac_id=%d)=%pM\n", __func__, mac_id, pstadel->macaddr);
1319
1320 if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
1321 return;
1322
1323 mlmeext_sta_del_event_callback23a(adapter);
1324
1325 spin_lock_bh(&pmlmepriv->lock);
1326
1327 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
1328 if (adapter->mlmepriv.to_roaming > 0) {
1329 /* this stadel_event is caused by roaming,
1330 decrease to_roaming */
1331 pmlmepriv->to_roaming--;
1332 } else if (adapter->mlmepriv.to_roaming == 0)
1333 rtw_set_roaming(adapter, adapter->registrypriv.max_roaming_times);
1334 if (*((u16 *)pstadel->rsvd) != WLAN_REASON_EXPIRATION_CHK)
1335 rtw_set_roaming(adapter, 0); /* don't roam */
1336
1337 rtw_free_uc_swdec_pending_queue23a(adapter);
1338
1339 rtw_free_assoc_resources23a(adapter, 1);
1340 rtw_indicate_disconnect23a(adapter);
1341 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1342 /* remove the network entry in scanned_queue */
1343 pwlan = rtw_find_network23a(&pmlmepriv->scanned_queue,
1344 tgt_network->network.MacAddress);
1345 if (pwlan) {
1346 pwlan->fixed = false;
1347 rtw_free_network_nolock(pmlmepriv, pwlan);
1348 }
1349 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1350
1351 _rtw_roaming(adapter, tgt_network);
1352 }
1353
1354 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
1355 check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1356
1357 spin_lock_bh(&pstapriv->sta_hash_lock);
1358 rtw_free_stainfo23a(adapter, psta);
1359 spin_unlock_bh(&pstapriv->sta_hash_lock);
1360
1361 /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
1362 if (adapter->stapriv.asoc_sta_count == 1) {
1363 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1364 /* free old ibss network */
1365 /* pwlan = rtw_find_network23a(
1366 &pmlmepriv->scanned_queue, pstadel->macaddr); */
1367 pwlan = rtw_find_network23a(&pmlmepriv->scanned_queue,
1368 tgt_network->network.MacAddress);
1369 if (pwlan) {
1370 pwlan->fixed = false;
1371 rtw_free_network_nolock(pmlmepriv, pwlan);
1372 }
1373 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1374 /* re-create ibss */
1375 pdev_network = &adapter->registrypriv.dev_network;
1376
1377 memcpy(pdev_network, &tgt_network->network,
1378 get_wlan_bssid_ex_sz(&tgt_network->network));
1379
1380 rtw_do_join_adhoc(adapter);
1381 }
1382 }
1383
1384 spin_unlock_bh(&pmlmepriv->lock);
1385 }
1386
1387 /*
1388 * rtw23a_join_to_handler - Timeout/failure handler for CMD JoinBss
1389 * @adapter: pointer to _adapter structure
1390 */
rtw23a_join_to_handler(unsigned long data)1391 void rtw23a_join_to_handler (unsigned long data)
1392 {
1393 struct rtw_adapter *adapter = (struct rtw_adapter *)data;
1394 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1395 int do_join_r;
1396
1397 DBG_8723A("%s, fw_state=%x\n", __func__, get_fwstate(pmlmepriv));
1398
1399 if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
1400 return;
1401
1402 spin_lock_bh(&pmlmepriv->lock);
1403
1404 if (adapter->mlmepriv.to_roaming > 0) {
1405 /* join timeout caused by roaming */
1406 while (1) {
1407 pmlmepriv->to_roaming--;
1408 if (adapter->mlmepriv.to_roaming != 0) {
1409 /* try another */
1410 DBG_8723A("%s try another roaming\n", __func__);
1411 do_join_r = rtw_do_join(adapter);
1412 if (do_join_r != _SUCCESS) {
1413 DBG_8723A("%s roaming do_join return "
1414 "%d\n", __func__ , do_join_r);
1415 continue;
1416 }
1417 break;
1418 } else {
1419 DBG_8723A("%s We've try roaming but fail\n",
1420 __func__);
1421 rtw_indicate_disconnect23a(adapter);
1422 break;
1423 }
1424 }
1425 } else {
1426 rtw_indicate_disconnect23a(adapter);
1427 free_scanqueue(pmlmepriv);/* */
1428
1429 /* indicate disconnect for the case that join_timeout and
1430 check_fwstate != FW_LINKED */
1431 rtw_cfg80211_indicate_disconnect(adapter);
1432 }
1433
1434 spin_unlock_bh(&pmlmepriv->lock);
1435
1436 }
1437
1438 /*
1439 * rtw_scan_timeout_handler23a - Timeout/Failure handler for CMD SiteSurvey
1440 * @data: pointer to _adapter structure
1441 */
rtw_scan_timeout_handler23a(unsigned long data)1442 void rtw_scan_timeout_handler23a(unsigned long data)
1443 {
1444 struct rtw_adapter *adapter = (struct rtw_adapter *)data;
1445 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1446
1447 DBG_8723A("%s(%s): fw_state =%x\n", __func__, adapter->pnetdev->name,
1448 get_fwstate(pmlmepriv));
1449
1450 spin_lock_bh(&pmlmepriv->lock);
1451
1452 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
1453
1454 spin_unlock_bh(&pmlmepriv->lock);
1455
1456 rtw_cfg80211_indicate_scan_done(wdev_to_priv(adapter->rtw_wdev), true);
1457 }
1458
rtw_dynamic_check_timer_handler(unsigned long data)1459 void rtw_dynamic_check_timer_handler(unsigned long data)
1460 {
1461 struct rtw_adapter *adapter = (struct rtw_adapter *)data;
1462
1463 if (adapter->hw_init_completed == false)
1464 goto out;
1465
1466 if (adapter->bDriverStopped == true ||
1467 adapter->bSurpriseRemoved == true)
1468 goto out;
1469
1470 if (adapter->net_closed == true)
1471 goto out;
1472
1473 rtw_dynamic_chk_wk_cmd23a(adapter);
1474
1475 out:
1476 mod_timer(&adapter->mlmepriv.dynamic_chk_timer,
1477 jiffies + msecs_to_jiffies(2000));
1478 }
1479
rtw_is_scan_deny(struct rtw_adapter * adapter)1480 inline bool rtw_is_scan_deny(struct rtw_adapter *adapter)
1481 {
1482 struct mlme_priv *mlmepriv = &adapter->mlmepriv;
1483
1484 return (atomic_read(&mlmepriv->set_scan_deny) != 0) ? true : false;
1485 }
1486
rtw_clear_scan_deny(struct rtw_adapter * adapter)1487 void rtw_clear_scan_deny(struct rtw_adapter *adapter)
1488 {
1489 struct mlme_priv *mlmepriv = &adapter->mlmepriv;
1490
1491 atomic_set(&mlmepriv->set_scan_deny, 0);
1492 }
1493
rtw_set_scan_deny_timer_hdl(unsigned long data)1494 void rtw_set_scan_deny_timer_hdl(unsigned long data)
1495 {
1496 struct rtw_adapter *adapter = (struct rtw_adapter *)data;
1497
1498 rtw_clear_scan_deny(adapter);
1499 }
1500
rtw_set_scan_deny(struct rtw_adapter * adapter,u32 ms)1501 void rtw_set_scan_deny(struct rtw_adapter *adapter, u32 ms)
1502 {
1503 struct mlme_priv *mlmepriv = &adapter->mlmepriv;
1504
1505 atomic_set(&mlmepriv->set_scan_deny, 1);
1506 mod_timer(&mlmepriv->set_scan_deny_timer,
1507 jiffies + msecs_to_jiffies(ms));
1508 }
1509
1510 #if defined(IEEE80211_SCAN_RESULT_EXPIRE)
1511 #define RTW_SCAN_RESULT_EXPIRE \
1512 ((IEEE80211_SCAN_RESULT_EXPIRE / (HZ*1000)) - 1000) /* 3000 -1000 */
1513 #else
1514 #define RTW_SCAN_RESULT_EXPIRE 2000
1515 #endif
1516
1517 /*
1518 * Select a new join candidate from the original @param candidate and
1519 * @param competitor
1520 * @return true: candidate is updated
1521 * @return false: candidate is not updated
1522 */
rtw_check_join_candidate(struct mlme_priv * pmlmepriv,struct wlan_network ** candidate,struct wlan_network * competitor)1523 static int rtw_check_join_candidate(struct mlme_priv *pmlmepriv,
1524 struct wlan_network **candidate,
1525 struct wlan_network *competitor)
1526 {
1527 int updated = false;
1528 struct rtw_adapter *adapter;
1529
1530 adapter = container_of(pmlmepriv, struct rtw_adapter, mlmepriv);
1531
1532 /* check bssid, if needed */
1533 if (pmlmepriv->assoc_by_bssid == true) {
1534 if (!ether_addr_equal(competitor->network.MacAddress,
1535 pmlmepriv->assoc_bssid))
1536 goto exit;
1537 }
1538
1539 /* check ssid, if needed */
1540 if (pmlmepriv->assoc_ssid.ssid_len) {
1541 if (competitor->network.Ssid.ssid_len !=
1542 pmlmepriv->assoc_ssid.ssid_len ||
1543 memcmp(competitor->network.Ssid.ssid,
1544 pmlmepriv->assoc_ssid.ssid,
1545 pmlmepriv->assoc_ssid.ssid_len))
1546 goto exit;
1547 }
1548
1549 if (rtw_is_desired_network(adapter, competitor) == false)
1550 goto exit;
1551
1552 if (adapter->mlmepriv.to_roaming > 0) {
1553 unsigned int passed;
1554
1555 passed = jiffies_to_msecs(jiffies - competitor->last_scanned);
1556 if (passed >= RTW_SCAN_RESULT_EXPIRE ||
1557 is_same_ess(&competitor->network,
1558 &pmlmepriv->cur_network.network) == false)
1559 goto exit;
1560 }
1561
1562 if (!*candidate ||
1563 (*candidate)->network.Rssi<competitor->network.Rssi) {
1564 *candidate = competitor;
1565 updated = true;
1566 }
1567
1568 if (updated) {
1569 DBG_8723A("[by_bssid:%u][assoc_ssid:%s][to_roaming:%u] new candidate: %s(%pM) rssi:%d\n",
1570 pmlmepriv->assoc_by_bssid,
1571 pmlmepriv->assoc_ssid.ssid,
1572 adapter->mlmepriv.to_roaming,
1573 (*candidate)->network.Ssid.ssid,
1574 (*candidate)->network.MacAddress,
1575 (int)(*candidate)->network.Rssi);
1576 }
1577
1578 exit:
1579 return updated;
1580 }
1581
1582 /*
1583 Calling context:
1584 The caller of the sub-routine will be in critical section...
1585
1586 The caller must hold the following spinlock
1587
1588 pmlmepriv->lock
1589
1590 */
1591
rtw_do_join(struct rtw_adapter * padapter)1592 static int rtw_do_join(struct rtw_adapter *padapter)
1593 {
1594 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1595 int ret;
1596
1597 pmlmepriv->cur_network.join_res = -2;
1598
1599 set_fwstate(pmlmepriv, _FW_UNDER_LINKING);
1600
1601 pmlmepriv->to_join = true;
1602
1603 ret = rtw_select_and_join_from_scanned_queue23a(pmlmepriv);
1604 if (ret == _SUCCESS) {
1605 pmlmepriv->to_join = false;
1606 } else {
1607 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1608 /* switch to ADHOC_MASTER */
1609 ret = rtw_do_join_adhoc(padapter);
1610 if (ret != _SUCCESS)
1611 goto exit;
1612 } else {
1613 /* can't associate ; reset under-linking */
1614 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1615
1616 ret = _FAIL;
1617 pmlmepriv->to_join = false;
1618 }
1619 }
1620
1621 exit:
1622 return ret;
1623 }
1624
1625 static struct wlan_network *
rtw_select_candidate_from_queue(struct mlme_priv * pmlmepriv)1626 rtw_select_candidate_from_queue(struct mlme_priv *pmlmepriv)
1627 {
1628 struct wlan_network *pnetwork, *candidate = NULL;
1629 struct rtw_queue *queue = &pmlmepriv->scanned_queue;
1630 struct list_head *phead, *plist, *ptmp;
1631
1632 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1633 phead = get_list_head(queue);
1634
1635 list_for_each_safe(plist, ptmp, phead) {
1636 pnetwork = container_of(plist, struct wlan_network, list);
1637 if (!pnetwork) {
1638 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1639 "%s: return _FAIL:(pnetwork == NULL)\n",
1640 __func__);
1641 goto exit;
1642 }
1643
1644 rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork);
1645 }
1646
1647 exit:
1648 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1649 return candidate;
1650 }
1651
1652
rtw_do_join_adhoc(struct rtw_adapter * adapter)1653 int rtw_do_join_adhoc(struct rtw_adapter *adapter)
1654 {
1655 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1656 struct wlan_bssid_ex *pdev_network;
1657 u8 *ibss;
1658 int ret;
1659
1660 pdev_network = &adapter->registrypriv.dev_network;
1661 ibss = adapter->registrypriv.dev_network.MacAddress;
1662
1663 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
1664
1665 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1666 "switching to adhoc master\n");
1667
1668 memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid,
1669 sizeof(struct cfg80211_ssid));
1670
1671 rtw_update_registrypriv_dev_network23a(adapter);
1672 rtw_generate_random_ibss23a(ibss);
1673
1674 pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;
1675
1676 ret = rtw_createbss_cmd23a(adapter);
1677 if (ret != _SUCCESS) {
1678 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1679 "Error =>rtw_createbss_cmd23a status FAIL\n");
1680 } else {
1681 pmlmepriv->to_join = false;
1682 }
1683
1684 return ret;
1685 }
1686
rtw_do_join_network(struct rtw_adapter * adapter,struct wlan_network * candidate)1687 int rtw_do_join_network(struct rtw_adapter *adapter,
1688 struct wlan_network *candidate)
1689 {
1690 int ret;
1691
1692 /* check for situation of _FW_LINKED */
1693 if (check_fwstate(&adapter->mlmepriv, _FW_LINKED)) {
1694 DBG_8723A("%s: _FW_LINKED while ask_for_joinbss!\n", __func__);
1695
1696 rtw_disassoc_cmd23a(adapter, 0, true);
1697 rtw_indicate_disconnect23a(adapter);
1698 rtw_free_assoc_resources23a(adapter, 0);
1699 }
1700 set_fwstate(&adapter->mlmepriv, _FW_UNDER_LINKING);
1701
1702 ret = rtw_joinbss_cmd23a(adapter, candidate);
1703
1704 if (ret == _SUCCESS)
1705 mod_timer(&adapter->mlmepriv.assoc_timer,
1706 jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT));
1707
1708 return ret;
1709 }
1710
rtw_select_and_join_from_scanned_queue23a(struct mlme_priv * pmlmepriv)1711 int rtw_select_and_join_from_scanned_queue23a(struct mlme_priv *pmlmepriv)
1712 {
1713 struct rtw_adapter *adapter;
1714 struct wlan_network *candidate = NULL;
1715 int ret;
1716
1717 adapter = pmlmepriv->nic_hdl;
1718
1719 candidate = rtw_select_candidate_from_queue(pmlmepriv);
1720 if (!candidate) {
1721 DBG_8723A("%s: return _FAIL(candidate == NULL)\n", __func__);
1722 ret = _FAIL;
1723 goto exit;
1724 } else {
1725 DBG_8723A("%s: candidate: %s(%pM, ch:%u)\n",
1726 __func__,
1727 candidate->network.Ssid.ssid,
1728 candidate->network.MacAddress,
1729 candidate->network.DSConfig);
1730 }
1731
1732 ret = rtw_do_join_network(adapter, candidate);
1733
1734 exit:
1735 return ret;
1736 }
1737
rtw_set_auth23a(struct rtw_adapter * adapter,struct security_priv * psecuritypriv)1738 int rtw_set_auth23a(struct rtw_adapter *adapter,
1739 struct security_priv *psecuritypriv)
1740 {
1741 struct cmd_obj *pcmd;
1742 struct setauth_parm *psetauthparm;
1743 struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
1744 int res = _SUCCESS;
1745
1746 pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1747 if (!pcmd) {
1748 res = _FAIL; /* try again */
1749 goto exit;
1750 }
1751
1752 psetauthparm = kzalloc(sizeof(struct setauth_parm), GFP_KERNEL);
1753 if (!psetauthparm) {
1754 kfree(pcmd);
1755 res = _FAIL;
1756 goto exit;
1757 }
1758
1759 psetauthparm->mode = (unsigned char)psecuritypriv->dot11AuthAlgrthm;
1760
1761 pcmd->cmdcode = _SetAuth_CMD_;
1762 pcmd->parmbuf = (unsigned char *)psetauthparm;
1763 pcmd->cmdsz = (sizeof(struct setauth_parm));
1764 pcmd->rsp = NULL;
1765 pcmd->rspsz = 0;
1766
1767 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1768 "after enqueue set_auth_cmd, auth_mode=%x\n",
1769 psecuritypriv->dot11AuthAlgrthm);
1770
1771 res = rtw_enqueue_cmd23a(pcmdpriv, pcmd);
1772
1773 exit:
1774
1775 return res;
1776 }
1777
rtw_set_key23a(struct rtw_adapter * adapter,struct security_priv * psecuritypriv,int keyid,u8 set_tx)1778 int rtw_set_key23a(struct rtw_adapter *adapter,
1779 struct security_priv *psecuritypriv, int keyid, u8 set_tx)
1780 {
1781 u8 keylen;
1782 struct cmd_obj *pcmd;
1783 struct setkey_parm *psetkeyparm;
1784 struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
1785 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1786 int res = _SUCCESS;
1787
1788 if (keyid >= 4) {
1789 res = _FAIL;
1790 goto exit;
1791 }
1792
1793 pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
1794 if (!pcmd) {
1795 res = _FAIL; /* try again */
1796 goto exit;
1797 }
1798 psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL);
1799 if (!psetkeyparm) {
1800 kfree(pcmd);
1801 res = _FAIL;
1802 goto exit;
1803 }
1804
1805 if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
1806 psetkeyparm->algorithm = (unsigned char)
1807 psecuritypriv->dot118021XGrpPrivacy;
1808 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1809 "rtw_set_key23a: psetkeyparm->algorithm = (unsigned char)psecuritypriv->dot118021XGrpPrivacy =%d\n",
1810 psetkeyparm->algorithm);
1811 } else {
1812 psetkeyparm->algorithm = (u8)psecuritypriv->dot11PrivacyAlgrthm;
1813 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1814 "rtw_set_key23a: psetkeyparm->algorithm = (u8)psecuritypriv->dot11PrivacyAlgrthm =%d\n",
1815 psetkeyparm->algorithm);
1816 }
1817 psetkeyparm->keyid = keyid;/* 0~3 */
1818 psetkeyparm->set_tx = set_tx;
1819 if (is_wep_enc(psetkeyparm->algorithm))
1820 pmlmepriv->key_mask |= BIT(psetkeyparm->keyid);
1821
1822 DBG_8723A("==> rtw_set_key23a algorithm(%x), keyid(%x), key_mask(%x)\n",
1823 psetkeyparm->algorithm, psetkeyparm->keyid,
1824 pmlmepriv->key_mask);
1825 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1826 "rtw_set_key23a: psetkeyparm->algorithm =%d psetkeyparm->keyid = (u8)keyid =%d\n",
1827 psetkeyparm->algorithm, keyid);
1828
1829 switch (psetkeyparm->algorithm) {
1830 case WLAN_CIPHER_SUITE_WEP40:
1831 keylen = 5;
1832 memcpy(&psetkeyparm->key[0],
1833 &psecuritypriv->wep_key[keyid].key, keylen);
1834 break;
1835 case WLAN_CIPHER_SUITE_WEP104:
1836 keylen = 13;
1837 memcpy(&psetkeyparm->key[0],
1838 &psecuritypriv->wep_key[keyid].key, keylen);
1839 break;
1840 case WLAN_CIPHER_SUITE_TKIP:
1841 keylen = 16;
1842 memcpy(&psetkeyparm->key,
1843 &psecuritypriv->dot118021XGrpKey[keyid], keylen);
1844 psetkeyparm->grpkey = 1;
1845 break;
1846 case WLAN_CIPHER_SUITE_CCMP:
1847 keylen = 16;
1848 memcpy(&psetkeyparm->key,
1849 &psecuritypriv->dot118021XGrpKey[keyid], keylen);
1850 psetkeyparm->grpkey = 1;
1851 break;
1852 default:
1853 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
1854 "rtw_set_key23a:psecuritypriv->dot11PrivacyAlgrthm = %x (must be 1 or 2 or 4 or 5)\n",
1855 psecuritypriv->dot11PrivacyAlgrthm);
1856 res = _FAIL;
1857 kfree(pcmd);
1858 kfree(psetkeyparm);
1859 goto exit;
1860 }
1861
1862 pcmd->cmdcode = _SetKey_CMD_;
1863 pcmd->parmbuf = (u8 *)psetkeyparm;
1864 pcmd->cmdsz = (sizeof(struct setkey_parm));
1865 pcmd->rsp = NULL;
1866 pcmd->rspsz = 0;
1867
1868 /* sema_init(&pcmd->cmd_sem, 0); */
1869
1870 res = rtw_enqueue_cmd23a(pcmdpriv, pcmd);
1871
1872 exit:
1873
1874 return res;
1875 }
1876
1877 /* adjust IEs for rtw_joinbss_cmd23a in WMM */
rtw_restruct_wmm_ie23a(struct rtw_adapter * adapter,u8 * in_ie,u8 * out_ie,uint in_len,uint initial_out_len)1878 int rtw_restruct_wmm_ie23a(struct rtw_adapter *adapter, u8 *in_ie,
1879 u8 *out_ie, uint in_len, uint initial_out_len)
1880 {
1881 int ielength;
1882 const u8 *p;
1883
1884 ielength = initial_out_len;
1885
1886 p = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1887 WLAN_OUI_TYPE_MICROSOFT_WMM,
1888 in_ie, in_len);
1889
1890 if (p && p[1]) {
1891 memcpy(out_ie + initial_out_len, p, 9);
1892
1893 out_ie[initial_out_len + 1] = 7;
1894 out_ie[initial_out_len + 6] = 0;
1895 out_ie[initial_out_len + 8] = 0;
1896
1897 ielength += 9;
1898 }
1899
1900 return ielength;
1901 }
1902
1903 /* */
1904 /* Ported from 8185: IsInPreAuthKeyList().
1905 (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.) */
1906 /* Added by Annie, 2006-05-07. */
1907 /* */
1908 /* Search by BSSID, */
1909 /* Return Value: */
1910 /* -1 :if there is no pre-auth key in the table */
1911 /* >= 0 :if there is pre-auth key, and return the entry id */
1912 /* */
1913 /* */
1914
SecIsInPMKIDList(struct rtw_adapter * Adapter,u8 * bssid)1915 static int SecIsInPMKIDList(struct rtw_adapter *Adapter, u8 *bssid)
1916 {
1917 struct security_priv *psecuritypriv = &Adapter->securitypriv;
1918 int i = 0;
1919
1920 do {
1921 if (psecuritypriv->PMKIDList[i].bUsed &&
1922 ether_addr_equal(psecuritypriv->PMKIDList[i].Bssid, bssid)) {
1923 break;
1924 } else {
1925 i++;
1926 /* continue; */
1927 }
1928 } while (i < NUM_PMKID_CACHE);
1929
1930 if (i == NUM_PMKID_CACHE)
1931 i = -1;/* Could not find. */
1932 else {
1933 /* There is one Pre-Authentication Key for
1934 the specific BSSID. */
1935 }
1936
1937 return i;
1938 }
1939
1940 /* */
1941 /* Check the RSN IE length */
1942 /* If the RSN IE length <= 20, the RSN IE didn't include
1943 the PMKID information */
1944 /* 0-11th element in the array are the fixed IE */
1945 /* 12th element in the array is the IE */
1946 /* 13th element in the array is the IE length */
1947 /* */
1948
rtw_append_pmkid(struct rtw_adapter * Adapter,int iEntry,u8 * ie,uint ie_len)1949 static int rtw_append_pmkid(struct rtw_adapter *Adapter, int iEntry,
1950 u8 *ie, uint ie_len)
1951 {
1952 struct security_priv *psecuritypriv = &Adapter->securitypriv;
1953
1954 if (ie[1] <= 20) {
1955 /* The RSN IE didn't include the PMK ID,
1956 append the PMK information */
1957 ie[ie_len] = 1;
1958 ie_len++;
1959 ie[ie_len] = 0; /* PMKID count = 0x0100 */
1960 ie_len++;
1961 memcpy(&ie[ie_len],
1962 &psecuritypriv->PMKIDList[iEntry].PMKID, 16);
1963
1964 ie_len += 16;
1965 ie[1] += 18;/* PMKID length = 2+16 */
1966 }
1967 return ie_len;
1968 }
1969
rtw_restruct_sec_ie23a(struct rtw_adapter * adapter,u8 * in_ie,u8 * out_ie,uint in_len)1970 int rtw_restruct_sec_ie23a(struct rtw_adapter *adapter, u8 *in_ie, u8 *out_ie,
1971 uint in_len)
1972 {
1973 u8 authmode;
1974 uint ielength;
1975 int iEntry;
1976 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1977 struct security_priv *psecuritypriv = &adapter->securitypriv;
1978 uint ndisauthmode = psecuritypriv->ndisauthtype;
1979 uint ndissecuritytype = psecuritypriv->ndisencryptstatus;
1980
1981 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
1982 "+rtw_restruct_sec_ie23a: ndisauthmode=%d ndissecuritytype=%d\n",
1983 ndisauthmode, ndissecuritytype);
1984
1985 ielength = 0;
1986 if (ndisauthmode == Ndis802_11AuthModeWPA ||
1987 ndisauthmode == Ndis802_11AuthModeWPAPSK)
1988 authmode = WLAN_EID_VENDOR_SPECIFIC;
1989 if (ndisauthmode == Ndis802_11AuthModeWPA2 ||
1990 ndisauthmode == Ndis802_11AuthModeWPA2PSK)
1991 authmode = WLAN_EID_RSN;
1992
1993 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
1994 memcpy(out_ie + ielength, psecuritypriv->wps_ie,
1995 psecuritypriv->wps_ie_len);
1996
1997 ielength += psecuritypriv->wps_ie_len;
1998 } else if (authmode == WLAN_EID_VENDOR_SPECIFIC ||
1999 authmode == WLAN_EID_RSN) {
2000 /* copy RSN or SSN */
2001 memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0],
2002 psecuritypriv->supplicant_ie[1] + 2);
2003 ielength += psecuritypriv->supplicant_ie[1] + 2;
2004 }
2005
2006 iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
2007 if (iEntry < 0)
2008 return ielength;
2009 else {
2010 if (authmode == WLAN_EID_RSN)
2011 ielength = rtw_append_pmkid(adapter, iEntry,
2012 out_ie, ielength);
2013 }
2014
2015 return ielength;
2016 }
2017
rtw_init_registrypriv_dev_network23a(struct rtw_adapter * adapter)2018 void rtw_init_registrypriv_dev_network23a(struct rtw_adapter *adapter)
2019 {
2020 struct registry_priv *pregistrypriv = &adapter->registrypriv;
2021 struct eeprom_priv *peepriv = &adapter->eeprompriv;
2022 struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
2023 u8 *myhwaddr = myid(peepriv);
2024
2025 ether_addr_copy(pdev_network->MacAddress, myhwaddr);
2026
2027 memcpy(&pdev_network->Ssid, &pregistrypriv->ssid,
2028 sizeof(struct cfg80211_ssid));
2029
2030 pdev_network->beacon_interval = 100;
2031 }
2032
rtw_update_registrypriv_dev_network23a(struct rtw_adapter * adapter)2033 void rtw_update_registrypriv_dev_network23a(struct rtw_adapter *adapter)
2034 {
2035 int sz = 0;
2036 struct registry_priv *pregistrypriv = &adapter->registrypriv;
2037 struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network;
2038 struct security_priv *psecuritypriv = &adapter->securitypriv;
2039 struct wlan_network *cur_network = &adapter->mlmepriv.cur_network;
2040 /* struct xmit_priv *pxmitpriv = &adapter->xmitpriv; */
2041
2042 pdev_network->Privacy =
2043 (psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0);
2044
2045 pdev_network->Rssi = 0;
2046
2047 pdev_network->DSConfig = pregistrypriv->channel;
2048 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
2049 "pregistrypriv->channel =%d, pdev_network->DSConfig = 0x%x\n",
2050 pregistrypriv->channel, pdev_network->DSConfig);
2051
2052 if (cur_network->network.ifmode == NL80211_IFTYPE_ADHOC)
2053 pdev_network->ATIMWindow = 0;
2054
2055 pdev_network->ifmode = cur_network->network.ifmode;
2056
2057 /* 1. Supported rates */
2058 /* 2. IE */
2059
2060 sz = rtw_generate_ie23a(pregistrypriv);
2061
2062 pdev_network->IELength = sz;
2063
2064 pdev_network->Length =
2065 get_wlan_bssid_ex_sz(pdev_network);
2066
2067 /* notes: translate IELength & Length after assign the
2068 Length to cmdsz in createbss_cmd(); */
2069 /* pdev_network->IELength = cpu_to_le32(sz); */
2070 }
2071
2072 /* the function is at passive_level */
rtw_joinbss_reset23a(struct rtw_adapter * padapter)2073 void rtw_joinbss_reset23a(struct rtw_adapter *padapter)
2074 {
2075 u8 threshold;
2076 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2077 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
2078
2079 /* todo: if you want to do something io/reg/hw setting
2080 before join_bss, please add code here */
2081
2082 pmlmepriv->num_FortyMHzIntolerant = 0;
2083
2084 pmlmepriv->num_sta_no_ht = 0;
2085
2086 phtpriv->ampdu_enable = false;/* reset to disabled */
2087
2088 /* TH = 1 => means that invalidate usb rx aggregation */
2089 /* TH = 0 => means that validate usb rx aggregation, use init value. */
2090 if (phtpriv->ht_option) {
2091 if (padapter->registrypriv.wifi_spec == 1)
2092 threshold = 1;
2093 else
2094 threshold = 0;
2095 } else
2096 threshold = 1;
2097
2098 rtl8723a_set_rxdma_agg_pg_th(padapter, threshold);
2099 }
2100
2101 /* the function is >= passive_level */
rtw_restructure_ht_ie23a(struct rtw_adapter * padapter,u8 * in_ie,u8 * out_ie,uint in_len,uint * pout_len)2102 bool rtw_restructure_ht_ie23a(struct rtw_adapter *padapter, u8 *in_ie,
2103 u8 *out_ie, uint in_len, uint *pout_len)
2104 {
2105 u32 out_len;
2106 int max_rx_ampdu_factor;
2107 unsigned char *pframe;
2108 const u8 *p;
2109 struct ieee80211_ht_cap ht_capie;
2110 u8 WMM_IE[7] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
2111 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2112 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
2113
2114 phtpriv->ht_option = false;
2115
2116 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, in_ie, in_len);
2117
2118 if (p && p[1] > 0) {
2119 u32 rx_packet_offset, max_recvbuf_sz;
2120
2121 if (pmlmepriv->qos_option == 0) {
2122 out_len = *pout_len;
2123 pframe = rtw_set_ie23a(out_ie + out_len,
2124 WLAN_EID_VENDOR_SPECIFIC,
2125 sizeof(WMM_IE), WMM_IE,
2126 pout_len);
2127
2128 pmlmepriv->qos_option = 1;
2129 }
2130
2131 out_len = *pout_len;
2132
2133 memset(&ht_capie, 0, sizeof(struct ieee80211_ht_cap));
2134
2135 ht_capie.cap_info = cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
2136 IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 |
2137 IEEE80211_HT_CAP_TX_STBC | IEEE80211_HT_CAP_DSSSCCK40);
2138
2139 GetHalDefVar8192CUsb(padapter, HAL_DEF_RX_PACKET_OFFSET,
2140 &rx_packet_offset);
2141 GetHalDefVar8192CUsb(padapter, HAL_DEF_MAX_RECVBUF_SZ,
2142 &max_recvbuf_sz);
2143
2144 GetHalDefVar8192CUsb(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR,
2145 &max_rx_ampdu_factor);
2146 ht_capie.ampdu_params_info = max_rx_ampdu_factor & 0x03;
2147
2148 if (padapter->securitypriv.dot11PrivacyAlgrthm ==
2149 WLAN_CIPHER_SUITE_CCMP)
2150 ht_capie.ampdu_params_info |=
2151 (IEEE80211_HT_AMPDU_PARM_DENSITY& (0x07 << 2));
2152 else
2153 ht_capie.ampdu_params_info |=
2154 (IEEE80211_HT_AMPDU_PARM_DENSITY & 0x00);
2155
2156 pframe = rtw_set_ie23a(out_ie + out_len, WLAN_EID_HT_CAPABILITY,
2157 sizeof(struct ieee80211_ht_cap),
2158 (unsigned char *)&ht_capie, pout_len);
2159
2160 phtpriv->ht_option = true;
2161
2162 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, in_ie, in_len);
2163 if (p && (p[1] == sizeof(struct ieee80211_ht_operation))) {
2164 out_len = *pout_len;
2165 pframe = rtw_set_ie23a(out_ie + out_len,
2166 WLAN_EID_HT_OPERATION,
2167 p[1], p + 2 , pout_len);
2168 }
2169 }
2170
2171 return phtpriv->ht_option;
2172 }
2173
2174 /* the function is > passive_level (in critical_section) */
rtw_update_ht_cap23a(struct rtw_adapter * padapter,u8 * pie,uint ie_len)2175 void rtw_update_ht_cap23a(struct rtw_adapter *padapter, u8 *pie, uint ie_len)
2176 {
2177 u8 max_ampdu_sz;
2178 const u8 *p;
2179 struct ieee80211_ht_cap *pht_capie;
2180 struct ieee80211_ht_operation *pht_addtinfo;
2181 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2182 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
2183 struct registry_priv *pregistrypriv = &padapter->registrypriv;
2184 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2185 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2186
2187 if (!phtpriv->ht_option)
2188 return;
2189
2190 if ((!pmlmeinfo->HT_info_enable) || (!pmlmeinfo->HT_caps_enable))
2191 return;
2192
2193 DBG_8723A("+rtw_update_ht_cap23a()\n");
2194
2195 /* maybe needs check if ap supports rx ampdu. */
2196 if (!phtpriv->ampdu_enable && pregistrypriv->ampdu_enable == 1) {
2197 if (pregistrypriv->wifi_spec == 1)
2198 phtpriv->ampdu_enable = false;
2199 else
2200 phtpriv->ampdu_enable = true;
2201 } else if (pregistrypriv->ampdu_enable == 2)
2202 phtpriv->ampdu_enable = true;
2203
2204 /* check Max Rx A-MPDU Size */
2205 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pie, ie_len);
2206
2207 if (p && p[1] > 0) {
2208 pht_capie = (struct ieee80211_ht_cap *)(p + 2);
2209 max_ampdu_sz = pht_capie->ampdu_params_info &
2210 IEEE80211_HT_AMPDU_PARM_FACTOR;
2211 /* max_ampdu_sz (kbytes); */
2212 max_ampdu_sz = 1 << (max_ampdu_sz + 3);
2213
2214 phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
2215 }
2216
2217 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION, pie, ie_len);
2218 if (p && p[1] > 0) {
2219 pht_addtinfo = (struct ieee80211_ht_operation *)(p + 2);
2220 /* todo: */
2221 }
2222
2223 /* update cur_bwmode & cur_ch_offset */
2224 if (pregistrypriv->cbw40_enable &&
2225 pmlmeinfo->ht_cap.cap_info &
2226 cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
2227 pmlmeinfo->HT_info.ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY) {
2228 int i;
2229 u8 rf_type;
2230
2231 rf_type = rtl8723a_get_rf_type(padapter);
2232
2233 /* update the MCS rates */
2234 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
2235 if (rf_type == RF_1T1R || rf_type == RF_1T2R)
2236 pmlmeinfo->ht_cap.mcs.rx_mask[i] &=
2237 MCS_rate_1R23A[i];
2238 else
2239 pmlmeinfo->ht_cap.mcs.rx_mask[i] &=
2240 MCS_rate_2R23A[i];
2241 }
2242 /* switch to the 40M Hz mode according to the AP */
2243 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
2244 switch (pmlmeinfo->HT_info.ht_param &
2245 IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
2246 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
2247 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
2248 break;
2249
2250 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
2251 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
2252 break;
2253
2254 default:
2255 pmlmeext->cur_ch_offset =
2256 HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2257 break;
2258 }
2259 }
2260
2261 /* */
2262 /* Config SM Power Save setting */
2263 /* */
2264 pmlmeinfo->SM_PS =
2265 (le16_to_cpu(pmlmeinfo->ht_cap.cap_info) &
2266 IEEE80211_HT_CAP_SM_PS) >> IEEE80211_HT_CAP_SM_PS_SHIFT;
2267 if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
2268 DBG_8723A("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __func__);
2269
2270 /* */
2271 /* Config current HT Protection mode. */
2272 /* */
2273 pmlmeinfo->HT_protection =
2274 le16_to_cpu(pmlmeinfo->HT_info.operation_mode) &
2275 IEEE80211_HT_OP_MODE_PROTECTION;
2276 }
2277
rtw_issue_addbareq_cmd23a(struct rtw_adapter * padapter,struct xmit_frame * pxmitframe)2278 void rtw_issue_addbareq_cmd23a(struct rtw_adapter *padapter,
2279 struct xmit_frame *pxmitframe)
2280 {
2281 u8 issued;
2282 int priority;
2283 struct sta_info *psta;
2284 struct ht_priv *phtpriv;
2285 struct pkt_attrib *pattrib = &pxmitframe->attrib;
2286 s32 bmcst = is_multicast_ether_addr(pattrib->ra);
2287
2288 if (bmcst || padapter->mlmepriv.LinkDetectInfo.NumTxOkInPeriod < 100)
2289 return;
2290
2291 priority = pattrib->priority;
2292
2293 if (pattrib->psta)
2294 psta = pattrib->psta;
2295 else {
2296 DBG_8723A("%s, call rtw_get_stainfo23a()\n", __func__);
2297 psta = rtw_get_stainfo23a(&padapter->stapriv, pattrib->ra);
2298 }
2299
2300 if (!psta) {
2301 DBG_8723A("%s, psta == NUL\n", __func__);
2302 return;
2303 }
2304
2305 if (!(psta->state &_FW_LINKED)) {
2306 DBG_8723A("%s, psta->state(0x%x) != _FW_LINKED\n",
2307 __func__, psta->state);
2308 return;
2309 }
2310
2311 phtpriv = &psta->htpriv;
2312
2313 if (phtpriv->ht_option && phtpriv->ampdu_enable) {
2314 issued = (phtpriv->agg_enable_bitmap>>priority)&0x1;
2315 issued |= (phtpriv->candidate_tid_bitmap>>priority)&0x1;
2316
2317 if (issued == 0) {
2318 DBG_8723A("rtw_issue_addbareq_cmd23a, p =%d\n",
2319 priority);
2320 psta->htpriv.candidate_tid_bitmap |= BIT(priority);
2321 rtw_addbareq_cmd23a(padapter, (u8) priority,
2322 pattrib->ra);
2323 }
2324 }
2325 }
2326
rtw_linked_check(struct rtw_adapter * padapter)2327 int rtw_linked_check(struct rtw_adapter *padapter)
2328 {
2329 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) ||
2330 check_fwstate(&padapter->mlmepriv,
2331 WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE)) {
2332 if (padapter->stapriv.asoc_sta_count > 2)
2333 return true;
2334 } else { /* Station mode */
2335 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED))
2336 return true;
2337 }
2338 return false;
2339 }
2340