1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2019 Realtek Corporation.
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 <hal_data.h>
18
19 extern void indicate_wx_scan_complete_event(_adapter *padapter);
20 extern u8 rtw_do_join(_adapter *padapter);
21
22
rtw_init_mlme_timer(_adapter * padapter)23 void rtw_init_mlme_timer(_adapter *padapter)
24 {
25 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
26
27 rtw_init_timer(&(pmlmepriv->assoc_timer), padapter, rtw_join_timeout_handler, padapter);
28 rtw_init_timer(&(pmlmepriv->scan_to_timer), padapter, rtw_scan_timeout_handler, padapter);
29
30 #ifdef CONFIG_SET_SCAN_DENY_TIMER
31 rtw_init_timer(&(pmlmepriv->set_scan_deny_timer), padapter, rtw_set_scan_deny_timer_hdl, padapter);
32 #endif
33
34 #ifdef RTK_DMP_PLATFORM
35 _init_workitem(&(pmlmepriv->Linkup_workitem), Linkup_workitem_callback, padapter);
36 _init_workitem(&(pmlmepriv->Linkdown_workitem), Linkdown_workitem_callback, padapter);
37 #endif
38 }
39
_rtw_init_mlme_priv(_adapter * padapter)40 sint _rtw_init_mlme_priv(_adapter *padapter)
41 {
42 sint i;
43 u8 *pbuf;
44 struct wlan_network *pnetwork;
45 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
46 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
47 sint res = _SUCCESS;
48 #ifdef CONFIG_RTW_MULTI_AP
49 struct unassoc_sta_info *unassoc_sta;
50 #endif
51
52
53 /* We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). */
54 /* _rtw_memset((u8 *)pmlmepriv, 0, sizeof(struct mlme_priv)); */
55
56
57 /*qos_priv*/
58 /*pmlmepriv->qospriv.qos_option = pregistrypriv->wmm_enable;*/
59
60 /*ht_priv*/
61 #ifdef CONFIG_80211N_HT
62 pmlmepriv->htpriv.ampdu_enable = _FALSE;/*set to disabled*/
63 #endif
64
65 pmlmepriv->nic_hdl = (u8 *)padapter;
66
67 pmlmepriv->pscanned = NULL;
68 init_fwstate(pmlmepriv, WIFI_STATION_STATE);
69 pmlmepriv->cur_network.network.InfrastructureMode = Ndis802_11AutoUnknown;
70 pmlmepriv->scan_mode = SCAN_ACTIVE; /* 1: active, 0: pasive. Maybe someday we should rename this varable to "active_mode" (Jeff) */
71
72 _rtw_spinlock_init(&(pmlmepriv->lock));
73 _rtw_init_queue(&(pmlmepriv->free_bss_pool));
74 _rtw_init_queue(&(pmlmepriv->scanned_queue));
75
76 set_scanned_network_val(pmlmepriv, 0);
77
78 _rtw_memset(&pmlmepriv->assoc_ssid, 0, sizeof(NDIS_802_11_SSID));
79
80 if (padapter->registrypriv.max_bss_cnt != 0)
81 pmlmepriv->max_bss_cnt = padapter->registrypriv.max_bss_cnt;
82 else if (rfctl->max_chan_nums <= MAX_CHANNEL_NUM_2G)
83 pmlmepriv->max_bss_cnt = MAX_BSS_CNT;
84 else
85 pmlmepriv->max_bss_cnt = MAX_BSS_CNT + MAX_BSS_CNT;
86
87
88 pbuf = rtw_zvmalloc(pmlmepriv->max_bss_cnt * (sizeof(struct wlan_network)));
89
90 if (pbuf == NULL) {
91 res = _FAIL;
92 goto exit;
93 }
94 pmlmepriv->free_bss_buf = pbuf;
95
96 pnetwork = (struct wlan_network *)pbuf;
97
98 for (i = 0; i < pmlmepriv->max_bss_cnt; i++) {
99 _rtw_init_listhead(&(pnetwork->list));
100
101 rtw_list_insert_tail(&(pnetwork->list), &(pmlmepriv->free_bss_pool.queue));
102
103 pnetwork++;
104 }
105
106 #ifdef CONFIG_RTW_MULTI_AP
107 if (is_primary_adapter(padapter)) {
108 _rtw_init_queue(&(pmlmepriv->free_unassoc_sta_queue));
109 _rtw_init_queue(&(pmlmepriv->unassoc_sta_queue));
110 for (i = 0; i < UNASOC_STA_SRC_NUM; i++)
111 pmlmepriv->unassoc_sta_mode_of_stype[i] = padapter->registrypriv.unassoc_sta_mode_of_stype[i];
112 if (padapter->registrypriv.max_unassoc_sta_cnt != 0)
113 pmlmepriv->max_unassoc_sta_cnt = padapter->registrypriv.max_unassoc_sta_cnt;
114 else if (rfctl->max_chan_nums <= MAX_CHANNEL_NUM_2G)
115 pmlmepriv->max_unassoc_sta_cnt = MAX_UNASSOC_STA_CNT;
116 else
117 pmlmepriv->max_unassoc_sta_cnt = MAX_UNASSOC_STA_CNT * 2;
118 pbuf = rtw_zvmalloc(pmlmepriv->max_unassoc_sta_cnt * (sizeof(struct unassoc_sta_info)));
119 if (pbuf == NULL) {
120 res = _FAIL;
121 goto exit;
122 }
123 pmlmepriv->free_unassoc_sta_buf = pbuf;
124 unassoc_sta = (struct unassoc_sta_info *) pbuf;
125 for (i = 0; i < pmlmepriv->max_unassoc_sta_cnt; i++) {
126 _rtw_init_listhead(&(unassoc_sta->list));
127 rtw_list_insert_tail(&(unassoc_sta->list), &(pmlmepriv->free_unassoc_sta_queue.queue));
128 unassoc_sta++;
129 }
130 }
131 #endif
132 /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
133
134 rtw_clear_scan_deny(padapter);
135 #ifdef CONFIG_ARP_KEEP_ALIVE
136 pmlmepriv->bGetGateway = 0;
137 pmlmepriv->GetGatewayTryCnt = 0;
138 #endif
139
140 #ifdef CONFIG_LAYER2_ROAMING
141 #define RTW_ROAM_SCAN_RESULT_EXP_MS (5*1000)
142 #define RTW_ROAM_RSSI_DIFF_TH 10
143 #define RTW_ROAM_SCAN_INTERVAL (5) /* 5*(2 second)*/
144 #define RTW_ROAM_RSSI_THRESHOLD 70
145
146 pmlmepriv->roam_flags = 0
147 | RTW_ROAM_ON_EXPIRED
148 #ifdef CONFIG_LAYER2_ROAMING_RESUME
149 | RTW_ROAM_ON_RESUME
150 #endif
151 #ifdef CONFIG_LAYER2_ROAMING_ACTIVE
152 | RTW_ROAM_ACTIVE
153 #endif
154 ;
155
156 pmlmepriv->roam_scanr_exp_ms = RTW_ROAM_SCAN_RESULT_EXP_MS;
157 pmlmepriv->roam_rssi_diff_th = RTW_ROAM_RSSI_DIFF_TH;
158 pmlmepriv->roam_scan_int = RTW_ROAM_SCAN_INTERVAL;
159 pmlmepriv->roam_rssi_threshold = RTW_ROAM_RSSI_THRESHOLD;
160 pmlmepriv->need_to_roam = _FALSE;
161 pmlmepriv->last_roaming = rtw_get_current_time();
162 #endif /* CONFIG_LAYER2_ROAMING */
163
164 #ifdef CONFIG_RTW_80211R
165 rtw_ft_info_init(&pmlmepriv->ft_roam);
166 #endif
167 #ifdef CONFIG_LAYER2_ROAMING
168 #if defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K)
169 rtw_roam_nb_info_init(padapter);
170 pmlmepriv->ch_cnt = 0;
171 #endif
172 #endif
173
174 pmlmepriv->defs_lmt_sta = 2;
175 pmlmepriv->defs_lmt_time = 5;
176
177 rtw_init_mlme_timer(padapter);
178
179 exit:
180
181
182 return res;
183 }
184
185 void rtw_mfree_mlme_priv_lock(struct mlme_priv *pmlmepriv);
rtw_mfree_mlme_priv_lock(struct mlme_priv * pmlmepriv)186 void rtw_mfree_mlme_priv_lock(struct mlme_priv *pmlmepriv)
187 {
188 _rtw_spinlock_free(&pmlmepriv->lock);
189 _rtw_spinlock_free(&(pmlmepriv->free_bss_pool.lock));
190 _rtw_spinlock_free(&(pmlmepriv->scanned_queue.lock));
191 #ifdef CONFIG_RTW_MULTI_AP
192 if (is_primary_adapter(mlme_to_adapter(pmlmepriv))) {
193 _rtw_spinlock_free(&(pmlmepriv->unassoc_sta_queue.lock));
194 _rtw_spinlock_free(&(pmlmepriv->free_unassoc_sta_queue.lock));
195 }
196 #endif
197 }
198
rtw_free_mlme_priv_ie_data(struct mlme_priv * pmlmepriv)199 void rtw_free_mlme_priv_ie_data(struct mlme_priv *pmlmepriv)
200 {
201 rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
202 rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
203 #if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
204 rtw_buf_free(&pmlmepriv->wps_beacon_ie, &pmlmepriv->wps_beacon_ie_len);
205 rtw_buf_free(&pmlmepriv->wps_probe_req_ie, &pmlmepriv->wps_probe_req_ie_len);
206 rtw_buf_free(&pmlmepriv->wps_probe_resp_ie, &pmlmepriv->wps_probe_resp_ie_len);
207 rtw_buf_free(&pmlmepriv->wps_assoc_resp_ie, &pmlmepriv->wps_assoc_resp_ie_len);
208
209 rtw_buf_free(&pmlmepriv->p2p_beacon_ie, &pmlmepriv->p2p_beacon_ie_len);
210 rtw_buf_free(&pmlmepriv->p2p_probe_req_ie, &pmlmepriv->p2p_probe_req_ie_len);
211 rtw_buf_free(&pmlmepriv->p2p_probe_resp_ie, &pmlmepriv->p2p_probe_resp_ie_len);
212 rtw_buf_free(&pmlmepriv->p2p_go_probe_resp_ie, &pmlmepriv->p2p_go_probe_resp_ie_len);
213 rtw_buf_free(&pmlmepriv->p2p_assoc_req_ie, &pmlmepriv->p2p_assoc_req_ie_len);
214 rtw_buf_free(&pmlmepriv->p2p_assoc_resp_ie, &pmlmepriv->p2p_assoc_resp_ie_len);
215 #endif
216
217 #if defined(CONFIG_WFD) && defined(CONFIG_IOCTL_CFG80211)
218 rtw_buf_free(&pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len);
219 rtw_buf_free(&pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len);
220 rtw_buf_free(&pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len);
221 rtw_buf_free(&pmlmepriv->wfd_go_probe_resp_ie, &pmlmepriv->wfd_go_probe_resp_ie_len);
222 rtw_buf_free(&pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len);
223 rtw_buf_free(&pmlmepriv->wfd_assoc_resp_ie, &pmlmepriv->wfd_assoc_resp_ie_len);
224 #endif
225
226 #ifdef CONFIG_RTW_80211R
227 rtw_buf_free(&pmlmepriv->auth_rsp, &pmlmepriv->auth_rsp_len);
228 #endif
229 #ifdef CONFIG_RTW_MBO
230 rtw_buf_free(&pmlmepriv->pcell_data_cap_ie, &pmlmepriv->cell_data_cap_len);
231 #endif
232 }
233
234 #if defined(CONFIG_WFD) && defined(CONFIG_IOCTL_CFG80211)
rtw_mlme_update_wfd_ie_data(struct mlme_priv * mlme,u8 type,u8 * ie,u32 ie_len)235 int rtw_mlme_update_wfd_ie_data(struct mlme_priv *mlme, u8 type, u8 *ie, u32 ie_len)
236 {
237 _adapter *adapter = mlme_to_adapter(mlme);
238 struct wifi_display_info *wfd_info = &adapter->wfd_info;
239 u8 clear = 0;
240 u8 **t_ie = NULL;
241 u32 *t_ie_len = NULL;
242 int ret = _FAIL;
243
244 if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST))
245 goto success;
246
247 if (wfd_info->wfd_enable == _TRUE)
248 goto success; /* WFD IE is build by self */
249
250 if (!ie && !ie_len)
251 clear = 1;
252 else if (!ie || !ie_len) {
253 RTW_PRINT(FUNC_ADPT_FMT" type:%u, ie:%p, ie_len:%u"
254 , FUNC_ADPT_ARG(adapter), type, ie, ie_len);
255 rtw_warn_on(1);
256 goto exit;
257 }
258
259 switch (type) {
260 case MLME_BEACON_IE:
261 t_ie = &mlme->wfd_beacon_ie;
262 t_ie_len = &mlme->wfd_beacon_ie_len;
263 break;
264 case MLME_PROBE_REQ_IE:
265 t_ie = &mlme->wfd_probe_req_ie;
266 t_ie_len = &mlme->wfd_probe_req_ie_len;
267 break;
268 case MLME_PROBE_RESP_IE:
269 t_ie = &mlme->wfd_probe_resp_ie;
270 t_ie_len = &mlme->wfd_probe_resp_ie_len;
271 break;
272 case MLME_GO_PROBE_RESP_IE:
273 t_ie = &mlme->wfd_go_probe_resp_ie;
274 t_ie_len = &mlme->wfd_go_probe_resp_ie_len;
275 break;
276 case MLME_ASSOC_REQ_IE:
277 t_ie = &mlme->wfd_assoc_req_ie;
278 t_ie_len = &mlme->wfd_assoc_req_ie_len;
279 break;
280 case MLME_ASSOC_RESP_IE:
281 t_ie = &mlme->wfd_assoc_resp_ie;
282 t_ie_len = &mlme->wfd_assoc_resp_ie_len;
283 break;
284 default:
285 RTW_PRINT(FUNC_ADPT_FMT" unsupported type:%u"
286 , FUNC_ADPT_ARG(adapter), type);
287 rtw_warn_on(1);
288 goto exit;
289 }
290
291 if (*t_ie) {
292 u32 free_len = *t_ie_len;
293 *t_ie_len = 0;
294 rtw_mfree(*t_ie, free_len);
295 *t_ie = NULL;
296 }
297
298 if (!clear) {
299 *t_ie = rtw_malloc(ie_len);
300 if (*t_ie == NULL) {
301 RTW_ERR(FUNC_ADPT_FMT" type:%u, rtw_malloc() fail\n"
302 , FUNC_ADPT_ARG(adapter), type);
303 goto exit;
304 }
305 _rtw_memcpy(*t_ie, ie, ie_len);
306 *t_ie_len = ie_len;
307 }
308
309 if (*t_ie && *t_ie_len) {
310 u8 *attr_content;
311 u32 attr_contentlen = 0;
312
313 attr_content = rtw_get_wfd_attr_content(*t_ie, *t_ie_len, WFD_ATTR_DEVICE_INFO, NULL, &attr_contentlen);
314 if (attr_content && attr_contentlen) {
315 if (RTW_GET_BE16(attr_content + 2) != wfd_info->rtsp_ctrlport) {
316 wfd_info->rtsp_ctrlport = RTW_GET_BE16(attr_content + 2);
317 RTW_INFO(FUNC_ADPT_FMT" type:%u, RTSP CTRL port = %u\n"
318 , FUNC_ADPT_ARG(adapter), type, wfd_info->rtsp_ctrlport);
319 }
320 }
321 }
322
323 success:
324 ret = _SUCCESS;
325
326 exit:
327 return ret;
328 }
329 #endif /* defined(CONFIG_WFD) && defined(CONFIG_IOCTL_CFG80211) */
330
_rtw_free_mlme_priv(struct mlme_priv * pmlmepriv)331 void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv)
332 {
333 _adapter *adapter = mlme_to_adapter(pmlmepriv);
334 if (NULL == pmlmepriv) {
335 rtw_warn_on(1);
336 goto exit;
337 }
338 rtw_free_mlme_priv_ie_data(pmlmepriv);
339
340 if (pmlmepriv) {
341 rtw_mfree_mlme_priv_lock(pmlmepriv);
342
343 if (pmlmepriv->free_bss_buf)
344 rtw_vmfree(pmlmepriv->free_bss_buf, pmlmepriv->max_bss_cnt * sizeof(struct wlan_network));
345 #ifdef CONFIG_RTW_MULTI_AP
346 if (is_primary_adapter(adapter)) {
347 if (pmlmepriv->free_unassoc_sta_buf)
348 rtw_vmfree(pmlmepriv->free_unassoc_sta_buf, pmlmepriv->max_unassoc_sta_cnt * sizeof(struct unassoc_sta_info));
349 }
350 #endif
351 }
352 exit:
353 return;
354 }
355
_rtw_enqueue_network(_queue * queue,struct wlan_network * pnetwork)356 sint _rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork)
357 {
358 _irqL irqL;
359
360
361 if (pnetwork == NULL)
362 goto exit;
363
364 _enter_critical_bh(&queue->lock, &irqL);
365
366 rtw_list_insert_tail(&pnetwork->list, &queue->queue);
367
368 _exit_critical_bh(&queue->lock, &irqL);
369
370 exit:
371
372
373 return _SUCCESS;
374 }
375
376 /*
377 struct wlan_network *_rtw_dequeue_network(_queue *queue)
378 {
379 _irqL irqL;
380
381 struct wlan_network *pnetwork;
382
383
384 _enter_critical_bh(&queue->lock, &irqL);
385
386 if (_rtw_queue_empty(queue) == _TRUE)
387
388 pnetwork = NULL;
389
390 else
391 {
392 pnetwork = LIST_CONTAINOR(get_next(&queue->queue), struct wlan_network, list);
393
394 rtw_list_delete(&(pnetwork->list));
395 }
396
397 _exit_critical_bh(&queue->lock, &irqL);
398
399
400 return pnetwork;
401 }
402 */
403
_rtw_alloc_network(struct mlme_priv * pmlmepriv)404 struct wlan_network *_rtw_alloc_network(struct mlme_priv *pmlmepriv) /* (_queue *free_queue) */
405 {
406 _irqL irqL;
407 struct wlan_network *pnetwork;
408 _queue *free_queue = &pmlmepriv->free_bss_pool;
409 _list *plist = NULL;
410
411
412 _enter_critical_bh(&free_queue->lock, &irqL);
413
414 if (_rtw_queue_empty(free_queue) == _TRUE) {
415 pnetwork = NULL;
416 goto exit;
417 }
418 plist = get_next(&(free_queue->queue));
419
420 pnetwork = LIST_CONTAINOR(plist , struct wlan_network, list);
421
422 rtw_list_delete(&pnetwork->list);
423
424 pnetwork->network_type = 0;
425 pnetwork->fixed = _FALSE;
426 pnetwork->last_scanned = rtw_get_current_time();
427 pnetwork->last_non_hidden_ssid_ap = pnetwork->last_scanned;
428 #if defined(CONFIG_RTW_MESH) && CONFIG_RTW_MESH_ACNODE_PREVENT
429 pnetwork->acnode_stime = 0;
430 pnetwork->acnode_notify_etime = 0;
431 #endif
432
433 pnetwork->aid = 0;
434 pnetwork->join_res = 0;
435
436 pmlmepriv->num_of_scanned++;
437
438 exit:
439 _exit_critical_bh(&free_queue->lock, &irqL);
440
441
442 return pnetwork;
443 }
444
_rtw_free_network(struct mlme_priv * pmlmepriv,struct wlan_network * pnetwork,u8 isfreeall)445 void _rtw_free_network(struct mlme_priv *pmlmepriv , struct wlan_network *pnetwork, u8 isfreeall)
446 {
447 u32 delta_time;
448 u32 lifetime = SCANQUEUE_LIFETIME;
449 _irqL irqL;
450 _queue *free_queue = &(pmlmepriv->free_bss_pool);
451
452
453 if (pnetwork == NULL)
454 goto exit;
455
456 if (pnetwork->fixed == _TRUE)
457 goto exit;
458
459 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) ||
460 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE))
461 lifetime = 1;
462
463 if (!isfreeall) {
464 delta_time = (u32) rtw_get_passing_time_ms(pnetwork->last_scanned);
465 if (delta_time < lifetime) /* unit:msec */
466 goto exit;
467 }
468
469 _enter_critical_bh(&free_queue->lock, &irqL);
470
471 rtw_list_delete(&(pnetwork->list));
472
473 rtw_list_insert_tail(&(pnetwork->list), &(free_queue->queue));
474
475 pmlmepriv->num_of_scanned--;
476
477
478 /* RTW_INFO("_rtw_free_network:SSID=%s\n", pnetwork->network.Ssid.Ssid); */
479
480 _exit_critical_bh(&free_queue->lock, &irqL);
481
482 exit:
483 return;
484 }
485
_rtw_free_network_nolock(struct mlme_priv * pmlmepriv,struct wlan_network * pnetwork)486 void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork)
487 {
488
489 _queue *free_queue = &(pmlmepriv->free_bss_pool);
490
491
492 if (pnetwork == NULL)
493 goto exit;
494
495 if (pnetwork->fixed == _TRUE)
496 goto exit;
497
498 /* _enter_critical(&free_queue->lock, &irqL); */
499
500 rtw_list_delete(&(pnetwork->list));
501
502 rtw_list_insert_tail(&(pnetwork->list), get_list_head(free_queue));
503
504 pmlmepriv->num_of_scanned--;
505
506 /* _exit_critical(&free_queue->lock, &irqL); */
507
508 exit:
509 return;
510 }
511
_rtw_free_network_queue(_adapter * padapter,u8 isfreeall)512 void _rtw_free_network_queue(_adapter *padapter, u8 isfreeall)
513 {
514 _irqL irqL;
515 _list *phead, *plist;
516 struct wlan_network *pnetwork;
517 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
518 _queue *scanned_queue = &pmlmepriv->scanned_queue;
519
520
521
522 _enter_critical_bh(&scanned_queue->lock, &irqL);
523
524 phead = get_list_head(scanned_queue);
525 plist = get_next(phead);
526
527 while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
528
529 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
530
531 plist = get_next(plist);
532
533 _rtw_free_network(pmlmepriv, pnetwork, isfreeall);
534
535 }
536
537 _exit_critical_bh(&scanned_queue->lock, &irqL);
538
539
540 }
541
542
543
544
rtw_if_up(_adapter * padapter)545 sint rtw_if_up(_adapter *padapter)
546 {
547
548 sint res;
549
550 if (RTW_CANNOT_RUN(padapter) ||
551 (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _FALSE)) {
552 res = _FALSE;
553 } else
554 res = _TRUE;
555
556 return res;
557 }
558
559
rtw_generate_random_ibss(u8 * pibss)560 void rtw_generate_random_ibss(u8 *pibss)
561 {
562 *((u32 *)(&pibss[2])) = rtw_random32();
563 pibss[0] = 0x02; /* in ad-hoc mode local bit must set to 1 */
564 pibss[1] = 0x11;
565 pibss[2] = 0x87;
566 }
567
rtw_get_capability_from_ie(u8 * ie)568 u8 *rtw_get_capability_from_ie(u8 *ie)
569 {
570 return ie + 8 + 2;
571 }
572
573
rtw_get_capability(WLAN_BSSID_EX * bss)574 u16 rtw_get_capability(WLAN_BSSID_EX *bss)
575 {
576 u16 val;
577
578 _rtw_memcpy((u8 *)&val, rtw_get_capability_from_ie(bss->IEs), 2);
579
580 return le16_to_cpu(val);
581 }
582
rtw_get_timestampe_from_ie(u8 * ie)583 u8 *rtw_get_timestampe_from_ie(u8 *ie)
584 {
585 return ie + 0;
586 }
587
rtw_get_beacon_interval_from_ie(u8 * ie)588 u8 *rtw_get_beacon_interval_from_ie(u8 *ie)
589 {
590 return ie + 8;
591 }
592
593
rtw_init_mlme_priv(_adapter * padapter)594 int rtw_init_mlme_priv(_adapter *padapter) /* (struct mlme_priv *pmlmepriv) */
595 {
596 int res;
597 res = _rtw_init_mlme_priv(padapter);/* (pmlmepriv); */
598 return res;
599 }
600
rtw_free_mlme_priv(struct mlme_priv * pmlmepriv)601 void rtw_free_mlme_priv(struct mlme_priv *pmlmepriv)
602 {
603 _rtw_free_mlme_priv(pmlmepriv);
604 }
605
606 int rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork);
rtw_enqueue_network(_queue * queue,struct wlan_network * pnetwork)607 int rtw_enqueue_network(_queue *queue, struct wlan_network *pnetwork)
608 {
609 int res;
610 res = _rtw_enqueue_network(queue, pnetwork);
611 return res;
612 }
613
614 /*
615 static struct wlan_network *rtw_dequeue_network(_queue *queue)
616 {
617 struct wlan_network *pnetwork;
618 pnetwork = _rtw_dequeue_network(queue);
619 return pnetwork;
620 }
621 */
622
623 struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv);
rtw_alloc_network(struct mlme_priv * pmlmepriv)624 struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv) /* (_queue *free_queue) */
625 {
626 struct wlan_network *pnetwork;
627 pnetwork = _rtw_alloc_network(pmlmepriv);
628 return pnetwork;
629 }
630
631 void rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 is_freeall);
rtw_free_network(struct mlme_priv * pmlmepriv,struct wlan_network * pnetwork,u8 is_freeall)632 void rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwork, u8 is_freeall)/* (struct wlan_network *pnetwork, _queue *free_queue) */
633 {
634 _rtw_free_network(pmlmepriv, pnetwork, is_freeall);
635 }
636
637 void rtw_free_network_nolock(_adapter *padapter, struct wlan_network *pnetwork);
rtw_free_network_nolock(_adapter * padapter,struct wlan_network * pnetwork)638 void rtw_free_network_nolock(_adapter *padapter, struct wlan_network *pnetwork)
639 {
640 _rtw_free_network_nolock(&(padapter->mlmepriv), pnetwork);
641 #ifdef CONFIG_IOCTL_CFG80211
642 rtw_cfg80211_unlink_bss(padapter, pnetwork);
643 #endif /* CONFIG_IOCTL_CFG80211 */
644 }
645
646
rtw_free_network_queue(_adapter * dev,u8 isfreeall)647 void rtw_free_network_queue(_adapter *dev, u8 isfreeall)
648 {
649 _rtw_free_network_queue(dev, isfreeall);
650 }
651
_rtw_find_network(_queue * scanned_queue,const u8 * addr)652 struct wlan_network *_rtw_find_network(_queue *scanned_queue, const u8 *addr)
653 {
654 _list *phead, *plist;
655 struct wlan_network *pnetwork = NULL;
656 u8 zero_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
657
658 if (_rtw_memcmp(zero_addr, addr, ETH_ALEN)) {
659 pnetwork = NULL;
660 goto exit;
661 }
662
663 phead = get_list_head(scanned_queue);
664 plist = get_next(phead);
665
666 while (plist != phead) {
667 pnetwork = LIST_CONTAINOR(plist, struct wlan_network , list);
668
669 if (_rtw_memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN) == _TRUE)
670 break;
671
672 plist = get_next(plist);
673 }
674
675 if (plist == phead)
676 pnetwork = NULL;
677
678 exit:
679 return pnetwork;
680 }
681
rtw_find_network(_queue * scanned_queue,const u8 * addr)682 struct wlan_network *rtw_find_network(_queue *scanned_queue, const u8 *addr)
683 {
684 struct wlan_network *pnetwork;
685 _irqL irqL;
686
687 _enter_critical_bh(&scanned_queue->lock, &irqL);
688 pnetwork = _rtw_find_network(scanned_queue, addr);
689 _exit_critical_bh(&scanned_queue->lock, &irqL);
690
691 return pnetwork;
692 }
693
rtw_is_same_ibss(_adapter * adapter,struct wlan_network * pnetwork)694 int rtw_is_same_ibss(_adapter *adapter, struct wlan_network *pnetwork)
695 {
696 int ret = _TRUE;
697 struct security_priv *psecuritypriv = &adapter->securitypriv;
698
699 if ((psecuritypriv->dot11PrivacyAlgrthm != _NO_PRIVACY_) &&
700 (pnetwork->network.Privacy == 0))
701 ret = _FALSE;
702 else if ((psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_) &&
703 (pnetwork->network.Privacy == 1))
704 ret = _FALSE;
705 else
706 ret = _TRUE;
707
708 return ret;
709
710 }
711
is_same_ess(WLAN_BSSID_EX * a,WLAN_BSSID_EX * b)712 inline int is_same_ess(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b)
713 {
714 return (a->Ssid.SsidLength == b->Ssid.SsidLength)
715 && _rtw_memcmp(a->Ssid.Ssid, b->Ssid.Ssid, a->Ssid.SsidLength) == _TRUE;
716 }
717
is_same_network(WLAN_BSSID_EX * src,WLAN_BSSID_EX * dst,u8 feature)718 int is_same_network(WLAN_BSSID_EX *src, WLAN_BSSID_EX *dst, u8 feature)
719 {
720 u16 s_cap, d_cap;
721
722
723 if (rtw_bug_check(dst, src, &s_cap, &d_cap) == _FALSE)
724 return _FALSE;
725
726 _rtw_memcpy((u8 *)&s_cap, rtw_get_capability_from_ie(src->IEs), 2);
727 _rtw_memcpy((u8 *)&d_cap, rtw_get_capability_from_ie(dst->IEs), 2);
728
729
730 s_cap = le16_to_cpu(s_cap);
731 d_cap = le16_to_cpu(d_cap);
732
733
734 #ifdef CONFIG_P2P
735 if ((feature == 1) && /* 1: P2P supported */
736 (_rtw_memcmp(src->MacAddress, dst->MacAddress, ETH_ALEN) == _TRUE)
737 )
738 return _TRUE;
739 #endif
740
741 /* Wi-Fi driver doesn't consider the situation of BCN and ProbRsp sent from the same hidden AP,
742 * it considers these two packets are sent from different AP.
743 * Therefore, the scan queue may store two scan results of the same hidden AP, likes below.
744 *
745 * index bssid ch RSSI SdBm Noise age flag ssid
746 * 1 00:e0:4c:55:50:01 153 -73 -73 0 7044 [WPS][ESS] RTK5G
747 * 3 00:e0:4c:55:50:01 153 -73 -73 0 7044 [WPS][ESS]
748 *
749 * Original rules will compare Ssid, SsidLength, MacAddress, s_cap, d_cap at the same time.
750 * Wi-Fi driver will assume that the BCN and ProbRsp sent from the same hidden AP are the same network
751 * after we add an additional rule to compare SsidLength and Ssid.
752 * It means the scan queue will not store two scan results of the same hidden AP, it only store ProbRsp.
753 * For customer request.
754 */
755
756 if (((_rtw_memcmp(src->MacAddress, dst->MacAddress, ETH_ALEN)) == _TRUE) &&
757 ((s_cap & WLAN_CAPABILITY_IBSS) == (d_cap & WLAN_CAPABILITY_IBSS)) &&
758 ((s_cap & WLAN_CAPABILITY_BSS) == (d_cap & WLAN_CAPABILITY_BSS))) {
759 if ((src->Ssid.SsidLength == dst->Ssid.SsidLength) &&
760 (((_rtw_memcmp(src->Ssid.Ssid, dst->Ssid.Ssid, src->Ssid.SsidLength)) == _TRUE) || //Case of normal AP
761 (is_all_null(src->Ssid.Ssid, src->Ssid.SsidLength) == _TRUE || is_all_null(dst->Ssid.Ssid, dst->Ssid.SsidLength) == _TRUE))) //Case of hidden AP
762 return _TRUE;
763 else if ((src->Ssid.SsidLength == 0 || dst->Ssid.SsidLength == 0)) //Case of hidden AP
764 return _TRUE;
765 else
766 return _FALSE;
767 } else {
768 return _FALSE;
769 }
770 }
771
_rtw_find_same_network(_queue * scanned_queue,struct wlan_network * network)772 struct wlan_network *_rtw_find_same_network(_queue *scanned_queue, struct wlan_network *network)
773 {
774 _list *phead, *plist;
775 struct wlan_network *found = NULL;
776
777 phead = get_list_head(scanned_queue);
778 plist = get_next(phead);
779
780 while (plist != phead) {
781 found = LIST_CONTAINOR(plist, struct wlan_network , list);
782
783 if (is_same_network(&network->network, &found->network, 0))
784 break;
785
786 plist = get_next(plist);
787 }
788
789 if (plist == phead)
790 found = NULL;
791
792 return found;
793 }
794
rtw_find_same_network(_queue * scanned_queue,struct wlan_network * network)795 struct wlan_network *rtw_find_same_network(_queue *scanned_queue, struct wlan_network *network)
796 {
797 _irqL irqL;
798 struct wlan_network *found = NULL;
799
800 if (scanned_queue == NULL || network == NULL)
801 goto exit;
802
803 _enter_critical_bh(&scanned_queue->lock, &irqL);
804 found = _rtw_find_same_network(scanned_queue, network);
805 _exit_critical_bh(&scanned_queue->lock, &irqL);
806
807 exit:
808 return found;
809 }
810
rtw_get_oldest_wlan_network(_queue * scanned_queue)811 struct wlan_network *rtw_get_oldest_wlan_network(_queue *scanned_queue)
812 {
813 _list *plist, *phead;
814
815
816 struct wlan_network *pwlan = NULL;
817 struct wlan_network *oldest = NULL;
818 phead = get_list_head(scanned_queue);
819
820 plist = get_next(phead);
821
822 while (1) {
823
824 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
825 break;
826
827 pwlan = LIST_CONTAINOR(plist, struct wlan_network, list);
828
829 if (pwlan->fixed != _TRUE) {
830 if (oldest == NULL || rtw_time_after(oldest->last_scanned, pwlan->last_scanned))
831 oldest = pwlan;
832 }
833
834 plist = get_next(plist);
835 }
836 return oldest;
837
838 }
839
update_network(WLAN_BSSID_EX * dst,WLAN_BSSID_EX * src,_adapter * padapter,bool update_ie)840 void update_network(WLAN_BSSID_EX *dst, WLAN_BSSID_EX *src,
841 _adapter *padapter, bool update_ie)
842 {
843 #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) && 1
844 u8 ss_ori = dst->PhyInfo.SignalStrength;
845 u8 sq_ori = dst->PhyInfo.SignalQuality;
846 u8 ss_smp = src->PhyInfo.SignalStrength;
847 long rssi_smp = src->Rssi;
848 #endif
849 long rssi_ori = dst->Rssi;
850
851 u8 sq_smp = src->PhyInfo.SignalQuality;
852 u8 ss_final;
853 u8 sq_final;
854 long rssi_final;
855
856
857 #ifdef CONFIG_ANTENNA_DIVERSITY
858 rtw_hal_antdiv_rssi_compared(padapter, dst, src); /* this will update src.Rssi, need consider again */
859 #endif
860
861 #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) && 1
862 if (strcmp(dst->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
863 RTW_INFO(FUNC_ADPT_FMT" %s("MAC_FMT", ch%u) ss_ori:%3u, sq_ori:%3u, rssi_ori:%3ld, ss_smp:%3u, sq_smp:%3u, rssi_smp:%3ld\n"
864 , FUNC_ADPT_ARG(padapter)
865 , src->Ssid.Ssid, MAC_ARG(src->MacAddress), src->Configuration.DSConfig
866 , ss_ori, sq_ori, rssi_ori
867 , ss_smp, sq_smp, rssi_smp
868 );
869 }
870 #endif
871
872 /* The rule below is 1/5 for sample value, 4/5 for history value */
873 if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) && is_same_network(&(padapter->mlmepriv.cur_network.network), src, 0)) {
874 /* Take the recvpriv's value for the connected AP*/
875 ss_final = padapter->recvpriv.signal_strength;
876 sq_final = padapter->recvpriv.signal_qual;
877 /* the rssi value here is undecorated, and will be used for antenna diversity */
878 if (sq_smp != 101) /* from the right channel */
879 rssi_final = (src->Rssi + dst->Rssi * 4) / 5;
880 else
881 rssi_final = rssi_ori;
882 } else {
883 if (sq_smp != 101) { /* from the right channel */
884 ss_final = ((u32)(src->PhyInfo.SignalStrength) + (u32)(dst->PhyInfo.SignalStrength) * 4) / 5;
885 sq_final = ((u32)(src->PhyInfo.SignalQuality) + (u32)(dst->PhyInfo.SignalQuality) * 4) / 5;
886 rssi_final = (src->Rssi + dst->Rssi * 4) / 5;
887 } else {
888 /* bss info not receving from the right channel, use the original RX signal infos */
889 ss_final = dst->PhyInfo.SignalStrength;
890 sq_final = dst->PhyInfo.SignalQuality;
891 rssi_final = dst->Rssi;
892 }
893
894 }
895
896 if (update_ie) {
897 dst->Reserved[0] = src->Reserved[0];
898 dst->Reserved[1] = src->Reserved[1];
899 _rtw_memcpy((u8 *)dst, (u8 *)src, get_WLAN_BSSID_EX_sz(src));
900 }
901
902 dst->PhyInfo.SignalStrength = ss_final;
903 dst->PhyInfo.SignalQuality = sq_final;
904 dst->Rssi = rssi_final;
905
906 #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) && 1
907 if (strcmp(dst->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
908 RTW_INFO(FUNC_ADPT_FMT" %s("MAC_FMT"), SignalStrength:%u, SignalQuality:%u, RawRSSI:%ld\n"
909 , FUNC_ADPT_ARG(padapter)
910 , dst->Ssid.Ssid, MAC_ARG(dst->MacAddress), dst->PhyInfo.SignalStrength, dst->PhyInfo.SignalQuality, dst->Rssi);
911 }
912 #endif
913
914 #if 0 /* old codes, may be useful one day...
915 * RTW_INFO("update_network: rssi=0x%lx dst->Rssi=%d ,dst->Rssi=0x%lx , src->Rssi=0x%lx",(dst->Rssi+src->Rssi)/2,dst->Rssi,dst->Rssi,src->Rssi); */
916 if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) && is_same_network(&(padapter->mlmepriv.cur_network.network), src)) {
917
918 /* RTW_INFO("b:ssid=%s update_network: src->rssi=0x%d padapter->recvpriv.ui_rssi=%d\n",src->Ssid.Ssid,src->Rssi,padapter->recvpriv.signal); */
919 if (padapter->recvpriv.signal_qual_data.total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX) {
920 padapter->recvpriv.signal_qual_data.total_num = PHY_LINKQUALITY_SLID_WIN_MAX;
921 last_evm = padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index];
922 padapter->recvpriv.signal_qual_data.total_val -= last_evm;
923 }
924 padapter->recvpriv.signal_qual_data.total_val += query_rx_pwr_percentage(src->Rssi);
925
926 padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index++] = query_rx_pwr_percentage(src->Rssi);
927 if (padapter->recvpriv.signal_qual_data.index >= PHY_LINKQUALITY_SLID_WIN_MAX)
928 padapter->recvpriv.signal_qual_data.index = 0;
929
930 /* RTW_INFO("Total SQ=%d pattrib->signal_qual= %d\n", padapter->recvpriv.signal_qual_data.total_val, src->Rssi); */
931
932 /* <1> Showed on UI for user,in percentage. */
933 tmpVal = padapter->recvpriv.signal_qual_data.total_val / padapter->recvpriv.signal_qual_data.total_num;
934 padapter->recvpriv.signal = (u8)tmpVal; /* Link quality */
935
936 src->Rssi = translate_percentage_to_dbm(padapter->recvpriv.signal) ;
937 } else {
938 /* RTW_INFO("ELSE:ssid=%s update_network: src->rssi=0x%d dst->rssi=%d\n",src->Ssid.Ssid,src->Rssi,dst->Rssi); */
939 src->Rssi = (src->Rssi + dst->Rssi) / 2; /* dBM */
940 }
941
942 /* RTW_INFO("a:update_network: src->rssi=0x%d padapter->recvpriv.ui_rssi=%d\n",src->Rssi,padapter->recvpriv.signal); */
943
944 #endif
945
946 }
947
update_current_network(_adapter * adapter,WLAN_BSSID_EX * pnetwork)948 static void update_current_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork)
949 {
950 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
951
952
953 rtw_bug_check(&(pmlmepriv->cur_network.network),
954 &(pmlmepriv->cur_network.network),
955 &(pmlmepriv->cur_network.network),
956 &(pmlmepriv->cur_network.network));
957
958 if ((check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) && (is_same_network(&(pmlmepriv->cur_network.network), pnetwork, 0))) {
959
960 /* if(pmlmepriv->cur_network.network.IELength<= pnetwork->IELength) */
961 {
962 update_network(&(pmlmepriv->cur_network.network), pnetwork, adapter, _TRUE);
963 rtw_update_protection(adapter, (pmlmepriv->cur_network.network.IEs) + sizeof(NDIS_802_11_FIXED_IEs),
964 pmlmepriv->cur_network.network.IELength);
965 }
966 }
967
968
969 }
970
971
972 /*
973
974 Caller must hold pmlmepriv->lock first.
975
976
977 */
rtw_update_scanned_network(_adapter * adapter,WLAN_BSSID_EX * target)978 bool rtw_update_scanned_network(_adapter *adapter, WLAN_BSSID_EX *target)
979 {
980 _irqL irqL;
981 _list *plist, *phead;
982 u32 bssid_ex_sz;
983 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
984 #ifdef CONFIG_P2P
985 struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
986 #endif /* CONFIG_P2P */
987 _queue *queue = &(pmlmepriv->scanned_queue);
988 struct wlan_network *pnetwork = NULL;
989 struct wlan_network *choice = NULL;
990 int target_find = 0;
991 u8 feature = 0;
992 bool update_ie = _FALSE;
993
994 _enter_critical_bh(&queue->lock, &irqL);
995 phead = get_list_head(queue);
996 plist = get_next(phead);
997
998 #if 0
999 RTW_INFO("%s => ssid:%s , rssi:%ld , ss:%d\n",
1000 __func__, target->Ssid.Ssid, target->Rssi, target->PhyInfo.SignalStrength);
1001 #endif
1002
1003 #ifdef CONFIG_P2P
1004 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
1005 feature = 1; /* p2p enable */
1006 #endif
1007
1008 while (1) {
1009 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
1010 break;
1011
1012 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1013
1014 rtw_bug_check(pnetwork, pnetwork, pnetwork, pnetwork);
1015
1016 #ifdef CONFIG_P2P
1017 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
1018 (_rtw_memcmp(pnetwork->network.MacAddress, target->MacAddress, ETH_ALEN) == _TRUE)) {
1019 target_find = 1;
1020 break;
1021 }
1022 #endif
1023
1024 if (is_same_network(&(pnetwork->network), target, feature)) {
1025 target_find = 1;
1026 break;
1027 }
1028
1029 if (rtw_roam_flags(adapter)) {
1030 /* TODO: don't select netowrk in the same ess as choice if it's new enough*/
1031 }
1032 if (pnetwork->fixed) {
1033 plist = get_next(plist);
1034 continue;
1035 }
1036
1037 #ifdef CONFIG_RSSI_PRIORITY
1038 if ((choice == NULL) || (pnetwork->network.PhyInfo.SignalStrength < choice->network.PhyInfo.SignalStrength))
1039 #ifdef CONFIG_RTW_MESH
1040 if (!MLME_IS_MESH(adapter) || !MLME_IS_ASOC(adapter)
1041 || !rtw_bss_is_same_mbss(&pmlmepriv->cur_network.network, &pnetwork->network))
1042 #endif
1043 choice = pnetwork;
1044 #else
1045 if (choice == NULL || rtw_time_after(choice->last_scanned, pnetwork->last_scanned))
1046 #ifdef CONFIG_RTW_MESH
1047 if (!MLME_IS_MESH(adapter) || !MLME_IS_ASOC(adapter)
1048 || !rtw_bss_is_same_mbss(&pmlmepriv->cur_network.network, &pnetwork->network))
1049 #endif
1050 choice = pnetwork;
1051 #endif
1052 plist = get_next(plist);
1053
1054 }
1055
1056
1057 /* If we didn't find a match, then get a new network slot to initialize
1058 * with this beacon's information */
1059 /* if (rtw_end_of_queue_search(phead,plist)== _TRUE) { */
1060 if (!target_find) {
1061 if (_rtw_queue_empty(&(pmlmepriv->free_bss_pool)) == _TRUE) {
1062 /* If there are no more slots, expire the choice */
1063 /* list_del_init(&choice->list); */
1064 pnetwork = choice;
1065 if (pnetwork == NULL)
1066 goto unlock_scan_queue;
1067
1068 #ifdef CONFIG_RSSI_PRIORITY
1069 RTW_DBG("%s => ssid:%s ,bssid:"MAC_FMT" will be deleted from scanned_queue (rssi:%ld , ss:%d)\n",
1070 __func__, pnetwork->network.Ssid.Ssid, MAC_ARG(pnetwork->network.MacAddress), pnetwork->network.Rssi, pnetwork->network.PhyInfo.SignalStrength);
1071 #else
1072 RTW_DBG("%s => ssid:%s ,bssid:"MAC_FMT" will be deleted from scanned_queue\n",
1073 __func__, pnetwork->network.Ssid.Ssid, MAC_ARG(pnetwork->network.MacAddress));
1074 #endif
1075
1076 #ifdef CONFIG_ANTENNA_DIVERSITY
1077 rtw_hal_get_odm_var(adapter, HAL_ODM_ANTDIV_SELECT, &(target->PhyInfo.Optimum_antenna), NULL);
1078 #endif
1079 _rtw_memcpy(&(pnetwork->network), target, get_WLAN_BSSID_EX_sz(target));
1080 pnetwork->bcn_keys_valid = 0;
1081 if (target->Reserved[0] == BSS_TYPE_BCN || target->Reserved[0] == BSS_TYPE_PROB_RSP)
1082 rtw_update_bcn_keys_of_network(pnetwork);
1083 /* variable initialize */
1084 pnetwork->fixed = _FALSE;
1085 pnetwork->last_scanned = rtw_get_current_time();
1086 pnetwork->last_non_hidden_ssid_ap = pnetwork->last_scanned;
1087 #if defined(CONFIG_RTW_MESH) && CONFIG_RTW_MESH_ACNODE_PREVENT
1088 pnetwork->acnode_stime = 0;
1089 pnetwork->acnode_notify_etime = 0;
1090 #endif
1091
1092 pnetwork->network_type = 0;
1093 pnetwork->aid = 0;
1094 pnetwork->join_res = 0;
1095
1096 /* bss info not receving from the right channel */
1097 if (pnetwork->network.PhyInfo.SignalQuality == 101)
1098 pnetwork->network.PhyInfo.SignalQuality = 0;
1099 } else {
1100 /* Otherwise just pull from the free list */
1101
1102 pnetwork = rtw_alloc_network(pmlmepriv); /* will update scan_time */
1103 if (pnetwork == NULL)
1104 goto unlock_scan_queue;
1105
1106 bssid_ex_sz = get_WLAN_BSSID_EX_sz(target);
1107 target->Length = bssid_ex_sz;
1108 #ifdef CONFIG_ANTENNA_DIVERSITY
1109 rtw_hal_get_odm_var(adapter, HAL_ODM_ANTDIV_SELECT, &(target->PhyInfo.Optimum_antenna), NULL);
1110 #endif
1111 _rtw_memcpy(&(pnetwork->network), target, bssid_ex_sz);
1112 pnetwork->bcn_keys_valid = 0;
1113 if (target->Reserved[0] == BSS_TYPE_BCN || target->Reserved[0] == BSS_TYPE_PROB_RSP)
1114 rtw_update_bcn_keys_of_network(pnetwork);
1115
1116 /* bss info not receving from the right channel */
1117 if (pnetwork->network.PhyInfo.SignalQuality == 101)
1118 pnetwork->network.PhyInfo.SignalQuality = 0;
1119
1120 rtw_list_insert_tail(&(pnetwork->list), &(queue->queue));
1121
1122 }
1123 } else {
1124 /* we have an entry and we are going to update it. But this entry may
1125 * be already expired. In this case we do the same as we found a new
1126 * net and call the new_net handler
1127 */
1128 #if defined(CONFIG_RTW_MESH) && CONFIG_RTW_MESH_ACNODE_PREVENT
1129 systime last_scanned = pnetwork->last_scanned;
1130 #endif
1131 struct beacon_keys bcn_keys;
1132 bool bcn_keys_valid = 0;
1133 bool is_hidden_ssid_ap = 0;
1134
1135 pnetwork->last_scanned = rtw_get_current_time();
1136
1137 if (target->Reserved[0] == BSS_TYPE_BCN || target->Reserved[0] == BSS_TYPE_PROB_RSP) {
1138 if (target->InfrastructureMode == Ndis802_11Infrastructure) {
1139 is_hidden_ssid_ap = hidden_ssid_ap(target);
1140 if (!is_hidden_ssid_ap) /* update last time it's non hidden ssid AP */
1141 pnetwork->last_non_hidden_ssid_ap = rtw_get_current_time();
1142 }
1143 bcn_keys_valid = rtw_get_bcn_keys_from_bss(target, &bcn_keys);
1144 }
1145
1146 if (target->InfrastructureMode == Ndis802_11_mesh
1147 || target->Reserved[0] >= pnetwork->network.Reserved[0])
1148 update_ie = _TRUE;
1149 else if (target->InfrastructureMode == Ndis802_11Infrastructure && !pnetwork->fixed
1150 && rtw_get_passing_time_ms(pnetwork->last_non_hidden_ssid_ap) > SCANQUEUE_LIFETIME)
1151 update_ie = _TRUE;
1152 else if (bcn_keys_valid) {
1153 if (is_hidden_ssid(bcn_keys.ssid, bcn_keys.ssid_len)) {
1154 /* hidden ssid, replace with current beacon ssid directly */
1155 _rtw_memcpy(bcn_keys.ssid, pnetwork->bcn_keys.ssid, pnetwork->bcn_keys.ssid_len);
1156 bcn_keys.ssid_len = pnetwork->bcn_keys.ssid_len;
1157 }
1158 if (rtw_bcn_key_compare(&pnetwork->bcn_keys, &bcn_keys) == _FALSE)
1159 update_ie = _TRUE;
1160 }
1161
1162 #if defined(CONFIG_RTW_MESH) && CONFIG_RTW_MESH_ACNODE_PREVENT
1163 if (!MLME_IS_MESH(adapter) || !MLME_IS_ASOC(adapter)
1164 || pnetwork->network.Configuration.DSConfig != target->Configuration.DSConfig
1165 || rtw_get_passing_time_ms(last_scanned) > adapter->mesh_cfg.peer_sel_policy.scanr_exp_ms
1166 || !rtw_bss_is_same_mbss(&pnetwork->network, target)
1167 ) {
1168 pnetwork->acnode_stime = 0;
1169 pnetwork->acnode_notify_etime = 0;
1170 }
1171 #endif
1172
1173 if (bcn_keys_valid) {
1174 _rtw_memcpy(&pnetwork->bcn_keys, &bcn_keys, sizeof(bcn_keys));
1175 pnetwork->bcn_keys_valid = 1;
1176 } else if (update_ie)
1177 pnetwork->bcn_keys_valid = 0;
1178
1179 update_network(&(pnetwork->network), target, adapter, update_ie);
1180 }
1181
1182 #if defined(CONFIG_RTW_MESH) && CONFIG_RTW_MESH_ACNODE_PREVENT
1183 if (MLME_IS_MESH(adapter) && MLME_IS_ASOC(adapter))
1184 rtw_mesh_update_scanned_acnode_status(adapter, pnetwork);
1185 #endif
1186
1187 unlock_scan_queue:
1188 _exit_critical_bh(&queue->lock, &irqL);
1189
1190 #ifdef CONFIG_RTW_MESH
1191 if (pnetwork && MLME_IS_MESH(adapter)
1192 && check_fwstate(pmlmepriv, WIFI_ASOC_STATE)
1193 && !check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY)
1194 )
1195 rtw_chk_candidate_peer_notify(adapter, pnetwork);
1196 #endif
1197
1198 return update_ie;
1199 }
1200
1201 void rtw_add_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork);
rtw_add_network(_adapter * adapter,WLAN_BSSID_EX * pnetwork)1202 void rtw_add_network(_adapter *adapter, WLAN_BSSID_EX *pnetwork)
1203 {
1204 bool update_ie;
1205 /* _queue *queue = &(pmlmepriv->scanned_queue); */
1206
1207 /* _enter_critical_bh(&queue->lock, &irqL); */
1208
1209 #if defined(CONFIG_P2P) && defined(CONFIG_P2P_REMOVE_GROUP_INFO)
1210 if (adapter->registrypriv.wifi_spec == 0)
1211 rtw_bss_ex_del_p2p_attr(pnetwork, P2P_ATTR_GROUP_INFO);
1212 #endif
1213 if (!hal_chk_wl_func(adapter, WL_FUNC_MIRACAST))
1214 rtw_bss_ex_del_wfd_ie(pnetwork);
1215 /* Wi-Fi driver will update the current network if the scan result of the connected AP be updated by scan. */
1216 update_ie = rtw_update_scanned_network(adapter, pnetwork);
1217
1218 if (update_ie)
1219 update_current_network(adapter, pnetwork);
1220
1221 /* _exit_critical_bh(&queue->lock, &irqL); */
1222
1223 }
1224
1225 #ifdef CONFIG_RTW_MULTI_AP
rtw_unassoc_sta_set_mode(_adapter * adapter,u8 stype,u8 mode)1226 void rtw_unassoc_sta_set_mode(_adapter *adapter, u8 stype, u8 mode)
1227 {
1228 if (stype >= UNASOC_STA_SRC_NUM
1229 || mode >= UNASOC_STA_MODE_NUM)
1230 return;
1231
1232 adapter = GET_PRIMARY_ADAPTER(adapter);
1233
1234 if (adapter->mlmepriv.unassoc_sta_mode_of_stype[stype] == mode)
1235 return;
1236
1237 adapter->mlmepriv.unassoc_sta_mode_of_stype[stype] = mode;
1238
1239 rtw_run_in_thread_cmd_wait(adapter, ((void *)(rtw_hal_rcr_set_chk_bssid_act_non)), adapter, 2000);
1240 }
1241
rtw_unassoc_sta_src_chk(_adapter * adapter,u8 stype)1242 bool rtw_unassoc_sta_src_chk(_adapter *adapter, u8 stype)
1243 {
1244 if (stype >= UNASOC_STA_SRC_NUM)
1245 return 0;
1246
1247 adapter = GET_PRIMARY_ADAPTER(adapter);
1248
1249 return adapter->mlmepriv.unassoc_sta_mode_of_stype[stype] == UNASOC_STA_MODE_ALL
1250 || (adapter->mlmepriv.unassoc_sta_mode_of_stype[stype] == UNASOC_STA_MODE_INTERESTED
1251 && adapter->mlmepriv.interested_unassoc_sta_cnt)
1252 ;
1253 }
1254
1255 const char *unasoc_sta_src_str[] = {
1256 "BMC",
1257 "NMY_UC",
1258 };
1259
1260 const char *unasoc_sta_mode_str[] = {
1261 "DISABLED",
1262 "INTERESTED",
1263 "ALL",
1264 };
1265
dump_unassoc_sta(void * sel,_adapter * adapter)1266 void dump_unassoc_sta(void *sel, _adapter *adapter)
1267 {
1268 struct mlme_priv *mlmepriv;
1269 _queue *queue;
1270 _list *list, *head;
1271 struct unassoc_sta_info **unassoc_sta_arr;
1272 struct unassoc_sta_info *unassoc_sta;
1273 u16 i, unassoc_sta_cnt = 0;
1274
1275 adapter = GET_PRIMARY_ADAPTER(adapter);
1276 mlmepriv = &(adapter->mlmepriv);
1277 queue = &(mlmepriv->unassoc_sta_queue);
1278
1279 for (i = 0; i < UNASOC_STA_SRC_NUM; i++) {
1280 RTW_PRINT_SEL(sel, "[%u]%-6s:%u(%s)\n", i, unasoc_sta_src_str[i]
1281 , mlmepriv->unassoc_sta_mode_of_stype[i], unasoc_sta_mode_str[mlmepriv->unassoc_sta_mode_of_stype[i]]);
1282 }
1283 RTW_PRINT_SEL(sel, "interested_unassoc_sta_cnt:%u\n", mlmepriv->interested_unassoc_sta_cnt);
1284
1285 unassoc_sta_arr = rtw_zvmalloc(mlmepriv->max_unassoc_sta_cnt * sizeof(struct unassoc_sta_info *));
1286 if (!unassoc_sta_arr)
1287 return;
1288
1289 enter_critical_bh(&queue->lock);
1290 head = get_list_head(queue);
1291 list = get_next(head);
1292
1293 while (rtw_end_of_queue_search(head, list) == _FALSE) {
1294 unassoc_sta = LIST_CONTAINOR(list, struct unassoc_sta_info, list);
1295 list = get_next(list);
1296
1297 unassoc_sta_arr[unassoc_sta_cnt++] = unassoc_sta;
1298 }
1299
1300 exit_critical_bh(&queue->lock);
1301
1302 RTW_PRINT_SEL(sel, " %17s %18s %6s\n", "mac_addr", "measure_delta_time", "rssi");
1303
1304 for (i = 0; i < unassoc_sta_cnt; i++) {
1305 u8 rcpi;
1306 s8 rx_power;
1307 u32 measure_delta_time;
1308
1309 unassoc_sta = unassoc_sta_arr[i];
1310
1311 measure_delta_time = rtw_systime_to_ms(rtw_get_current_time() - unassoc_sta->time);
1312
1313 RTW_PRINT_SEL(sel, "%c "MAC_FMT" %18u %6d\n"
1314 , unassoc_sta->interested ? '*' : ' '
1315 , MAC_ARG(unassoc_sta->addr), measure_delta_time, unassoc_sta->recv_signal_power);
1316 }
1317
1318 rtw_vmfree(unassoc_sta_arr, mlmepriv->max_unassoc_sta_cnt * sizeof(struct unassoc_sta_info *));
1319 }
1320
del_unassoc_sta(struct mlme_priv * mlmepriv,struct unassoc_sta_info * unassoc_sta)1321 static void del_unassoc_sta(struct mlme_priv *mlmepriv, struct unassoc_sta_info *unassoc_sta)
1322 {
1323 _irqL irqL;
1324 _queue *free_queue = &(mlmepriv->free_unassoc_sta_queue);
1325
1326 if (unassoc_sta->interested)
1327 mlmepriv->interested_unassoc_sta_cnt--;
1328 if (mlmepriv->interested_unassoc_sta_cnt == 0) {
1329 rtw_run_in_thread_cmd(mlme_to_adapter(mlmepriv)
1330 , ((void *)(rtw_hal_rcr_set_chk_bssid_act_non)), mlme_to_adapter(mlmepriv));
1331 }
1332
1333 _enter_critical_bh(&free_queue->lock, &irqL);
1334 rtw_list_delete(&(unassoc_sta->list));
1335 rtw_list_insert_tail(&(unassoc_sta->list), &(free_queue->queue));
1336 _exit_critical_bh(&free_queue->lock, &irqL);
1337 }
1338
del_unassoc_sta_chk(struct mlme_priv * mlmepriv,struct unassoc_sta_info * unassoc_sta)1339 static u8 del_unassoc_sta_chk(struct mlme_priv *mlmepriv, struct unassoc_sta_info *unassoc_sta)
1340 {
1341 systime cur, lifetime;
1342
1343 if (unassoc_sta == NULL)
1344 return UNASOC_STA_DEL_CHK_SKIP;
1345
1346 if (unassoc_sta->interested)
1347 return UNASOC_STA_DEL_CHK_SKIP;
1348
1349 cur = rtw_get_current_time();
1350 lifetime = unassoc_sta->time + rtw_ms_to_systime(UNASSOC_STA_LIFETIME_MS);
1351 if (rtw_time_before(cur, lifetime))
1352 return UNASOC_STA_DEL_CHK_ALIVE;
1353
1354 del_unassoc_sta(mlmepriv, unassoc_sta);
1355
1356 return UNASOC_STA_DEL_CHK_DELETED;
1357 }
1358
alloc_unassoc_sta(struct mlme_priv * mlmepriv)1359 static struct unassoc_sta_info *alloc_unassoc_sta(struct mlme_priv *mlmepriv)
1360 {
1361 _irqL irqL;
1362 struct unassoc_sta_info *unassoc_sta;
1363 _queue *free_queue = &mlmepriv->free_unassoc_sta_queue;
1364 _list *list = NULL;
1365
1366
1367 _enter_critical_bh(&free_queue->lock, &irqL);
1368
1369 if (_rtw_queue_empty(free_queue) == _TRUE) {
1370 unassoc_sta = NULL;
1371 goto exit;
1372 }
1373 list = get_next(&(free_queue->queue));
1374
1375 unassoc_sta = LIST_CONTAINOR(list, struct unassoc_sta_info, list);
1376
1377 rtw_list_delete(&unassoc_sta->list);
1378
1379 _rtw_memset(unassoc_sta->addr, 0, ETH_ALEN);
1380 unassoc_sta->recv_signal_power = 0;
1381 unassoc_sta->time = 0;
1382 unassoc_sta->interested = 0;
1383 exit:
1384 _exit_critical_bh(&free_queue->lock, &irqL);
1385
1386 return unassoc_sta;
1387
1388 }
1389
rtw_del_unassoc_sta_queue(_adapter * adapter)1390 void rtw_del_unassoc_sta_queue(_adapter *adapter)
1391 {
1392 struct unassoc_sta_info *unassoc_sta;
1393 struct mlme_priv *mlmepriv;
1394 _queue *queue;
1395 _irqL irqL;
1396 _list *head, *list;
1397
1398 adapter = GET_PRIMARY_ADAPTER(adapter);
1399 mlmepriv = &(adapter->mlmepriv);
1400 queue = &(mlmepriv->unassoc_sta_queue);
1401
1402 _enter_critical_bh(&queue->lock, &irqL);
1403 head = get_list_head(queue);
1404 list = get_next(head);
1405
1406 while ((rtw_end_of_queue_search(head, list)) == _FALSE) {
1407 unassoc_sta = LIST_CONTAINOR(list , struct unassoc_sta_info, list);
1408 list = get_next(list);
1409
1410 del_unassoc_sta(mlmepriv, unassoc_sta);
1411 }
1412
1413 _exit_critical_bh(&queue->lock, &irqL);
1414
1415 }
1416
rtw_del_unassoc_sta(_adapter * adapter,u8 * addr)1417 void rtw_del_unassoc_sta(_adapter *adapter, u8 *addr)
1418 {
1419 struct unassoc_sta_info *unassoc_sta;
1420 struct mlme_priv *mlmepriv;
1421 _queue *queue;
1422 _irqL irqL;
1423 _list *head, *list;
1424
1425 adapter = GET_PRIMARY_ADAPTER(adapter);
1426 mlmepriv = &(adapter->mlmepriv);
1427 queue = &(mlmepriv->unassoc_sta_queue);
1428
1429 _enter_critical_bh(&queue->lock, &irqL);
1430 head = get_list_head(queue);
1431 list = get_next(head);
1432
1433 while ((rtw_end_of_queue_search(head, list)) == _FALSE) {
1434 unassoc_sta = LIST_CONTAINOR(list , struct unassoc_sta_info, list);
1435 list = get_next(list);
1436
1437 if (_rtw_memcmp(addr, unassoc_sta->addr, ETH_ALEN) == _TRUE) {
1438 del_unassoc_sta(mlmepriv, unassoc_sta);
1439 goto unlock_unassoc_sta_queue;
1440 }
1441 }
1442
1443 unlock_unassoc_sta_queue:
1444 _exit_critical_bh(&queue->lock, &irqL);
1445 }
1446
rtw_rx_add_unassoc_sta(_adapter * adapter,u8 stype,u8 * addr,s8 recv_signal_power)1447 void rtw_rx_add_unassoc_sta(_adapter *adapter, u8 stype, u8 *addr, s8 recv_signal_power)
1448 {
1449 struct unassoc_sta_info *unassoc_sta;
1450 struct unassoc_sta_info *oldest_unassoc_sta = NULL;
1451 struct mlme_priv *mlmepriv;
1452 _queue *queue;
1453 _irqL irqL;
1454 _list *head, *list;
1455
1456 adapter = GET_PRIMARY_ADAPTER(adapter);
1457 mlmepriv = &(adapter->mlmepriv);
1458 queue = &(mlmepriv->unassoc_sta_queue);
1459
1460 _enter_critical_bh(&queue->lock, &irqL);
1461 head = get_list_head(queue);
1462 list = get_next(head);
1463
1464 while ((rtw_end_of_queue_search(head, list)) == _FALSE) {
1465 unassoc_sta = LIST_CONTAINOR(list , struct unassoc_sta_info, list);
1466 list = get_next(list);
1467
1468 if (_rtw_memcmp(addr, unassoc_sta->addr, ETH_ALEN) == _TRUE) {
1469 if (unassoc_sta->interested
1470 || mlmepriv->unassoc_sta_mode_of_stype[stype] >= UNASOC_STA_MODE_ALL
1471 ) {
1472 unassoc_sta->recv_signal_power = recv_signal_power;
1473 unassoc_sta->time = rtw_get_current_time();
1474 goto unlock_unassoc_sta_queue;
1475 }
1476 }
1477
1478 if (del_unassoc_sta_chk(mlmepriv, unassoc_sta) == UNASOC_STA_DEL_CHK_ALIVE) {
1479 if (oldest_unassoc_sta == NULL)
1480 oldest_unassoc_sta = unassoc_sta;
1481 else if (rtw_time_before(unassoc_sta->time, oldest_unassoc_sta->time))
1482 oldest_unassoc_sta = unassoc_sta;
1483 }
1484 }
1485
1486 if (mlmepriv->unassoc_sta_mode_of_stype[stype] <= UNASOC_STA_MODE_INTERESTED)
1487 goto unlock_unassoc_sta_queue;
1488
1489 unassoc_sta = alloc_unassoc_sta(mlmepriv);
1490 if (unassoc_sta == NULL) {
1491 RTW_INFO(FUNC_ADPT_FMT": Allocate fail\n", FUNC_ADPT_ARG(adapter));
1492 if (oldest_unassoc_sta) {
1493 RTW_INFO(FUNC_ADPT_FMT": Delete oldest entry and try again.\n", FUNC_ADPT_ARG(adapter));
1494 del_unassoc_sta(mlmepriv, oldest_unassoc_sta);
1495 unassoc_sta = alloc_unassoc_sta(mlmepriv);
1496 } else
1497 goto unlock_unassoc_sta_queue;
1498 }
1499 _rtw_memcpy(unassoc_sta->addr, addr, ETH_ALEN);
1500 unassoc_sta->recv_signal_power = recv_signal_power;
1501 unassoc_sta->time = rtw_get_current_time();
1502 rtw_list_insert_tail(&(unassoc_sta->list), &(queue->queue));
1503
1504 unlock_unassoc_sta_queue:
1505 _exit_critical_bh(&queue->lock, &irqL);
1506 }
1507
rtw_add_interested_unassoc_sta(_adapter * adapter,u8 * addr)1508 void rtw_add_interested_unassoc_sta(_adapter *adapter, u8 *addr)
1509 {
1510 struct unassoc_sta_info *unassoc_sta;
1511 struct unassoc_sta_info *oldest_unassoc_sta = NULL;
1512 struct mlme_priv *mlmepriv;
1513 _queue *queue;
1514 _irqL irqL;
1515 _list *head, *list;
1516
1517 adapter = GET_PRIMARY_ADAPTER(adapter);
1518 mlmepriv = &(adapter->mlmepriv);
1519 queue = &(mlmepriv->unassoc_sta_queue);
1520
1521 _enter_critical_bh(&queue->lock, &irqL);
1522 head = get_list_head(queue);
1523 list = get_next(head);
1524
1525 while ((rtw_end_of_queue_search(head, list)) == _FALSE) {
1526 unassoc_sta = LIST_CONTAINOR(list , struct unassoc_sta_info, list);
1527 list = get_next(list);
1528
1529 if (_rtw_memcmp(addr, unassoc_sta->addr, ETH_ALEN) == _TRUE) {
1530 if (!unassoc_sta->interested) {
1531 unassoc_sta->interested = 1;
1532 mlmepriv->interested_unassoc_sta_cnt++;
1533 if (mlmepriv->interested_unassoc_sta_cnt == 1) {
1534 rtw_run_in_thread_cmd(mlme_to_adapter(mlmepriv)
1535 , ((void *)(rtw_hal_rcr_set_chk_bssid_act_non)), mlme_to_adapter(mlmepriv));
1536 }
1537 }
1538 goto unlock_unassoc_sta_queue;
1539 }
1540
1541 if (del_unassoc_sta_chk(mlmepriv, unassoc_sta) == UNASOC_STA_DEL_CHK_ALIVE) {
1542 if (oldest_unassoc_sta == NULL)
1543 oldest_unassoc_sta = unassoc_sta;
1544 else if (rtw_time_after(unassoc_sta->time, oldest_unassoc_sta->time))
1545 oldest_unassoc_sta = unassoc_sta;
1546 }
1547 }
1548 unassoc_sta = alloc_unassoc_sta(mlmepriv);
1549 if (unassoc_sta == NULL) {
1550 RTW_INFO(FUNC_ADPT_FMT": Allocate fail\n", FUNC_ADPT_ARG(adapter));
1551 if (oldest_unassoc_sta) {
1552 RTW_INFO(FUNC_ADPT_FMT": Delete oldest entry and try again.\n", FUNC_ADPT_ARG(adapter));
1553 del_unassoc_sta(mlmepriv, oldest_unassoc_sta);
1554 unassoc_sta = alloc_unassoc_sta(mlmepriv);
1555 } else
1556 goto unlock_unassoc_sta_queue;
1557 }
1558 _rtw_memcpy(unassoc_sta->addr, addr, ETH_ALEN);
1559 unassoc_sta->interested = 1;
1560 unassoc_sta->recv_signal_power = 0;
1561 unassoc_sta->time = rtw_get_current_time() - rtw_ms_to_systime(UNASSOC_STA_LIFETIME_MS);
1562 rtw_list_insert_tail(&(unassoc_sta->list), &(queue->queue));
1563 mlmepriv->interested_unassoc_sta_cnt++;
1564 if (mlmepriv->interested_unassoc_sta_cnt == 1) {
1565 rtw_run_in_thread_cmd(mlme_to_adapter(mlmepriv)
1566 , ((void *)(rtw_hal_rcr_set_chk_bssid_act_non)), mlme_to_adapter(mlmepriv));
1567 }
1568
1569 unlock_unassoc_sta_queue:
1570 _exit_critical_bh(&queue->lock, &irqL);
1571 }
1572
rtw_undo_interested_unassoc_sta(_adapter * adapter,u8 * addr)1573 void rtw_undo_interested_unassoc_sta(_adapter *adapter, u8 *addr)
1574 {
1575 struct unassoc_sta_info *unassoc_sta;
1576 struct mlme_priv *mlmepriv;
1577 _queue *queue;
1578 _irqL irqL;
1579 _list *head, *list;
1580
1581 adapter = GET_PRIMARY_ADAPTER(adapter);
1582 mlmepriv = &(adapter->mlmepriv);
1583 queue = &(mlmepriv->unassoc_sta_queue);
1584
1585 _enter_critical_bh(&queue->lock, &irqL);
1586 head = get_list_head(queue);
1587 list = get_next(head);
1588
1589 while ((rtw_end_of_queue_search(head, list)) == _FALSE) {
1590 unassoc_sta = LIST_CONTAINOR(list , struct unassoc_sta_info, list);
1591 list = get_next(list);
1592
1593 if (_rtw_memcmp(addr, unassoc_sta->addr, ETH_ALEN) == _TRUE) {
1594 if (unassoc_sta->interested) {
1595 unassoc_sta->interested = 0;
1596 mlmepriv->interested_unassoc_sta_cnt--;
1597 if (mlmepriv->interested_unassoc_sta_cnt == 0) {
1598 rtw_run_in_thread_cmd(mlme_to_adapter(mlmepriv)
1599 , ((void *)(rtw_hal_rcr_set_chk_bssid_act_non)), mlme_to_adapter(mlmepriv));
1600 }
1601 }
1602 goto unlock_unassoc_sta_queue;
1603 }
1604 }
1605 unlock_unassoc_sta_queue:
1606 _exit_critical_bh(&queue->lock, &irqL);
1607 }
1608
rtw_undo_all_interested_unassoc_sta(_adapter * adapter)1609 void rtw_undo_all_interested_unassoc_sta(_adapter *adapter)
1610 {
1611 struct unassoc_sta_info *unassoc_sta;
1612 struct mlme_priv *mlmepriv;
1613 _queue *queue;
1614 _irqL irqL;
1615 _list *head, *list;
1616
1617 adapter = GET_PRIMARY_ADAPTER(adapter);
1618 mlmepriv = &(adapter->mlmepriv);
1619 queue = &(mlmepriv->unassoc_sta_queue);
1620
1621 _enter_critical_bh(&queue->lock, &irqL);
1622 head = get_list_head(queue);
1623 list = get_next(head);
1624
1625 while ((rtw_end_of_queue_search(head, list)) == _FALSE) {
1626 unassoc_sta = LIST_CONTAINOR(list , struct unassoc_sta_info, list);
1627 list = get_next(list);
1628
1629 if (unassoc_sta->interested) {
1630 unassoc_sta->interested = 0;
1631 mlmepriv->interested_unassoc_sta_cnt--;
1632 if (mlmepriv->interested_unassoc_sta_cnt == 0) {
1633 rtw_run_in_thread_cmd(mlme_to_adapter(mlmepriv)
1634 , ((void *)(rtw_hal_rcr_set_chk_bssid_act_non)), mlme_to_adapter(mlmepriv));
1635 goto unlock_unassoc_sta_queue;
1636 }
1637 }
1638 }
1639 unlock_unassoc_sta_queue:
1640 _exit_critical_bh(&queue->lock, &irqL);
1641 }
1642
1643
1644 #endif /* CONFIG_RTW_MULTI_AP */
1645
1646 /* select the desired network based on the capability of the (i)bss.
1647 * check items: (1) security
1648 * (2) network_type
1649 * (3) WMM
1650 * (4) HT
1651 * (5) others */
1652 int rtw_is_desired_network(_adapter *adapter, struct wlan_network *pnetwork);
rtw_is_desired_network(_adapter * adapter,struct wlan_network * pnetwork)1653 int rtw_is_desired_network(_adapter *adapter, struct wlan_network *pnetwork)
1654 {
1655 struct security_priv *psecuritypriv = &adapter->securitypriv;
1656 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1657 u32 desired_encmode;
1658 u32 privacy;
1659
1660 /* u8 wps_ie[512]; */
1661 uint wps_ielen;
1662
1663 int bselected = _TRUE;
1664
1665 desired_encmode = psecuritypriv->ndisencryptstatus;
1666 privacy = pnetwork->network.Privacy;
1667
1668 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
1669 if (rtw_get_wps_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_, pnetwork->network.IELength - _FIXED_IE_LENGTH_, NULL, &wps_ielen) != NULL)
1670 return _TRUE;
1671 else
1672 return _FALSE;
1673 }
1674 if (adapter->registrypriv.wifi_spec == 1) { /* for correct flow of 8021X to do.... */
1675 u8 *p = NULL;
1676 uint ie_len = 0;
1677
1678 if ((desired_encmode == Ndis802_11EncryptionDisabled) && (privacy != 0))
1679 bselected = _FALSE;
1680
1681 if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
1682 p = rtw_get_ie(pnetwork->network.IEs + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pnetwork->network.IELength - _BEACON_IE_OFFSET_));
1683 if (p && ie_len > 0)
1684 bselected = _TRUE;
1685 else
1686 bselected = _FALSE;
1687 }
1688 }
1689
1690
1691 if ((desired_encmode != Ndis802_11EncryptionDisabled) && (privacy == 0)) {
1692 RTW_INFO("desired_encmode: %d, privacy: %d\n", desired_encmode, privacy);
1693 bselected = _FALSE;
1694 }
1695
1696 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {
1697 if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
1698 bselected = _FALSE;
1699 }
1700
1701 #ifdef CONFIG_RTW_MBO
1702 if (rtw_mbo_disallowed_network(pnetwork) == _TRUE)
1703 bselected = _FALSE;
1704 #endif
1705
1706 return bselected;
1707 }
1708
1709 #ifdef CONFIG_80211D
process_80211d(PADAPTER padapter,WLAN_BSSID_EX * bssid)1710 static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid)
1711 {
1712 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
1713 struct registry_priv *pregistrypriv;
1714 struct mlme_ext_priv *pmlmeext;
1715 RT_CHANNEL_INFO *chplan_new;
1716 u8 channel;
1717 u8 i;
1718
1719
1720 pregistrypriv = &padapter->registrypriv;
1721 pmlmeext = &padapter->mlmeextpriv;
1722
1723 /* Adjust channel plan by AP Country IE */
1724 if (pregistrypriv->enable80211d
1725 && (!pmlmeext->update_channel_plan_by_ap_done)) {
1726 u8 *ie, *p;
1727 u32 len;
1728 RT_CHANNEL_PLAN chplan_ap;
1729 RT_CHANNEL_INFO *chplan_sta = NULL;
1730 u8 country[4];
1731 u8 fcn; /* first channel number */
1732 u8 noc; /* number of channel */
1733 u8 j, k;
1734
1735 ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
1736 if (!ie)
1737 return;
1738 if (len < 6)
1739 return;
1740
1741 ie += 2;
1742 p = ie;
1743 ie += len;
1744
1745 _rtw_memset(country, 0, 4);
1746 _rtw_memcpy(country, p, 3);
1747 p += 3;
1748 RTW_INFO("%s: 802.11d country=%s\n", __FUNCTION__, country);
1749
1750 i = 0;
1751 while ((ie - p) >= 3) {
1752 fcn = *(p++);
1753 noc = *(p++);
1754 p++;
1755
1756 for (j = 0; j < noc; j++) {
1757 if (fcn <= 14)
1758 channel = fcn + j; /* 2.4 GHz */
1759 else
1760 channel = fcn + j * 4; /* 5 GHz */
1761
1762 chplan_ap.Channel[i++] = channel;
1763 }
1764 }
1765 chplan_ap.Len = i;
1766
1767 #ifdef CONFIG_RTW_DEBUG
1768 i = 0;
1769 RTW_INFO("%s: AP[%s] channel plan {", __FUNCTION__, bssid->Ssid.Ssid);
1770 while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0)) {
1771 _RTW_INFO("%02d,", chplan_ap.Channel[i]);
1772 i++;
1773 }
1774 _RTW_INFO("}\n");
1775 #endif
1776
1777 chplan_sta = rtw_malloc(sizeof(RT_CHANNEL_INFO) * MAX_CHANNEL_NUM);
1778 if (!chplan_sta)
1779 goto done_update_chplan_from_ap;
1780
1781 _rtw_memcpy(chplan_sta, rfctl->channel_set, sizeof(RT_CHANNEL_INFO) * MAX_CHANNEL_NUM);
1782 #ifdef CONFIG_RTW_DEBUG
1783 i = 0;
1784 RTW_INFO("%s: STA channel plan {", __FUNCTION__);
1785 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
1786 _RTW_INFO("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType == SCAN_PASSIVE ? 'p' : 'a');
1787 i++;
1788 }
1789 _RTW_INFO("}\n");
1790 #endif
1791
1792 _rtw_memset(rfctl->channel_set, 0, sizeof(rfctl->channel_set));
1793 chplan_new = rfctl->channel_set;
1794
1795 i = j = k = 0;
1796 if (pregistrypriv->wireless_mode & WIRELESS_11G) {
1797 do {
1798 if ((i == MAX_CHANNEL_NUM)
1799 || (chplan_sta[i].ChannelNum == 0)
1800 || (chplan_sta[i].ChannelNum > 14))
1801 break;
1802
1803 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14))
1804 break;
1805
1806 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) {
1807 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
1808 chplan_new[k].ScanType = SCAN_ACTIVE;
1809 i++;
1810 j++;
1811 k++;
1812 } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) {
1813 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
1814 #if 0
1815 chplan_new[k].ScanType = chplan_sta[i].ScanType;
1816 #else
1817 chplan_new[k].ScanType = SCAN_PASSIVE;
1818 #endif
1819 i++;
1820 k++;
1821 } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) {
1822 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
1823 chplan_new[k].ScanType = SCAN_ACTIVE;
1824 j++;
1825 k++;
1826 }
1827 } while (1);
1828
1829 /* change AP not support channel to Passive scan */
1830 while ((i < MAX_CHANNEL_NUM)
1831 && (chplan_sta[i].ChannelNum != 0)
1832 && (chplan_sta[i].ChannelNum <= 14)) {
1833 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
1834 #if 0
1835 chplan_new[k].ScanType = chplan_sta[i].ScanType;
1836 #else
1837 chplan_new[k].ScanType = SCAN_PASSIVE;
1838 #endif
1839 i++;
1840 k++;
1841 }
1842
1843 /* add channel AP supported */
1844 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) {
1845 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
1846 chplan_new[k].ScanType = SCAN_ACTIVE;
1847 j++;
1848 k++;
1849 }
1850 } else {
1851 /* keep original STA 2.4G channel plan */
1852 while ((i < MAX_CHANNEL_NUM)
1853 && (chplan_sta[i].ChannelNum != 0)
1854 && (chplan_sta[i].ChannelNum <= 14)) {
1855 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
1856 chplan_new[k].ScanType = chplan_sta[i].ScanType;
1857 i++;
1858 k++;
1859 }
1860
1861 /* skip AP 2.4G channel plan */
1862 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
1863 j++;
1864 }
1865
1866 if (pregistrypriv->wireless_mode & WIRELESS_11A) {
1867 do {
1868 if ((i >= MAX_CHANNEL_NUM)
1869 || (chplan_sta[i].ChannelNum == 0))
1870 break;
1871
1872 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0))
1873 break;
1874
1875 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) {
1876 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
1877 chplan_new[k].ScanType = SCAN_ACTIVE;
1878 i++;
1879 j++;
1880 k++;
1881 } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) {
1882 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
1883 #if 0
1884 chplan_new[k].ScanType = chplan_sta[i].ScanType;
1885 #else
1886 chplan_new[k].ScanType = SCAN_PASSIVE;
1887 #endif
1888 i++;
1889 k++;
1890 } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) {
1891 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
1892 chplan_new[k].ScanType = SCAN_ACTIVE;
1893 j++;
1894 k++;
1895 }
1896 } while (1);
1897
1898 /* change AP not support channel to Passive scan */
1899 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
1900 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
1901 #if 0
1902 chplan_new[k].ScanType = chplan_sta[i].ScanType;
1903 #else
1904 chplan_new[k].ScanType = SCAN_PASSIVE;
1905 #endif
1906 i++;
1907 k++;
1908 }
1909
1910 /* add channel AP supported */
1911 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0)) {
1912 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
1913 chplan_new[k].ScanType = SCAN_ACTIVE;
1914 j++;
1915 k++;
1916 }
1917 } else {
1918 /* keep original STA 5G channel plan */
1919 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
1920 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
1921 chplan_new[k].ScanType = chplan_sta[i].ScanType;
1922 i++;
1923 k++;
1924 }
1925 }
1926
1927 pmlmeext->update_channel_plan_by_ap_done = 1;
1928
1929 #ifdef CONFIG_RTW_DEBUG
1930 k = 0;
1931 RTW_INFO("%s: new STA channel plan {", __FUNCTION__);
1932 while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0)) {
1933 _RTW_INFO("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType == SCAN_PASSIVE ? 'p' : 'c');
1934 k++;
1935 }
1936 _RTW_INFO("}\n");
1937 #endif
1938
1939 #if 0
1940 /* recover the right channel index */
1941 channel = chplan_sta[pmlmeext->sitesurvey_res.channel_idx].ChannelNum;
1942 k = 0;
1943 while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0)) {
1944 if (chplan_new[k].ChannelNum == channel) {
1945 RTW_INFO("%s: change mlme_ext sitesurvey channel index from %d to %d\n",
1946 __FUNCTION__, pmlmeext->sitesurvey_res.channel_idx, k);
1947 pmlmeext->sitesurvey_res.channel_idx = k;
1948 break;
1949 }
1950 k++;
1951 }
1952 #endif
1953
1954 done_update_chplan_from_ap:
1955 if (chplan_sta)
1956 rtw_mfree(chplan_sta, sizeof(RT_CHANNEL_INFO) * MAX_CHANNEL_NUM);
1957 }
1958 }
1959 #endif
1960
rtw_survey_event_callback(_adapter * adapter,u8 * pbuf)1961 void rtw_survey_event_callback(_adapter *adapter, u8 *pbuf)
1962 {
1963 _irqL irqL;
1964 u32 len;
1965 u8 val8;
1966 WLAN_BSSID_EX *pnetwork;
1967 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
1968
1969 pnetwork = (WLAN_BSSID_EX *)pbuf;
1970
1971 len = get_WLAN_BSSID_EX_sz(pnetwork);
1972 if (len > (sizeof(WLAN_BSSID_EX))) {
1973 return;
1974 }
1975
1976 #ifdef CONFIG_RTW_80211K
1977 val8 = 0;
1978 rtw_hal_get_hwreg(adapter, HW_VAR_FREECNT, &val8);
1979
1980 /* use TSF if no free run counter */
1981 if (val8==0)
1982 pnetwork->PhyInfo.free_cnt = (u32)rtw_hal_get_tsftr_by_port(
1983 adapter, rtw_hal_get_port(adapter));
1984 #endif
1985
1986 if (pnetwork->InfrastructureMode == Ndis802_11Infrastructure) {
1987 #ifdef CONFIG_80211D
1988 process_80211d(adapter, pnetwork);
1989 #endif
1990 rtw_process_beacon_hint(adapter, pnetwork);
1991 }
1992
1993 _enter_critical_bh(&pmlmepriv->lock, &irqL);
1994
1995 /* update IBSS_network 's timestamp */
1996 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == _TRUE) {
1997 if (_rtw_memcmp(&(pmlmepriv->cur_network.network.MacAddress), pnetwork->MacAddress, ETH_ALEN)) {
1998 struct wlan_network *ibss_wlan = NULL;
1999 _irqL irqL;
2000
2001 _rtw_memcpy(pmlmepriv->cur_network.network.IEs, pnetwork->IEs, 8);
2002 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2003 ibss_wlan = _rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->MacAddress);
2004 if (ibss_wlan) {
2005 _rtw_memcpy(ibss_wlan->network.IEs , pnetwork->IEs, 8);
2006 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2007 goto exit;
2008 }
2009 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2010 }
2011 }
2012
2013 /* lock pmlmepriv->lock when you accessing network_q */
2014 if ((check_fwstate(pmlmepriv, WIFI_UNDER_LINKING)) == _FALSE) {
2015 if (pnetwork->Ssid.Ssid[0] == 0)
2016 pnetwork->Ssid.SsidLength = 0;
2017 rtw_add_network(adapter, pnetwork);
2018 }
2019
2020 exit:
2021
2022 _exit_critical_bh(&pmlmepriv->lock, &irqL);
2023
2024
2025 return;
2026 }
2027
rtw_surveydone_event_callback(_adapter * adapter,u8 * pbuf)2028 void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf)
2029 {
2030 _irqL irqL;
2031 struct surveydone_event *parm = (struct surveydone_event *)pbuf;
2032 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
2033 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
2034
2035 #ifdef CONFIG_MLME_EXT
2036 mlmeext_surveydone_event_callback(adapter);
2037 #endif
2038
2039
2040 _enter_critical_bh(&pmlmepriv->lock, &irqL);
2041 if (pmlmepriv->wps_probe_req_ie) {
2042 u32 free_len = pmlmepriv->wps_probe_req_ie_len;
2043 pmlmepriv->wps_probe_req_ie_len = 0;
2044 rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
2045 pmlmepriv->wps_probe_req_ie = NULL;
2046 }
2047
2048
2049 if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _FALSE) {
2050 RTW_INFO(FUNC_ADPT_FMT" fw_state:0x%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv));
2051 /* rtw_warn_on(1); */
2052 }
2053
2054 if (pmlmeext->scan_abort == _TRUE)
2055 pmlmeext->scan_abort = _FALSE;
2056
2057 _clr_fwstate_(pmlmepriv, WIFI_UNDER_SURVEY);
2058 _exit_critical_bh(&pmlmepriv->lock, &irqL);
2059
2060 _cancel_timer_ex(&pmlmepriv->scan_to_timer);
2061
2062 _enter_critical_bh(&pmlmepriv->lock, &irqL);
2063
2064 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
2065 rtw_set_signal_stat_timer(&adapter->recvpriv);
2066 #endif
2067
2068 if (pmlmepriv->to_join == _TRUE) {
2069 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)) {
2070 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _FALSE) {
2071 set_fwstate(pmlmepriv, WIFI_UNDER_LINKING);
2072
2073 if (rtw_select_and_join_from_scanned_queue(pmlmepriv) == _SUCCESS)
2074 _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
2075 #ifdef CONFIG_AP_MODE
2076 else {
2077 WLAN_BSSID_EX *pdev_network = &(adapter->registrypriv.dev_network);
2078 u8 *pibss = adapter->registrypriv.dev_network.MacAddress;
2079
2080 /* pmlmepriv->fw_state ^= WIFI_UNDER_SURVEY; */ /* because don't set assoc_timer */
2081 _clr_fwstate_(pmlmepriv, WIFI_UNDER_SURVEY);
2082
2083
2084 _rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
2085 _rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
2086
2087 rtw_update_registrypriv_dev_network(adapter);
2088 rtw_generate_random_ibss(pibss);
2089
2090 /*pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;*/
2091 init_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
2092
2093 if (rtw_create_ibss_cmd(adapter, 0) != _SUCCESS)
2094 RTW_ERR("rtw_create_ibss_cmd FAIL\n");
2095
2096 pmlmepriv->to_join = _FALSE;
2097 }
2098 #endif /* CONFIG_AP_MODE */
2099 }
2100 } else {
2101 int s_ret;
2102 set_fwstate(pmlmepriv, WIFI_UNDER_LINKING);
2103 pmlmepriv->to_join = _FALSE;
2104 s_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);
2105 if (_SUCCESS == s_ret)
2106 _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
2107 else if (s_ret == 2) { /* there is no need to wait for join */
2108 _clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING);
2109 rtw_indicate_connect(adapter);
2110 } else {
2111 RTW_INFO("try_to_join, but select scanning queue fail, to_roam:%d\n", rtw_to_roam(adapter));
2112
2113 if (rtw_to_roam(adapter) != 0) {
2114 struct sitesurvey_parm scan_parm;
2115 u8 ssc_chk = rtw_sitesurvey_condition_check(adapter, _FALSE);
2116
2117 rtw_init_sitesurvey_parm(adapter, &scan_parm);
2118 _rtw_memcpy(&scan_parm.ssid[0], &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
2119 scan_parm.ssid_num = 1;
2120
2121 if (rtw_dec_to_roam(adapter) == 0
2122 || (ssc_chk != SS_ALLOW && ssc_chk != SS_DENY_BUSY_TRAFFIC)
2123 || _SUCCESS != rtw_sitesurvey_cmd(adapter, &scan_parm)
2124 ) {
2125 rtw_set_to_roam(adapter, 0);
2126 rtw_free_assoc_resources(adapter, _TRUE);
2127 rtw_indicate_disconnect(adapter, 0, _FALSE);
2128 } else
2129 pmlmepriv->to_join = _TRUE;
2130 } else
2131 rtw_indicate_disconnect(adapter, 0, _FALSE);
2132 _clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING);
2133 }
2134 }
2135 } else {
2136 if (rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)
2137 #if (defined(CONFIG_RTW_WNM) && defined(CONFIG_RTW_80211R))
2138 || rtw_wnm_btm_roam_triggered(adapter)
2139 #endif
2140 ) {
2141 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)
2142 && check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
2143 if (rtw_select_roaming_candidate(pmlmepriv) == _SUCCESS) {
2144 #ifdef CONFIG_RTW_80211R
2145 rtw_ft_start_roam(adapter,
2146 (u8 *)pmlmepriv->roam_network->network.MacAddress);
2147 #else
2148 receive_disconnect(adapter, pmlmepriv->cur_network.network.MacAddress
2149 , WLAN_REASON_ACTIVE_ROAM, _FALSE);
2150 #endif
2151 }
2152 }
2153 }
2154 }
2155
2156 /* RTW_INFO("scan complete in %dms\n",rtw_get_passing_time_ms(pmlmepriv->scan_start_time)); */
2157
2158 _exit_critical_bh(&pmlmepriv->lock, &irqL);
2159
2160 #ifdef CONFIG_P2P_PS
2161 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE)
2162 p2p_ps_wk_cmd(adapter, P2P_PS_SCAN_DONE, 0);
2163 #endif /* CONFIG_P2P_PS */
2164
2165 rtw_mi_os_xmit_schedule(adapter);
2166
2167 #ifdef CONFIG_DRVEXT_MODULE_WSC
2168 drvext_surveydone_callback(&adapter->drvextpriv);
2169 #endif
2170
2171 #ifdef DBG_CONFIG_ERROR_DETECT
2172 {
2173 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
2174 if (pmlmeext->sitesurvey_res.bss_cnt == 0) {
2175 /* rtw_hal_sreset_reset(adapter); */
2176 }
2177 }
2178 #endif
2179
2180 #ifdef CONFIG_IOCTL_CFG80211
2181 rtw_cfg80211_surveydone_event_callback(adapter);
2182 #endif /* CONFIG_IOCTL_CFG80211 */
2183
2184 rtw_indicate_scan_done(adapter, _FALSE);
2185
2186 #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_IOCTL_CFG80211)
2187 rtw_cfg80211_indicate_scan_done_for_buddy(adapter, _FALSE);
2188 #endif
2189
2190 #ifdef CONFIG_RTW_MESH
2191 #if CONFIG_RTW_MESH_OFFCH_CAND
2192 if (rtw_mesh_offch_candidate_accepted(adapter)) {
2193 u8 ch;
2194
2195 ch = rtw_mesh_select_operating_ch(adapter);
2196 if (ch && pmlmepriv->cur_network.network.Configuration.DSConfig != ch) {
2197 u8 ifbmp = rtw_mi_get_ap_mesh_ifbmp(adapter);
2198
2199 if (ifbmp) {
2200 /* switch to selected channel */
2201 rtw_change_bss_chbw_cmd(adapter, RTW_CMDF_DIRECTLY, ifbmp, 0, ch, REQ_BW_ORI, REQ_OFFSET_NONE);
2202 issue_probereq_ex(adapter, &pmlmepriv->cur_network.network.mesh_id, NULL, 0, 0, 0, 0);
2203 } else
2204 rtw_warn_on(1);
2205 }
2206 }
2207 #endif
2208 #endif /* CONFIG_RTW_MESH */
2209
2210 #ifdef CONFIG_RTW_ACS
2211 if (parm->acs) {
2212 u8 ifbmp = rtw_mi_get_ap_mesh_ifbmp(adapter);
2213
2214 if (ifbmp)
2215 rtw_change_bss_chbw_cmd(adapter, RTW_CMDF_DIRECTLY, ifbmp, 0, REQ_CH_INT_INFO, REQ_BW_ORI, REQ_OFFSET_NONE);
2216 }
2217 #endif
2218 }
2219
_rtw_sitesurvey_condition_check(const char * caller,_adapter * adapter,bool check_sc_interval)2220 u8 _rtw_sitesurvey_condition_check(const char *caller, _adapter *adapter, bool check_sc_interval)
2221 {
2222 u8 ss_condition = SS_ALLOW;
2223 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
2224 struct registry_priv *registry_par = &adapter->registrypriv;
2225
2226
2227 #ifdef CONFIG_MP_INCLUDED
2228 if (rtw_mp_mode_check(adapter)) {
2229 RTW_INFO("%s ("ADPT_FMT") MP mode block Scan request\n", caller, ADPT_ARG(adapter));
2230 ss_condition = SS_DENY_MP_MODE;
2231 goto _exit;
2232 }
2233 #endif
2234
2235 #ifdef DBG_LA_MODE
2236 if(registry_par->la_mode_en == 1 && MLME_IS_ASOC(adapter)) {
2237 RTW_INFO("%s ("ADPT_FMT") LA debug mode block Scan request\n", caller, ADPT_ARG(adapter));
2238 ss_condition = SS_DENY_LA_MODE;
2239 goto _exit;
2240 }
2241 #endif
2242
2243 #ifdef CONFIG_RTW_REPEATER_SON
2244 if (adapter->rtw_rson_scanstage == RSON_SCAN_PROCESS) {
2245 RTW_INFO("%s ("ADPT_FMT") blocking scan for under rson scanning process\n", caller, ADPT_ARG(adapter));
2246 ss_condition = SS_DENY_RSON_SCANING;
2247 goto _exit;
2248 }
2249 #endif
2250 #ifdef CONFIG_IOCTL_CFG80211
2251 if (adapter_wdev_data(adapter)->block_scan == _TRUE) {
2252 RTW_INFO("%s ("ADPT_FMT") wdev_priv.block_scan is set\n", caller, ADPT_ARG(adapter));
2253 ss_condition = SS_DENY_BLOCK_SCAN;
2254 goto _exit;
2255 }
2256 #endif
2257
2258 if (adapter_to_dvobj(adapter)->scan_deny == _TRUE) {
2259 RTW_INFO("%s ("ADPT_FMT") tpt mode, scan deny!\n", caller, ADPT_ARG(adapter));
2260 ss_condition = SS_DENY_BLOCK_SCAN;
2261 goto _exit;
2262 }
2263
2264 if (rtw_is_scan_deny(adapter)) {
2265 RTW_INFO("%s ("ADPT_FMT") : scan deny\n", caller, ADPT_ARG(adapter));
2266 ss_condition = SS_DENY_BY_DRV;
2267 goto _exit;
2268 }
2269
2270 #ifdef CONFIG_ADAPTIVITY_DENY_SCAN
2271 if (registry_par->adaptivity_en
2272 && rtw_phydm_get_edcca_flag(adapter)
2273 && rtw_is_2g_ch(GET_HAL_DATA(adapter)->current_channel)) {
2274 RTW_WARN(FUNC_ADPT_FMT": Adaptivity block scan! (ch=%u)\n",
2275 FUNC_ADPT_ARG(adapter),
2276 GET_HAL_DATA(adapter)->current_channel);
2277 ss_condition = SS_DENY_ADAPTIVITY;
2278 goto _exit;
2279 }
2280 #endif /* CONFIG_ADAPTIVITY_DENY_SCAN */
2281
2282 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)){
2283 if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
2284 RTW_INFO("%s ("ADPT_FMT") : scan abort!! AP mode process WPS\n", caller, ADPT_ARG(adapter));
2285 ss_condition = SS_DENY_SELF_AP_UNDER_WPS;
2286 goto _exit;
2287 } else if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING) == _TRUE) {
2288 RTW_INFO("%s ("ADPT_FMT") : scan abort!!AP mode under linking (fwstate=0x%x)\n",
2289 caller, ADPT_ARG(adapter), pmlmepriv->fw_state);
2290 ss_condition = SS_DENY_SELF_AP_UNDER_LINKING;
2291 goto _exit;
2292 } else if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE) {
2293 RTW_INFO("%s ("ADPT_FMT") : scan abort!!AP mode under survey (fwstate=0x%x)\n",
2294 caller, ADPT_ARG(adapter), pmlmepriv->fw_state);
2295 ss_condition = SS_DENY_SELF_AP_UNDER_SURVEY;
2296 goto _exit;
2297 }
2298 } else {
2299 if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING) == _TRUE) {
2300 RTW_INFO("%s ("ADPT_FMT") : scan abort!!STA mode under linking (fwstate=0x%x)\n",
2301 caller, ADPT_ARG(adapter), pmlmepriv->fw_state);
2302 ss_condition = SS_DENY_SELF_STA_UNDER_LINKING;
2303 goto _exit;
2304 } else if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY) == _TRUE) {
2305 RTW_INFO("%s ("ADPT_FMT") : scan abort!!STA mode under survey (fwstate=0x%x)\n",
2306 caller, ADPT_ARG(adapter), pmlmepriv->fw_state);
2307 ss_condition = SS_DENY_SELF_STA_UNDER_SURVEY;
2308 goto _exit;
2309 }
2310 }
2311
2312 #ifdef CONFIG_CONCURRENT_MODE
2313 if (rtw_mi_buddy_check_fwstate(adapter, WIFI_UNDER_LINKING | WIFI_UNDER_WPS)) {
2314 RTW_INFO("%s ("ADPT_FMT") : scan abort!! buddy_intf under linking or wps\n", caller, ADPT_ARG(adapter));
2315 ss_condition = SS_DENY_BUDDY_UNDER_LINK_WPS;
2316 goto _exit;
2317
2318 } else if (rtw_mi_buddy_check_fwstate(adapter, WIFI_UNDER_SURVEY)) {
2319 RTW_INFO("%s ("ADPT_FMT") : scan abort!! buddy_intf under survey\n", caller, ADPT_ARG(adapter));
2320 ss_condition = SS_DENY_BUDDY_UNDER_SURVEY;
2321 goto _exit;
2322 }
2323 #endif /* CONFIG_CONCURRENT_MODE */
2324
2325 #ifdef RTW_BUSY_DENY_SCAN
2326 /*
2327 * busy traffic check
2328 * Rules:
2329 * 1. If (scan interval <= BUSY_TRAFFIC_SCAN_DENY_PERIOD) always allow
2330 * scan, otherwise goto rule 2.
2331 * 2. Deny scan if any interface is busy, otherwise allow scan.
2332 */
2333 if (pmlmepriv->lastscantime
2334 && (rtw_get_passing_time_ms(pmlmepriv->lastscantime) >
2335 registry_par->scan_interval_thr)
2336 && rtw_mi_busy_traffic_check(adapter)) {
2337 RTW_WARN("%s ("ADPT_FMT") : scan abort!! BusyTraffic\n",
2338 caller, ADPT_ARG(adapter));
2339 ss_condition = SS_DENY_BUSY_TRAFFIC;
2340 goto _exit;
2341 }
2342 #endif /* RTW_BUSY_DENY_SCAN */
2343
2344 _exit:
2345 return ss_condition;
2346 }
2347
free_scanqueue(struct mlme_priv * pmlmepriv)2348 static void free_scanqueue(struct mlme_priv *pmlmepriv)
2349 {
2350 _irqL irqL, irqL0;
2351 _queue *free_queue = &pmlmepriv->free_bss_pool;
2352 _queue *scan_queue = &pmlmepriv->scanned_queue;
2353 _list *plist, *phead, *ptemp;
2354
2355
2356 _enter_critical_bh(&scan_queue->lock, &irqL0);
2357 _enter_critical_bh(&free_queue->lock, &irqL);
2358
2359 phead = get_list_head(scan_queue);
2360 plist = get_next(phead);
2361
2362 while (plist != phead) {
2363 ptemp = get_next(plist);
2364 rtw_list_delete(plist);
2365 rtw_list_insert_tail(plist, &free_queue->queue);
2366 plist = ptemp;
2367 pmlmepriv->num_of_scanned--;
2368 }
2369
2370 _exit_critical_bh(&free_queue->lock, &irqL);
2371 _exit_critical_bh(&scan_queue->lock, &irqL0);
2372
2373 }
2374
rtw_reset_rx_info(_adapter * adapter)2375 void rtw_reset_rx_info(_adapter *adapter)
2376 {
2377 struct recv_priv *precvpriv = &adapter->recvpriv;
2378
2379 precvpriv->dbg_rx_ampdu_drop_count = 0;
2380 precvpriv->dbg_rx_ampdu_forced_indicate_count = 0;
2381 precvpriv->dbg_rx_ampdu_loss_count = 0;
2382 precvpriv->dbg_rx_dup_mgt_frame_drop_count = 0;
2383 precvpriv->dbg_rx_ampdu_window_shift_cnt = 0;
2384 precvpriv->dbg_rx_drop_count = 0;
2385 precvpriv->dbg_rx_conflic_mac_addr_cnt = 0;
2386 }
2387
2388 /*
2389 *rtw_free_assoc_resources: the caller has to lock pmlmepriv->lock
2390 */
rtw_free_assoc_resources(_adapter * adapter,u8 lock_scanned_queue)2391 void rtw_free_assoc_resources(_adapter *adapter, u8 lock_scanned_queue)
2392 {
2393 _irqL irqL;
2394 struct wlan_network *pwlan = NULL;
2395 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
2396 struct wlan_network *tgt_network = &pmlmepriv->cur_network;
2397
2398
2399 #ifdef CONFIG_TDLS
2400 struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
2401 #endif /* CONFIG_TDLS */
2402
2403
2404 RTW_INFO("%s-"ADPT_FMT" tgt_network MacAddress=" MAC_FMT" ssid=%s\n",
2405 __func__, ADPT_ARG(adapter), MAC_ARG(tgt_network->network.MacAddress), tgt_network->network.Ssid.Ssid);
2406
2407 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
2408 struct sta_info *psta;
2409
2410 psta = rtw_get_stainfo(&adapter->stapriv, tgt_network->network.MacAddress);
2411
2412 #ifdef CONFIG_TDLS
2413 rtw_free_all_tdls_sta(adapter, _TRUE);
2414 rtw_reset_tdls_info(adapter);
2415
2416 if (ptdlsinfo->link_established == _TRUE)
2417 rtw_tdls_cmd(adapter, NULL, TDLS_RS_RCR);
2418 #endif /* CONFIG_TDLS */
2419
2420 /* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
2421 rtw_free_stainfo(adapter, psta);
2422 /* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
2423
2424 }
2425
2426 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
2427 struct sta_info *psta;
2428
2429 rtw_free_all_stainfo(adapter);
2430
2431 psta = rtw_get_bcmc_stainfo(adapter);
2432 /* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
2433 rtw_free_stainfo(adapter, psta);
2434 /* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
2435
2436 rtw_init_bcmc_stainfo(adapter);
2437 }
2438
2439 if (lock_scanned_queue)
2440 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2441
2442 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS) || (pmlmepriv->wpa_phase == _TRUE)){
2443 RTW_INFO("Dont free disconnecting network of scanned_queue due to uner %s %s phase\n\n",
2444 check_fwstate(pmlmepriv, WIFI_UNDER_WPS) ? "WPS" : "",
2445 (pmlmepriv->wpa_phase == _TRUE) ? "WPA" : "");
2446 } else {
2447 pwlan = _rtw_find_same_network(&pmlmepriv->scanned_queue, tgt_network);
2448 if (pwlan) {
2449 pwlan->fixed = _FALSE;
2450
2451 RTW_INFO("Free disconnecting network of scanned_queue\n");
2452 rtw_free_network_nolock(adapter, pwlan);
2453 #ifdef CONFIG_P2P
2454 if (!rtw_p2p_chk_state(&adapter->wdinfo, P2P_STATE_NONE)) {
2455 rtw_set_scan_deny(adapter, 2000);
2456 /* rtw_clear_scan_deny(adapter); */
2457 }
2458 #endif /* CONFIG_P2P */
2459 } else
2460 RTW_ERR("Free disconnecting network of scanned_queue failed due to pwlan == NULL\n\n");
2461 }
2462
2463 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) && (adapter->stapriv.asoc_sta_count == 1))
2464 /*||check_fwstate(pmlmepriv, WIFI_STATION_STATE)*/) {
2465 if (pwlan)
2466 rtw_free_network_nolock(adapter, pwlan);
2467 }
2468
2469 if (lock_scanned_queue)
2470 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2471
2472 adapter->securitypriv.key_mask = 0;
2473
2474 rtw_reset_rx_info(adapter);
2475
2476
2477 }
2478
2479 /*
2480 *rtw_indicate_connect: the caller has to lock pmlmepriv->lock
2481 */
rtw_indicate_connect(_adapter * padapter)2482 void rtw_indicate_connect(_adapter *padapter)
2483 {
2484 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2485
2486 pmlmepriv->to_join = _FALSE;
2487
2488 if (!check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) {
2489
2490 set_fwstate(pmlmepriv, WIFI_ASOC_STATE);
2491
2492 rtw_led_control(padapter, LED_CTL_LINK);
2493
2494 rtw_os_indicate_connect(padapter);
2495
2496 #ifdef CONFIG_RTW_WDS
2497 if (MLME_IS_STA(padapter))
2498 rtw_wds_gptr_tbl_init(padapter);
2499 #endif
2500 }
2501
2502 rtw_set_to_roam(padapter, 0);
2503 if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter))
2504 rtw_mi_set_scan_deny(padapter, 3000);
2505
2506
2507 }
2508
2509
2510 /*
2511 *rtw_indicate_disconnect: the caller has to lock pmlmepriv->lock
2512 */
rtw_indicate_disconnect(_adapter * padapter,u16 reason,u8 locally_generated)2513 void rtw_indicate_disconnect(_adapter *padapter, u16 reason, u8 locally_generated)
2514 {
2515 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2516 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2517 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2518 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
2519 #ifdef CONFIG_WAPI_SUPPORT
2520 struct sta_info *psta;
2521 struct sta_priv *pstapriv = &padapter->stapriv;
2522 #endif
2523 u8 *wps_ie = NULL;
2524 uint wpsie_len = 0;
2525
2526 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
2527 pmlmepriv->wpa_phase = _TRUE;
2528
2529 _clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING | WIFI_UNDER_WPS | WIFI_OP_CH_SWITCHING | WIFI_UNDER_KEY_HANDSHAKE);
2530
2531 /* force to clear cur_network_scanned's SELECTED REGISTRAR */
2532 if (pmlmepriv->cur_network_scanned) {
2533 WLAN_BSSID_EX *current_joined_bss = &(pmlmepriv->cur_network_scanned->network);
2534 if (current_joined_bss) {
2535 wps_ie = rtw_get_wps_ie(current_joined_bss->IEs + _FIXED_IE_LENGTH_,
2536 current_joined_bss->IELength - _FIXED_IE_LENGTH_, NULL, &wpsie_len);
2537 if (wps_ie && wpsie_len > 0) {
2538 u8 *attr = NULL;
2539 u32 attr_len;
2540 attr = rtw_get_wps_attr(wps_ie, wpsie_len, WPS_ATTR_SELECTED_REGISTRAR,
2541 NULL, &attr_len);
2542 if (attr)
2543 *(attr + 4) = 0;
2544 }
2545 }
2546 }
2547 /* RTW_INFO("clear wps when %s\n", __func__); */
2548
2549 if (rtw_to_roam(padapter) > 0)
2550 _clr_fwstate_(pmlmepriv, WIFI_ASOC_STATE);
2551
2552 #ifdef CONFIG_WAPI_SUPPORT
2553 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
2554 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
2555 rtw_wapi_return_one_sta_info(padapter, psta->cmn.mac_addr);
2556 else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
2557 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
2558 rtw_wapi_return_all_sta_info(padapter);
2559 #endif
2560
2561 if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)
2562 || (rtw_to_roam(padapter) <= 0)
2563 ) {
2564 #ifdef CONFIG_RTW_WDS
2565 adapter_set_use_wds(padapter, 0);
2566 rtw_wds_gptr_tbl_unregister(padapter);
2567 #endif
2568 #ifdef CONFIG_RTW_MULTI_AP
2569 padapter->multi_ap = 0;
2570 #endif
2571
2572 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
2573 if (ATOMIC_READ(&padapter->tbtx_tx_pause) == _TRUE) {
2574 ATOMIC_SET(&padapter->tbtx_tx_pause, _FALSE);
2575 rtw_tx_control_cmd(padapter);
2576 }
2577 #endif
2578
2579 rtw_os_indicate_disconnect(padapter, reason, locally_generated);
2580
2581 /* set ips_deny_time to avoid enter IPS before LPS leave */
2582 rtw_set_ips_deny(padapter, 3000);
2583
2584 _clr_fwstate_(pmlmepriv, WIFI_ASOC_STATE);
2585
2586 rtw_led_control(padapter, LED_CTL_NO_LINK);
2587
2588 rtw_clear_scan_deny(padapter);
2589 }
2590
2591 #ifdef CONFIG_P2P_PS
2592 p2p_ps_wk_cmd(padapter, P2P_PS_DISABLE, 1);
2593 #endif /* CONFIG_P2P_PS */
2594
2595 #ifdef CONFIG_LPS
2596 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 0);
2597 #endif
2598
2599 #ifdef CONFIG_BEAMFORMING
2600 beamforming_wk_cmd(padapter, BEAMFORMING_CTRL_LEAVE, cur_network->MacAddress, ETH_ALEN, 1);
2601 #endif /*CONFIG_BEAMFORMING*/
2602
2603 }
2604
rtw_indicate_scan_done(_adapter * padapter,bool aborted)2605 inline void rtw_indicate_scan_done(_adapter *padapter, bool aborted)
2606 {
2607 RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
2608
2609 rtw_os_indicate_scan_done(padapter, aborted);
2610
2611 #ifdef CONFIG_IPS
2612 if (is_primary_adapter(padapter)
2613 && (_FALSE == adapter_to_pwrctl(padapter)->bInSuspend)
2614 && (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE | WIFI_UNDER_LINKING) == _FALSE)) {
2615 struct pwrctrl_priv *pwrpriv;
2616
2617 pwrpriv = adapter_to_pwrctl(padapter);
2618 rtw_set_ips_deny(padapter, 0);
2619 #ifdef CONFIG_IPS_CHECK_IN_WD
2620 _set_timer(&adapter_to_dvobj(padapter)->dynamic_chk_timer, 1);
2621 #else /* !CONFIG_IPS_CHECK_IN_WD */
2622 _rtw_set_pwr_state_check_timer(pwrpriv, 1);
2623 #endif /* !CONFIG_IPS_CHECK_IN_WD */
2624 }
2625 #endif /* CONFIG_IPS */
2626 }
2627
_rtw_wait_scan_done(_adapter * adapter,u8 abort,u32 timeout_ms)2628 static u32 _rtw_wait_scan_done(_adapter *adapter, u8 abort, u32 timeout_ms)
2629 {
2630 systime start;
2631 u32 pass_ms;
2632 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
2633 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
2634
2635 start = rtw_get_current_time();
2636
2637 pmlmeext->scan_abort = abort;
2638
2639 while (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY)
2640 && rtw_get_passing_time_ms(start) <= timeout_ms) {
2641
2642 if (RTW_CANNOT_RUN(adapter))
2643 break;
2644
2645 RTW_INFO(FUNC_NDEV_FMT"fw_state=WIFI_UNDER_SURVEY!\n", FUNC_NDEV_ARG(adapter->pnetdev));
2646 rtw_msleep_os(20);
2647 }
2648
2649 if (_TRUE == abort) {
2650 if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY)) {
2651 if (!RTW_CANNOT_RUN(adapter))
2652 RTW_INFO(FUNC_NDEV_FMT"waiting for scan_abort time out!\n", FUNC_NDEV_ARG(adapter->pnetdev));
2653 #ifdef CONFIG_PLATFORM_MSTAR
2654 /*_clr_fwstate_(pmlmepriv, WIFI_UNDER_SURVEY);*/
2655 set_survey_timer(pmlmeext, 0);
2656 mlme_set_scan_to_timer(pmlmepriv, 50);
2657 #endif
2658 rtw_indicate_scan_done(adapter, _TRUE);
2659 }
2660 }
2661
2662 pmlmeext->scan_abort = _FALSE;
2663 pass_ms = rtw_get_passing_time_ms(start);
2664
2665 return pass_ms;
2666
2667 }
2668
rtw_scan_wait_completed(_adapter * adapter)2669 void rtw_scan_wait_completed(_adapter *adapter)
2670 {
2671 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
2672 struct ss_res *ss = &pmlmeext->sitesurvey_res;
2673
2674 _rtw_wait_scan_done(adapter, _FALSE, ss->scan_timeout_ms);
2675 }
2676
rtw_scan_abort_timeout(_adapter * adapter,u32 timeout_ms)2677 u32 rtw_scan_abort_timeout(_adapter *adapter, u32 timeout_ms)
2678 {
2679 return _rtw_wait_scan_done(adapter, _TRUE, timeout_ms);
2680 }
2681
rtw_scan_abort_no_wait(_adapter * adapter)2682 void rtw_scan_abort_no_wait(_adapter *adapter)
2683 {
2684 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
2685 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
2686
2687 if (check_fwstate(pmlmepriv, WIFI_UNDER_SURVEY))
2688 pmlmeext->scan_abort = _TRUE;
2689 }
2690
rtw_scan_abort(_adapter * adapter)2691 void rtw_scan_abort(_adapter *adapter)
2692 {
2693 rtw_scan_abort_timeout(adapter, 200);
2694 }
2695
_rtw_wait_join_done(_adapter * adapter,u8 abort,u32 timeout_ms)2696 static u32 _rtw_wait_join_done(_adapter *adapter, u8 abort, u32 timeout_ms)
2697 {
2698 systime start;
2699 u32 pass_ms;
2700 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
2701 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
2702
2703 start = rtw_get_current_time();
2704
2705 pmlmeext->join_abort = abort;
2706 if (abort)
2707 set_link_timer(pmlmeext, 1);
2708
2709 while (rtw_get_passing_time_ms(start) <= timeout_ms
2710 && (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING)
2711 #ifdef CONFIG_IOCTL_CFG80211
2712 || rtw_cfg80211_is_connect_requested(adapter)
2713 #endif
2714 )
2715 ) {
2716 if (RTW_CANNOT_RUN(adapter))
2717 break;
2718
2719 RTW_INFO(FUNC_ADPT_FMT" linking...\n", FUNC_ADPT_ARG(adapter));
2720 rtw_msleep_os(20);
2721 }
2722
2723 if (abort) {
2724 if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING)
2725 #ifdef CONFIG_IOCTL_CFG80211
2726 || rtw_cfg80211_is_connect_requested(adapter)
2727 #endif
2728 ) {
2729 if (!RTW_CANNOT_RUN(adapter))
2730 RTW_INFO(FUNC_ADPT_FMT" waiting for join_abort time out!\n", FUNC_ADPT_ARG(adapter));
2731 }
2732 }
2733
2734 pmlmeext->join_abort = 0;
2735 pass_ms = rtw_get_passing_time_ms(start);
2736
2737 return pass_ms;
2738 }
2739
rtw_join_abort_timeout(_adapter * adapter,u32 timeout_ms)2740 u32 rtw_join_abort_timeout(_adapter *adapter, u32 timeout_ms)
2741 {
2742 return _rtw_wait_join_done(adapter, _TRUE, timeout_ms);
2743 }
2744
rtw_joinbss_update_stainfo(_adapter * padapter,struct wlan_network * pnetwork)2745 static struct sta_info *rtw_joinbss_update_stainfo(_adapter *padapter, struct wlan_network *pnetwork)
2746 {
2747 int i;
2748 struct sta_info *psta = NULL;
2749 struct recv_reorder_ctrl *preorder_ctrl;
2750 struct sta_priv *pstapriv = &padapter->stapriv;
2751 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2752 #ifdef CONFIG_RTS_FULL_BW
2753 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2754 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
2755 #endif/*CONFIG_RTS_FULL_BW*/
2756
2757 psta = rtw_get_stainfo(pstapriv, pnetwork->network.MacAddress);
2758 if (psta == NULL)
2759 psta = rtw_alloc_stainfo(pstapriv, pnetwork->network.MacAddress);
2760
2761 if (psta) { /* update ptarget_sta */
2762 RTW_INFO("%s\n", __FUNCTION__);
2763
2764 psta->cmn.aid = pnetwork->join_res;
2765
2766 update_sta_info(padapter, psta);
2767
2768 /* update station supportRate */
2769 psta->bssratelen = rtw_get_rateset_len(pnetwork->network.SupportedRates);
2770 _rtw_memcpy(psta->bssrateset, pnetwork->network.SupportedRates, psta->bssratelen);
2771 rtw_hal_update_sta_ra_info(padapter, psta);
2772
2773 psta->wireless_mode = pmlmeext->cur_wireless_mode;
2774 rtw_hal_update_sta_wset(padapter, psta);
2775
2776 /* sta mode */
2777 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
2778
2779 /* security related */
2780 #ifdef CONFIG_RTW_80211R
2781 if ((padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
2782 && (psta->ft_pairwise_key_installed == _FALSE)) {
2783 #else
2784 if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
2785 #endif
2786 u8 *ie;
2787 sint ie_len;
2788 u8 mfp_opt = MFP_NO;
2789 u8 spp_opt = 0;
2790
2791 padapter->securitypriv.binstallGrpkey = _FALSE;
2792 padapter->securitypriv.busetkipkey = _FALSE;
2793 padapter->securitypriv.bgrpkey_handshake = _FALSE;
2794
2795 ie = rtw_get_ie(pnetwork->network.IEs + _BEACON_IE_OFFSET_, WLAN_EID_RSN
2796 , &ie_len, (pnetwork->network.IELength - _BEACON_IE_OFFSET_));
2797 if (ie && ie_len > 0
2798 && rtw_parse_wpa2_ie(ie, ie_len + 2, NULL, NULL, NULL, NULL, &mfp_opt, &spp_opt) == _SUCCESS
2799 ) {
2800 if (padapter->securitypriv.mfp_opt >= MFP_OPTIONAL && mfp_opt >= MFP_OPTIONAL)
2801 psta->flags |= WLAN_STA_MFP;
2802 }
2803
2804 if (padapter->securitypriv.dot11PrivacyAlgrthm != _NO_PRIVACY_ ) {
2805 /*check if amsdu is allowed */
2806 if (rtw_check_amsdu_disable(padapter->registrypriv.amsdu_mode, spp_opt) == _TRUE)
2807 psta->flags |= WLAN_STA_AMSDU_DISABLE;
2808 }
2809 psta->ieee8021x_blocked = _TRUE;
2810 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
2811
2812 _rtw_memset((u8 *)&psta->dot118021x_UncstKey, 0, sizeof(union Keytype));
2813 _rtw_memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof(union Keytype));
2814 _rtw_memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof(union Keytype));
2815 }
2816
2817 /* Commented by Albert 2012/07/21 */
2818 /* When doing the WPS, the wps_ie_len won't equal to 0 */
2819 /* And the Wi-Fi driver shouldn't allow the data packet to be tramsmitted. */
2820 if (padapter->securitypriv.wps_ie_len != 0) {
2821 psta->ieee8021x_blocked = _TRUE;
2822 padapter->securitypriv.wps_ie_len = 0;
2823 }
2824
2825
2826 /* for A-MPDU Rx reordering buffer control for sta_info */
2827 /* if A-MPDU Rx is enabled, reseting rx_ordering_ctrl wstart_b(indicate_seq) to default value=0xffff */
2828 /* todo: check if AP can send A-MPDU packets */
2829 for (i = 0; i < 16 ; i++) {
2830 /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */
2831 preorder_ctrl = &psta->recvreorder_ctrl[i];
2832 preorder_ctrl->enable = _FALSE;
2833 preorder_ctrl->indicate_seq = 0xffff;
2834 rtw_clear_bit(RTW_RECV_ACK_OR_TIMEOUT, &preorder_ctrl->rec_abba_rsp_ack);
2835 #ifdef DBG_RX_SEQ
2836 RTW_INFO("DBG_RX_SEQ "FUNC_ADPT_FMT" tid:%u SN_CLEAR indicate_seq:%u preorder_ctrl->rec_abba_rsp_ack:%lu\n"
2837 , FUNC_ADPT_ARG(padapter)
2838 , i
2839 , preorder_ctrl->indicate_seq
2840 ,preorder_ctrl->rec_abba_rsp_ack
2841 );
2842 #endif
2843 preorder_ctrl->wend_b = 0xffff;
2844 preorder_ctrl->wsize_b = 64;/* max_ampdu_sz; */ /* ex. 32(kbytes) -> wsize_b=32 */
2845 preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID;
2846 }
2847 }
2848
2849 #ifdef CONFIG_RTW_80211K
2850 _rtw_memcpy(&psta->rm_en_cap, pnetwork->network.PhyInfo.rm_en_cap, 5);
2851 #endif
2852 #ifdef CONFIG_RTW_MULTI_AP
2853 if (padapter->multi_ap & MULTI_AP_BACKHAUL_STA) {
2854 u8 multi_ap = rtw_get_multi_ap_ie_ext(pmlmepriv->assoc_rsp + sizeof(struct rtw_ieee80211_hdr_3addr) + 6
2855 , pmlmepriv->assoc_rsp_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 6);
2856
2857 if (multi_ap & MULTI_AP_BACKHAUL_BSS) /* backhaul bss, enable WDS */
2858 psta->flags |= WLAN_STA_MULTI_AP | WLAN_STA_WDS;
2859 else if (multi_ap & MULTI_AP_FRONTHAUL_BSS) /* fronthaul bss only */
2860 psta->flags |= WLAN_STA_MULTI_AP;
2861 }
2862 #endif
2863 #ifdef CONFIG_RTS_FULL_BW
2864 rtw_parse_sta_vendor_ie_8812(padapter, psta, BSS_EX_TLV_IES(&cur_network->network), BSS_EX_TLV_IES_LEN(&cur_network->network));
2865 #endif
2866 return psta;
2867
2868 }
2869
2870 /* pnetwork : returns from rtw_joinbss_event_callback
2871 * ptarget_wlan: found from scanned_queue */
2872 static void rtw_joinbss_update_network(_adapter *padapter, struct wlan_network *ptarget_wlan, struct wlan_network *pnetwork)
2873 {
2874 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2875 struct security_priv *psecuritypriv = &padapter->securitypriv;
2876 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
2877 sint tmp_fw_state = 0x0;
2878
2879 RTW_INFO("%s\n", __FUNCTION__);
2880
2881 /* why not use ptarget_wlan?? */
2882 _rtw_memcpy(&cur_network->network, &pnetwork->network, pnetwork->network.Length);
2883 /* some IEs in pnetwork is wrong, so we should use ptarget_wlan IEs */
2884 cur_network->network.IELength = ptarget_wlan->network.IELength;
2885 _rtw_memcpy(&cur_network->network.IEs[0], &ptarget_wlan->network.IEs[0], MAX_IE_SZ);
2886
2887 cur_network->aid = pnetwork->join_res;
2888
2889
2890 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
2891 rtw_set_signal_stat_timer(&padapter->recvpriv);
2892 #endif
2893 padapter->recvpriv.signal_strength = ptarget_wlan->network.PhyInfo.SignalStrength;
2894 padapter->recvpriv.signal_qual = ptarget_wlan->network.PhyInfo.SignalQuality;
2895 /* the ptarget_wlan->network.Rssi is raw data, we use ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled) */
2896 padapter->recvpriv.rssi = translate_percentage_to_dbm(ptarget_wlan->network.PhyInfo.SignalStrength);
2897 #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
2898 RTW_INFO(FUNC_ADPT_FMT" signal_strength:%3u, rssi:%3d, signal_qual:%3u"
2899 "\n"
2900 , FUNC_ADPT_ARG(padapter)
2901 , padapter->recvpriv.signal_strength
2902 , padapter->recvpriv.rssi
2903 , padapter->recvpriv.signal_qual
2904 );
2905 #endif
2906 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
2907 rtw_set_signal_stat_timer(&padapter->recvpriv);
2908 #endif
2909
2910 /* update fw_state */ /* will clr WIFI_UNDER_LINKING here indirectly */
2911
2912 switch (pnetwork->network.InfrastructureMode) {
2913 case Ndis802_11Infrastructure:
2914 /* Check encryption */
2915 if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
2916 tmp_fw_state = tmp_fw_state | WIFI_UNDER_KEY_HANDSHAKE;
2917
2918 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
2919 tmp_fw_state = tmp_fw_state | WIFI_UNDER_WPS;
2920
2921 init_fwstate(pmlmepriv, WIFI_STATION_STATE | tmp_fw_state);
2922
2923 break;
2924 case Ndis802_11IBSS:
2925 /*pmlmepriv->fw_state = WIFI_ADHOC_STATE;*/
2926 init_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
2927 break;
2928 default:
2929 /*pmlmepriv->fw_state = WIFI_NULL_STATE;*/
2930 init_fwstate(pmlmepriv, WIFI_NULL_STATE);
2931 break;
2932 }
2933
2934 rtw_update_protection(padapter, (cur_network->network.IEs) + sizeof(NDIS_802_11_FIXED_IEs),
2935 (cur_network->network.IELength));
2936
2937 #ifdef CONFIG_80211N_HT
2938 rtw_update_ht_cap(padapter, cur_network->network.IEs, cur_network->network.IELength, (u8) cur_network->network.Configuration.DSConfig);
2939 #endif
2940 }
2941
2942 /* Notes: the fucntion could be > passive_level (the same context as Rx tasklet)
2943 * pnetwork : returns from rtw_joinbss_event_callback
2944 * ptarget_wlan: found from scanned_queue
2945 * if join_res > 0, for (fw_state==WIFI_STATION_STATE), we check if "ptarget_sta" & "ptarget_wlan" exist.
2946 * if join_res > 0, for (fw_state==WIFI_ADHOC_STATE), we only check if "ptarget_wlan" exist.
2947 * if join_res > 0, update "cur_network->network" from "pnetwork->network" if (ptarget_wlan !=NULL).
2948 */
2949 /* #define REJOIN */
2950 void rtw_joinbss_event_prehandle(_adapter *adapter, u8 *pbuf, u16 status)
2951 {
2952 _irqL irqL;
2953 static u8 retry = 0;
2954 struct sta_info *ptarget_sta = NULL, *pcur_sta = NULL;
2955 struct sta_priv *pstapriv = &adapter->stapriv;
2956 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
2957 struct wlan_network *pnetwork = (struct wlan_network *)pbuf;
2958 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
2959 struct wlan_network *pcur_wlan = NULL, *ptarget_wlan = NULL;
2960 unsigned int the_same_macaddr = _FALSE;
2961
2962 rtw_get_encrypt_decrypt_from_registrypriv(adapter);
2963
2964 the_same_macaddr = _rtw_memcmp(pnetwork->network.MacAddress, cur_network->network.MacAddress, ETH_ALEN);
2965
2966 pnetwork->network.Length = get_WLAN_BSSID_EX_sz(&pnetwork->network);
2967 if (pnetwork->network.Length > sizeof(WLAN_BSSID_EX))
2968 goto exit;
2969
2970 _enter_critical_bh(&pmlmepriv->lock, &irqL);
2971
2972 pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
2973 pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0;
2974
2975
2976 if (pnetwork->join_res > 0) {
2977 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2978 retry = 0;
2979 if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING)) {
2980 /* s1. find ptarget_wlan */
2981 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
2982 if (the_same_macaddr == _TRUE)
2983 ptarget_wlan = _rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
2984 else {
2985 pcur_wlan = _rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
2986 if (pcur_wlan)
2987 pcur_wlan->fixed = _FALSE;
2988
2989 pcur_sta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
2990 if (pcur_sta) {
2991 /* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); */
2992 rtw_free_stainfo(adapter, pcur_sta);
2993 /* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL2); */
2994 }
2995
2996 ptarget_wlan = _rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.MacAddress);
2997 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
2998 if (ptarget_wlan)
2999 ptarget_wlan->fixed = _TRUE;
3000 }
3001 }
3002
3003 } else {
3004 ptarget_wlan = _rtw_find_same_network(&pmlmepriv->scanned_queue, pnetwork);
3005 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
3006 if (ptarget_wlan)
3007 ptarget_wlan->fixed = _TRUE;
3008 }
3009 }
3010
3011 /* s2. update cur_network */
3012 if (ptarget_wlan)
3013 rtw_joinbss_update_network(adapter, ptarget_wlan, pnetwork);
3014 else {
3015 RTW_PRINT("Can't find ptarget_wlan when joinbss_event callback\n");
3016 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
3017 goto ignore_joinbss_callback;
3018 }
3019
3020
3021 /* s3. find ptarget_sta & update ptarget_sta after update cur_network only for station mode */
3022 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
3023 ptarget_sta = rtw_joinbss_update_stainfo(adapter, pnetwork);
3024 if (ptarget_sta == NULL) {
3025 RTW_ERR("Can't update stainfo when joinbss_event callback\n");
3026 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
3027 goto ignore_joinbss_callback;
3028 }
3029
3030 /* Queue TX packets before FW/HW ready */
3031 /* clear in mlmeext_joinbss_event_callback() */
3032 rtw_xmit_queue_set(ptarget_sta);
3033 }
3034
3035 /* s4. indicate connect */
3036 if (MLME_IS_STA(adapter) || MLME_IS_ADHOC(adapter)) {
3037 pmlmepriv->cur_network_scanned = ptarget_wlan;
3038 rtw_indicate_connect(adapter);
3039 }
3040
3041 /* s5. Cancle assoc_timer */
3042 _cancel_timer_ex(&pmlmepriv->assoc_timer);
3043
3044
3045 } else {
3046 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
3047 goto ignore_joinbss_callback;
3048 }
3049
3050 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
3051
3052 } else if (pnetwork->join_res == -4) {
3053 rtw_reset_securitypriv(adapter);
3054 pmlmepriv->join_status = status;
3055 _set_timer(&pmlmepriv->assoc_timer, 1);
3056
3057 /* rtw_free_assoc_resources(adapter, _TRUE); */
3058
3059 if ((check_fwstate(pmlmepriv, WIFI_UNDER_LINKING)) == _TRUE) {
3060 _clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING);
3061 }
3062
3063 } else { /* if join_res < 0 (join fails), then try again */
3064
3065 #ifdef REJOIN
3066 res = _FAIL;
3067 if (retry < 2) {
3068 res = rtw_select_and_join_from_scanned_queue(pmlmepriv);
3069 }
3070
3071 if (res == _SUCCESS) {
3072 /* extend time of assoc_timer */
3073 _set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);
3074 retry++;
3075 } else if (res == 2) { /* there is no need to wait for join */
3076 _clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING);
3077 rtw_indicate_connect(adapter);
3078 } else {
3079 #endif
3080 pmlmepriv->join_status = status;
3081 _set_timer(&pmlmepriv->assoc_timer, 1);
3082 /* rtw_free_assoc_resources(adapter, _TRUE); */
3083 _clr_fwstate_(pmlmepriv, WIFI_UNDER_LINKING);
3084
3085 #ifdef REJOIN
3086 retry = 0;
3087 }
3088 #endif
3089 }
3090
3091 ignore_joinbss_callback:
3092 _exit_critical_bh(&pmlmepriv->lock, &irqL);
3093
3094 exit:
3095 return;
3096 }
3097
3098 void rtw_joinbss_event_callback(_adapter *adapter, u8 *pbuf)
3099 {
3100 struct wlan_network *pnetwork = (struct wlan_network *)pbuf;
3101
3102
3103 mlmeext_joinbss_event_callback(adapter, pnetwork->join_res);
3104
3105 rtw_mi_os_xmit_schedule(adapter);
3106
3107 }
3108
3109 void rtw_sta_media_status_rpt(_adapter *adapter, struct sta_info *sta, bool connected)
3110 {
3111 struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
3112 bool miracast_enabled = 0;
3113 bool miracast_sink = 0;
3114 u8 role = H2C_MSR_ROLE_RSVD;
3115
3116 if (sta == NULL) {
3117 RTW_PRINT(FUNC_ADPT_FMT" sta is NULL\n"
3118 , FUNC_ADPT_ARG(adapter));
3119 rtw_warn_on(1);
3120 return;
3121 }
3122
3123 if (sta->cmn.mac_id >= macid_ctl->num) {
3124 RTW_PRINT(FUNC_ADPT_FMT" invalid macid:%u\n"
3125 , FUNC_ADPT_ARG(adapter), sta->cmn.mac_id);
3126 rtw_warn_on(1);
3127 return;
3128 }
3129
3130 if (!rtw_macid_is_used(macid_ctl, sta->cmn.mac_id)) {
3131 RTW_PRINT(FUNC_ADPT_FMT" macid:%u not is used, set connected to 0\n"
3132 , FUNC_ADPT_ARG(adapter), sta->cmn.mac_id);
3133 connected = 0;
3134 rtw_warn_on(1);
3135 }
3136
3137 if (connected && !rtw_macid_is_bmc(macid_ctl, sta->cmn.mac_id)) {
3138 miracast_enabled = STA_OP_WFD_MODE(sta) != 0 && is_miracast_enabled(adapter);
3139 miracast_sink = miracast_enabled && (STA_OP_WFD_MODE(sta) & MIRACAST_SINK);
3140
3141 #ifdef CONFIG_TDLS
3142 if (sta->tdls_sta_state & TDLS_LINKED_STATE)
3143 role = H2C_MSR_ROLE_TDLS;
3144 else
3145 #endif
3146 if (MLME_IS_STA(adapter)) {
3147 if (MLME_IS_GC(adapter))
3148 role = H2C_MSR_ROLE_GO;
3149 else
3150 role = H2C_MSR_ROLE_AP;
3151 } else if (MLME_IS_AP(adapter)) {
3152 if (MLME_IS_GO(adapter))
3153 role = H2C_MSR_ROLE_GC;
3154 else
3155 role = H2C_MSR_ROLE_STA;
3156 } else if (MLME_IS_ADHOC(adapter) || MLME_IS_ADHOC_MASTER(adapter))
3157 role = H2C_MSR_ROLE_ADHOC;
3158 else if (MLME_IS_MESH(adapter))
3159 role = H2C_MSR_ROLE_MESH;
3160
3161 #ifdef CONFIG_WFD
3162 if (role == H2C_MSR_ROLE_GC
3163 || role == H2C_MSR_ROLE_GO
3164 || role == H2C_MSR_ROLE_TDLS
3165 ) {
3166 if (adapter->wfd_info.rtsp_ctrlport
3167 || adapter->wfd_info.tdls_rtsp_ctrlport
3168 || adapter->wfd_info.peer_rtsp_ctrlport)
3169 rtw_wfd_st_switch(sta, 1);
3170 }
3171 #endif
3172 }
3173
3174 rtw_hal_set_FwMediaStatusRpt_single_cmd(adapter
3175 , connected
3176 , miracast_enabled
3177 , miracast_sink
3178 , role
3179 , sta->cmn.mac_id
3180 );
3181 }
3182
3183 u8 rtw_sta_media_status_rpt_cmd(_adapter *adapter, struct sta_info *sta, bool connected)
3184 {
3185 struct cmd_priv *cmdpriv = &adapter->cmdpriv;
3186 struct cmd_obj *cmdobj;
3187 struct drvextra_cmd_parm *cmd_parm;
3188 struct sta_media_status_rpt_cmd_parm *rpt_parm;
3189 u8 res = _SUCCESS;
3190
3191 cmdobj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
3192 if (cmdobj == NULL) {
3193 res = _FAIL;
3194 goto exit;
3195 }
3196
3197 cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
3198 if (cmd_parm == NULL) {
3199 rtw_mfree((u8 *)cmdobj, sizeof(struct cmd_obj));
3200 res = _FAIL;
3201 goto exit;
3202 }
3203
3204 rpt_parm = (struct sta_media_status_rpt_cmd_parm *)rtw_zmalloc(sizeof(struct sta_media_status_rpt_cmd_parm));
3205 if (rpt_parm == NULL) {
3206 rtw_mfree((u8 *)cmdobj, sizeof(struct cmd_obj));
3207 rtw_mfree((u8 *)cmd_parm, sizeof(struct drvextra_cmd_parm));
3208 res = _FAIL;
3209 goto exit;
3210 }
3211
3212 rpt_parm->sta = sta;
3213 rpt_parm->connected = connected;
3214
3215 cmd_parm->ec_id = STA_MSTATUS_RPT_WK_CID;
3216 cmd_parm->type = 0;
3217 cmd_parm->size = sizeof(struct sta_media_status_rpt_cmd_parm);
3218 cmd_parm->pbuf = (u8 *)rpt_parm;
3219 init_h2fwcmd_w_parm_no_rsp(cmdobj, cmd_parm, CMD_SET_DRV_EXTRA);
3220
3221 res = rtw_enqueue_cmd(cmdpriv, cmdobj);
3222
3223 exit:
3224 return res;
3225 }
3226
3227 inline void rtw_sta_media_status_rpt_cmd_hdl(_adapter *adapter, struct sta_media_status_rpt_cmd_parm *parm)
3228 {
3229 rtw_sta_media_status_rpt(adapter, parm->sta, parm->connected);
3230 }
3231
3232 void rtw_stassoc_event_callback(_adapter *adapter, u8 *pbuf)
3233 {
3234 _irqL irqL;
3235 struct sta_info *psta;
3236 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
3237 struct stassoc_event *pstassoc = (struct stassoc_event *)pbuf;
3238 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
3239 struct wlan_network *ptarget_wlan = NULL;
3240
3241
3242 #if CONFIG_RTW_MACADDR_ACL
3243 if (rtw_access_ctrl(adapter, pstassoc->macaddr) == _FALSE)
3244 return;
3245 #endif
3246
3247 #if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
3248 if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
3249 psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
3250 if (psta) {
3251 u8 *passoc_req = NULL;
3252 u32 assoc_req_len = 0;
3253
3254 rtw_sta_media_status_rpt(adapter, psta, 1);
3255
3256 #ifdef CONFIG_MCC_MODE
3257 rtw_hal_mcc_update_macid_bitmap(adapter, psta->cmn.mac_id, _TRUE);
3258 #endif /* CONFIG_MCC_MODE */
3259
3260 #ifndef CONFIG_AUTO_AP_MODE
3261 ap_sta_info_defer_update(adapter, psta);
3262
3263 if (!MLME_IS_MESH(adapter)) {
3264 /* report to upper layer */
3265 RTW_INFO("indicate_sta_assoc_event to upper layer - hostapd\n");
3266 #ifdef CONFIG_IOCTL_CFG80211
3267 _enter_critical_bh(&psta->lock, &irqL);
3268 if (psta->passoc_req && psta->assoc_req_len > 0) {
3269 passoc_req = rtw_zmalloc(psta->assoc_req_len);
3270 if (passoc_req) {
3271 assoc_req_len = psta->assoc_req_len;
3272 _rtw_memcpy(passoc_req, psta->passoc_req, assoc_req_len);
3273 }
3274 }
3275 _exit_critical_bh(&psta->lock, &irqL);
3276
3277 if (passoc_req && assoc_req_len > 0) {
3278 rtw_cfg80211_indicate_sta_assoc(adapter, passoc_req, assoc_req_len);
3279 rtw_mfree(passoc_req, assoc_req_len);
3280 }
3281 #else /* !CONFIG_IOCTL_CFG80211 */
3282 rtw_indicate_sta_assoc_event(adapter, psta);
3283 #endif /* !CONFIG_IOCTL_CFG80211 */
3284 }
3285 #endif /* !CONFIG_AUTO_AP_MODE */
3286
3287 #ifdef CONFIG_BEAMFORMING
3288 beamforming_wk_cmd(adapter, BEAMFORMING_CTRL_ENTER, (u8 *)psta, sizeof(struct sta_info), 0);
3289 #endif/*CONFIG_BEAMFORMING*/
3290 if (is_wep_enc(adapter->securitypriv.dot11PrivacyAlgrthm))
3291 rtw_ap_wep_pk_setting(adapter, psta);
3292 }
3293 goto exit;
3294 }
3295 #endif /* defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
3296
3297 /* for AD-HOC mode */
3298 psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
3299 if (psta == NULL) {
3300 RTW_ERR(FUNC_ADPT_FMT" get no sta_info with "MAC_FMT"\n"
3301 , FUNC_ADPT_ARG(adapter), MAC_ARG(pstassoc->macaddr));
3302 rtw_warn_on(1);
3303 goto exit;
3304 }
3305
3306 rtw_sta_media_status_rpt(adapter, psta, 1);
3307
3308 if (adapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)
3309 psta->dot118021XPrivacy = adapter->securitypriv.dot11PrivacyAlgrthm;
3310
3311
3312 psta->ieee8021x_blocked = _FALSE;
3313
3314 _enter_critical_bh(&pmlmepriv->lock, &irqL);
3315
3316 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) ||
3317 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE)) {
3318 if (adapter->stapriv.asoc_sta_count == 2) {
3319 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
3320 ptarget_wlan = _rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.MacAddress);
3321 pmlmepriv->cur_network_scanned = ptarget_wlan;
3322 if (ptarget_wlan)
3323 ptarget_wlan->fixed = _TRUE;
3324 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
3325 /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
3326 rtw_indicate_connect(adapter);
3327 }
3328 }
3329
3330 _exit_critical_bh(&pmlmepriv->lock, &irqL);
3331
3332
3333 mlmeext_sta_add_event_callback(adapter, psta);
3334
3335 #ifdef CONFIG_RTL8711
3336 /* submit SetStaKey_cmd to tell fw, fw will allocate an CAM entry for this sta */
3337 rtw_setstakey_cmd(adapter, psta, GROUP_KEY, _TRUE);
3338 #endif
3339
3340 exit:
3341 #ifdef CONFIG_RTS_FULL_BW
3342 rtw_set_rts_bw(adapter);
3343 #endif/*CONFIG_RTS_FULL_BW*/
3344 return;
3345 }
3346
3347 #ifdef CONFIG_IEEE80211W
3348 void rtw_sta_timeout_event_callback(_adapter *adapter, u8 *pbuf)
3349 {
3350 #ifdef CONFIG_AP_MODE
3351 _irqL irqL;
3352 struct sta_info *psta;
3353 struct stadel_event *pstadel = (struct stadel_event *)pbuf;
3354 struct sta_priv *pstapriv = &adapter->stapriv;
3355
3356 psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr);
3357
3358 if (psta) {
3359 u8 updated = _FALSE;
3360
3361 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3362 if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) {
3363 rtw_list_delete(&psta->asoc_list);
3364 pstapriv->asoc_list_cnt--;
3365 #ifdef CONFIG_RTW_TOKEN_BASED_XMIT
3366 if (psta->tbtx_enable)
3367 pstapriv->tbtx_asoc_list_cnt--;
3368 #endif
3369 updated = ap_free_sta(adapter, psta, _TRUE, WLAN_REASON_PREV_AUTH_NOT_VALID, _TRUE);
3370 }
3371 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3372
3373 associated_clients_update(adapter, updated, STA_INFO_UPDATE_ALL);
3374 }
3375 #endif /* CONFIG_AP_MODE */
3376 }
3377 #endif /* CONFIG_IEEE80211W */
3378
3379 void rtw_sta_mstatus_disc_rpt(_adapter *adapter, u8 mac_id)
3380 {
3381 struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
3382
3383 if (mac_id < macid_ctl->num) {
3384 u8 id_is_shared = mac_id == RTW_DEFAULT_MGMT_MACID; /* TODO: real shared macid judgment */
3385
3386 RTW_INFO(FUNC_ADPT_FMT" - mac_id=%d%s\n", FUNC_ADPT_ARG(adapter)
3387 , mac_id, id_is_shared ? " shared" : "");
3388
3389 if (!id_is_shared) {
3390 rtw_hal_macid_drop(adapter, mac_id);
3391 rtw_hal_set_FwMediaStatusRpt_single_cmd(adapter, 0, 0, 0, 0, mac_id);
3392 /*
3393 * For safety, prevent from keeping macid sleep.
3394 * If we can sure all power mode enter/leave are paired,
3395 * this check can be removed.
3396 * Lucas@20131113
3397 */
3398 /* wakeup macid after disconnect. */
3399 /*if (MLME_IS_STA(adapter))*/
3400 rtw_hal_macid_wakeup(adapter, mac_id);
3401 }
3402 } else {
3403 RTW_PRINT(FUNC_ADPT_FMT" invalid macid:%u\n"
3404 , FUNC_ADPT_ARG(adapter), mac_id);
3405 rtw_warn_on(1);
3406 }
3407 }
3408 void rtw_sta_mstatus_report(_adapter *adapter)
3409 {
3410 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
3411 struct wlan_network *tgt_network = &pmlmepriv->cur_network;
3412 struct sta_info *psta = NULL;
3413
3414 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && check_fwstate(pmlmepriv, WIFI_ASOC_STATE)) {
3415 psta = rtw_get_stainfo(&adapter->stapriv, tgt_network->network.MacAddress);
3416 if (psta)
3417 rtw_sta_mstatus_disc_rpt(adapter, psta->cmn.mac_id);
3418 else {
3419 RTW_INFO("%s "ADPT_FMT" - mac_addr: "MAC_FMT" psta == NULL\n", __func__, ADPT_ARG(adapter), MAC_ARG(tgt_network->network.MacAddress));
3420 rtw_warn_on(1);
3421 }
3422 }
3423 }
3424
3425 void rtw_stadel_event_callback(_adapter *adapter, u8 *pbuf)
3426 {
3427 _irqL irqL, irqL2;
3428
3429 struct sta_info *psta;
3430 struct wlan_network *pwlan = NULL;
3431 WLAN_BSSID_EX *pdev_network = NULL;
3432 u8 *pibss = NULL;
3433 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
3434 struct stadel_event *pstadel = (struct stadel_event *)pbuf;
3435 struct wlan_network *tgt_network = &(pmlmepriv->cur_network);
3436
3437 RTW_INFO("%s(mac_id=%d)=" MAC_FMT "\n", __func__, pstadel->mac_id, MAC_ARG(pstadel->macaddr));
3438 rtw_sta_mstatus_disc_rpt(adapter, pstadel->mac_id);
3439
3440 #ifdef CONFIG_MCC_MODE
3441 rtw_hal_mcc_update_macid_bitmap(adapter, pstadel->mac_id, _FALSE);
3442 #endif /* CONFIG_MCC_MODE */
3443
3444 psta = rtw_get_stainfo(&adapter->stapriv, pstadel->macaddr);
3445
3446 if (psta == NULL) {
3447 RTW_INFO("%s(mac_id=%d)=" MAC_FMT " psta == NULL\n", __func__, pstadel->mac_id, MAC_ARG(pstadel->macaddr));
3448 /*rtw_warn_on(1);*/
3449 }
3450
3451 if (psta)
3452 rtw_wfd_st_switch(psta, 0);
3453
3454 if (MLME_IS_MESH(adapter)) {
3455 rtw_free_stainfo(adapter, psta);
3456 goto exit;
3457 }
3458
3459 #ifdef CONFIG_AP_MODE
3460 if (MLME_IS_AP(adapter)) {
3461 #ifdef CONFIG_IOCTL_CFG80211
3462 #ifdef COMPAT_KERNEL_RELEASE
3463
3464 #elif (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
3465 rtw_cfg80211_indicate_sta_disassoc(adapter, pstadel->macaddr, *(u16 *)pstadel->rsvd);
3466 #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) */
3467 #endif /* CONFIG_IOCTL_CFG80211 */
3468
3469 rtw_free_stainfo(adapter, psta);
3470
3471 goto exit;
3472 }
3473 #endif /* CONFIG_AP_MODE */
3474
3475 mlmeext_sta_del_event_callback(adapter);
3476
3477 _enter_critical_bh(&pmlmepriv->lock, &irqL2);
3478
3479 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
3480 u16 reason = *((unsigned short *)(pstadel->rsvd));
3481 bool roam = _FALSE;
3482 struct wlan_network *roam_target = NULL;
3483
3484 #ifdef CONFIG_LAYER2_ROAMING
3485 #ifdef CONFIG_RTW_80211R
3486 if (rtw_ft_roam_expired(adapter, reason))
3487 pmlmepriv->ft_roam.ft_roam_on_expired = _TRUE;
3488 else
3489 pmlmepriv->ft_roam.ft_roam_on_expired = _FALSE;
3490 #endif
3491 if (adapter->registrypriv.wifi_spec == 1)
3492 roam = _FALSE;
3493 else if (reason == WLAN_REASON_EXPIRATION_CHK && rtw_chk_roam_flags(adapter, RTW_ROAM_ON_EXPIRED))
3494 roam = _TRUE;
3495 else if (reason == WLAN_REASON_ACTIVE_ROAM && rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) {
3496 roam = _TRUE;
3497 roam_target = pmlmepriv->roam_network;
3498 }
3499
3500 #ifdef CONFIG_RTW_80211R
3501 if (reason == WLAN_REASON_ACTIVE_ROAM && rtw_ft_chk_flags(adapter, RTW_FT_BTM_ROAM)) {
3502 roam = _TRUE;
3503 roam_target = pmlmepriv->roam_network;
3504 }
3505 #endif
3506
3507 if (roam == _TRUE) {
3508 if (rtw_to_roam(adapter) > 0)
3509 rtw_dec_to_roam(adapter); /* this stadel_event is caused by roaming, decrease to_roam */
3510 else if (rtw_to_roam(adapter) == 0)
3511 rtw_set_to_roam(adapter, adapter->registrypriv.max_roaming_times);
3512 } else
3513 rtw_set_to_roam(adapter, 0);
3514 #endif /* CONFIG_LAYER2_ROAMING */
3515
3516 rtw_free_uc_swdec_pending_queue(adapter);
3517
3518 rtw_free_assoc_resources(adapter, _TRUE);
3519 rtw_free_mlme_priv_ie_data(pmlmepriv);
3520
3521 rtw_indicate_disconnect(adapter, *(u16 *)pstadel->rsvd, pstadel->locally_generated);
3522
3523 _rtw_roaming(adapter, roam_target);
3524 }
3525
3526 #ifdef CONFIG_AP_MODE
3527 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
3528 check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
3529
3530 /* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
3531 rtw_free_stainfo(adapter, psta);
3532 /* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
3533
3534 if (adapter->stapriv.asoc_sta_count == 1) { /* a sta + bc/mc_stainfo (not Ibss_stainfo) */
3535 /* rtw_indicate_disconnect(adapter); */ /* removed@20091105 */
3536 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
3537 /* free old ibss network */
3538 /* pwlan = _rtw_find_network(&pmlmepriv->scanned_queue, pstadel->macaddr); */
3539 pwlan = _rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);
3540 if (pwlan) {
3541 pwlan->fixed = _FALSE;
3542 rtw_free_network_nolock(adapter, pwlan);
3543 }
3544 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
3545 /* re-create ibss */
3546 pdev_network = &(adapter->registrypriv.dev_network);
3547 pibss = adapter->registrypriv.dev_network.MacAddress;
3548
3549 _rtw_memcpy(pdev_network, &tgt_network->network, get_WLAN_BSSID_EX_sz(&tgt_network->network));
3550
3551 _rtw_memset(&pdev_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
3552 _rtw_memcpy(&pdev_network->Ssid, &pmlmepriv->assoc_ssid, sizeof(NDIS_802_11_SSID));
3553
3554 rtw_update_registrypriv_dev_network(adapter);
3555
3556 rtw_generate_random_ibss(pibss);
3557
3558 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
3559 set_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
3560 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_STATE);
3561 }
3562
3563 if (rtw_create_ibss_cmd(adapter, 0) != _SUCCESS)
3564 RTW_ERR("rtw_create_ibss_cmd FAIL\n");
3565
3566 }
3567
3568 }
3569 #endif /* CONFIG_AP_MODE */
3570 _exit_critical_bh(&pmlmepriv->lock, &irqL2);
3571 exit:
3572 #ifdef CONFIG_RTS_FULL_BW
3573 rtw_set_rts_bw(adapter);
3574 #endif/*CONFIG_RTS_FULL_BW*/
3575 return;
3576 }
3577
3578 void rtw_wmm_event_callback(PADAPTER padapter, u8 *pbuf)
3579 {
3580
3581 WMMOnAssocRsp(padapter);
3582
3583
3584 }
3585
3586 /*
3587 * rtw_join_timeout_handler - Timeout/failure handler for CMD JoinBss
3588 */
3589 void rtw_join_timeout_handler(void *ctx)
3590 {
3591 _adapter *adapter = (_adapter *)ctx;
3592 _irqL irqL;
3593 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
3594
3595 #if 0
3596 if (rtw_is_drv_stopped(adapter)) {
3597 _rtw_up_sema(&pmlmepriv->assoc_terminate);
3598 return;
3599 }
3600 #endif
3601
3602
3603
3604 RTW_INFO("%s, fw_state=%x\n", __FUNCTION__, get_fwstate(pmlmepriv));
3605
3606 if (RTW_CANNOT_RUN(adapter))
3607 return;
3608
3609
3610 _enter_critical_bh(&pmlmepriv->lock, &irqL);
3611
3612 #ifdef CONFIG_LAYER2_ROAMING
3613 if (rtw_to_roam(adapter) > 0) { /* join timeout caused by roaming */
3614 while (1) {
3615 rtw_dec_to_roam(adapter);
3616 if (rtw_to_roam(adapter) != 0) { /* try another */
3617 int do_join_r;
3618 RTW_INFO("%s try another roaming\n", __FUNCTION__);
3619 do_join_r = rtw_do_join(adapter);
3620 if (_SUCCESS != do_join_r) {
3621 RTW_INFO("%s roaming do_join return %d\n", __FUNCTION__ , do_join_r);
3622 continue;
3623 }
3624 break;
3625 } else {
3626 RTW_INFO("%s We've try roaming but fail\n", __FUNCTION__);
3627 #ifdef CONFIG_RTW_80211R
3628 rtw_ft_clr_flags(adapter, RTW_FT_PEER_EN|RTW_FT_PEER_OTD_EN);
3629 rtw_ft_reset_status(adapter);
3630 #endif
3631 rtw_indicate_disconnect(adapter, pmlmepriv->join_status, _FALSE);
3632 break;
3633 }
3634 }
3635
3636 } else
3637 #endif
3638 {
3639 rtw_indicate_disconnect(adapter, pmlmepriv->join_status, _FALSE);
3640 free_scanqueue(pmlmepriv);/* ??? */
3641
3642 #ifdef CONFIG_IOCTL_CFG80211
3643 /* indicate disconnect for the case that join_timeout and check_fwstate != FW_LINKED */
3644 rtw_cfg80211_indicate_disconnect(adapter, pmlmepriv->join_status, _FALSE);
3645 #endif /* CONFIG_IOCTL_CFG80211 */
3646
3647 }
3648
3649 pmlmepriv->join_status = 0; /* reset */
3650
3651 _exit_critical_bh(&pmlmepriv->lock, &irqL);
3652
3653
3654 #ifdef CONFIG_DRVEXT_MODULE_WSC
3655 drvext_assoc_fail_indicate(&adapter->drvextpriv);
3656 #endif
3657
3658
3659
3660 }
3661
3662 /*
3663 * rtw_scan_timeout_handler - Timeout/Faliure handler for CMD SiteSurvey
3664 * @adapter: pointer to _adapter structure
3665 */
3666 void rtw_scan_timeout_handler(void *ctx)
3667 {
3668 _adapter *adapter = (_adapter *)ctx;
3669 _irqL irqL;
3670 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
3671 RTW_INFO(FUNC_ADPT_FMT" fw_state=%x\n", FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv));
3672
3673 _enter_critical_bh(&pmlmepriv->lock, &irqL);
3674
3675 _clr_fwstate_(pmlmepriv, WIFI_UNDER_SURVEY);
3676
3677 _exit_critical_bh(&pmlmepriv->lock, &irqL);
3678
3679 #ifdef CONFIG_IOCTL_CFG80211
3680 rtw_cfg80211_surveydone_event_callback(adapter);
3681 #endif /* CONFIG_IOCTL_CFG80211 */
3682
3683 rtw_indicate_scan_done(adapter, _TRUE);
3684
3685 #if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_IOCTL_CFG80211)
3686 rtw_cfg80211_indicate_scan_done_for_buddy(adapter, _TRUE);
3687 #endif
3688 }
3689
3690 void rtw_mlme_reset_auto_scan_int(_adapter *adapter, u8 *reason)
3691 {
3692 #if defined(CONFIG_RTW_MESH) && defined(CONFIG_DFS_MASTER)
3693 #if CONFIG_RTW_MESH_OFFCH_CAND
3694 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
3695 #endif
3696 #endif
3697 u8 u_ch;
3698 u32 interval_ms = 0xffffffff; /* 0xffffffff: special value to make min() works well, also means no auto scan */
3699
3700 *reason = RTW_AUTO_SCAN_REASON_UNSPECIFIED;
3701 rtw_mi_get_ch_setting_union(adapter, &u_ch, NULL, NULL);
3702
3703 if (hal_chk_bw_cap(adapter, BW_CAP_40M)
3704 && is_client_associated_to_ap(adapter) == _TRUE
3705 && u_ch >= 1 && u_ch <= 14
3706 && adapter->registrypriv.wifi_spec
3707 /* TODO: AP Connected is 40MHz capability? */
3708 ) {
3709 interval_ms = rtw_min(interval_ms, 60 * 1000);
3710 *reason |= RTW_AUTO_SCAN_REASON_2040_BSS;
3711 }
3712
3713 #ifdef CONFIG_RTW_MESH
3714 #if CONFIG_RTW_MESH_OFFCH_CAND
3715 if (adapter->mesh_cfg.peer_sel_policy.offch_find_int_ms
3716 && rtw_mesh_offch_candidate_accepted(adapter)
3717 #ifdef CONFIG_DFS_MASTER
3718 && (!rfctl->radar_detect_ch || (IS_CH_WAITING(rfctl) && !IS_UNDER_CAC(rfctl)))
3719 #endif
3720 ) {
3721 interval_ms = rtw_min(interval_ms, adapter->mesh_cfg.peer_sel_policy.offch_find_int_ms);
3722 *reason |= RTW_AUTO_SCAN_REASON_MESH_OFFCH_CAND;
3723 }
3724 #endif
3725 #endif /* CONFIG_RTW_MESH */
3726
3727 if (interval_ms == 0xffffffff)
3728 interval_ms = 0;
3729
3730 rtw_mlme_set_auto_scan_int(adapter, interval_ms);
3731 return;
3732 }
3733
3734 void rtw_drv_scan_by_self(_adapter *padapter, u8 reason)
3735 {
3736 struct sitesurvey_parm parm;
3737 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3738 int i;
3739 #if 1
3740 u8 ssc_chk;
3741
3742 ssc_chk = rtw_sitesurvey_condition_check(padapter, _FALSE);
3743 if( ssc_chk == SS_DENY_BUSY_TRAFFIC) {
3744 #ifdef CONFIG_LAYER2_ROAMING
3745 if (rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE) && pmlmepriv->need_to_roam == _TRUE)
3746 RTW_INFO(FUNC_ADPT_FMT" need to roam, don't care BusyTraffic\n", FUNC_ADPT_ARG(padapter));
3747 else
3748 #endif
3749 RTW_INFO(FUNC_ADPT_FMT" exit BusyTraffic\n", FUNC_ADPT_ARG(padapter));
3750 goto exit;
3751 }
3752 else if (ssc_chk != SS_ALLOW)
3753 goto exit;
3754
3755 if (!rtw_is_adapter_up(padapter))
3756 goto exit;
3757 #else
3758 if (rtw_is_scan_deny(padapter))
3759 goto exit;
3760
3761 if (!rtw_is_adapter_up(padapter))
3762 goto exit;
3763
3764 if (rtw_mi_busy_traffic_check(padapter)) {
3765 #ifdef CONFIG_LAYER2_ROAMING
3766 if (rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE) && pmlmepriv->need_to_roam == _TRUE) {
3767 RTW_INFO("need to roam, don't care BusyTraffic\n");
3768 } else
3769 #endif
3770 {
3771 RTW_INFO(FUNC_ADPT_FMT" exit BusyTraffic\n", FUNC_ADPT_ARG(padapter));
3772 goto exit;
3773 }
3774 }
3775 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) && check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
3776 RTW_INFO(FUNC_ADPT_FMT" WIFI_AP_STATE && WIFI_UNDER_WPS\n", FUNC_ADPT_ARG(padapter));
3777 goto exit;
3778 }
3779 if (check_fwstate(pmlmepriv, (WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING)) == _TRUE) {
3780 RTW_INFO(FUNC_ADPT_FMT" WIFI_UNDER_SURVEY|WIFI_UNDER_LINKING\n", FUNC_ADPT_ARG(padapter));
3781 goto exit;
3782 }
3783
3784 #ifdef CONFIG_CONCURRENT_MODE
3785 if (rtw_mi_buddy_check_fwstate(padapter, (WIFI_UNDER_SURVEY | WIFI_UNDER_LINKING | WIFI_UNDER_WPS))) {
3786 RTW_INFO(FUNC_ADPT_FMT", but buddy_intf is under scanning or linking or wps_phase\n", FUNC_ADPT_ARG(padapter));
3787 goto exit;
3788 }
3789 #endif
3790 #endif
3791
3792 RTW_INFO(FUNC_ADPT_FMT" reason:0x%02x\n", FUNC_ADPT_ARG(padapter), reason);
3793
3794 #ifdef CONFIG_LAYER2_ROAMING
3795 if ((reason == RTW_AUTO_SCAN_REASON_ROAM_ACTIVE) &&
3796 (rtw_get_passing_time_ms(pmlmepriv->last_roaming) >= pmlmepriv->roam_scan_int*2000))
3797 pmlmepriv->last_roaming = rtw_get_current_time();
3798 else
3799 goto exit;
3800 #endif
3801 /* only for 20/40 BSS */
3802 if (reason == RTW_AUTO_SCAN_REASON_2040_BSS) {
3803 rtw_init_sitesurvey_parm(padapter, &parm);
3804 for (i=0;i<14;i++) {
3805 parm.ch[i].hw_value = i + 1;
3806 parm.ch[i].flags = RTW_IEEE80211_CHAN_PASSIVE_SCAN;
3807 }
3808 parm.ch_num = 14;
3809 rtw_set_802_11_bssid_list_scan(padapter, &parm);
3810 goto exit;
3811 }
3812
3813 #if defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K)
3814 if ((reason == RTW_AUTO_SCAN_REASON_ROAM)
3815 && (rtw_roam_nb_scan_list_set(padapter, &parm)))
3816 goto exit;
3817 #endif
3818
3819 rtw_set_802_11_bssid_list_scan(padapter, NULL);
3820 exit:
3821 return;
3822 }
3823
3824 static void rtw_auto_scan_handler(_adapter *padapter)
3825 {
3826 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3827 u8 reason = RTW_AUTO_SCAN_REASON_UNSPECIFIED;
3828 #ifdef CONFIG_LAYER2_ROAMING
3829 struct recv_priv *precvpriv = &padapter->recvpriv;
3830 #endif
3831
3832 rtw_mlme_reset_auto_scan_int(padapter, &reason);
3833
3834 #ifdef CONFIG_P2P
3835 if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
3836 goto exit;
3837 #endif
3838
3839 #ifdef CONFIG_TDLS
3840 if (padapter->tdlsinfo.link_established == _TRUE)
3841 goto exit;
3842 #endif
3843
3844 #ifdef CONFIG_LAYER2_ROAMING
3845 if (is_client_associated_to_ap(padapter) &&
3846 rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE)) {
3847 RTW_INFO("signal_strength_data.avg_val = %d\n", precvpriv->signal_strength_data.avg_val);
3848 if (precvpriv->signal_strength_data.avg_val < pmlmepriv->roam_rssi_threshold) {
3849 #ifdef CONFIG_RTW_80211K
3850 rtw_roam_nb_discover(padapter, _FALSE);
3851 #endif
3852 pmlmepriv->need_to_roam = _TRUE;
3853 reason = RTW_AUTO_SCAN_REASON_ROAM_ACTIVE;
3854 goto do_scan;
3855 } else
3856 pmlmepriv->need_to_roam = _FALSE;
3857 }
3858 #endif
3859
3860 if (pmlmepriv->auto_scan_int_ms == 0
3861 || rtw_get_passing_time_ms(pmlmepriv->scan_start_time) < pmlmepriv->auto_scan_int_ms)
3862 goto exit;
3863
3864 do_scan:
3865 rtw_drv_scan_by_self(padapter, reason);
3866
3867 exit:
3868 return;
3869 }
3870 static u8 is_drv_in_lps(_adapter *adapter)
3871 {
3872 u8 is_in_lps = _FALSE;
3873
3874 #ifdef CONFIG_LPS_LCLK_WD_TIMER /* to avoid leaving lps 32k frequently*/
3875 if ((adapter_to_pwrctl(adapter)->bFwCurrentInPSMode == _TRUE)
3876 #ifdef CONFIG_BT_COEXIST
3877 && (rtw_btcoex_IsBtControlLps(adapter) == _FALSE)
3878 #endif
3879 )
3880 is_in_lps = _TRUE;
3881 #endif /* CONFIG_LPS_LCLK_WD_TIMER*/
3882 return is_in_lps;
3883 }
3884 void rtw_iface_dynamic_check_timer_handlder(_adapter *adapter)
3885 {
3886 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
3887
3888 if (adapter->net_closed == _TRUE)
3889 return;
3890 #ifdef CONFIG_LPS_LCLK_WD_TIMER /* to avoid leaving lps 32k frequently*/
3891 if (is_drv_in_lps(adapter)) {
3892 u8 bEnterPS;
3893
3894 linked_status_chk(adapter, 1);
3895
3896 bEnterPS = traffic_status_watchdog(adapter, 1);
3897 if (bEnterPS) {
3898 /* rtw_lps_ctrl_wk_cmd(adapter, LPS_CTRL_ENTER, 0); */
3899 rtw_hal_dm_watchdog_in_lps(adapter);
3900 } else {
3901 /* call rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 0) in traffic_status_watchdog() */
3902 }
3903 }
3904 #endif /* CONFIG_LPS_LCLK_WD_TIMER */
3905
3906 /* auto site survey */
3907 rtw_auto_scan_handler(adapter);
3908
3909 #ifdef CONFIG_AP_MODE
3910 if (MLME_IS_AP(adapter)|| MLME_IS_MESH(adapter)) {
3911 #ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
3912 expire_timeout_chk(adapter);
3913 #endif /* !CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
3914
3915 #ifdef CONFIG_BMC_TX_RATE_SELECT
3916 rtw_update_bmc_sta_tx_rate(adapter);
3917 #endif /*CONFIG_BMC_TX_RATE_SELECT*/
3918 }
3919 #endif /*CONFIG_AP_MODE*/
3920
3921
3922 #ifdef CONFIG_BR_EXT
3923 if (!adapter_use_wds(adapter)) {
3924 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
3925 rcu_read_lock();
3926 #endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) */
3927
3928 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
3929 if (adapter->pnetdev->br_port
3930 #else /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
3931 if (rcu_dereference(adapter->pnetdev->rx_handler_data)
3932 #endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
3933 && (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE)) {
3934 /* expire NAT2.5 entry */
3935 void nat25_db_expire(_adapter *priv);
3936 nat25_db_expire(adapter);
3937
3938 if (adapter->pppoe_connection_in_progress > 0)
3939 adapter->pppoe_connection_in_progress--;
3940 /* due to rtw_dynamic_check_timer_handlder() is called every 2 seconds */
3941 if (adapter->pppoe_connection_in_progress > 0)
3942 adapter->pppoe_connection_in_progress--;
3943 }
3944
3945 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
3946 rcu_read_unlock();
3947 #endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) */
3948 }
3949 #endif /* CONFIG_BR_EXT */
3950
3951 }
3952
3953 /*TP_avg(t) = (1/10) * TP_avg(t-1) + (9/10) * TP(t) MBps*/
3954 static void collect_sta_traffic_statistics(_adapter *adapter)
3955 {
3956 struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
3957 struct sta_info *sta;
3958 u64 curr_tx_bytes = 0, curr_rx_bytes = 0;
3959 u32 curr_tx_mbytes = 0, curr_rx_mbytes = 0;
3960 int i;
3961
3962 for (i = 0; i < MACID_NUM_SW_LIMIT; i++) {
3963 sta = macid_ctl->sta[i];
3964 if (sta && !is_broadcast_mac_addr(sta->cmn.mac_addr)) {
3965 if (sta->sta_stats.last_tx_bytes > sta->sta_stats.tx_bytes)
3966 sta->sta_stats.last_tx_bytes = sta->sta_stats.tx_bytes;
3967 if (sta->sta_stats.last_rx_bytes > sta->sta_stats.rx_bytes)
3968 sta->sta_stats.last_rx_bytes = sta->sta_stats.rx_bytes;
3969 if (sta->sta_stats.last_rx_bc_bytes > sta->sta_stats.rx_bc_bytes)
3970 sta->sta_stats.last_rx_bc_bytes = sta->sta_stats.rx_bc_bytes;
3971 if (sta->sta_stats.last_rx_mc_bytes > sta->sta_stats.rx_mc_bytes)
3972 sta->sta_stats.last_rx_mc_bytes = sta->sta_stats.rx_mc_bytes;
3973
3974 curr_tx_bytes = sta->sta_stats.tx_bytes - sta->sta_stats.last_tx_bytes;
3975 curr_rx_bytes = sta->sta_stats.rx_bytes - sta->sta_stats.last_rx_bytes;
3976 sta->sta_stats.tx_tp_kbits = (curr_tx_bytes * 8 / 2) >> 10;/*Kbps*/
3977 sta->sta_stats.rx_tp_kbits = (curr_rx_bytes * 8 / 2) >> 10;/*Kbps*/
3978
3979 sta->sta_stats.smooth_tx_tp_kbits = (sta->sta_stats.smooth_tx_tp_kbits * 6 / 10) + (sta->sta_stats.tx_tp_kbits * 4 / 10);/*Kbps*/
3980 sta->sta_stats.smooth_rx_tp_kbits = (sta->sta_stats.smooth_rx_tp_kbits * 6 / 10) + (sta->sta_stats.rx_tp_kbits * 4 / 10);/*Kbps*/
3981
3982 curr_tx_mbytes = (curr_tx_bytes / 2) >> 20;/*MBps*/
3983 curr_rx_mbytes = (curr_rx_bytes / 2) >> 20;/*MBps*/
3984
3985 sta->cmn.tx_moving_average_tp =
3986 (sta->cmn.tx_moving_average_tp / 10) + (curr_tx_mbytes * 9 / 10); /*MBps*/
3987
3988 sta->cmn.rx_moving_average_tp =
3989 (sta->cmn.rx_moving_average_tp / 10) + (curr_rx_mbytes * 9 /10); /*MBps*/
3990
3991 rtw_collect_bcn_info(sta->padapter);
3992
3993 if (adapter->bsta_tp_dump)
3994 dump_sta_traffic(RTW_DBGDUMP, adapter, sta);
3995
3996 sta->sta_stats.last_tx_bytes = sta->sta_stats.tx_bytes;
3997 sta->sta_stats.last_rx_bytes = sta->sta_stats.rx_bytes;
3998 sta->sta_stats.last_rx_bc_bytes = sta->sta_stats.rx_bc_bytes;
3999 sta->sta_stats.last_rx_mc_bytes = sta->sta_stats.rx_mc_bytes;
4000 }
4001 }
4002 }
4003
4004 void rtw_sta_traffic_info(void *sel, _adapter *adapter)
4005 {
4006 struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
4007 struct sta_info *sta;
4008 int i;
4009
4010 for (i = 0; i < MACID_NUM_SW_LIMIT; i++) {
4011 sta = macid_ctl->sta[i];
4012 if (sta && !is_broadcast_mac_addr(sta->cmn.mac_addr))
4013 dump_sta_traffic(sel, adapter, sta);
4014 }
4015 }
4016
4017 /*#define DBG_TRAFFIC_STATISTIC*/
4018 static void collect_traffic_statistics(_adapter *padapter)
4019 {
4020 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
4021
4022 /*_rtw_memset(&pdvobjpriv->traffic_stat, 0, sizeof(struct rtw_traffic_statistics));*/
4023
4024 /* Tx bytes reset*/
4025 pdvobjpriv->traffic_stat.tx_bytes = 0;
4026 pdvobjpriv->traffic_stat.tx_pkts = 0;
4027 pdvobjpriv->traffic_stat.tx_drop = 0;
4028
4029 /* Rx bytes reset*/
4030 pdvobjpriv->traffic_stat.rx_bytes = 0;
4031 pdvobjpriv->traffic_stat.rx_pkts = 0;
4032 pdvobjpriv->traffic_stat.rx_drop = 0;
4033
4034 rtw_mi_traffic_statistics(padapter);
4035
4036 /* Calculate throughput in last interval */
4037 pdvobjpriv->traffic_stat.cur_tx_bytes = pdvobjpriv->traffic_stat.tx_bytes - pdvobjpriv->traffic_stat.last_tx_bytes;
4038 pdvobjpriv->traffic_stat.cur_rx_bytes = pdvobjpriv->traffic_stat.rx_bytes - pdvobjpriv->traffic_stat.last_rx_bytes;
4039 pdvobjpriv->traffic_stat.last_tx_bytes = pdvobjpriv->traffic_stat.tx_bytes;
4040 pdvobjpriv->traffic_stat.last_rx_bytes = pdvobjpriv->traffic_stat.rx_bytes;
4041
4042 pdvobjpriv->traffic_stat.cur_tx_tp = (u32)(pdvobjpriv->traffic_stat.cur_tx_bytes * 8 / 2 / 1024 / 1024);/*Mbps*/
4043 pdvobjpriv->traffic_stat.cur_rx_tp = (u32)(pdvobjpriv->traffic_stat.cur_rx_bytes * 8 / 2 / 1024 / 1024);/*Mbps*/
4044
4045 #ifdef DBG_TRAFFIC_STATISTIC
4046 RTW_INFO("\n========================\n");
4047 RTW_INFO("cur_tx_bytes:%lld\n", pdvobjpriv->traffic_stat.cur_tx_bytes);
4048 RTW_INFO("cur_rx_bytes:%lld\n", pdvobjpriv->traffic_stat.cur_rx_bytes);
4049
4050 RTW_INFO("last_tx_bytes:%lld\n", pdvobjpriv->traffic_stat.last_tx_bytes);
4051 RTW_INFO("last_rx_bytes:%lld\n", pdvobjpriv->traffic_stat.last_rx_bytes);
4052
4053 RTW_INFO("cur_tx_tp:%d (Mbps)\n", pdvobjpriv->traffic_stat.cur_tx_tp);
4054 RTW_INFO("cur_rx_tp:%d (Mbps)\n", pdvobjpriv->traffic_stat.cur_rx_tp);
4055 #endif
4056
4057 #ifdef CONFIG_RTW_NAPI
4058 #ifdef CONFIG_RTW_NAPI_DYNAMIC
4059 dynamic_napi_th_chk (padapter);
4060 #endif /* CONFIG_RTW_NAPI_DYNAMIC */
4061 #endif
4062
4063 }
4064
4065 void rtw_dynamic_check_timer_handlder(void *ctx)
4066 {
4067 struct dvobj_priv *pdvobj = (struct dvobj_priv *)ctx;
4068 _adapter *adapter = dvobj_get_primary_adapter(pdvobj);
4069
4070 if (!adapter)
4071 goto exit;
4072
4073 #if (MP_DRIVER == 1)
4074 if (adapter->registrypriv.mp_mode == 1 && adapter->mppriv.mp_dm == 0) { /* for MP ODM dynamic Tx power tracking */
4075 /* RTW_INFO("%s mp_dm =0 return\n", __func__); */
4076 goto exit;
4077 }
4078 #endif
4079
4080 if (!rtw_is_hw_init_completed(adapter))
4081 goto exit;
4082
4083 if (RTW_CANNOT_RUN(adapter))
4084 goto exit;
4085
4086 collect_traffic_statistics(adapter);
4087 collect_sta_traffic_statistics(adapter);
4088 rtw_mi_dynamic_check_timer_handlder(adapter);
4089
4090 if (!is_drv_in_lps(adapter))
4091 rtw_dynamic_chk_wk_cmd(adapter);
4092
4093 exit:
4094 _set_timer(&pdvobj->dynamic_chk_timer, 2000);
4095 }
4096
4097
4098 #ifdef CONFIG_SET_SCAN_DENY_TIMER
4099 inline bool rtw_is_scan_deny(_adapter *adapter)
4100 {
4101 struct mlme_priv *mlmepriv = &adapter->mlmepriv;
4102 return (ATOMIC_READ(&mlmepriv->set_scan_deny) != 0) ? _TRUE : _FALSE;
4103 }
4104
4105 inline void rtw_clear_scan_deny(_adapter *adapter)
4106 {
4107 struct mlme_priv *mlmepriv = &adapter->mlmepriv;
4108 ATOMIC_SET(&mlmepriv->set_scan_deny, 0);
4109 if (0)
4110 RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
4111 }
4112
4113 void rtw_set_scan_deny_timer_hdl(void *ctx)
4114 {
4115 _adapter *adapter = (_adapter *)ctx;
4116
4117 rtw_clear_scan_deny(adapter);
4118 }
4119 void rtw_set_scan_deny(_adapter *adapter, u32 ms)
4120 {
4121 struct mlme_priv *mlmepriv = &adapter->mlmepriv;
4122 if (0)
4123 RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
4124 ATOMIC_SET(&mlmepriv->set_scan_deny, 1);
4125 _set_timer(&mlmepriv->set_scan_deny_timer, ms);
4126 }
4127 #endif
4128
4129 #ifdef CONFIG_LAYER2_ROAMING
4130 /*
4131 * Select a new roaming candidate from the original @param candidate and @param competitor
4132 * @return _TRUE: candidate is updated
4133 * @return _FALSE: candidate is not updated
4134 */
4135 static int rtw_check_roaming_candidate(struct mlme_priv *mlme
4136 , struct wlan_network **candidate, struct wlan_network *competitor)
4137 {
4138 int updated = _FALSE;
4139 _adapter *adapter = container_of(mlme, _adapter, mlmepriv);
4140 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
4141 RT_CHANNEL_INFO *chset = rfctl->channel_set;
4142 u8 ch = competitor->network.Configuration.DSConfig;
4143
4144 if (rtw_chset_search_ch(chset, ch) < 0)
4145 goto exit;
4146 if (IS_DFS_SLAVE_WITH_RD(rfctl)
4147 && !rtw_rfctl_dfs_domain_unknown(rfctl)
4148 && rtw_chset_is_ch_non_ocp(chset, ch))
4149 goto exit;
4150
4151 #if defined(CONFIG_RTW_REPEATER_SON) && (!defined(CONFIG_RTW_REPEATER_SON_ROOT))
4152 if (rtw_rson_isupdate_roamcan(mlme, candidate, competitor))
4153 goto update;
4154 goto exit;
4155 #endif
4156
4157 if (is_same_ess(&competitor->network, &mlme->cur_network.network) == _FALSE)
4158 goto exit;
4159
4160 if (rtw_is_desired_network(adapter, competitor) == _FALSE)
4161 goto exit;
4162
4163 #ifdef CONFIG_LAYER2_ROAMING
4164 if (mlme->need_to_roam == _FALSE)
4165 goto exit;
4166 #endif
4167
4168 RTW_INFO("roam candidate:%s %s("MAC_FMT", ch%3u) rssi:%d, age:%5d\n",
4169 (competitor == mlme->cur_network_scanned) ? "*" : " " ,
4170 competitor->network.Ssid.Ssid,
4171 MAC_ARG(competitor->network.MacAddress),
4172 competitor->network.Configuration.DSConfig,
4173 (int)competitor->network.Rssi,
4174 rtw_get_passing_time_ms(competitor->last_scanned)
4175 );
4176
4177 /* got specific addr to roam */
4178 if (!is_zero_mac_addr(mlme->roam_tgt_addr)) {
4179 if (_rtw_memcmp(mlme->roam_tgt_addr, competitor->network.MacAddress, ETH_ALEN) == _TRUE)
4180 goto update;
4181 else
4182 goto exit;
4183 }
4184
4185 #ifdef CONFIG_RTW_80211R
4186 if (rtw_ft_chk_flags(adapter, RTW_FT_PEER_EN)) {
4187 if (rtw_ft_chk_roaming_candidate(adapter, competitor) == _FALSE)
4188 goto exit;
4189 }
4190
4191 #ifdef CONFIG_RTW_WNM
4192 if (rtw_wnm_btm_diff_bss(adapter) &&
4193 rtw_wnm_btm_roam_candidate(adapter, competitor)) {
4194 goto update;
4195 }
4196 #endif
4197 #endif
4198
4199 #if 1
4200 if (rtw_get_passing_time_ms(competitor->last_scanned) >= mlme->roam_scanr_exp_ms)
4201 goto exit;
4202
4203 if (competitor->network.Rssi - mlme->cur_network_scanned->network.Rssi < mlme->roam_rssi_diff_th)
4204 goto exit;
4205
4206 if (*candidate != NULL && (*candidate)->network.Rssi >= competitor->network.Rssi)
4207 goto exit;
4208 #else
4209 goto exit;
4210 #endif
4211
4212 update:
4213 *candidate = competitor;
4214 updated = _TRUE;
4215
4216 exit:
4217 return updated;
4218 }
4219
4220 int rtw_select_roaming_candidate(struct mlme_priv *mlme)
4221 {
4222 _irqL irqL;
4223 int ret = _FAIL;
4224 _list *phead;
4225 _adapter *adapter;
4226 _queue *queue = &(mlme->scanned_queue);
4227 struct wlan_network *pnetwork = NULL;
4228 struct wlan_network *candidate = NULL;
4229
4230 if (mlme->cur_network_scanned == NULL) {
4231 rtw_warn_on(1);
4232 goto exit;
4233 }
4234
4235 _enter_critical_bh(&(mlme->scanned_queue.lock), &irqL);
4236 phead = get_list_head(queue);
4237 adapter = (_adapter *)mlme->nic_hdl;
4238
4239 mlme->pscanned = get_next(phead);
4240
4241 while (!rtw_end_of_queue_search(phead, mlme->pscanned)) {
4242
4243 pnetwork = LIST_CONTAINOR(mlme->pscanned, struct wlan_network, list);
4244 if (pnetwork == NULL) {
4245 ret = _FAIL;
4246 goto exit;
4247 }
4248
4249 mlme->pscanned = get_next(mlme->pscanned);
4250
4251 if (0)
4252 RTW_INFO("%s("MAC_FMT", ch%u) rssi:%d\n"
4253 , pnetwork->network.Ssid.Ssid
4254 , MAC_ARG(pnetwork->network.MacAddress)
4255 , pnetwork->network.Configuration.DSConfig
4256 , (int)pnetwork->network.Rssi);
4257
4258 rtw_check_roaming_candidate(mlme, &candidate, pnetwork);
4259
4260 }
4261
4262 if (candidate == NULL) {
4263 /* if parent note lost the path to root and there is no other cadidate, report disconnection */
4264 #if defined(CONFIG_RTW_REPEATER_SON) && (!defined(CONFIG_RTW_REPEATER_SON_ROOT))
4265 struct rtw_rson_struct rson_curr;
4266 u8 rson_score;
4267
4268 rtw_get_rson_struct(&(mlme->cur_network_scanned->network), &rson_curr);
4269 rson_score = rtw_cal_rson_score(&rson_curr, mlme->cur_network_scanned->network.Rssi);
4270 if (check_fwstate(mlme, WIFI_ASOC_STATE)
4271 && ((rson_score == RTW_RSON_SCORE_NOTCNNT)
4272 || (rson_score == RTW_RSON_SCORE_NOTSUP)))
4273 receive_disconnect(adapter, mlme->cur_network_scanned->network.MacAddress
4274 , WLAN_REASON_EXPIRATION_CHK, _FALSE);
4275 #endif
4276 RTW_INFO("%s: return _FAIL(candidate == NULL)\n", __FUNCTION__);
4277 ret = _FAIL;
4278 goto exit;
4279 } else {
4280 #if defined(CONFIG_RTW_REPEATER_SON) && (!defined(CONFIG_RTW_REPEATER_SON_ROOT))
4281 struct rtw_rson_struct rson_curr;
4282 u8 rson_score;
4283
4284 rtw_get_rson_struct(&(candidate->network), &rson_curr);
4285 rson_score = rtw_cal_rson_score(&rson_curr, candidate->network.Rssi);
4286 RTW_INFO("%s: candidate: %s("MAC_FMT", ch:%u) rson_score:%d\n", __FUNCTION__,
4287 candidate->network.Ssid.Ssid, MAC_ARG(candidate->network.MacAddress),
4288 candidate->network.Configuration.DSConfig, rson_score);
4289 #else
4290 RTW_INFO("%s: candidate: %s("MAC_FMT", ch:%u)\n", __FUNCTION__,
4291 candidate->network.Ssid.Ssid, MAC_ARG(candidate->network.MacAddress),
4292 candidate->network.Configuration.DSConfig);
4293 #endif
4294 mlme->roam_network = candidate;
4295
4296 if (_rtw_memcmp(candidate->network.MacAddress, mlme->roam_tgt_addr, ETH_ALEN) == _TRUE)
4297 _rtw_memset(mlme->roam_tgt_addr, 0, ETH_ALEN);
4298 }
4299
4300 ret = _SUCCESS;
4301 exit:
4302 _exit_critical_bh(&(mlme->scanned_queue.lock), &irqL);
4303
4304 return ret;
4305 }
4306 #endif /* CONFIG_LAYER2_ROAMING */
4307
4308 /*
4309 * Select a new join candidate from the original @param candidate and @param competitor
4310 * @return _TRUE: candidate is updated
4311 * @return _FALSE: candidate is not updated
4312 */
4313 static int rtw_check_join_candidate(struct mlme_priv *mlme
4314 , struct wlan_network **candidate, struct wlan_network *competitor)
4315 {
4316 int updated = _FALSE;
4317 _adapter *adapter = container_of(mlme, _adapter, mlmepriv);
4318 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
4319 RT_CHANNEL_INFO *chset = rfctl->channel_set;
4320 u8 ch = competitor->network.Configuration.DSConfig;
4321
4322 if (rtw_chset_search_ch(chset, ch) < 0)
4323 goto exit;
4324 if (IS_DFS_SLAVE_WITH_RD(rfctl)
4325 && !rtw_rfctl_dfs_domain_unknown(rfctl)
4326 && rtw_chset_is_ch_non_ocp(chset, ch))
4327 goto exit;
4328
4329 #if defined(CONFIG_RTW_REPEATER_SON) && (!defined(CONFIG_RTW_REPEATER_SON_ROOT))
4330 s16 rson_score;
4331 struct rtw_rson_struct rson_data;
4332
4333 if (rtw_rson_choose(candidate, competitor)) {
4334 *candidate = competitor;
4335 rtw_get_rson_struct(&((*candidate)->network), &rson_data);
4336 rson_score = rtw_cal_rson_score(&rson_data, (*candidate)->network.Rssi);
4337 RTW_INFO("[assoc_ssid:%s] new candidate: %s("MAC_FMT", ch%u) rson_score:%d\n",
4338 mlme->assoc_ssid.Ssid,
4339 (*candidate)->network.Ssid.Ssid,
4340 MAC_ARG((*candidate)->network.MacAddress),
4341 (*candidate)->network.Configuration.DSConfig,
4342 rson_score);
4343 return _TRUE;
4344 }
4345 return _FALSE;
4346 #endif
4347
4348 /* check bssid, if needed */
4349 if (mlme->assoc_by_bssid == _TRUE) {
4350 if (_rtw_memcmp(competitor->network.MacAddress, mlme->assoc_bssid, ETH_ALEN) == _FALSE)
4351 goto exit;
4352 }
4353
4354 /* check ssid, if needed */
4355 if (mlme->assoc_ssid.Ssid[0] && mlme->assoc_ssid.SsidLength) {
4356 if (competitor->network.Ssid.SsidLength != mlme->assoc_ssid.SsidLength
4357 || _rtw_memcmp(competitor->network.Ssid.Ssid, mlme->assoc_ssid.Ssid, mlme->assoc_ssid.SsidLength) == _FALSE
4358 )
4359 goto exit;
4360 }
4361
4362 if (rtw_is_desired_network(adapter, competitor) == _FALSE)
4363 goto exit;
4364
4365 #ifdef CONFIG_LAYER2_ROAMING
4366 if (rtw_to_roam(adapter) > 0) {
4367 if (rtw_get_passing_time_ms(competitor->last_scanned) >= mlme->roam_scanr_exp_ms
4368 || is_same_ess(&competitor->network, &mlme->cur_network.network) == _FALSE
4369 )
4370 goto exit;
4371 }
4372 #endif
4373
4374 if (*candidate == NULL || (*candidate)->network.Rssi < competitor->network.Rssi) {
4375 *candidate = competitor;
4376 updated = _TRUE;
4377 }
4378
4379 if (updated) {
4380 RTW_INFO("[by_bssid:%u][assoc_ssid:%s][to_roam:%u] "
4381 "new candidate: %s("MAC_FMT", ch%u) rssi:%d\n",
4382 mlme->assoc_by_bssid,
4383 mlme->assoc_ssid.Ssid,
4384 rtw_to_roam(adapter),
4385 (*candidate)->network.Ssid.Ssid,
4386 MAC_ARG((*candidate)->network.MacAddress),
4387 (*candidate)->network.Configuration.DSConfig,
4388 (int)(*candidate)->network.Rssi
4389 );
4390 }
4391
4392 exit:
4393 return updated;
4394 }
4395
4396 /*
4397 Calling context:
4398 The caller of the sub-routine will be in critical section...
4399
4400 The caller must hold the following spinlock
4401
4402 pmlmepriv->lock
4403
4404
4405 */
4406
4407 int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv)
4408 {
4409 _irqL irqL;
4410 int ret;
4411 _list *phead;
4412 _adapter *adapter;
4413 _queue *queue = &(pmlmepriv->scanned_queue);
4414 struct wlan_network *pnetwork = NULL;
4415 struct wlan_network *candidate = NULL;
4416 #ifdef CONFIG_ANTENNA_DIVERSITY
4417 u8 bSupportAntDiv = _FALSE;
4418 #endif
4419
4420 adapter = (_adapter *)pmlmepriv->nic_hdl;
4421
4422 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4423
4424 #ifdef CONFIG_LAYER2_ROAMING
4425 if (pmlmepriv->roam_network) {
4426 candidate = pmlmepriv->roam_network;
4427 pmlmepriv->roam_network = NULL;
4428 goto candidate_exist;
4429 }
4430 #endif
4431
4432 phead = get_list_head(queue);
4433 pmlmepriv->pscanned = get_next(phead);
4434
4435 while (!rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) {
4436
4437 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
4438 if (pnetwork == NULL) {
4439 ret = _FAIL;
4440 goto exit;
4441 }
4442
4443 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
4444
4445 if (0)
4446 RTW_INFO("%s("MAC_FMT", ch%u) rssi:%d\n"
4447 , pnetwork->network.Ssid.Ssid
4448 , MAC_ARG(pnetwork->network.MacAddress)
4449 , pnetwork->network.Configuration.DSConfig
4450 , (int)pnetwork->network.Rssi);
4451
4452 rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork);
4453
4454 }
4455
4456 if (candidate == NULL) {
4457 RTW_INFO("%s: return _FAIL(candidate == NULL)\n", __FUNCTION__);
4458 #ifdef CONFIG_WOWLAN
4459 _clr_fwstate_(pmlmepriv, WIFI_ASOC_STATE | WIFI_UNDER_LINKING);
4460 #endif
4461 ret = _FAIL;
4462 goto exit;
4463 } else {
4464 RTW_INFO("%s: candidate: %s("MAC_FMT", ch:%u)\n", __FUNCTION__,
4465 candidate->network.Ssid.Ssid, MAC_ARG(candidate->network.MacAddress),
4466 candidate->network.Configuration.DSConfig);
4467 goto candidate_exist;
4468 }
4469
4470 candidate_exist:
4471
4472 /* check for situation of WIFI_ASOC_STATE */
4473 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4474 RTW_INFO("%s: WIFI_ASOC_STATE while ask_for_joinbss!!!\n", __FUNCTION__);
4475
4476 #if 0 /* for WPA/WPA2 authentication, wpa_supplicant will expect authentication from AP, it is needed to reconnect AP... */
4477 if (is_same_network(&pmlmepriv->cur_network.network, &candidate->network)) {
4478 RTW_INFO("%s: WIFI_ASOC_STATE and is same network, it needn't join again\n", __FUNCTION__);
4479
4480 rtw_indicate_connect(adapter);/* rtw_indicate_connect again */
4481
4482 ret = 2;
4483 goto exit;
4484 } else
4485 #endif
4486 {
4487 rtw_disassoc_cmd(adapter, 0, 0);
4488 rtw_indicate_disconnect(adapter, 0, _FALSE);
4489 rtw_free_assoc_resources_cmd(adapter, _TRUE, 0);
4490 }
4491 }
4492
4493 #ifdef CONFIG_ANTENNA_DIVERSITY
4494 rtw_hal_get_def_var(adapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &(bSupportAntDiv));
4495 if (_TRUE == bSupportAntDiv) {
4496 u8 CurrentAntenna;
4497 rtw_hal_get_odm_var(adapter, HAL_ODM_ANTDIV_SELECT, &(CurrentAntenna), NULL);
4498 RTW_INFO("#### Opt_Ant_(%s) , cur_Ant(%s)\n",
4499 (MAIN_ANT == candidate->network.PhyInfo.Optimum_antenna) ? "MAIN_ANT" : "AUX_ANT",
4500 (MAIN_ANT == CurrentAntenna) ? "MAIN_ANT" : "AUX_ANT"
4501 );
4502 }
4503 #endif
4504 set_fwstate(pmlmepriv, WIFI_UNDER_LINKING);
4505 ret = rtw_joinbss_cmd(adapter, candidate);
4506
4507 exit:
4508 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4509
4510
4511 return ret;
4512 }
4513
4514 sint rtw_set_auth(_adapter *adapter, struct security_priv *psecuritypriv)
4515 {
4516 struct cmd_obj *pcmd;
4517 struct setauth_parm *psetauthparm;
4518 struct cmd_priv *pcmdpriv = &(adapter->cmdpriv);
4519 sint res = _SUCCESS;
4520
4521
4522 pcmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
4523 if (pcmd == NULL) {
4524 res = _FAIL; /* try again */
4525 goto exit;
4526 }
4527
4528 psetauthparm = (struct setauth_parm *)rtw_zmalloc(sizeof(struct setauth_parm));
4529 if (psetauthparm == NULL) {
4530 rtw_mfree((unsigned char *)pcmd, sizeof(struct cmd_obj));
4531 res = _FAIL;
4532 goto exit;
4533 }
4534
4535 _rtw_memset(psetauthparm, 0, sizeof(struct setauth_parm));
4536 psetauthparm->mode = (unsigned char)psecuritypriv->dot11AuthAlgrthm;
4537
4538 pcmd->cmdcode = CMD_SET_AUTH;
4539 pcmd->parmbuf = (unsigned char *)psetauthparm;
4540 pcmd->cmdsz = (sizeof(struct setauth_parm));
4541 pcmd->rsp = NULL;
4542 pcmd->rspsz = 0;
4543
4544
4545 _rtw_init_listhead(&pcmd->list);
4546
4547
4548 res = rtw_enqueue_cmd(pcmdpriv, pcmd);
4549
4550 exit:
4551
4552
4553 return res;
4554
4555 }
4556
4557
4558 sint rtw_set_key(_adapter *adapter, struct security_priv *psecuritypriv, sint keyid, u8 set_tx, bool enqueue)
4559 {
4560 u8 keylen;
4561 struct cmd_obj *pcmd;
4562 struct setkey_parm *psetkeyparm;
4563 struct cmd_priv *pcmdpriv = &(adapter->cmdpriv);
4564 sint res = _SUCCESS;
4565
4566
4567 psetkeyparm = (struct setkey_parm *)rtw_zmalloc(sizeof(struct setkey_parm));
4568 if (psetkeyparm == NULL) {
4569 res = _FAIL;
4570 goto exit;
4571 }
4572 _rtw_memset(psetkeyparm, 0, sizeof(struct setkey_parm));
4573
4574 if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
4575 psetkeyparm->algorithm = (unsigned char)psecuritypriv->dot118021XGrpPrivacy;
4576 } else {
4577 psetkeyparm->algorithm = (u8)psecuritypriv->dot11PrivacyAlgrthm;
4578
4579 }
4580 psetkeyparm->keyid = (u8)keyid;/* 0~3 */
4581 psetkeyparm->set_tx = set_tx;
4582 if (is_wep_enc(psetkeyparm->algorithm))
4583 adapter->securitypriv.key_mask |= BIT(psetkeyparm->keyid);
4584
4585 RTW_INFO("==> rtw_set_key algorithm(%x),keyid(%x),key_mask(%x)\n", psetkeyparm->algorithm, psetkeyparm->keyid, adapter->securitypriv.key_mask);
4586
4587 switch (psetkeyparm->algorithm) {
4588
4589 case _WEP40_:
4590 keylen = 5;
4591 _rtw_memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen);
4592 break;
4593 case _WEP104_:
4594 keylen = 13;
4595 _rtw_memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen);
4596 break;
4597 case _TKIP_:
4598 keylen = 16;
4599 _rtw_memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
4600 break;
4601 case _AES_:
4602 case _GCMP_:
4603 keylen = 16;
4604 _rtw_memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
4605 break;
4606 case _GCMP_256_:
4607 case _CCMP_256_:
4608 keylen = 32;
4609 _rtw_memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
4610 break;
4611 default:
4612 res = _FAIL;
4613 rtw_mfree((unsigned char *)psetkeyparm, sizeof(struct setkey_parm));
4614 goto exit;
4615 }
4616
4617
4618 if (enqueue) {
4619 pcmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
4620 if (pcmd == NULL) {
4621 rtw_mfree((unsigned char *)psetkeyparm, sizeof(struct setkey_parm));
4622 res = _FAIL; /* try again */
4623 goto exit;
4624 }
4625
4626 pcmd->cmdcode =CMD_SET_KEY;
4627 pcmd->parmbuf = (u8 *)psetkeyparm;
4628 pcmd->cmdsz = (sizeof(struct setkey_parm));
4629 pcmd->rsp = NULL;
4630 pcmd->rspsz = 0;
4631
4632 _rtw_init_listhead(&pcmd->list);
4633
4634 /* _rtw_init_sema(&(pcmd->cmd_sem), 0); */
4635
4636 res = rtw_enqueue_cmd(pcmdpriv, pcmd);
4637 } else {
4638 setkey_hdl(adapter, (u8 *)psetkeyparm);
4639 rtw_mfree((u8 *) psetkeyparm, sizeof(struct setkey_parm));
4640 }
4641 exit:
4642 return res;
4643
4644 }
4645
4646 #ifdef CONFIG_WMMPS_STA
4647 /*
4648 * rtw_uapsd_use_default_setting
4649 * This function is used for setting default uapsd max sp length to uapsd_max_sp_len
4650 * in qos_priv data structure from registry. In additional, it will also map default uapsd
4651 * ac to each uapsd TID, delivery-enabled and trigger-enabled of corresponding TID.
4652 *
4653 * Arguments:
4654 * @padapter: _adapter pointer.
4655 *
4656 * Auther: Arvin Liu
4657 * Date: 2017/05/03
4658 */
4659 void rtw_uapsd_use_default_setting(_adapter *padapter)
4660 {
4661 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4662 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
4663 struct registry_priv *pregistrypriv = &padapter->registrypriv;
4664
4665 if (pregistrypriv->uapsd_ac_enable != 0) {
4666 pqospriv->uapsd_max_sp_len = pregistrypriv->uapsd_max_sp_len;
4667
4668 CLEAR_FLAGS(pqospriv->uapsd_tid);
4669 CLEAR_FLAGS(pqospriv->uapsd_tid_delivery_enabled);
4670 CLEAR_FLAGS(pqospriv->uapsd_tid_trigger_enabled);
4671
4672 /* check the uapsd setting of AC_VO from registry then map these setting to each TID if necessary */
4673 if(TEST_FLAG(pregistrypriv->uapsd_ac_enable, DRV_CFG_UAPSD_VO)) {
4674 SET_FLAG(pqospriv->uapsd_tid, WMM_TID7);
4675 SET_FLAG(pqospriv->uapsd_tid_delivery_enabled, WMM_TID7);
4676 SET_FLAG(pqospriv->uapsd_tid_trigger_enabled, WMM_TID7);
4677 SET_FLAG(pqospriv->uapsd_tid, WMM_TID6);
4678 SET_FLAG(pqospriv->uapsd_tid_delivery_enabled, WMM_TID6);
4679 SET_FLAG(pqospriv->uapsd_tid_trigger_enabled, WMM_TID6);
4680 }
4681
4682 /* check the uapsd setting of AC_VI from registry then map these setting to each TID if necessary */
4683 if(TEST_FLAG(pregistrypriv->uapsd_ac_enable, DRV_CFG_UAPSD_VI)) {
4684 SET_FLAG(pqospriv->uapsd_tid, WMM_TID5);
4685 SET_FLAG(pqospriv->uapsd_tid_delivery_enabled, WMM_TID5);
4686 SET_FLAG(pqospriv->uapsd_tid_trigger_enabled, WMM_TID5);
4687 SET_FLAG(pqospriv->uapsd_tid, WMM_TID4);
4688 SET_FLAG(pqospriv->uapsd_tid_delivery_enabled, WMM_TID4);
4689 SET_FLAG(pqospriv->uapsd_tid_trigger_enabled, WMM_TID4);
4690 }
4691
4692 /* check the uapsd setting of AC_BK from registry then map these setting to each TID if necessary */
4693 if(TEST_FLAG(pregistrypriv->uapsd_ac_enable, DRV_CFG_UAPSD_BK)) {
4694 SET_FLAG(pqospriv->uapsd_tid, WMM_TID2);
4695 SET_FLAG(pqospriv->uapsd_tid_delivery_enabled, WMM_TID2);
4696 SET_FLAG(pqospriv->uapsd_tid_trigger_enabled, WMM_TID2);
4697 SET_FLAG(pqospriv->uapsd_tid, WMM_TID1);
4698 SET_FLAG(pqospriv->uapsd_tid_delivery_enabled, WMM_TID1);
4699 SET_FLAG(pqospriv->uapsd_tid_trigger_enabled, WMM_TID1);
4700 }
4701
4702 /* check the uapsd setting of AC_BE from registry then map these setting to each TID if necessary */
4703 if(TEST_FLAG(pregistrypriv->uapsd_ac_enable, DRV_CFG_UAPSD_BE)) {
4704 SET_FLAG(pqospriv->uapsd_tid, WMM_TID3);
4705 SET_FLAG(pqospriv->uapsd_tid_delivery_enabled, WMM_TID3);
4706 SET_FLAG(pqospriv->uapsd_tid_trigger_enabled, WMM_TID3);
4707 SET_FLAG(pqospriv->uapsd_tid, WMM_TID0);
4708 SET_FLAG(pqospriv->uapsd_tid_delivery_enabled, WMM_TID0);
4709 SET_FLAG(pqospriv->uapsd_tid_trigger_enabled, WMM_TID0);
4710 }
4711
4712 RTW_INFO("[WMMPS] UAPSD MAX SP Len = 0x%02x, UAPSD TID enabled = 0x%02x\n",
4713 pqospriv->uapsd_max_sp_len, (u8)pqospriv->uapsd_tid);
4714 }
4715
4716 }
4717
4718 /*
4719 * rtw_is_wmmps_mode
4720 * This function is used for checking whether Driver and an AP support uapsd function or not.
4721 * If both of them support uapsd function, it will return true. Otherwise returns false.
4722 *
4723 * Arguments:
4724 * @padapter: _adapter pointer.
4725 *
4726 * Auther: Arvin Liu
4727 * Date: 2017/06/12
4728 */
4729 bool rtw_is_wmmps_mode(_adapter *padapter)
4730 {
4731 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4732 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
4733
4734 if ((pqospriv->uapsd_ap_supported) && ((pqospriv->uapsd_tid & BIT_MASK_TID_TC) != 0))
4735 return _TRUE;
4736
4737 return _FALSE;
4738 }
4739 #endif /* CONFIG_WMMPS_STA */
4740
4741 /* adjust IEs for rtw_joinbss_cmd in WMM */
4742 int rtw_restruct_wmm_ie(_adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len, uint initial_out_len)
4743 {
4744 #ifdef CONFIG_WMMPS_STA
4745 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4746 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
4747 #endif /* CONFIG_WMMPS_STA */
4748 unsigned int ielength = 0;
4749 unsigned int i, j;
4750 u8 qos_info = 0;
4751
4752 i = 12; /* after the fixed IE */
4753 while (i < in_len) {
4754 ielength = initial_out_len;
4755
4756 if (in_ie[i] == 0xDD && in_ie[i + 2] == 0x00 && in_ie[i + 3] == 0x50 && in_ie[i + 4] == 0xF2 && in_ie[i + 5] == 0x02 && i + 5 < in_len) { /* WMM element ID and OUI */
4757
4758 /* Append WMM IE to the last index of out_ie */
4759 #if 0
4760 for (j = i; j < i + (in_ie[i + 1] + 2); j++) {
4761 out_ie[ielength] = in_ie[j];
4762 ielength++;
4763 }
4764 out_ie[initial_out_len + 8] = 0x00; /* force the QoS Info Field to be zero */
4765 #endif
4766
4767 for (j = i; j < i + 9; j++) {
4768 out_ie[ielength] = in_ie[j];
4769 ielength++;
4770 }
4771 out_ie[initial_out_len + 1] = 0x07;
4772 out_ie[initial_out_len + 6] = 0x00;
4773
4774 #ifdef CONFIG_WMMPS_STA
4775 switch(pqospriv->uapsd_max_sp_len) {
4776 case NO_LIMIT:
4777 /* do nothing */
4778 break;
4779 case TWO_MSDU:
4780 SET_FLAG(qos_info, BIT5);
4781 break;
4782 case FOUR_MSDU:
4783 SET_FLAG(qos_info, BIT6);
4784 break;
4785 case SIX_MSDU:
4786 SET_FLAG(qos_info, BIT5);
4787 SET_FLAG(qos_info, BIT6);
4788 break;
4789 default:
4790 /* do nothing */
4791 break;
4792 };
4793
4794 /* check TID7 and TID6 for AC_VO to set corresponding Qos_info bit in WMM IE */
4795 if((TEST_FLAG(pqospriv->uapsd_tid, WMM_TID7)) && (TEST_FLAG(pqospriv->uapsd_tid, WMM_TID6)))
4796 SET_FLAG(qos_info, WMM_IE_UAPSD_VO);
4797 /* check TID5 and TID4 for AC_VI to set corresponding Qos_info bit in WMM IE */
4798 if((TEST_FLAG(pqospriv->uapsd_tid, WMM_TID5)) && (TEST_FLAG(pqospriv->uapsd_tid, WMM_TID4)))
4799 SET_FLAG(qos_info, WMM_IE_UAPSD_VI);
4800 /* check TID2 and TID1 for AC_BK to set corresponding Qos_info bit in WMM IE */
4801 if((TEST_FLAG(pqospriv->uapsd_tid, WMM_TID2)) && (TEST_FLAG(pqospriv->uapsd_tid, WMM_TID1)))
4802 SET_FLAG(qos_info, WMM_IE_UAPSD_BK);
4803 /* check TID3 and TID0 for AC_BE to set corresponding Qos_info bit in WMM IE */
4804 if((TEST_FLAG(pqospriv->uapsd_tid, WMM_TID3)) && (TEST_FLAG(pqospriv->uapsd_tid, WMM_TID0)))
4805 SET_FLAG(qos_info, WMM_IE_UAPSD_BE);
4806 #endif /* CONFIG_WMMPS_STA */
4807
4808 out_ie[initial_out_len + 8] = qos_info;
4809
4810 break;
4811 }
4812
4813 i += (in_ie[i + 1] + 2); /* to the next IE element */
4814 }
4815
4816 return ielength;
4817
4818 }
4819
4820
4821 /*
4822 * Ported from 8185: IsInPreAuthKeyList(). (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.)
4823 * Added by Annie, 2006-05-07.
4824 *
4825 * Search by BSSID,
4826 * Return Value:
4827 * -1 :if there is no pre-auth key in the table
4828 * >=0 :if there is pre-auth key, and return the entry id
4829 *
4830 * */
4831
4832 static int SecIsInPMKIDList(_adapter *Adapter, u8 *bssid)
4833 {
4834 struct security_priv *psecuritypriv = &Adapter->securitypriv;
4835 int i = 0;
4836
4837 do {
4838 if ((psecuritypriv->PMKIDList[i].bUsed) &&
4839 (_rtw_memcmp(psecuritypriv->PMKIDList[i].Bssid, bssid, ETH_ALEN) == _TRUE))
4840 break;
4841 else {
4842 i++;
4843 /* continue; */
4844 }
4845
4846 } while (i < NUM_PMKID_CACHE);
4847
4848 if (i == NUM_PMKID_CACHE) {
4849 i = -1;/* Could not find. */
4850 } else {
4851 /* There is one Pre-Authentication Key for the specific BSSID. */
4852 }
4853
4854 return i;
4855
4856 }
4857
4858 int rtw_cached_pmkid(_adapter *Adapter, u8 *bssid)
4859 {
4860 return SecIsInPMKIDList(Adapter, bssid);
4861 }
4862
4863 int rtw_rsn_sync_pmkid(_adapter *adapter, u8 *ie, uint ie_len, int i_ent)
4864 {
4865 struct security_priv *sec = &adapter->securitypriv;
4866 struct rsne_info info;
4867 u8 gm_cs[4];
4868 int i;
4869
4870 rtw_rsne_info_parse(ie, ie_len, &info);
4871
4872 if (info.err) {
4873 RTW_WARN(FUNC_ADPT_FMT" rtw_rsne_info_parse error\n"
4874 , FUNC_ADPT_ARG(adapter));
4875 return 0;
4876 }
4877
4878 if (i_ent < 0 && info.pmkid_cnt == 0)
4879 goto exit;
4880
4881 if (i_ent >= 0 && info.pmkid_cnt == 1 && _rtw_memcmp(info.pmkid_list, sec->PMKIDList[i_ent].PMKID, 16)) {
4882 RTW_INFO(FUNC_ADPT_FMT" has carried the same PMKID:"KEY_FMT"\n"
4883 , FUNC_ADPT_ARG(adapter), KEY_ARG(&sec->PMKIDList[i_ent].PMKID));
4884 goto exit;
4885 }
4886
4887 /* bakcup group mgmt cs */
4888 if (info.gmcs)
4889 _rtw_memcpy(gm_cs, info.gmcs, 4);
4890
4891 if (info.pmkid_cnt) {
4892 RTW_INFO(FUNC_ADPT_FMT" remove original PMKID, count:%u\n"
4893 , FUNC_ADPT_ARG(adapter), info.pmkid_cnt);
4894 for (i = 0; i < info.pmkid_cnt; i++)
4895 RTW_INFO(" "KEY_FMT"\n", KEY_ARG(info.pmkid_list + i * 16));
4896 }
4897
4898 if (i_ent >= 0) {
4899 RTW_INFO(FUNC_ADPT_FMT" append PMKID:"KEY_FMT"\n"
4900 , FUNC_ADPT_ARG(adapter), KEY_ARG(sec->PMKIDList[i_ent].PMKID));
4901
4902 info.pmkid_cnt = 1; /* update new pmkid_cnt */
4903 _rtw_memcpy(info.pmkid_list, sec->PMKIDList[i_ent].PMKID, 16);
4904 } else
4905 info.pmkid_cnt = 0; /* update new pmkid_cnt */
4906
4907 RTW_PUT_LE16(info.pmkid_list - 2, info.pmkid_cnt);
4908 if (info.gmcs)
4909 _rtw_memcpy(info.pmkid_list + 16 * info.pmkid_cnt, gm_cs, 4);
4910
4911 ie_len = 1 + 1 + 2 + 4
4912 + 2 + 4 * info.pcs_cnt
4913 + 2 + 4 * info.akm_cnt
4914 + 2
4915 + 2 + 16 * info.pmkid_cnt
4916 + (info.gmcs ? 4 : 0)
4917 ;
4918
4919 ie[1] = (u8)(ie_len - 2);
4920
4921 exit:
4922 return ie_len;
4923 }
4924
4925 sint rtw_restruct_sec_ie(_adapter *adapter, u8 *out_ie)
4926 {
4927 u8 authmode = 0x0;
4928 uint ielength = 0;
4929 int iEntry;
4930
4931 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4932 struct security_priv *psecuritypriv = &adapter->securitypriv;
4933 uint ndisauthmode = psecuritypriv->ndisauthtype;
4934
4935 if ((ndisauthmode == Ndis802_11AuthModeWPA) || (ndisauthmode == Ndis802_11AuthModeWPAPSK))
4936 authmode = _WPA_IE_ID_;
4937 if ((ndisauthmode == Ndis802_11AuthModeWPA2) || (ndisauthmode == Ndis802_11AuthModeWPA2PSK))
4938 authmode = _WPA2_IE_ID_;
4939
4940 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
4941 _rtw_memcpy(out_ie, psecuritypriv->wps_ie, psecuritypriv->wps_ie_len);
4942 ielength = psecuritypriv->wps_ie_len;
4943
4944 } else if ((authmode == _WPA_IE_ID_) || (authmode == _WPA2_IE_ID_)) {
4945 /* copy RSN or SSN */
4946 _rtw_memcpy(out_ie, psecuritypriv->supplicant_ie, psecuritypriv->supplicant_ie[1] + 2);
4947 /* debug for CONFIG_IEEE80211W
4948 {
4949 int jj;
4950 printk("supplicant_ie_length=%d &&&&&&&&&&&&&&&&&&&\n", psecuritypriv->supplicant_ie[1]+2);
4951 for(jj=0; jj < psecuritypriv->supplicant_ie[1]+2; jj++)
4952 printk(" %02x ", psecuritypriv->supplicant_ie[jj]);
4953 printk("\n");
4954 }*/
4955 ielength = psecuritypriv->supplicant_ie[1] + 2;
4956 rtw_report_sec_ie(adapter, authmode, psecuritypriv->supplicant_ie);
4957 }
4958
4959 if (authmode == WLAN_EID_RSN) {
4960 iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
4961 ielength = rtw_rsn_sync_pmkid(adapter, out_ie, ielength, iEntry);
4962 }
4963
4964 return ielength;
4965 }
4966
4967 void rtw_init_registrypriv_dev_network(_adapter *adapter)
4968 {
4969 struct registry_priv *pregistrypriv = &adapter->registrypriv;
4970 WLAN_BSSID_EX *pdev_network = &pregistrypriv->dev_network;
4971 u8 *myhwaddr = adapter_mac_addr(adapter);
4972
4973
4974 _rtw_memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN);
4975
4976 _rtw_memcpy(&pdev_network->Ssid, &pregistrypriv->ssid, sizeof(NDIS_802_11_SSID));
4977
4978 pdev_network->Configuration.Length = sizeof(NDIS_802_11_CONFIGURATION);
4979 pdev_network->Configuration.BeaconPeriod = 100;
4980 }
4981
4982 void rtw_update_registrypriv_dev_network(_adapter *adapter)
4983 {
4984 int sz = 0;
4985 struct registry_priv *pregistrypriv = &adapter->registrypriv;
4986 WLAN_BSSID_EX *pdev_network = &pregistrypriv->dev_network;
4987 struct security_priv *psecuritypriv = &adapter->securitypriv;
4988 struct wlan_network *cur_network = &adapter->mlmepriv.cur_network;
4989 /* struct xmit_priv *pxmitpriv = &adapter->xmitpriv; */
4990 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
4991
4992
4993 #if 0
4994 pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense;
4995 pxmitpriv->vcs = pregistrypriv->vcs_type;
4996 pxmitpriv->vcs_type = pregistrypriv->vcs_type;
4997 /* pxmitpriv->rts_thresh = pregistrypriv->rts_thresh; */
4998 pxmitpriv->frag_len = pregistrypriv->frag_thresh;
4999
5000 adapter->qospriv.qos_option = pregistrypriv->wmm_enable;
5001 #endif
5002
5003 pdev_network->Privacy = (psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0) ; /* adhoc no 802.1x */
5004
5005 pdev_network->Rssi = 0;
5006
5007 pdev_network->Configuration.DSConfig = (pregistrypriv->channel);
5008
5009 if (cur_network->network.InfrastructureMode == Ndis802_11IBSS) {
5010 pdev_network->Configuration.ATIMWindow = (0);
5011
5012 if (pmlmeext->cur_channel != 0)
5013 pdev_network->Configuration.DSConfig = pmlmeext->cur_channel;
5014 else
5015 pdev_network->Configuration.DSConfig = 1;
5016 }
5017
5018 pdev_network->InfrastructureMode = (cur_network->network.InfrastructureMode);
5019
5020 /* 1. Supported rates */
5021 /* 2. IE */
5022
5023 /* rtw_set_supported_rate(pdev_network->SupportedRates, pregistrypriv->wireless_mode) ; */ /* will be called in rtw_generate_ie */
5024 sz = rtw_generate_ie(pregistrypriv);
5025
5026 pdev_network->IELength = sz;
5027
5028 pdev_network->Length = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX *)pdev_network);
5029
5030 /* notes: translate IELength & Length after assign the Length to cmdsz in createbss_cmd(); */
5031 /* pdev_network->IELength = cpu_to_le32(sz); */
5032
5033
5034 }
5035
5036 void rtw_get_encrypt_decrypt_from_registrypriv(_adapter *adapter)
5037 {
5038
5039
5040
5041 }
5042
5043 /* the fucntion is at passive_level */
5044 void rtw_joinbss_reset(_adapter *padapter)
5045 {
5046 u8 threshold;
5047 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5048 /* todo: if you want to do something io/reg/hw setting before join_bss, please add code here */
5049
5050 #ifdef CONFIG_80211N_HT
5051 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
5052
5053 pmlmepriv->num_FortyMHzIntolerant = 0;
5054
5055 pmlmepriv->num_sta_no_ht = 0;
5056
5057 phtpriv->ampdu_enable = _FALSE;/* reset to disabled */
5058
5059 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
5060 /* TH=1 => means that invalidate usb rx aggregation */
5061 /* TH=0 => means that validate usb rx aggregation, use init value. */
5062 if (phtpriv->ht_option) {
5063 if (padapter->registrypriv.wifi_spec == 1)
5064 threshold = 1;
5065 else
5066 threshold = 0;
5067 rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
5068 } else {
5069 threshold = 1;
5070 rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
5071 }
5072 #endif/* #if defined( CONFIG_USB_HCI) || defined (CONFIG_SDIO_HCI) */
5073
5074 #endif/* #ifdef CONFIG_80211N_HT */
5075
5076 }
5077
5078
5079 #ifdef CONFIG_80211N_HT
5080 void rtw_ht_use_default_setting(_adapter *padapter)
5081 {
5082 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5083 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
5084 struct registry_priv *pregistrypriv = &padapter->registrypriv;
5085 BOOLEAN bHwLDPCSupport = _FALSE, bHwSTBCSupport = _FALSE;
5086 #ifdef CONFIG_BEAMFORMING
5087 BOOLEAN bHwSupportBeamformer = _FALSE, bHwSupportBeamformee = _FALSE;
5088 #endif /* CONFIG_BEAMFORMING */
5089
5090 if (pregistrypriv->wifi_spec)
5091 phtpriv->bss_coexist = 1;
5092 else
5093 phtpriv->bss_coexist = 0;
5094
5095 phtpriv->sgi_40m = TEST_FLAG(pregistrypriv->short_gi, BIT1) ? _TRUE : _FALSE;
5096 phtpriv->sgi_20m = TEST_FLAG(pregistrypriv->short_gi, BIT0) ? _TRUE : _FALSE;
5097
5098 /* LDPC support */
5099 rtw_hal_get_def_var(padapter, HAL_DEF_RX_LDPC, (u8 *)&bHwLDPCSupport);
5100 CLEAR_FLAGS(phtpriv->ldpc_cap);
5101 if (bHwLDPCSupport) {
5102 if (TEST_FLAG(pregistrypriv->ldpc_cap, BIT4))
5103 SET_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_RX);
5104 }
5105 rtw_hal_get_def_var(padapter, HAL_DEF_TX_LDPC, (u8 *)&bHwLDPCSupport);
5106 if (bHwLDPCSupport) {
5107 if (TEST_FLAG(pregistrypriv->ldpc_cap, BIT5))
5108 SET_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_TX);
5109 }
5110 if (phtpriv->ldpc_cap)
5111 RTW_INFO("[HT] HAL Support LDPC = 0x%02X\n", phtpriv->ldpc_cap);
5112
5113 /* STBC */
5114 rtw_hal_get_def_var(padapter, HAL_DEF_TX_STBC, (u8 *)&bHwSTBCSupport);
5115 CLEAR_FLAGS(phtpriv->stbc_cap);
5116 if (bHwSTBCSupport) {
5117 if (TEST_FLAG(pregistrypriv->stbc_cap, BIT5))
5118 SET_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX);
5119 }
5120 rtw_hal_get_def_var(padapter, HAL_DEF_RX_STBC, (u8 *)&bHwSTBCSupport);
5121 if (bHwSTBCSupport) {
5122 if (TEST_FLAG(pregistrypriv->stbc_cap, BIT4))
5123 SET_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX);
5124 }
5125 if (phtpriv->stbc_cap)
5126 RTW_INFO("[HT] HAL Support STBC = 0x%02X\n", phtpriv->stbc_cap);
5127
5128 /* Beamforming setting */
5129 CLEAR_FLAGS(phtpriv->beamform_cap);
5130 #ifdef CONFIG_BEAMFORMING
5131 #ifdef RTW_BEAMFORMING_VERSION_2
5132 /* only enable beamforming in STA client mode */
5133 if (MLME_IS_STA(padapter) && !MLME_IS_GC(padapter)
5134 && !MLME_IS_ADHOC(padapter)
5135 && !MLME_IS_MESH(padapter))
5136 #endif
5137 {
5138 rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&bHwSupportBeamformer);
5139 rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&bHwSupportBeamformee);
5140 if (TEST_FLAG(pregistrypriv->beamform_cap, BIT4) && bHwSupportBeamformer) {
5141 SET_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE);
5142 RTW_INFO("[HT] HAL Support Beamformer\n");
5143 }
5144 if (TEST_FLAG(pregistrypriv->beamform_cap, BIT5) && bHwSupportBeamformee) {
5145 SET_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE);
5146 RTW_INFO("[HT] HAL Support Beamformee\n");
5147 }
5148 }
5149 #endif /* CONFIG_BEAMFORMING */
5150 }
5151 void rtw_build_wmm_ie_ht(_adapter *padapter, u8 *out_ie, uint *pout_len)
5152 {
5153 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
5154 int out_len;
5155 u8 *pframe;
5156
5157 if (padapter->mlmepriv.qospriv.qos_option == 0) {
5158 out_len = *pout_len;
5159 pframe = rtw_set_ie(out_ie + out_len, _VENDOR_SPECIFIC_IE_,
5160 _WMM_IE_Length_, WMM_IE, pout_len);
5161
5162 padapter->mlmepriv.qospriv.qos_option = 1;
5163 }
5164 }
5165 #if defined(CONFIG_80211N_HT)
5166 /* the fucntion is >= passive_level */
5167 unsigned int rtw_restructure_ht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len, u8 channel)
5168 {
5169 u32 ielen, out_len;
5170 u32 rx_packet_offset, max_recvbuf_sz;
5171 HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor;
5172 HT_CAP_AMPDU_DENSITY best_ampdu_density;
5173 unsigned char *p, *pframe;
5174 struct rtw_ieee80211_ht_cap ht_capie;
5175 u8 cbw40_enable = 0, rf_num = 0, rx_stbc_nss = 0, rx_nss = 0;
5176 struct registry_priv *pregistrypriv = &padapter->registrypriv;
5177 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5178 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
5179 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5180 #ifdef CONFIG_80211AC_VHT
5181 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5182 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
5183 #endif /* CONFIG_80211AC_VHT */
5184
5185 phtpriv->ht_option = _FALSE;
5186
5187 out_len = *pout_len;
5188
5189 _rtw_memset(&ht_capie, 0, sizeof(struct rtw_ieee80211_ht_cap));
5190
5191 ht_capie.cap_info = IEEE80211_HT_CAP_DSSSCCK40;
5192
5193 if (phtpriv->sgi_20m)
5194 ht_capie.cap_info |= IEEE80211_HT_CAP_SGI_20;
5195
5196 /* check if 40MHz is allowed according to hal cap and registry */
5197 if (hal_chk_bw_cap(padapter, BW_CAP_40M)) {
5198 if (channel > 14) {
5199 if (REGSTY_IS_BW_5G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
5200 cbw40_enable = 1;
5201 } else {
5202 if (REGSTY_IS_BW_2G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
5203 cbw40_enable = 1;
5204 }
5205 }
5206
5207 if (cbw40_enable) {
5208 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
5209 RT_CHANNEL_INFO *chset = rfctl->channel_set;
5210 u8 oper_bw = CHANNEL_WIDTH_20, oper_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5211
5212 if (in_ie == NULL) {
5213 /* TDLS: TODO 20/40 issue */
5214 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
5215 oper_bw = padapter->mlmeextpriv.cur_bwmode;
5216 if (oper_bw > CHANNEL_WIDTH_40)
5217 oper_bw = CHANNEL_WIDTH_40;
5218 } else
5219 /* TDLS: TODO 40? */
5220 oper_bw = CHANNEL_WIDTH_40;
5221 } else {
5222 p = rtw_get_ie(in_ie, WLAN_EID_HT_OPERATION, &ielen, in_len);
5223 if (p && ielen == HT_OP_IE_LEN) {
5224 if (GET_HT_OP_ELE_STA_CHL_WIDTH(p + 2)) {
5225 switch (GET_HT_OP_ELE_2ND_CHL_OFFSET(p + 2)) {
5226 case SCA:
5227 oper_bw = CHANNEL_WIDTH_40;
5228 oper_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
5229 break;
5230 case SCB:
5231 oper_bw = CHANNEL_WIDTH_40;
5232 oper_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
5233 break;
5234 }
5235 }
5236 }
5237 // IOT issue : AP TP-Link WDR6500
5238 if(oper_bw == CHANNEL_WIDTH_40){
5239 p = rtw_get_ie(in_ie, WLAN_EID_HT_CAP, &ielen, in_len);
5240 if (p && ielen == HT_CAP_IE_LEN) {
5241 oper_bw = GET_HT_CAP_ELE_CHL_WIDTH(p + 2) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20;
5242 if(oper_bw == CHANNEL_WIDTH_20)
5243 oper_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5244 }
5245 }
5246 }
5247
5248 /* adjust bw to fit in channel plan setting */
5249 if (oper_bw == CHANNEL_WIDTH_40
5250 && oper_offset != HAL_PRIME_CHNL_OFFSET_DONT_CARE /* check this because TDLS has no info to set offset */
5251 && (!rtw_chset_is_chbw_valid(chset, channel, oper_bw, oper_offset, 1, 1)
5252 || (IS_DFS_SLAVE_WITH_RD(rfctl)
5253 && !rtw_rfctl_dfs_domain_unknown(rfctl)
5254 && rtw_chset_is_chbw_non_ocp(chset, channel, oper_bw, oper_offset))
5255 )
5256 ) {
5257 oper_bw = CHANNEL_WIDTH_20;
5258 oper_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5259 rtw_warn_on(!rtw_chset_is_chbw_valid(chset, channel, oper_bw, oper_offset, 1, 1));
5260 if (IS_DFS_SLAVE_WITH_RD(rfctl) && !rtw_rfctl_dfs_domain_unknown(rfctl))
5261 rtw_warn_on(rtw_chset_is_chbw_non_ocp(chset, channel, oper_bw, oper_offset));
5262 }
5263
5264 if (oper_bw == CHANNEL_WIDTH_40) {
5265 ht_capie.cap_info |= IEEE80211_HT_CAP_SUP_WIDTH;
5266 if (phtpriv->sgi_40m)
5267 ht_capie.cap_info |= IEEE80211_HT_CAP_SGI_40;
5268 }
5269
5270 cbw40_enable = oper_bw == CHANNEL_WIDTH_40 ? 1 : 0;
5271 }
5272
5273 /* todo: disable SM power save mode */
5274 ht_capie.cap_info |= IEEE80211_HT_CAP_SM_PS;
5275
5276 /* RX LDPC */
5277 if (TEST_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_RX)) {
5278 ht_capie.cap_info |= IEEE80211_HT_CAP_LDPC_CODING;
5279 RTW_INFO("[HT] Declare supporting RX LDPC\n");
5280 }
5281
5282 /* TX STBC */
5283 if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX)) {
5284 ht_capie.cap_info |= IEEE80211_HT_CAP_TX_STBC;
5285 RTW_INFO("[HT] Declare supporting TX STBC\n");
5286 }
5287
5288 /* RX STBC */
5289 if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX)) {
5290 if ((pregistrypriv->rx_stbc == 0x3) || /* enable for 2.4/5 GHz */
5291 ((channel <= 14) && (pregistrypriv->rx_stbc == 0x1)) || /* enable for 2.4GHz */
5292 ((channel > 14) && (pregistrypriv->rx_stbc == 0x2)) || /* enable for 5GHz */
5293 (pregistrypriv->wifi_spec == 1)) {
5294 /* HAL_DEF_RX_STBC means STBC RX spatial stream, todo: VHT 4 streams */
5295 rtw_hal_get_def_var(padapter, HAL_DEF_RX_STBC, (u8 *)(&rx_stbc_nss));
5296 SET_HT_CAP_ELE_RX_STBC(&ht_capie, rx_stbc_nss);
5297 RTW_INFO("[HT] Declare supporting RX STBC = %d\n", rx_stbc_nss);
5298 }
5299 }
5300
5301 /* fill default supported_mcs_set */
5302 _rtw_memcpy(ht_capie.supp_mcs_set, pmlmeext->default_supported_mcs_set, 16);
5303
5304 /* update default supported_mcs_set */
5305 rx_nss = GET_HAL_RX_NSS(padapter);
5306
5307 switch (rx_nss) {
5308 case 1:
5309 set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_1R);
5310 break;
5311 case 2:
5312 #ifdef CONFIG_DISABLE_MCS13TO15
5313 if (cbw40_enable && pregistrypriv->wifi_spec != 1)
5314 set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_2R_13TO15_OFF);
5315 else
5316 #endif
5317 set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_2R);
5318 break;
5319 case 3:
5320 set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_3R);
5321 break;
5322 case 4:
5323 set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_4R);
5324 break;
5325 default:
5326 RTW_WARN("rf_type:%d or rx_nss:%u is not expected\n", GET_HAL_RFPATH(padapter), rx_nss);
5327 }
5328
5329 {
5330 rtw_hal_get_def_var(padapter, HAL_DEF_RX_PACKET_OFFSET, &rx_packet_offset);
5331 rtw_hal_get_def_var(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz);
5332 if (max_recvbuf_sz - rx_packet_offset >= (8191 - 256)) {
5333 RTW_INFO("%s IEEE80211_HT_CAP_MAX_AMSDU is set\n", __FUNCTION__);
5334 ht_capie.cap_info = ht_capie.cap_info | IEEE80211_HT_CAP_MAX_AMSDU;
5335 }
5336 }
5337 /*
5338 AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
5339 AMPDU_para [4:2]:Min MPDU Start Spacing
5340 */
5341
5342 /*
5343 #if defined(CONFIG_RTL8188E) && defined(CONFIG_SDIO_HCI)
5344 ht_capie.ampdu_params_info = 2;
5345 #else
5346 ht_capie.ampdu_params_info = (IEEE80211_HT_CAP_AMPDU_FACTOR&0x03);
5347 #endif
5348 */
5349
5350 if (padapter->driver_rx_ampdu_factor != 0xFF)
5351 max_rx_ampdu_factor = (HT_CAP_AMPDU_FACTOR)padapter->driver_rx_ampdu_factor;
5352 else
5353 rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
5354
5355 /* rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor); */
5356 ht_capie.ampdu_params_info = (max_rx_ampdu_factor & 0x03);
5357
5358 if (padapter->driver_rx_ampdu_spacing != 0xFF)
5359 ht_capie.ampdu_params_info |= ((padapter->driver_rx_ampdu_spacing & 0x07) << 2);
5360 else {
5361 if (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_) {
5362 /*
5363 * Todo : Each chip must to ask DD , this chip best ampdu_density setting
5364 * By yiwei.sun
5365 */
5366 rtw_hal_get_def_var(padapter, HW_VAR_BEST_AMPDU_DENSITY, &best_ampdu_density);
5367
5368 ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & (best_ampdu_density << 2));
5369
5370 } else
5371 ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & 0x00);
5372 }
5373 #ifdef CONFIG_BEAMFORMING
5374 ht_capie.tx_BF_cap_info = 0;
5375
5376 /* HT Beamformer*/
5377 if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE)) {
5378 /* Transmit NDP Capable */
5379 SET_HT_CAP_TXBF_TRANSMIT_NDP_CAP(&ht_capie, 1);
5380 /* Explicit Compressed Steering Capable */
5381 SET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(&ht_capie, 1);
5382 /* Compressed Steering Number Antennas */
5383 SET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(&ht_capie, 1);
5384 rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMER_CAP, (u8 *)&rf_num);
5385 SET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(&ht_capie, rf_num);
5386 }
5387
5388 /* HT Beamformee */
5389 if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE)) {
5390 /* Receive NDP Capable */
5391 SET_HT_CAP_TXBF_RECEIVE_NDP_CAP(&ht_capie, 1);
5392 /* Explicit Compressed Beamforming Feedback Capable */
5393 SET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(&ht_capie, 2);
5394
5395 rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMEE_CAP, (u8 *)&rf_num);
5396 #ifdef CONFIG_80211AC_VHT
5397 /* IOT action suggested by Yu Chen 2017/3/3 */
5398 if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM) &&
5399 !pvhtpriv->ap_bf_cap.is_mu_bfer &&
5400 pvhtpriv->ap_bf_cap.su_sound_dim == 2)
5401 rf_num = (rf_num >= 2 ? 2 : rf_num);
5402 #endif
5403 SET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(&ht_capie, rf_num);
5404 }
5405 #endif/*CONFIG_BEAMFORMING*/
5406
5407 pframe = rtw_set_ie(out_ie + out_len, _HT_CAPABILITY_IE_,
5408 sizeof(struct rtw_ieee80211_ht_cap), (unsigned char *)&ht_capie, pout_len);
5409
5410 phtpriv->ht_option = _TRUE;
5411
5412 if (in_ie != NULL) {
5413 p = rtw_get_ie(in_ie, _HT_ADD_INFO_IE_, &ielen, in_len);
5414 if (p && (ielen == sizeof(struct ieee80211_ht_addt_info))) {
5415 out_len = *pout_len;
5416 pframe = rtw_set_ie(out_ie + out_len, _HT_ADD_INFO_IE_, ielen, p + 2 , pout_len);
5417 }
5418 }
5419
5420 return phtpriv->ht_option;
5421
5422 }
5423
5424 /* the fucntion is > passive_level (in critical_section) */
5425 void rtw_update_ht_cap(_adapter *padapter, u8 *pie, uint ie_len, u8 channel)
5426 {
5427 u8 *p, max_ampdu_sz;
5428 int len;
5429 /* struct sta_info *bmc_sta, *psta; */
5430 struct rtw_ieee80211_ht_cap *pht_capie;
5431 struct ieee80211_ht_addt_info *pht_addtinfo;
5432 /* struct recv_reorder_ctrl *preorder_ctrl; */
5433 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5434 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
5435 /* struct recv_priv *precvpriv = &padapter->recvpriv; */
5436 struct registry_priv *pregistrypriv = &padapter->registrypriv;
5437 /* struct wlan_network *pcur_network = &(pmlmepriv->cur_network);; */
5438 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5439 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5440 u8 cbw40_enable = 0;
5441
5442
5443 if (!phtpriv->ht_option)
5444 return;
5445
5446 if ((!pmlmeinfo->HT_info_enable) || (!pmlmeinfo->HT_caps_enable))
5447 return;
5448
5449 RTW_INFO("+rtw_update_ht_cap()\n");
5450
5451 /* maybe needs check if ap supports rx ampdu. */
5452 if ((phtpriv->ampdu_enable == _FALSE) && (pregistrypriv->ampdu_enable == 1)) {
5453 if (pregistrypriv->wifi_spec == 1) {
5454 /* remove this part because testbed AP should disable RX AMPDU */
5455 /* phtpriv->ampdu_enable = _FALSE; */
5456 phtpriv->ampdu_enable = _TRUE;
5457 } else
5458 phtpriv->ampdu_enable = _TRUE;
5459 }
5460
5461
5462 /* check Max Rx A-MPDU Size */
5463 len = 0;
5464 p = rtw_get_ie(pie + sizeof(NDIS_802_11_FIXED_IEs), _HT_CAPABILITY_IE_, &len, ie_len - sizeof(NDIS_802_11_FIXED_IEs));
5465 if (p && len > 0) {
5466 pht_capie = (struct rtw_ieee80211_ht_cap *)(p + 2);
5467 max_ampdu_sz = (pht_capie->ampdu_params_info & IEEE80211_HT_CAP_AMPDU_FACTOR);
5468 max_ampdu_sz = 1 << (max_ampdu_sz + 3); /* max_ampdu_sz (kbytes); */
5469
5470 /* RTW_INFO("rtw_update_ht_cap(): max_ampdu_sz=%d\n", max_ampdu_sz); */
5471 phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
5472
5473 }
5474
5475
5476 len = 0;
5477 p = rtw_get_ie(pie + sizeof(NDIS_802_11_FIXED_IEs), _HT_ADD_INFO_IE_, &len, ie_len - sizeof(NDIS_802_11_FIXED_IEs));
5478 if (p && len > 0) {
5479 pht_addtinfo = (struct ieee80211_ht_addt_info *)(p + 2);
5480 /* todo: */
5481 }
5482
5483 if (hal_chk_bw_cap(padapter, BW_CAP_40M)) {
5484 if (channel > 14) {
5485 if (REGSTY_IS_BW_5G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
5486 cbw40_enable = 1;
5487 } else {
5488 if (REGSTY_IS_BW_2G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
5489 cbw40_enable = 1;
5490 }
5491 }
5492
5493 /* update cur_bwmode & cur_ch_offset */
5494 if ((cbw40_enable) &&
5495 (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & BIT(1)) &&
5496 (pmlmeinfo->HT_info.infos[0] & BIT(2))) {
5497 int i;
5498 u8 rx_nss = 0;
5499
5500 rx_nss = GET_HAL_RX_NSS(padapter);
5501
5502 /* update the MCS set */
5503 for (i = 0; i < 16; i++)
5504 pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= pmlmeext->default_supported_mcs_set[i];
5505
5506 /* update the MCS rates */
5507 switch (rx_nss) {
5508 case 1:
5509 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_1R);
5510 break;
5511 case 2:
5512 #ifdef CONFIG_DISABLE_MCS13TO15
5513 if (pmlmeext->cur_bwmode == CHANNEL_WIDTH_40 && pregistrypriv->wifi_spec != 1)
5514 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R_13TO15_OFF);
5515 else
5516 #endif
5517 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R);
5518 break;
5519 case 3:
5520 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_3R);
5521 break;
5522 case 4:
5523 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_4R);
5524 break;
5525 default:
5526 RTW_WARN("rx_nss:%u is not expected\n", rx_nss);
5527 }
5528
5529 /* switch to the 40M Hz mode accoring to the AP */
5530 /* pmlmeext->cur_bwmode = CHANNEL_WIDTH_40; */
5531 switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) {
5532 case EXTCHNL_OFFSET_UPPER:
5533 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
5534 break;
5535
5536 case EXTCHNL_OFFSET_LOWER:
5537 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
5538 break;
5539
5540 default:
5541 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
5542 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5543 RTW_INFO("%s : ch offset is not assigned for HT40 mod , update cur_bwmode=%u, cur_ch_offset=%u\n",
5544 __func__, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
5545 break;
5546 }
5547 }
5548
5549 /* */
5550 /* Config SM Power Save setting */
5551 /* */
5552 pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2;
5553 if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC) {
5554 #if 0
5555 u8 i;
5556 /* update the MCS rates */
5557 for (i = 0; i < 16; i++)
5558 pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
5559 #endif
5560 RTW_INFO("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __FUNCTION__);
5561 }
5562
5563 /* */
5564 /* Config current HT Protection mode. */
5565 /* */
5566 pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;
5567 }
5568 #endif
5569
5570 #ifdef CONFIG_TDLS
5571 void rtw_issue_addbareq_cmd_tdls(_adapter *padapter, struct xmit_frame *pxmitframe)
5572 {
5573 struct pkt_attrib *pattrib = &pxmitframe->attrib;
5574 struct sta_info *ptdls_sta = NULL;
5575 u8 issued;
5576 int priority;
5577 struct ht_priv *phtpriv;
5578
5579 priority = pattrib->priority;
5580
5581 if (pattrib->direct_link == _TRUE) {
5582 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->dst);
5583 if ((ptdls_sta != NULL) && (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)) {
5584 phtpriv = &ptdls_sta->htpriv;
5585
5586 if ((phtpriv->ht_option == _TRUE) && (phtpriv->ampdu_enable == _TRUE)) {
5587 issued = (phtpriv->agg_enable_bitmap >> priority) & 0x1;
5588 issued |= (phtpriv->candidate_tid_bitmap >> priority) & 0x1;
5589
5590 if (0 == issued) {
5591 RTW_INFO("[%s], p=%d\n", __FUNCTION__, priority);
5592 ptdls_sta->htpriv.candidate_tid_bitmap |= BIT((u8)priority);
5593 rtw_addbareq_cmd(padapter, (u8)priority, pattrib->dst);
5594 }
5595 }
5596 }
5597 }
5598 }
5599 #endif /* CONFIG_TDLS */
5600
5601 #ifdef CONFIG_80211N_HT
5602 static u8 rtw_issue_addbareq_check(_adapter *padapter, struct xmit_frame *pxmitframe, u8 issue_when_busy)
5603 {
5604 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5605 struct registry_priv *pregistry = &padapter->registrypriv;
5606 struct pkt_attrib *pattrib = &pxmitframe->attrib;
5607 s32 bmcst = IS_MCAST(pattrib->ra);
5608
5609 if (bmcst)
5610 return _FALSE;
5611
5612 if (pregistry->tx_quick_addba_req == 0) {
5613 if ((issue_when_busy == _TRUE) && (pmlmepriv->LinkDetectInfo.bBusyTraffic == _FALSE))
5614 return _FALSE;
5615
5616 if (pmlmepriv->LinkDetectInfo.NumTxOkInPeriod < 100)
5617 return _FALSE;
5618 }
5619
5620 return _TRUE;
5621 }
5622
5623 void rtw_issue_addbareq_cmd(_adapter *padapter, struct xmit_frame *pxmitframe, u8 issue_when_busy)
5624 {
5625 u8 issued;
5626 int priority;
5627 struct sta_info *psta = NULL;
5628 struct ht_priv *phtpriv;
5629 struct pkt_attrib *pattrib = &pxmitframe->attrib;
5630
5631 if (rtw_issue_addbareq_check(padapter,pxmitframe, issue_when_busy) == _FALSE)
5632 return;
5633
5634 priority = pattrib->priority;
5635
5636 #ifdef CONFIG_TDLS
5637 rtw_issue_addbareq_cmd_tdls(padapter, pxmitframe);
5638 #endif /* CONFIG_TDLS */
5639
5640 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
5641 if (pattrib->psta != psta) {
5642 RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
5643 return;
5644 }
5645
5646 if (psta == NULL) {
5647 RTW_INFO("%s, psta==NUL\n", __func__);
5648 return;
5649 }
5650
5651 if (!(psta->state & WIFI_ASOC_STATE)) {
5652 RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state);
5653 return;
5654 }
5655
5656
5657 phtpriv = &psta->htpriv;
5658
5659 if ((phtpriv->ht_option == _TRUE) && (phtpriv->ampdu_enable == _TRUE)) {
5660 issued = (phtpriv->agg_enable_bitmap >> priority) & 0x1;
5661 issued |= (phtpriv->candidate_tid_bitmap >> priority) & 0x1;
5662
5663 if (0 == issued) {
5664 RTW_INFO("rtw_issue_addbareq_cmd, p=%d\n", priority);
5665 psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority);
5666 rtw_addbareq_cmd(padapter, (u8) priority, pattrib->ra);
5667 }
5668 }
5669
5670 }
5671 #endif /* CONFIG_80211N_HT */
5672 void rtw_append_exented_cap(_adapter *padapter, u8 *out_ie, uint *pout_len)
5673 {
5674 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5675 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
5676 #ifdef CONFIG_80211AC_VHT
5677 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
5678 #endif /* CONFIG_80211AC_VHT */
5679 u8 cap_content[8] = { 0 };
5680 u8 *pframe;
5681 u8 null_content[8] = {0};
5682
5683 if (phtpriv->bss_coexist)
5684 SET_EXT_CAPABILITY_ELE_BSS_COEXIST(cap_content, 1);
5685
5686 #ifdef CONFIG_80211AC_VHT
5687 if (pvhtpriv->vht_option)
5688 SET_EXT_CAPABILITY_ELE_OP_MODE_NOTIF(cap_content, 1);
5689 #endif /* CONFIG_80211AC_VHT */
5690 #ifdef CONFIG_RTW_WNM
5691 rtw_wnm_set_ext_cap_btm(cap_content, 1);
5692 #endif
5693
5694 #ifdef CONFIG_RTW_MBO
5695 rtw_mbo_set_ext_cap_internw(cap_content, 1);
5696 #endif
5697 /*
5698 From 802.11 specification,if a STA does not support any of capabilities defined
5699 in the Extended Capabilities element, then the STA is not required to
5700 transmit the Extended Capabilities element.
5701 */
5702 if (_FALSE == _rtw_memcmp(cap_content, null_content, 8))
5703 pframe = rtw_set_ie(out_ie + *pout_len, EID_EXTCapability, 8, cap_content , pout_len);
5704 }
5705 #endif
5706
5707 #ifdef CONFIG_LAYER2_ROAMING
5708 inline void rtw_set_to_roam(_adapter *adapter, u8 to_roam)
5709 {
5710 if (to_roam == 0)
5711 adapter->mlmepriv.to_join = _FALSE;
5712 adapter->mlmepriv.to_roam = to_roam;
5713 }
5714
5715 inline u8 rtw_dec_to_roam(_adapter *adapter)
5716 {
5717 adapter->mlmepriv.to_roam--;
5718 return adapter->mlmepriv.to_roam;
5719 }
5720
5721 inline u8 rtw_to_roam(_adapter *adapter)
5722 {
5723 return adapter->mlmepriv.to_roam;
5724 }
5725
5726 void rtw_roaming(_adapter *padapter, struct wlan_network *tgt_network)
5727 {
5728 _irqL irqL;
5729 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5730
5731 _enter_critical_bh(&pmlmepriv->lock, &irqL);
5732 _rtw_roaming(padapter, tgt_network);
5733 _exit_critical_bh(&pmlmepriv->lock, &irqL);
5734 }
5735 void _rtw_roaming(_adapter *padapter, struct wlan_network *tgt_network)
5736 {
5737 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5738 struct wlan_network *cur_network = &pmlmepriv->cur_network;
5739 int do_join_r;
5740
5741 if (0 < rtw_to_roam(padapter)) {
5742 RTW_INFO("roaming from %s("MAC_FMT"), length:%d\n",
5743 cur_network->network.Ssid.Ssid, MAC_ARG(cur_network->network.MacAddress),
5744 cur_network->network.Ssid.SsidLength);
5745 _rtw_memcpy(&pmlmepriv->assoc_ssid, &cur_network->network.Ssid, sizeof(NDIS_802_11_SSID));
5746 pmlmepriv->assoc_ch = 0;
5747 pmlmepriv->assoc_by_bssid = _FALSE;
5748
5749 #ifdef CONFIG_WAPI_SUPPORT
5750 rtw_wapi_return_all_sta_info(padapter);
5751 #endif
5752
5753 while (1) {
5754 do_join_r = rtw_do_join(padapter);
5755 if (_SUCCESS == do_join_r)
5756 break;
5757 else {
5758 RTW_INFO("roaming do_join return %d\n", do_join_r);
5759 rtw_dec_to_roam(padapter);
5760
5761 if (rtw_to_roam(padapter) > 0)
5762 continue;
5763 else {
5764 RTW_INFO("%s(%d) -to roaming fail, indicate_disconnect\n", __FUNCTION__, __LINE__);
5765 #ifdef CONFIG_RTW_80211R
5766 rtw_ft_clr_flags(padapter, RTW_FT_PEER_EN|RTW_FT_PEER_OTD_EN);
5767 rtw_ft_reset_status(padapter);
5768 #endif
5769 rtw_indicate_disconnect(padapter, 0, _FALSE);
5770 break;
5771 }
5772 }
5773 }
5774 }
5775
5776 }
5777 #endif /* CONFIG_LAYER2_ROAMING */
5778
5779 bool rtw_adjust_chbw(_adapter *adapter, u8 req_ch, u8 *req_bw, u8 *req_offset)
5780 {
5781 struct registry_priv *regsty = adapter_to_regsty(adapter);
5782 u8 allowed_bw;
5783
5784 if (req_ch < 14)
5785 allowed_bw = REGSTY_BW_2G(regsty);
5786 else if (req_ch == 14)
5787 allowed_bw = CHANNEL_WIDTH_20;
5788 else
5789 allowed_bw = REGSTY_BW_5G(regsty);
5790
5791 allowed_bw = hal_largest_bw(adapter, allowed_bw);
5792
5793 if (allowed_bw == CHANNEL_WIDTH_80 && *req_bw > CHANNEL_WIDTH_80)
5794 *req_bw = CHANNEL_WIDTH_80;
5795 else if (allowed_bw == CHANNEL_WIDTH_40 && *req_bw > CHANNEL_WIDTH_40)
5796 *req_bw = CHANNEL_WIDTH_40;
5797 else if (allowed_bw == CHANNEL_WIDTH_20 && *req_bw > CHANNEL_WIDTH_20) {
5798 *req_bw = CHANNEL_WIDTH_20;
5799 *req_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5800 } else
5801 return _FALSE;
5802
5803 return _TRUE;
5804 }
5805
5806 sint rtw_linked_check(_adapter *padapter)
5807 {
5808 if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)
5809 || MLME_IS_ADHOC(padapter) || MLME_IS_ADHOC_MASTER(padapter)
5810 ) {
5811 if (padapter->stapriv.asoc_sta_count > 2)
5812 return _TRUE;
5813 } else {
5814 /* Station mode */
5815 if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _TRUE)
5816 return _TRUE;
5817 }
5818 return _FALSE;
5819 }
5820 /*#define DBG_ADAPTER_STATE_CHK*/
5821 u8 rtw_is_adapter_up(_adapter *padapter)
5822 {
5823 if (padapter == NULL)
5824 return _FALSE;
5825
5826 if (RTW_CANNOT_RUN(padapter)) {
5827 #ifdef DBG_ADAPTER_STATE_CHK
5828 RTW_INFO(FUNC_ADPT_FMT " FALSE -bDriverStopped(%s) bSurpriseRemoved(%s)\n"
5829 , FUNC_ADPT_ARG(padapter)
5830 , rtw_is_drv_stopped(padapter) ? "True" : "False"
5831 , rtw_is_surprise_removed(padapter) ? "True" : "False");
5832 #endif
5833 return _FALSE;
5834 }
5835
5836 if (!rtw_is_hw_init_completed(padapter)) {
5837 #ifdef DBG_ADAPTER_STATE_CHK
5838 RTW_INFO(FUNC_ADPT_FMT " FALSE -(hw_init_completed == _FALSE)\n", FUNC_ADPT_ARG(padapter));
5839 #endif
5840 return _FALSE;
5841 }
5842
5843 if (padapter->bup == _FALSE) {
5844 #ifdef DBG_ADAPTER_STATE_CHK
5845 RTW_INFO(FUNC_ADPT_FMT " FALSE -(bup == _FALSE)\n", FUNC_ADPT_ARG(padapter));
5846 #endif
5847 return _FALSE;
5848 }
5849
5850 return _TRUE;
5851 }
5852
5853 bool is_miracast_enabled(_adapter *adapter)
5854 {
5855 bool enabled = 0;
5856 #ifdef CONFIG_WFD
5857 struct wifi_display_info *wfdinfo = &adapter->wfd_info;
5858
5859 enabled = (wfdinfo->stack_wfd_mode & (MIRACAST_SOURCE | MIRACAST_SINK))
5860 || (wfdinfo->op_wfd_mode & (MIRACAST_SOURCE | MIRACAST_SINK));
5861 #endif
5862
5863 return enabled;
5864 }
5865
5866 bool rtw_chk_miracast_mode(_adapter *adapter, u8 mode)
5867 {
5868 bool ret = 0;
5869 #ifdef CONFIG_WFD
5870 struct wifi_display_info *wfdinfo = &adapter->wfd_info;
5871
5872 ret = (wfdinfo->stack_wfd_mode & mode) || (wfdinfo->op_wfd_mode & mode);
5873 #endif
5874
5875 return ret;
5876 }
5877
5878 const char *get_miracast_mode_str(int mode)
5879 {
5880 if (mode == MIRACAST_SOURCE)
5881 return "SOURCE";
5882 else if (mode == MIRACAST_SINK)
5883 return "SINK";
5884 else if (mode == (MIRACAST_SOURCE | MIRACAST_SINK))
5885 return "SOURCE&SINK";
5886 else if (mode == MIRACAST_DISABLED)
5887 return "DISABLED";
5888 else
5889 return "INVALID";
5890 }
5891
5892 #ifdef CONFIG_WFD
5893 static bool wfd_st_match_rule(_adapter *adapter, u8 *local_naddr, u8 *local_port, u8 *remote_naddr, u8 *remote_port)
5894 {
5895 struct wifi_display_info *wfdinfo = &adapter->wfd_info;
5896
5897 if (ntohs(*((u16 *)local_port)) == wfdinfo->rtsp_ctrlport
5898 || ntohs(*((u16 *)local_port)) == wfdinfo->tdls_rtsp_ctrlport
5899 || ntohs(*((u16 *)remote_port)) == wfdinfo->peer_rtsp_ctrlport)
5900 return _TRUE;
5901 return _FALSE;
5902 }
5903
5904 static struct st_register wfd_st_reg = {
5905 .s_proto = 0x06,
5906 .rule = wfd_st_match_rule,
5907 };
5908 #endif /* CONFIG_WFD */
5909
5910 inline void rtw_wfd_st_switch(struct sta_info *sta, bool on)
5911 {
5912 #ifdef CONFIG_WFD
5913 if (on)
5914 rtw_st_ctl_register(&sta->st_ctl, SESSION_TRACKER_REG_ID_WFD, &wfd_st_reg);
5915 else
5916 rtw_st_ctl_unregister(&sta->st_ctl, SESSION_TRACKER_REG_ID_WFD);
5917 #endif
5918 }
5919
5920 void dump_arp_pkt(void *sel, u8 *da, u8 *sa, u8 *arp, bool tx)
5921 {
5922 RTW_PRINT_SEL(sel, "%s ARP da="MAC_FMT", sa="MAC_FMT"\n"
5923 , tx ? "send" : "recv", MAC_ARG(da), MAC_ARG(sa));
5924 RTW_PRINT_SEL(sel, "htype=%u, ptype=0x%04x, hlen=%u, plen=%u, oper=%u\n"
5925 , GET_ARP_HTYPE(arp), GET_ARP_PTYPE(arp), GET_ARP_HLEN(arp)
5926 , GET_ARP_PLEN(arp), GET_ARP_OPER(arp));
5927 RTW_PRINT_SEL(sel, "sha="MAC_FMT", spa="IP_FMT"\n"
5928 , MAC_ARG(ARP_SENDER_MAC_ADDR(arp)), IP_ARG(ARP_SENDER_IP_ADDR(arp)));
5929 RTW_PRINT_SEL(sel, "tha="MAC_FMT", tpa="IP_FMT"\n"
5930 , MAC_ARG(ARP_TARGET_MAC_ADDR(arp)), IP_ARG(ARP_TARGET_IP_ADDR(arp)));
5931 }
5932
5933