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 /* only for 20/40 BSS */
3795 if (reason == RTW_AUTO_SCAN_REASON_2040_BSS) {
3796 rtw_init_sitesurvey_parm(padapter, &parm);
3797 for (i=0;i<14;i++) {
3798 parm.ch[i].hw_value = i + 1;
3799 parm.ch[i].flags = RTW_IEEE80211_CHAN_PASSIVE_SCAN;
3800 }
3801 parm.ch_num = 14;
3802 rtw_set_802_11_bssid_list_scan(padapter, &parm);
3803 goto exit;
3804 }
3805
3806 #if defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K)
3807 if ((reason == RTW_AUTO_SCAN_REASON_ROAM)
3808 && (rtw_roam_nb_scan_list_set(padapter, &parm)))
3809 goto exit;
3810 #endif
3811
3812 rtw_set_802_11_bssid_list_scan(padapter, NULL);
3813 exit:
3814 return;
3815 }
3816
3817 static void rtw_auto_scan_handler(_adapter *padapter)
3818 {
3819 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3820 u8 reason = RTW_AUTO_SCAN_REASON_UNSPECIFIED;
3821
3822 rtw_mlme_reset_auto_scan_int(padapter, &reason);
3823
3824 #ifdef CONFIG_P2P
3825 if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
3826 goto exit;
3827 #endif
3828
3829 #ifdef CONFIG_TDLS
3830 if (padapter->tdlsinfo.link_established == _TRUE)
3831 goto exit;
3832 #endif
3833
3834 if (pmlmepriv->auto_scan_int_ms == 0
3835 || rtw_get_passing_time_ms(pmlmepriv->scan_start_time) < pmlmepriv->auto_scan_int_ms)
3836 goto exit;
3837
3838 rtw_drv_scan_by_self(padapter, reason);
3839
3840 exit:
3841 return;
3842 }
3843 static u8 is_drv_in_lps(_adapter *adapter)
3844 {
3845 u8 is_in_lps = _FALSE;
3846
3847 #ifdef CONFIG_LPS_LCLK_WD_TIMER /* to avoid leaving lps 32k frequently*/
3848 if ((adapter_to_pwrctl(adapter)->bFwCurrentInPSMode == _TRUE)
3849 #ifdef CONFIG_BT_COEXIST
3850 && (rtw_btcoex_IsBtControlLps(adapter) == _FALSE)
3851 #endif
3852 )
3853 is_in_lps = _TRUE;
3854 #endif /* CONFIG_LPS_LCLK_WD_TIMER*/
3855 return is_in_lps;
3856 }
3857 void rtw_iface_dynamic_check_timer_handlder(_adapter *adapter)
3858 {
3859 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
3860
3861 if (adapter->net_closed == _TRUE)
3862 return;
3863 #ifdef CONFIG_LPS_LCLK_WD_TIMER /* to avoid leaving lps 32k frequently*/
3864 if (is_drv_in_lps(adapter)) {
3865 u8 bEnterPS;
3866
3867 linked_status_chk(adapter, 1);
3868
3869 bEnterPS = traffic_status_watchdog(adapter, 1);
3870 if (bEnterPS) {
3871 /* rtw_lps_ctrl_wk_cmd(adapter, LPS_CTRL_ENTER, 0); */
3872 rtw_hal_dm_watchdog_in_lps(adapter);
3873 } else {
3874 /* call rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 0) in traffic_status_watchdog() */
3875 }
3876 }
3877 #endif /* CONFIG_LPS_LCLK_WD_TIMER */
3878
3879 /* auto site survey */
3880 rtw_auto_scan_handler(adapter);
3881
3882 #ifdef CONFIG_AP_MODE
3883 if (MLME_IS_AP(adapter)|| MLME_IS_MESH(adapter)) {
3884 #ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
3885 expire_timeout_chk(adapter);
3886 #endif /* !CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
3887
3888 #ifdef CONFIG_BMC_TX_RATE_SELECT
3889 rtw_update_bmc_sta_tx_rate(adapter);
3890 #endif /*CONFIG_BMC_TX_RATE_SELECT*/
3891 }
3892 #endif /*CONFIG_AP_MODE*/
3893
3894
3895 #ifdef CONFIG_BR_EXT
3896 if (!adapter_use_wds(adapter)) {
3897 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
3898 rcu_read_lock();
3899 #endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) */
3900
3901 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
3902 if (adapter->pnetdev->br_port
3903 #else /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
3904 if (rcu_dereference(adapter->pnetdev->rx_handler_data)
3905 #endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
3906 && (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE)) {
3907 /* expire NAT2.5 entry */
3908 void nat25_db_expire(_adapter *priv);
3909 nat25_db_expire(adapter);
3910
3911 if (adapter->pppoe_connection_in_progress > 0)
3912 adapter->pppoe_connection_in_progress--;
3913 /* due to rtw_dynamic_check_timer_handlder() is called every 2 seconds */
3914 if (adapter->pppoe_connection_in_progress > 0)
3915 adapter->pppoe_connection_in_progress--;
3916 }
3917
3918 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35))
3919 rcu_read_unlock();
3920 #endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35)) */
3921 }
3922 #endif /* CONFIG_BR_EXT */
3923
3924 }
3925
3926 /*TP_avg(t) = (1/10) * TP_avg(t-1) + (9/10) * TP(t) MBps*/
3927 static void collect_sta_traffic_statistics(_adapter *adapter)
3928 {
3929 struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
3930 struct sta_info *sta;
3931 u64 curr_tx_bytes = 0, curr_rx_bytes = 0;
3932 u32 curr_tx_mbytes = 0, curr_rx_mbytes = 0;
3933 int i;
3934
3935 for (i = 0; i < MACID_NUM_SW_LIMIT; i++) {
3936 sta = macid_ctl->sta[i];
3937 if (sta && !is_broadcast_mac_addr(sta->cmn.mac_addr)) {
3938 if (sta->sta_stats.last_tx_bytes > sta->sta_stats.tx_bytes)
3939 sta->sta_stats.last_tx_bytes = sta->sta_stats.tx_bytes;
3940 if (sta->sta_stats.last_rx_bytes > sta->sta_stats.rx_bytes)
3941 sta->sta_stats.last_rx_bytes = sta->sta_stats.rx_bytes;
3942 if (sta->sta_stats.last_rx_bc_bytes > sta->sta_stats.rx_bc_bytes)
3943 sta->sta_stats.last_rx_bc_bytes = sta->sta_stats.rx_bc_bytes;
3944 if (sta->sta_stats.last_rx_mc_bytes > sta->sta_stats.rx_mc_bytes)
3945 sta->sta_stats.last_rx_mc_bytes = sta->sta_stats.rx_mc_bytes;
3946
3947 curr_tx_bytes = sta->sta_stats.tx_bytes - sta->sta_stats.last_tx_bytes;
3948 curr_rx_bytes = sta->sta_stats.rx_bytes - sta->sta_stats.last_rx_bytes;
3949 sta->sta_stats.tx_tp_kbits = (curr_tx_bytes * 8 / 2) >> 10;/*Kbps*/
3950 sta->sta_stats.rx_tp_kbits = (curr_rx_bytes * 8 / 2) >> 10;/*Kbps*/
3951
3952 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*/
3953 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*/
3954
3955 curr_tx_mbytes = (curr_tx_bytes / 2) >> 20;/*MBps*/
3956 curr_rx_mbytes = (curr_rx_bytes / 2) >> 20;/*MBps*/
3957
3958 sta->cmn.tx_moving_average_tp =
3959 (sta->cmn.tx_moving_average_tp / 10) + (curr_tx_mbytes * 9 / 10); /*MBps*/
3960
3961 sta->cmn.rx_moving_average_tp =
3962 (sta->cmn.rx_moving_average_tp / 10) + (curr_rx_mbytes * 9 /10); /*MBps*/
3963
3964 rtw_collect_bcn_info(sta->padapter);
3965
3966 if (adapter->bsta_tp_dump)
3967 dump_sta_traffic(RTW_DBGDUMP, adapter, sta);
3968
3969 sta->sta_stats.last_tx_bytes = sta->sta_stats.tx_bytes;
3970 sta->sta_stats.last_rx_bytes = sta->sta_stats.rx_bytes;
3971 sta->sta_stats.last_rx_bc_bytes = sta->sta_stats.rx_bc_bytes;
3972 sta->sta_stats.last_rx_mc_bytes = sta->sta_stats.rx_mc_bytes;
3973 }
3974 }
3975 }
3976
3977 void rtw_sta_traffic_info(void *sel, _adapter *adapter)
3978 {
3979 struct macid_ctl_t *macid_ctl = &adapter->dvobj->macid_ctl;
3980 struct sta_info *sta;
3981 int i;
3982
3983 for (i = 0; i < MACID_NUM_SW_LIMIT; i++) {
3984 sta = macid_ctl->sta[i];
3985 if (sta && !is_broadcast_mac_addr(sta->cmn.mac_addr))
3986 dump_sta_traffic(sel, adapter, sta);
3987 }
3988 }
3989
3990 /*#define DBG_TRAFFIC_STATISTIC*/
3991 static void collect_traffic_statistics(_adapter *padapter)
3992 {
3993 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
3994
3995 /*_rtw_memset(&pdvobjpriv->traffic_stat, 0, sizeof(struct rtw_traffic_statistics));*/
3996
3997 /* Tx bytes reset*/
3998 pdvobjpriv->traffic_stat.tx_bytes = 0;
3999 pdvobjpriv->traffic_stat.tx_pkts = 0;
4000 pdvobjpriv->traffic_stat.tx_drop = 0;
4001
4002 /* Rx bytes reset*/
4003 pdvobjpriv->traffic_stat.rx_bytes = 0;
4004 pdvobjpriv->traffic_stat.rx_pkts = 0;
4005 pdvobjpriv->traffic_stat.rx_drop = 0;
4006
4007 rtw_mi_traffic_statistics(padapter);
4008
4009 /* Calculate throughput in last interval */
4010 pdvobjpriv->traffic_stat.cur_tx_bytes = pdvobjpriv->traffic_stat.tx_bytes - pdvobjpriv->traffic_stat.last_tx_bytes;
4011 pdvobjpriv->traffic_stat.cur_rx_bytes = pdvobjpriv->traffic_stat.rx_bytes - pdvobjpriv->traffic_stat.last_rx_bytes;
4012 pdvobjpriv->traffic_stat.last_tx_bytes = pdvobjpriv->traffic_stat.tx_bytes;
4013 pdvobjpriv->traffic_stat.last_rx_bytes = pdvobjpriv->traffic_stat.rx_bytes;
4014
4015 pdvobjpriv->traffic_stat.cur_tx_tp = (u32)(pdvobjpriv->traffic_stat.cur_tx_bytes * 8 / 2 / 1024 / 1024);/*Mbps*/
4016 pdvobjpriv->traffic_stat.cur_rx_tp = (u32)(pdvobjpriv->traffic_stat.cur_rx_bytes * 8 / 2 / 1024 / 1024);/*Mbps*/
4017
4018 #ifdef DBG_TRAFFIC_STATISTIC
4019 RTW_INFO("\n========================\n");
4020 RTW_INFO("cur_tx_bytes:%lld\n", pdvobjpriv->traffic_stat.cur_tx_bytes);
4021 RTW_INFO("cur_rx_bytes:%lld\n", pdvobjpriv->traffic_stat.cur_rx_bytes);
4022
4023 RTW_INFO("last_tx_bytes:%lld\n", pdvobjpriv->traffic_stat.last_tx_bytes);
4024 RTW_INFO("last_rx_bytes:%lld\n", pdvobjpriv->traffic_stat.last_rx_bytes);
4025
4026 RTW_INFO("cur_tx_tp:%d (Mbps)\n", pdvobjpriv->traffic_stat.cur_tx_tp);
4027 RTW_INFO("cur_rx_tp:%d (Mbps)\n", pdvobjpriv->traffic_stat.cur_rx_tp);
4028 #endif
4029
4030 #ifdef CONFIG_RTW_NAPI
4031 #ifdef CONFIG_RTW_NAPI_DYNAMIC
4032 dynamic_napi_th_chk (padapter);
4033 #endif /* CONFIG_RTW_NAPI_DYNAMIC */
4034 #endif
4035
4036 }
4037
4038 void rtw_dynamic_check_timer_handlder(void *ctx)
4039 {
4040 struct dvobj_priv *pdvobj = (struct dvobj_priv *)ctx;
4041 _adapter *adapter = dvobj_get_primary_adapter(pdvobj);
4042
4043 if (!adapter)
4044 goto exit;
4045
4046 #if (MP_DRIVER == 1)
4047 if (adapter->registrypriv.mp_mode == 1 && adapter->mppriv.mp_dm == 0) { /* for MP ODM dynamic Tx power tracking */
4048 /* RTW_INFO("%s mp_dm =0 return\n", __func__); */
4049 goto exit;
4050 }
4051 #endif
4052
4053 if (!rtw_is_hw_init_completed(adapter))
4054 goto exit;
4055
4056 if (RTW_CANNOT_RUN(adapter))
4057 goto exit;
4058
4059 collect_traffic_statistics(adapter);
4060 collect_sta_traffic_statistics(adapter);
4061 rtw_mi_dynamic_check_timer_handlder(adapter);
4062
4063 if (!is_drv_in_lps(adapter))
4064 rtw_dynamic_chk_wk_cmd(adapter);
4065
4066 exit:
4067 _set_timer(&pdvobj->dynamic_chk_timer, 2000);
4068 }
4069
4070
4071 #ifdef CONFIG_SET_SCAN_DENY_TIMER
4072 inline bool rtw_is_scan_deny(_adapter *adapter)
4073 {
4074 struct mlme_priv *mlmepriv = &adapter->mlmepriv;
4075 return (ATOMIC_READ(&mlmepriv->set_scan_deny) != 0) ? _TRUE : _FALSE;
4076 }
4077
4078 inline void rtw_clear_scan_deny(_adapter *adapter)
4079 {
4080 struct mlme_priv *mlmepriv = &adapter->mlmepriv;
4081 ATOMIC_SET(&mlmepriv->set_scan_deny, 0);
4082 if (0)
4083 RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
4084 }
4085
4086 void rtw_set_scan_deny_timer_hdl(void *ctx)
4087 {
4088 _adapter *adapter = (_adapter *)ctx;
4089
4090 rtw_clear_scan_deny(adapter);
4091 }
4092 void rtw_set_scan_deny(_adapter *adapter, u32 ms)
4093 {
4094 struct mlme_priv *mlmepriv = &adapter->mlmepriv;
4095 if (0)
4096 RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
4097 ATOMIC_SET(&mlmepriv->set_scan_deny, 1);
4098 _set_timer(&mlmepriv->set_scan_deny_timer, ms);
4099 }
4100 #endif
4101
4102 #ifdef CONFIG_LAYER2_ROAMING
4103 /*
4104 * Select a new roaming candidate from the original @param candidate and @param competitor
4105 * @return _TRUE: candidate is updated
4106 * @return _FALSE: candidate is not updated
4107 */
4108 static int rtw_check_roaming_candidate(struct mlme_priv *mlme
4109 , struct wlan_network **candidate, struct wlan_network *competitor)
4110 {
4111 int updated = _FALSE;
4112 _adapter *adapter = container_of(mlme, _adapter, mlmepriv);
4113 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
4114 RT_CHANNEL_INFO *chset = rfctl->channel_set;
4115 u8 ch = competitor->network.Configuration.DSConfig;
4116
4117 if (rtw_chset_search_ch(chset, ch) < 0)
4118 goto exit;
4119 if (IS_DFS_SLAVE_WITH_RD(rfctl)
4120 && !rtw_rfctl_dfs_domain_unknown(rfctl)
4121 && rtw_chset_is_ch_non_ocp(chset, ch))
4122 goto exit;
4123
4124 #if defined(CONFIG_RTW_REPEATER_SON) && (!defined(CONFIG_RTW_REPEATER_SON_ROOT))
4125 if (rtw_rson_isupdate_roamcan(mlme, candidate, competitor))
4126 goto update;
4127 goto exit;
4128 #endif
4129
4130 if (is_same_ess(&competitor->network, &mlme->cur_network.network) == _FALSE)
4131 goto exit;
4132
4133 if (rtw_is_desired_network(adapter, competitor) == _FALSE)
4134 goto exit;
4135
4136 #ifdef CONFIG_LAYER2_ROAMING
4137 if (mlme->need_to_roam == _FALSE)
4138 goto exit;
4139 #endif
4140
4141 RTW_INFO("roam candidate:%s %s("MAC_FMT", ch%3u) rssi:%d, age:%5d\n",
4142 (competitor == mlme->cur_network_scanned) ? "*" : " " ,
4143 competitor->network.Ssid.Ssid,
4144 MAC_ARG(competitor->network.MacAddress),
4145 competitor->network.Configuration.DSConfig,
4146 (int)competitor->network.Rssi,
4147 rtw_get_passing_time_ms(competitor->last_scanned)
4148 );
4149
4150 /* got specific addr to roam */
4151 if (!is_zero_mac_addr(mlme->roam_tgt_addr)) {
4152 if (_rtw_memcmp(mlme->roam_tgt_addr, competitor->network.MacAddress, ETH_ALEN) == _TRUE)
4153 goto update;
4154 else
4155 goto exit;
4156 }
4157
4158 #ifdef CONFIG_RTW_80211R
4159 if (rtw_ft_chk_flags(adapter, RTW_FT_PEER_EN)) {
4160 if (rtw_ft_chk_roaming_candidate(adapter, competitor) == _FALSE)
4161 goto exit;
4162 }
4163
4164 #ifdef CONFIG_RTW_WNM
4165 if (rtw_wnm_btm_diff_bss(adapter) &&
4166 rtw_wnm_btm_roam_candidate(adapter, competitor)) {
4167 goto update;
4168 }
4169 #endif
4170 #endif
4171
4172 #if 1
4173 if (rtw_get_passing_time_ms(competitor->last_scanned) >= mlme->roam_scanr_exp_ms)
4174 goto exit;
4175
4176 if (competitor->network.Rssi - mlme->cur_network_scanned->network.Rssi < mlme->roam_rssi_diff_th)
4177 goto exit;
4178
4179 if (*candidate != NULL && (*candidate)->network.Rssi >= competitor->network.Rssi)
4180 goto exit;
4181 #else
4182 goto exit;
4183 #endif
4184
4185 update:
4186 *candidate = competitor;
4187 updated = _TRUE;
4188
4189 exit:
4190 return updated;
4191 }
4192
4193 int rtw_select_roaming_candidate(struct mlme_priv *mlme)
4194 {
4195 _irqL irqL;
4196 int ret = _FAIL;
4197 _list *phead;
4198 _adapter *adapter;
4199 _queue *queue = &(mlme->scanned_queue);
4200 struct wlan_network *pnetwork = NULL;
4201 struct wlan_network *candidate = NULL;
4202
4203 if (mlme->cur_network_scanned == NULL) {
4204 rtw_warn_on(1);
4205 goto exit;
4206 }
4207
4208 _enter_critical_bh(&(mlme->scanned_queue.lock), &irqL);
4209 phead = get_list_head(queue);
4210 adapter = (_adapter *)mlme->nic_hdl;
4211
4212 mlme->pscanned = get_next(phead);
4213
4214 while (!rtw_end_of_queue_search(phead, mlme->pscanned)) {
4215
4216 pnetwork = LIST_CONTAINOR(mlme->pscanned, struct wlan_network, list);
4217 if (pnetwork == NULL) {
4218 ret = _FAIL;
4219 goto exit;
4220 }
4221
4222 mlme->pscanned = get_next(mlme->pscanned);
4223
4224 if (0)
4225 RTW_INFO("%s("MAC_FMT", ch%u) rssi:%d\n"
4226 , pnetwork->network.Ssid.Ssid
4227 , MAC_ARG(pnetwork->network.MacAddress)
4228 , pnetwork->network.Configuration.DSConfig
4229 , (int)pnetwork->network.Rssi);
4230
4231 rtw_check_roaming_candidate(mlme, &candidate, pnetwork);
4232
4233 }
4234
4235 if (candidate == NULL) {
4236 /* if parent note lost the path to root and there is no other cadidate, report disconnection */
4237 #if defined(CONFIG_RTW_REPEATER_SON) && (!defined(CONFIG_RTW_REPEATER_SON_ROOT))
4238 struct rtw_rson_struct rson_curr;
4239 u8 rson_score;
4240
4241 rtw_get_rson_struct(&(mlme->cur_network_scanned->network), &rson_curr);
4242 rson_score = rtw_cal_rson_score(&rson_curr, mlme->cur_network_scanned->network.Rssi);
4243 if (check_fwstate(mlme, WIFI_ASOC_STATE)
4244 && ((rson_score == RTW_RSON_SCORE_NOTCNNT)
4245 || (rson_score == RTW_RSON_SCORE_NOTSUP)))
4246 receive_disconnect(adapter, mlme->cur_network_scanned->network.MacAddress
4247 , WLAN_REASON_EXPIRATION_CHK, _FALSE);
4248 #endif
4249 RTW_INFO("%s: return _FAIL(candidate == NULL)\n", __FUNCTION__);
4250 ret = _FAIL;
4251 goto exit;
4252 } else {
4253 #if defined(CONFIG_RTW_REPEATER_SON) && (!defined(CONFIG_RTW_REPEATER_SON_ROOT))
4254 struct rtw_rson_struct rson_curr;
4255 u8 rson_score;
4256
4257 rtw_get_rson_struct(&(candidate->network), &rson_curr);
4258 rson_score = rtw_cal_rson_score(&rson_curr, candidate->network.Rssi);
4259 RTW_INFO("%s: candidate: %s("MAC_FMT", ch:%u) rson_score:%d\n", __FUNCTION__,
4260 candidate->network.Ssid.Ssid, MAC_ARG(candidate->network.MacAddress),
4261 candidate->network.Configuration.DSConfig, rson_score);
4262 #else
4263 RTW_INFO("%s: candidate: %s("MAC_FMT", ch:%u)\n", __FUNCTION__,
4264 candidate->network.Ssid.Ssid, MAC_ARG(candidate->network.MacAddress),
4265 candidate->network.Configuration.DSConfig);
4266 #endif
4267 mlme->roam_network = candidate;
4268
4269 if (_rtw_memcmp(candidate->network.MacAddress, mlme->roam_tgt_addr, ETH_ALEN) == _TRUE)
4270 _rtw_memset(mlme->roam_tgt_addr, 0, ETH_ALEN);
4271 }
4272
4273 ret = _SUCCESS;
4274 exit:
4275 _exit_critical_bh(&(mlme->scanned_queue.lock), &irqL);
4276
4277 return ret;
4278 }
4279 #endif /* CONFIG_LAYER2_ROAMING */
4280
4281 /*
4282 * Select a new join candidate from the original @param candidate and @param competitor
4283 * @return _TRUE: candidate is updated
4284 * @return _FALSE: candidate is not updated
4285 */
4286 static int rtw_check_join_candidate(struct mlme_priv *mlme
4287 , struct wlan_network **candidate, struct wlan_network *competitor)
4288 {
4289 int updated = _FALSE;
4290 _adapter *adapter = container_of(mlme, _adapter, mlmepriv);
4291 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
4292 RT_CHANNEL_INFO *chset = rfctl->channel_set;
4293 u8 ch = competitor->network.Configuration.DSConfig;
4294
4295 if (rtw_chset_search_ch(chset, ch) < 0)
4296 goto exit;
4297 if (IS_DFS_SLAVE_WITH_RD(rfctl)
4298 && !rtw_rfctl_dfs_domain_unknown(rfctl)
4299 && rtw_chset_is_ch_non_ocp(chset, ch))
4300 goto exit;
4301
4302 #if defined(CONFIG_RTW_REPEATER_SON) && (!defined(CONFIG_RTW_REPEATER_SON_ROOT))
4303 s16 rson_score;
4304 struct rtw_rson_struct rson_data;
4305
4306 if (rtw_rson_choose(candidate, competitor)) {
4307 *candidate = competitor;
4308 rtw_get_rson_struct(&((*candidate)->network), &rson_data);
4309 rson_score = rtw_cal_rson_score(&rson_data, (*candidate)->network.Rssi);
4310 RTW_INFO("[assoc_ssid:%s] new candidate: %s("MAC_FMT", ch%u) rson_score:%d\n",
4311 mlme->assoc_ssid.Ssid,
4312 (*candidate)->network.Ssid.Ssid,
4313 MAC_ARG((*candidate)->network.MacAddress),
4314 (*candidate)->network.Configuration.DSConfig,
4315 rson_score);
4316 return _TRUE;
4317 }
4318 return _FALSE;
4319 #endif
4320
4321 /* check bssid, if needed */
4322 if (mlme->assoc_by_bssid == _TRUE) {
4323 if (_rtw_memcmp(competitor->network.MacAddress, mlme->assoc_bssid, ETH_ALEN) == _FALSE)
4324 goto exit;
4325 }
4326
4327 /* check ssid, if needed */
4328 if (mlme->assoc_ssid.Ssid[0] && mlme->assoc_ssid.SsidLength) {
4329 if (competitor->network.Ssid.SsidLength != mlme->assoc_ssid.SsidLength
4330 || _rtw_memcmp(competitor->network.Ssid.Ssid, mlme->assoc_ssid.Ssid, mlme->assoc_ssid.SsidLength) == _FALSE
4331 )
4332 goto exit;
4333 }
4334
4335 if (rtw_is_desired_network(adapter, competitor) == _FALSE)
4336 goto exit;
4337
4338 #ifdef CONFIG_LAYER2_ROAMING
4339 if (rtw_to_roam(adapter) > 0) {
4340 if (rtw_get_passing_time_ms(competitor->last_scanned) >= mlme->roam_scanr_exp_ms
4341 || is_same_ess(&competitor->network, &mlme->cur_network.network) == _FALSE
4342 )
4343 goto exit;
4344 }
4345 #endif
4346
4347 if (*candidate == NULL || (*candidate)->network.Rssi < competitor->network.Rssi) {
4348 *candidate = competitor;
4349 updated = _TRUE;
4350 }
4351
4352 if (updated) {
4353 RTW_INFO("[by_bssid:%u][assoc_ssid:%s][to_roam:%u] "
4354 "new candidate: %s("MAC_FMT", ch%u) rssi:%d\n",
4355 mlme->assoc_by_bssid,
4356 mlme->assoc_ssid.Ssid,
4357 rtw_to_roam(adapter),
4358 (*candidate)->network.Ssid.Ssid,
4359 MAC_ARG((*candidate)->network.MacAddress),
4360 (*candidate)->network.Configuration.DSConfig,
4361 (int)(*candidate)->network.Rssi
4362 );
4363 }
4364
4365 exit:
4366 return updated;
4367 }
4368
4369 /*
4370 Calling context:
4371 The caller of the sub-routine will be in critical section...
4372
4373 The caller must hold the following spinlock
4374
4375 pmlmepriv->lock
4376
4377
4378 */
4379
4380 int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv)
4381 {
4382 _irqL irqL;
4383 int ret;
4384 _list *phead;
4385 _adapter *adapter;
4386 _queue *queue = &(pmlmepriv->scanned_queue);
4387 struct wlan_network *pnetwork = NULL;
4388 struct wlan_network *candidate = NULL;
4389 #ifdef CONFIG_ANTENNA_DIVERSITY
4390 u8 bSupportAntDiv = _FALSE;
4391 #endif
4392
4393 adapter = (_adapter *)pmlmepriv->nic_hdl;
4394
4395 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4396
4397 #ifdef CONFIG_LAYER2_ROAMING
4398 if (pmlmepriv->roam_network) {
4399 candidate = pmlmepriv->roam_network;
4400 pmlmepriv->roam_network = NULL;
4401 goto candidate_exist;
4402 }
4403 #endif
4404
4405 phead = get_list_head(queue);
4406 pmlmepriv->pscanned = get_next(phead);
4407
4408 while (!rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) {
4409
4410 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
4411 if (pnetwork == NULL) {
4412 ret = _FAIL;
4413 goto exit;
4414 }
4415
4416 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
4417
4418 if (0)
4419 RTW_INFO("%s("MAC_FMT", ch%u) rssi:%d\n"
4420 , pnetwork->network.Ssid.Ssid
4421 , MAC_ARG(pnetwork->network.MacAddress)
4422 , pnetwork->network.Configuration.DSConfig
4423 , (int)pnetwork->network.Rssi);
4424
4425 rtw_check_join_candidate(pmlmepriv, &candidate, pnetwork);
4426
4427 }
4428
4429 if (candidate == NULL) {
4430 RTW_INFO("%s: return _FAIL(candidate == NULL)\n", __FUNCTION__);
4431 #ifdef CONFIG_WOWLAN
4432 _clr_fwstate_(pmlmepriv, WIFI_ASOC_STATE | WIFI_UNDER_LINKING);
4433 #endif
4434 ret = _FAIL;
4435 goto exit;
4436 } else {
4437 RTW_INFO("%s: candidate: %s("MAC_FMT", ch:%u)\n", __FUNCTION__,
4438 candidate->network.Ssid.Ssid, MAC_ARG(candidate->network.MacAddress),
4439 candidate->network.Configuration.DSConfig);
4440 goto candidate_exist;
4441 }
4442
4443 candidate_exist:
4444
4445 /* check for situation of WIFI_ASOC_STATE */
4446 if (check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE) {
4447 RTW_INFO("%s: WIFI_ASOC_STATE while ask_for_joinbss!!!\n", __FUNCTION__);
4448
4449 #if 0 /* for WPA/WPA2 authentication, wpa_supplicant will expect authentication from AP, it is needed to reconnect AP... */
4450 if (is_same_network(&pmlmepriv->cur_network.network, &candidate->network)) {
4451 RTW_INFO("%s: WIFI_ASOC_STATE and is same network, it needn't join again\n", __FUNCTION__);
4452
4453 rtw_indicate_connect(adapter);/* rtw_indicate_connect again */
4454
4455 ret = 2;
4456 goto exit;
4457 } else
4458 #endif
4459 {
4460 rtw_disassoc_cmd(adapter, 0, 0);
4461 rtw_indicate_disconnect(adapter, 0, _FALSE);
4462 rtw_free_assoc_resources_cmd(adapter, _TRUE, 0);
4463 }
4464 }
4465
4466 #ifdef CONFIG_ANTENNA_DIVERSITY
4467 rtw_hal_get_def_var(adapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &(bSupportAntDiv));
4468 if (_TRUE == bSupportAntDiv) {
4469 u8 CurrentAntenna;
4470 rtw_hal_get_odm_var(adapter, HAL_ODM_ANTDIV_SELECT, &(CurrentAntenna), NULL);
4471 RTW_INFO("#### Opt_Ant_(%s) , cur_Ant(%s)\n",
4472 (MAIN_ANT == candidate->network.PhyInfo.Optimum_antenna) ? "MAIN_ANT" : "AUX_ANT",
4473 (MAIN_ANT == CurrentAntenna) ? "MAIN_ANT" : "AUX_ANT"
4474 );
4475 }
4476 #endif
4477 set_fwstate(pmlmepriv, WIFI_UNDER_LINKING);
4478 ret = rtw_joinbss_cmd(adapter, candidate);
4479
4480 exit:
4481 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4482
4483
4484 return ret;
4485 }
4486
4487 sint rtw_set_auth(_adapter *adapter, struct security_priv *psecuritypriv)
4488 {
4489 struct cmd_obj *pcmd;
4490 struct setauth_parm *psetauthparm;
4491 struct cmd_priv *pcmdpriv = &(adapter->cmdpriv);
4492 sint res = _SUCCESS;
4493
4494
4495 pcmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
4496 if (pcmd == NULL) {
4497 res = _FAIL; /* try again */
4498 goto exit;
4499 }
4500
4501 psetauthparm = (struct setauth_parm *)rtw_zmalloc(sizeof(struct setauth_parm));
4502 if (psetauthparm == NULL) {
4503 rtw_mfree((unsigned char *)pcmd, sizeof(struct cmd_obj));
4504 res = _FAIL;
4505 goto exit;
4506 }
4507
4508 _rtw_memset(psetauthparm, 0, sizeof(struct setauth_parm));
4509 psetauthparm->mode = (unsigned char)psecuritypriv->dot11AuthAlgrthm;
4510
4511 pcmd->cmdcode = CMD_SET_AUTH;
4512 pcmd->parmbuf = (unsigned char *)psetauthparm;
4513 pcmd->cmdsz = (sizeof(struct setauth_parm));
4514 pcmd->rsp = NULL;
4515 pcmd->rspsz = 0;
4516
4517
4518 _rtw_init_listhead(&pcmd->list);
4519
4520
4521 res = rtw_enqueue_cmd(pcmdpriv, pcmd);
4522
4523 exit:
4524
4525
4526 return res;
4527
4528 }
4529
4530
4531 sint rtw_set_key(_adapter *adapter, struct security_priv *psecuritypriv, sint keyid, u8 set_tx, bool enqueue)
4532 {
4533 u8 keylen;
4534 struct cmd_obj *pcmd;
4535 struct setkey_parm *psetkeyparm;
4536 struct cmd_priv *pcmdpriv = &(adapter->cmdpriv);
4537 sint res = _SUCCESS;
4538
4539
4540 psetkeyparm = (struct setkey_parm *)rtw_zmalloc(sizeof(struct setkey_parm));
4541 if (psetkeyparm == NULL) {
4542 res = _FAIL;
4543 goto exit;
4544 }
4545 _rtw_memset(psetkeyparm, 0, sizeof(struct setkey_parm));
4546
4547 if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) {
4548 psetkeyparm->algorithm = (unsigned char)psecuritypriv->dot118021XGrpPrivacy;
4549 } else {
4550 psetkeyparm->algorithm = (u8)psecuritypriv->dot11PrivacyAlgrthm;
4551
4552 }
4553 psetkeyparm->keyid = (u8)keyid;/* 0~3 */
4554 psetkeyparm->set_tx = set_tx;
4555 if (is_wep_enc(psetkeyparm->algorithm))
4556 adapter->securitypriv.key_mask |= BIT(psetkeyparm->keyid);
4557
4558 RTW_INFO("==> rtw_set_key algorithm(%x),keyid(%x),key_mask(%x)\n", psetkeyparm->algorithm, psetkeyparm->keyid, adapter->securitypriv.key_mask);
4559
4560 switch (psetkeyparm->algorithm) {
4561
4562 case _WEP40_:
4563 keylen = 5;
4564 _rtw_memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen);
4565 break;
4566 case _WEP104_:
4567 keylen = 13;
4568 _rtw_memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen);
4569 break;
4570 case _TKIP_:
4571 keylen = 16;
4572 _rtw_memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
4573 break;
4574 case _AES_:
4575 case _GCMP_:
4576 keylen = 16;
4577 _rtw_memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
4578 break;
4579 case _GCMP_256_:
4580 case _CCMP_256_:
4581 keylen = 32;
4582 _rtw_memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
4583 break;
4584 default:
4585 res = _FAIL;
4586 rtw_mfree((unsigned char *)psetkeyparm, sizeof(struct setkey_parm));
4587 goto exit;
4588 }
4589
4590
4591 if (enqueue) {
4592 pcmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
4593 if (pcmd == NULL) {
4594 rtw_mfree((unsigned char *)psetkeyparm, sizeof(struct setkey_parm));
4595 res = _FAIL; /* try again */
4596 goto exit;
4597 }
4598
4599 pcmd->cmdcode =CMD_SET_KEY;
4600 pcmd->parmbuf = (u8 *)psetkeyparm;
4601 pcmd->cmdsz = (sizeof(struct setkey_parm));
4602 pcmd->rsp = NULL;
4603 pcmd->rspsz = 0;
4604
4605 _rtw_init_listhead(&pcmd->list);
4606
4607 /* _rtw_init_sema(&(pcmd->cmd_sem), 0); */
4608
4609 res = rtw_enqueue_cmd(pcmdpriv, pcmd);
4610 } else {
4611 setkey_hdl(adapter, (u8 *)psetkeyparm);
4612 rtw_mfree((u8 *) psetkeyparm, sizeof(struct setkey_parm));
4613 }
4614 exit:
4615 return res;
4616
4617 }
4618
4619 #ifdef CONFIG_WMMPS_STA
4620 /*
4621 * rtw_uapsd_use_default_setting
4622 * This function is used for setting default uapsd max sp length to uapsd_max_sp_len
4623 * in qos_priv data structure from registry. In additional, it will also map default uapsd
4624 * ac to each uapsd TID, delivery-enabled and trigger-enabled of corresponding TID.
4625 *
4626 * Arguments:
4627 * @padapter: _adapter pointer.
4628 *
4629 * Auther: Arvin Liu
4630 * Date: 2017/05/03
4631 */
4632 void rtw_uapsd_use_default_setting(_adapter *padapter)
4633 {
4634 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4635 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
4636 struct registry_priv *pregistrypriv = &padapter->registrypriv;
4637
4638 if (pregistrypriv->uapsd_ac_enable != 0) {
4639 pqospriv->uapsd_max_sp_len = pregistrypriv->uapsd_max_sp_len;
4640
4641 CLEAR_FLAGS(pqospriv->uapsd_tid);
4642 CLEAR_FLAGS(pqospriv->uapsd_tid_delivery_enabled);
4643 CLEAR_FLAGS(pqospriv->uapsd_tid_trigger_enabled);
4644
4645 /* check the uapsd setting of AC_VO from registry then map these setting to each TID if necessary */
4646 if(TEST_FLAG(pregistrypriv->uapsd_ac_enable, DRV_CFG_UAPSD_VO)) {
4647 SET_FLAG(pqospriv->uapsd_tid, WMM_TID7);
4648 SET_FLAG(pqospriv->uapsd_tid_delivery_enabled, WMM_TID7);
4649 SET_FLAG(pqospriv->uapsd_tid_trigger_enabled, WMM_TID7);
4650 SET_FLAG(pqospriv->uapsd_tid, WMM_TID6);
4651 SET_FLAG(pqospriv->uapsd_tid_delivery_enabled, WMM_TID6);
4652 SET_FLAG(pqospriv->uapsd_tid_trigger_enabled, WMM_TID6);
4653 }
4654
4655 /* check the uapsd setting of AC_VI from registry then map these setting to each TID if necessary */
4656 if(TEST_FLAG(pregistrypriv->uapsd_ac_enable, DRV_CFG_UAPSD_VI)) {
4657 SET_FLAG(pqospriv->uapsd_tid, WMM_TID5);
4658 SET_FLAG(pqospriv->uapsd_tid_delivery_enabled, WMM_TID5);
4659 SET_FLAG(pqospriv->uapsd_tid_trigger_enabled, WMM_TID5);
4660 SET_FLAG(pqospriv->uapsd_tid, WMM_TID4);
4661 SET_FLAG(pqospriv->uapsd_tid_delivery_enabled, WMM_TID4);
4662 SET_FLAG(pqospriv->uapsd_tid_trigger_enabled, WMM_TID4);
4663 }
4664
4665 /* check the uapsd setting of AC_BK from registry then map these setting to each TID if necessary */
4666 if(TEST_FLAG(pregistrypriv->uapsd_ac_enable, DRV_CFG_UAPSD_BK)) {
4667 SET_FLAG(pqospriv->uapsd_tid, WMM_TID2);
4668 SET_FLAG(pqospriv->uapsd_tid_delivery_enabled, WMM_TID2);
4669 SET_FLAG(pqospriv->uapsd_tid_trigger_enabled, WMM_TID2);
4670 SET_FLAG(pqospriv->uapsd_tid, WMM_TID1);
4671 SET_FLAG(pqospriv->uapsd_tid_delivery_enabled, WMM_TID1);
4672 SET_FLAG(pqospriv->uapsd_tid_trigger_enabled, WMM_TID1);
4673 }
4674
4675 /* check the uapsd setting of AC_BE from registry then map these setting to each TID if necessary */
4676 if(TEST_FLAG(pregistrypriv->uapsd_ac_enable, DRV_CFG_UAPSD_BE)) {
4677 SET_FLAG(pqospriv->uapsd_tid, WMM_TID3);
4678 SET_FLAG(pqospriv->uapsd_tid_delivery_enabled, WMM_TID3);
4679 SET_FLAG(pqospriv->uapsd_tid_trigger_enabled, WMM_TID3);
4680 SET_FLAG(pqospriv->uapsd_tid, WMM_TID0);
4681 SET_FLAG(pqospriv->uapsd_tid_delivery_enabled, WMM_TID0);
4682 SET_FLAG(pqospriv->uapsd_tid_trigger_enabled, WMM_TID0);
4683 }
4684
4685 RTW_INFO("[WMMPS] UAPSD MAX SP Len = 0x%02x, UAPSD TID enabled = 0x%02x\n",
4686 pqospriv->uapsd_max_sp_len, (u8)pqospriv->uapsd_tid);
4687 }
4688
4689 }
4690
4691 /*
4692 * rtw_is_wmmps_mode
4693 * This function is used for checking whether Driver and an AP support uapsd function or not.
4694 * If both of them support uapsd function, it will return true. Otherwise returns false.
4695 *
4696 * Arguments:
4697 * @padapter: _adapter pointer.
4698 *
4699 * Auther: Arvin Liu
4700 * Date: 2017/06/12
4701 */
4702 bool rtw_is_wmmps_mode(_adapter *padapter)
4703 {
4704 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4705 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
4706
4707 if ((pqospriv->uapsd_ap_supported) && ((pqospriv->uapsd_tid & BIT_MASK_TID_TC) != 0))
4708 return _TRUE;
4709
4710 return _FALSE;
4711 }
4712 #endif /* CONFIG_WMMPS_STA */
4713
4714 /* adjust IEs for rtw_joinbss_cmd in WMM */
4715 int rtw_restruct_wmm_ie(_adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_len, uint initial_out_len)
4716 {
4717 #ifdef CONFIG_WMMPS_STA
4718 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4719 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
4720 #endif /* CONFIG_WMMPS_STA */
4721 unsigned int ielength = 0;
4722 unsigned int i, j;
4723 u8 qos_info = 0;
4724
4725 i = 12; /* after the fixed IE */
4726 while (i < in_len) {
4727 ielength = initial_out_len;
4728
4729 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 */
4730
4731 /* Append WMM IE to the last index of out_ie */
4732 #if 0
4733 for (j = i; j < i + (in_ie[i + 1] + 2); j++) {
4734 out_ie[ielength] = in_ie[j];
4735 ielength++;
4736 }
4737 out_ie[initial_out_len + 8] = 0x00; /* force the QoS Info Field to be zero */
4738 #endif
4739
4740 for (j = i; j < i + 9; j++) {
4741 out_ie[ielength] = in_ie[j];
4742 ielength++;
4743 }
4744 out_ie[initial_out_len + 1] = 0x07;
4745 out_ie[initial_out_len + 6] = 0x00;
4746
4747 #ifdef CONFIG_WMMPS_STA
4748 switch(pqospriv->uapsd_max_sp_len) {
4749 case NO_LIMIT:
4750 /* do nothing */
4751 break;
4752 case TWO_MSDU:
4753 SET_FLAG(qos_info, BIT5);
4754 break;
4755 case FOUR_MSDU:
4756 SET_FLAG(qos_info, BIT6);
4757 break;
4758 case SIX_MSDU:
4759 SET_FLAG(qos_info, BIT5);
4760 SET_FLAG(qos_info, BIT6);
4761 break;
4762 default:
4763 /* do nothing */
4764 break;
4765 };
4766
4767 /* check TID7 and TID6 for AC_VO to set corresponding Qos_info bit in WMM IE */
4768 if((TEST_FLAG(pqospriv->uapsd_tid, WMM_TID7)) && (TEST_FLAG(pqospriv->uapsd_tid, WMM_TID6)))
4769 SET_FLAG(qos_info, WMM_IE_UAPSD_VO);
4770 /* check TID5 and TID4 for AC_VI to set corresponding Qos_info bit in WMM IE */
4771 if((TEST_FLAG(pqospriv->uapsd_tid, WMM_TID5)) && (TEST_FLAG(pqospriv->uapsd_tid, WMM_TID4)))
4772 SET_FLAG(qos_info, WMM_IE_UAPSD_VI);
4773 /* check TID2 and TID1 for AC_BK to set corresponding Qos_info bit in WMM IE */
4774 if((TEST_FLAG(pqospriv->uapsd_tid, WMM_TID2)) && (TEST_FLAG(pqospriv->uapsd_tid, WMM_TID1)))
4775 SET_FLAG(qos_info, WMM_IE_UAPSD_BK);
4776 /* check TID3 and TID0 for AC_BE to set corresponding Qos_info bit in WMM IE */
4777 if((TEST_FLAG(pqospriv->uapsd_tid, WMM_TID3)) && (TEST_FLAG(pqospriv->uapsd_tid, WMM_TID0)))
4778 SET_FLAG(qos_info, WMM_IE_UAPSD_BE);
4779 #endif /* CONFIG_WMMPS_STA */
4780
4781 out_ie[initial_out_len + 8] = qos_info;
4782
4783 break;
4784 }
4785
4786 i += (in_ie[i + 1] + 2); /* to the next IE element */
4787 }
4788
4789 return ielength;
4790
4791 }
4792
4793
4794 /*
4795 * Ported from 8185: IsInPreAuthKeyList(). (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.)
4796 * Added by Annie, 2006-05-07.
4797 *
4798 * Search by BSSID,
4799 * Return Value:
4800 * -1 :if there is no pre-auth key in the table
4801 * >=0 :if there is pre-auth key, and return the entry id
4802 *
4803 * */
4804
4805 static int SecIsInPMKIDList(_adapter *Adapter, u8 *bssid)
4806 {
4807 struct security_priv *psecuritypriv = &Adapter->securitypriv;
4808 int i = 0;
4809
4810 do {
4811 if ((psecuritypriv->PMKIDList[i].bUsed) &&
4812 (_rtw_memcmp(psecuritypriv->PMKIDList[i].Bssid, bssid, ETH_ALEN) == _TRUE))
4813 break;
4814 else {
4815 i++;
4816 /* continue; */
4817 }
4818
4819 } while (i < NUM_PMKID_CACHE);
4820
4821 if (i == NUM_PMKID_CACHE) {
4822 i = -1;/* Could not find. */
4823 } else {
4824 /* There is one Pre-Authentication Key for the specific BSSID. */
4825 }
4826
4827 return i;
4828
4829 }
4830
4831 int rtw_cached_pmkid(_adapter *Adapter, u8 *bssid)
4832 {
4833 return SecIsInPMKIDList(Adapter, bssid);
4834 }
4835
4836 int rtw_rsn_sync_pmkid(_adapter *adapter, u8 *ie, uint ie_len, int i_ent)
4837 {
4838 struct security_priv *sec = &adapter->securitypriv;
4839 struct rsne_info info;
4840 u8 gm_cs[4];
4841 int i;
4842
4843 rtw_rsne_info_parse(ie, ie_len, &info);
4844
4845 if (info.err) {
4846 RTW_WARN(FUNC_ADPT_FMT" rtw_rsne_info_parse error\n"
4847 , FUNC_ADPT_ARG(adapter));
4848 return 0;
4849 }
4850
4851 if (i_ent < 0 && info.pmkid_cnt == 0)
4852 goto exit;
4853
4854 if (i_ent >= 0 && info.pmkid_cnt == 1 && _rtw_memcmp(info.pmkid_list, sec->PMKIDList[i_ent].PMKID, 16)) {
4855 RTW_INFO(FUNC_ADPT_FMT" has carried the same PMKID:"KEY_FMT"\n"
4856 , FUNC_ADPT_ARG(adapter), KEY_ARG(&sec->PMKIDList[i_ent].PMKID));
4857 goto exit;
4858 }
4859
4860 /* bakcup group mgmt cs */
4861 if (info.gmcs)
4862 _rtw_memcpy(gm_cs, info.gmcs, 4);
4863
4864 if (info.pmkid_cnt) {
4865 RTW_INFO(FUNC_ADPT_FMT" remove original PMKID, count:%u\n"
4866 , FUNC_ADPT_ARG(adapter), info.pmkid_cnt);
4867 for (i = 0; i < info.pmkid_cnt; i++)
4868 RTW_INFO(" "KEY_FMT"\n", KEY_ARG(info.pmkid_list + i * 16));
4869 }
4870
4871 if (i_ent >= 0) {
4872 RTW_INFO(FUNC_ADPT_FMT" append PMKID:"KEY_FMT"\n"
4873 , FUNC_ADPT_ARG(adapter), KEY_ARG(sec->PMKIDList[i_ent].PMKID));
4874
4875 info.pmkid_cnt = 1; /* update new pmkid_cnt */
4876 _rtw_memcpy(info.pmkid_list, sec->PMKIDList[i_ent].PMKID, 16);
4877 } else
4878 info.pmkid_cnt = 0; /* update new pmkid_cnt */
4879
4880 RTW_PUT_LE16(info.pmkid_list - 2, info.pmkid_cnt);
4881 if (info.gmcs)
4882 _rtw_memcpy(info.pmkid_list + 16 * info.pmkid_cnt, gm_cs, 4);
4883
4884 ie_len = 1 + 1 + 2 + 4
4885 + 2 + 4 * info.pcs_cnt
4886 + 2 + 4 * info.akm_cnt
4887 + 2
4888 + 2 + 16 * info.pmkid_cnt
4889 + (info.gmcs ? 4 : 0)
4890 ;
4891
4892 ie[1] = (u8)(ie_len - 2);
4893
4894 exit:
4895 return ie_len;
4896 }
4897
4898 sint rtw_restruct_sec_ie(_adapter *adapter, u8 *out_ie)
4899 {
4900 u8 authmode = 0x0;
4901 uint ielength = 0;
4902 int iEntry;
4903
4904 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
4905 struct security_priv *psecuritypriv = &adapter->securitypriv;
4906 uint ndisauthmode = psecuritypriv->ndisauthtype;
4907
4908 if ((ndisauthmode == Ndis802_11AuthModeWPA) || (ndisauthmode == Ndis802_11AuthModeWPAPSK))
4909 authmode = _WPA_IE_ID_;
4910 if ((ndisauthmode == Ndis802_11AuthModeWPA2) || (ndisauthmode == Ndis802_11AuthModeWPA2PSK))
4911 authmode = _WPA2_IE_ID_;
4912
4913 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
4914 _rtw_memcpy(out_ie, psecuritypriv->wps_ie, psecuritypriv->wps_ie_len);
4915 ielength = psecuritypriv->wps_ie_len;
4916
4917 } else if ((authmode == _WPA_IE_ID_) || (authmode == _WPA2_IE_ID_)) {
4918 /* copy RSN or SSN */
4919 _rtw_memcpy(out_ie, psecuritypriv->supplicant_ie, psecuritypriv->supplicant_ie[1] + 2);
4920 /* debug for CONFIG_IEEE80211W
4921 {
4922 int jj;
4923 printk("supplicant_ie_length=%d &&&&&&&&&&&&&&&&&&&\n", psecuritypriv->supplicant_ie[1]+2);
4924 for(jj=0; jj < psecuritypriv->supplicant_ie[1]+2; jj++)
4925 printk(" %02x ", psecuritypriv->supplicant_ie[jj]);
4926 printk("\n");
4927 }*/
4928 ielength = psecuritypriv->supplicant_ie[1] + 2;
4929 rtw_report_sec_ie(adapter, authmode, psecuritypriv->supplicant_ie);
4930 }
4931
4932 if (authmode == WLAN_EID_RSN) {
4933 iEntry = SecIsInPMKIDList(adapter, pmlmepriv->assoc_bssid);
4934 ielength = rtw_rsn_sync_pmkid(adapter, out_ie, ielength, iEntry);
4935 }
4936
4937 if ((psecuritypriv->auth_type == MLME_AUTHTYPE_SAE) &&
4938 (psecuritypriv->rsnx_ie_len >= 3)) {
4939 u8 *_pos = out_ie + (psecuritypriv->supplicant_ie[1] + 2);
4940 _rtw_memcpy(_pos, psecuritypriv->rsnx_ie,
4941 psecuritypriv->rsnx_ie_len);
4942 ielength += psecuritypriv->rsnx_ie_len;
4943 RTW_INFO_DUMP("update IE for RSNX :", out_ie, ielength);
4944 }
4945
4946 return ielength;
4947 }
4948
4949 void rtw_init_registrypriv_dev_network(_adapter *adapter)
4950 {
4951 struct registry_priv *pregistrypriv = &adapter->registrypriv;
4952 WLAN_BSSID_EX *pdev_network = &pregistrypriv->dev_network;
4953 u8 *myhwaddr = adapter_mac_addr(adapter);
4954
4955
4956 _rtw_memcpy(pdev_network->MacAddress, myhwaddr, ETH_ALEN);
4957
4958 _rtw_memcpy(&pdev_network->Ssid, &pregistrypriv->ssid, sizeof(NDIS_802_11_SSID));
4959
4960 pdev_network->Configuration.Length = sizeof(NDIS_802_11_CONFIGURATION);
4961 pdev_network->Configuration.BeaconPeriod = 100;
4962 }
4963
4964 void rtw_update_registrypriv_dev_network(_adapter *adapter)
4965 {
4966 int sz = 0;
4967 struct registry_priv *pregistrypriv = &adapter->registrypriv;
4968 WLAN_BSSID_EX *pdev_network = &pregistrypriv->dev_network;
4969 struct security_priv *psecuritypriv = &adapter->securitypriv;
4970 struct wlan_network *cur_network = &adapter->mlmepriv.cur_network;
4971 /* struct xmit_priv *pxmitpriv = &adapter->xmitpriv; */
4972 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
4973
4974
4975 #if 0
4976 pxmitpriv->vcs_setting = pregistrypriv->vrtl_carrier_sense;
4977 pxmitpriv->vcs = pregistrypriv->vcs_type;
4978 pxmitpriv->vcs_type = pregistrypriv->vcs_type;
4979 /* pxmitpriv->rts_thresh = pregistrypriv->rts_thresh; */
4980 pxmitpriv->frag_len = pregistrypriv->frag_thresh;
4981
4982 adapter->qospriv.qos_option = pregistrypriv->wmm_enable;
4983 #endif
4984
4985 pdev_network->Privacy = (psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0) ; /* adhoc no 802.1x */
4986
4987 pdev_network->Rssi = 0;
4988
4989 pdev_network->Configuration.DSConfig = (pregistrypriv->channel);
4990
4991 if (cur_network->network.InfrastructureMode == Ndis802_11IBSS) {
4992 pdev_network->Configuration.ATIMWindow = (0);
4993
4994 if (pmlmeext->cur_channel != 0)
4995 pdev_network->Configuration.DSConfig = pmlmeext->cur_channel;
4996 else
4997 pdev_network->Configuration.DSConfig = 1;
4998 }
4999
5000 pdev_network->InfrastructureMode = (cur_network->network.InfrastructureMode);
5001
5002 /* 1. Supported rates */
5003 /* 2. IE */
5004
5005 /* rtw_set_supported_rate(pdev_network->SupportedRates, pregistrypriv->wireless_mode) ; */ /* will be called in rtw_generate_ie */
5006 sz = rtw_generate_ie(pregistrypriv);
5007
5008 pdev_network->IELength = sz;
5009
5010 pdev_network->Length = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX *)pdev_network);
5011
5012 /* notes: translate IELength & Length after assign the Length to cmdsz in createbss_cmd(); */
5013 /* pdev_network->IELength = cpu_to_le32(sz); */
5014
5015
5016 }
5017
5018 void rtw_get_encrypt_decrypt_from_registrypriv(_adapter *adapter)
5019 {
5020
5021
5022
5023 }
5024
5025 /* the fucntion is at passive_level */
5026 void rtw_joinbss_reset(_adapter *padapter)
5027 {
5028 u8 threshold;
5029 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5030 /* todo: if you want to do something io/reg/hw setting before join_bss, please add code here */
5031
5032 #ifdef CONFIG_80211N_HT
5033 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
5034
5035 pmlmepriv->num_FortyMHzIntolerant = 0;
5036
5037 pmlmepriv->num_sta_no_ht = 0;
5038
5039 phtpriv->ampdu_enable = _FALSE;/* reset to disabled */
5040
5041 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
5042 /* TH=1 => means that invalidate usb rx aggregation */
5043 /* TH=0 => means that validate usb rx aggregation, use init value. */
5044 if (phtpriv->ht_option) {
5045 if (padapter->registrypriv.wifi_spec == 1)
5046 threshold = 1;
5047 else
5048 threshold = 0;
5049 rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
5050 } else {
5051 threshold = 1;
5052 rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
5053 }
5054 #endif/* #if defined( CONFIG_USB_HCI) || defined (CONFIG_SDIO_HCI) */
5055
5056 #endif/* #ifdef CONFIG_80211N_HT */
5057
5058 }
5059
5060
5061 #ifdef CONFIG_80211N_HT
5062 void rtw_ht_use_default_setting(_adapter *padapter)
5063 {
5064 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5065 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
5066 struct registry_priv *pregistrypriv = &padapter->registrypriv;
5067 BOOLEAN bHwLDPCSupport = _FALSE, bHwSTBCSupport = _FALSE;
5068 #ifdef CONFIG_BEAMFORMING
5069 BOOLEAN bHwSupportBeamformer = _FALSE, bHwSupportBeamformee = _FALSE;
5070 #endif /* CONFIG_BEAMFORMING */
5071
5072 if (pregistrypriv->wifi_spec)
5073 phtpriv->bss_coexist = 1;
5074 else
5075 phtpriv->bss_coexist = 0;
5076
5077 phtpriv->sgi_40m = TEST_FLAG(pregistrypriv->short_gi, BIT1) ? _TRUE : _FALSE;
5078 phtpriv->sgi_20m = TEST_FLAG(pregistrypriv->short_gi, BIT0) ? _TRUE : _FALSE;
5079
5080 /* LDPC support */
5081 rtw_hal_get_def_var(padapter, HAL_DEF_RX_LDPC, (u8 *)&bHwLDPCSupport);
5082 CLEAR_FLAGS(phtpriv->ldpc_cap);
5083 if (bHwLDPCSupport) {
5084 if (TEST_FLAG(pregistrypriv->ldpc_cap, BIT4))
5085 SET_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_RX);
5086 }
5087 rtw_hal_get_def_var(padapter, HAL_DEF_TX_LDPC, (u8 *)&bHwLDPCSupport);
5088 if (bHwLDPCSupport) {
5089 if (TEST_FLAG(pregistrypriv->ldpc_cap, BIT5))
5090 SET_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_TX);
5091 }
5092 if (phtpriv->ldpc_cap)
5093 RTW_INFO("[HT] HAL Support LDPC = 0x%02X\n", phtpriv->ldpc_cap);
5094
5095 /* STBC */
5096 rtw_hal_get_def_var(padapter, HAL_DEF_TX_STBC, (u8 *)&bHwSTBCSupport);
5097 CLEAR_FLAGS(phtpriv->stbc_cap);
5098 if (bHwSTBCSupport) {
5099 if (TEST_FLAG(pregistrypriv->stbc_cap, BIT5))
5100 SET_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX);
5101 }
5102 rtw_hal_get_def_var(padapter, HAL_DEF_RX_STBC, (u8 *)&bHwSTBCSupport);
5103 if (bHwSTBCSupport) {
5104 if (TEST_FLAG(pregistrypriv->stbc_cap, BIT4))
5105 SET_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX);
5106 }
5107 if (phtpriv->stbc_cap)
5108 RTW_INFO("[HT] HAL Support STBC = 0x%02X\n", phtpriv->stbc_cap);
5109
5110 /* Beamforming setting */
5111 CLEAR_FLAGS(phtpriv->beamform_cap);
5112 #ifdef CONFIG_BEAMFORMING
5113 #ifdef RTW_BEAMFORMING_VERSION_2
5114 /* only enable beamforming in STA client mode */
5115 if (MLME_IS_STA(padapter) && !MLME_IS_GC(padapter)
5116 && !MLME_IS_ADHOC(padapter)
5117 && !MLME_IS_MESH(padapter))
5118 #endif
5119 {
5120 rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMER, (u8 *)&bHwSupportBeamformer);
5121 rtw_hal_get_def_var(padapter, HAL_DEF_EXPLICIT_BEAMFORMEE, (u8 *)&bHwSupportBeamformee);
5122 if (TEST_FLAG(pregistrypriv->beamform_cap, BIT4) && bHwSupportBeamformer) {
5123 SET_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE);
5124 RTW_INFO("[HT] HAL Support Beamformer\n");
5125 }
5126 if (TEST_FLAG(pregistrypriv->beamform_cap, BIT5) && bHwSupportBeamformee) {
5127 SET_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE);
5128 RTW_INFO("[HT] HAL Support Beamformee\n");
5129 }
5130 }
5131 #endif /* CONFIG_BEAMFORMING */
5132 }
5133 void rtw_build_wmm_ie_ht(_adapter *padapter, u8 *out_ie, uint *pout_len)
5134 {
5135 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
5136 int out_len;
5137 u8 *pframe;
5138
5139 if (padapter->mlmepriv.qospriv.qos_option == 0) {
5140 out_len = *pout_len;
5141 pframe = rtw_set_ie(out_ie + out_len, _VENDOR_SPECIFIC_IE_,
5142 _WMM_IE_Length_, WMM_IE, pout_len);
5143
5144 padapter->mlmepriv.qospriv.qos_option = 1;
5145 }
5146 }
5147 #if defined(CONFIG_80211N_HT)
5148 /* the fucntion is >= passive_level */
5149 unsigned int rtw_restructure_ht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, uint in_len, uint *pout_len, u8 channel)
5150 {
5151 u32 ielen, out_len;
5152 u32 rx_packet_offset, max_recvbuf_sz;
5153 HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor;
5154 HT_CAP_AMPDU_DENSITY best_ampdu_density;
5155 unsigned char *p, *pframe;
5156 struct rtw_ieee80211_ht_cap ht_capie;
5157 u8 cbw40_enable = 0, rf_num = 0, rx_stbc_nss = 0, rx_nss = 0;
5158 struct registry_priv *pregistrypriv = &padapter->registrypriv;
5159 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5160 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
5161 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5162 #ifdef CONFIG_80211AC_VHT
5163 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5164 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
5165 #endif /* CONFIG_80211AC_VHT */
5166
5167 phtpriv->ht_option = _FALSE;
5168
5169 out_len = *pout_len;
5170
5171 _rtw_memset(&ht_capie, 0, sizeof(struct rtw_ieee80211_ht_cap));
5172
5173 ht_capie.cap_info = IEEE80211_HT_CAP_DSSSCCK40;
5174
5175 if (phtpriv->sgi_20m)
5176 ht_capie.cap_info |= IEEE80211_HT_CAP_SGI_20;
5177
5178 /* check if 40MHz is allowed according to hal cap and registry */
5179 if (hal_chk_bw_cap(padapter, BW_CAP_40M)) {
5180 if (channel > 14) {
5181 if (REGSTY_IS_BW_5G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
5182 cbw40_enable = 1;
5183 } else {
5184 if (REGSTY_IS_BW_2G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
5185 cbw40_enable = 1;
5186 }
5187 }
5188
5189 if (cbw40_enable) {
5190 struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
5191 RT_CHANNEL_INFO *chset = rfctl->channel_set;
5192 u8 oper_bw = CHANNEL_WIDTH_20, oper_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5193
5194 if (in_ie == NULL) {
5195 /* TDLS: TODO 20/40 issue */
5196 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
5197 oper_bw = padapter->mlmeextpriv.cur_bwmode;
5198 if (oper_bw > CHANNEL_WIDTH_40)
5199 oper_bw = CHANNEL_WIDTH_40;
5200 } else
5201 /* TDLS: TODO 40? */
5202 oper_bw = CHANNEL_WIDTH_40;
5203 } else {
5204 p = rtw_get_ie(in_ie, WLAN_EID_HT_OPERATION, &ielen, in_len);
5205 if (p && ielen == HT_OP_IE_LEN) {
5206 if (GET_HT_OP_ELE_STA_CHL_WIDTH(p + 2)) {
5207 switch (GET_HT_OP_ELE_2ND_CHL_OFFSET(p + 2)) {
5208 case SCA:
5209 oper_bw = CHANNEL_WIDTH_40;
5210 oper_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
5211 break;
5212 case SCB:
5213 oper_bw = CHANNEL_WIDTH_40;
5214 oper_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
5215 break;
5216 }
5217 }
5218 }
5219 // IOT issue : AP TP-Link WDR6500
5220 if(oper_bw == CHANNEL_WIDTH_40){
5221 p = rtw_get_ie(in_ie, WLAN_EID_HT_CAP, &ielen, in_len);
5222 if (p && ielen == HT_CAP_IE_LEN) {
5223 oper_bw = GET_HT_CAP_ELE_CHL_WIDTH(p + 2) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20;
5224 if(oper_bw == CHANNEL_WIDTH_20)
5225 oper_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5226 }
5227 }
5228 }
5229
5230 /* adjust bw to fit in channel plan setting */
5231 if (oper_bw == CHANNEL_WIDTH_40
5232 && oper_offset != HAL_PRIME_CHNL_OFFSET_DONT_CARE /* check this because TDLS has no info to set offset */
5233 && (!rtw_chset_is_chbw_valid(chset, channel, oper_bw, oper_offset, 1, 1)
5234 || (IS_DFS_SLAVE_WITH_RD(rfctl)
5235 && !rtw_rfctl_dfs_domain_unknown(rfctl)
5236 && rtw_chset_is_chbw_non_ocp(chset, channel, oper_bw, oper_offset))
5237 )
5238 ) {
5239 oper_bw = CHANNEL_WIDTH_20;
5240 oper_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5241 rtw_warn_on(!rtw_chset_is_chbw_valid(chset, channel, oper_bw, oper_offset, 1, 1));
5242 if (IS_DFS_SLAVE_WITH_RD(rfctl) && !rtw_rfctl_dfs_domain_unknown(rfctl))
5243 rtw_warn_on(rtw_chset_is_chbw_non_ocp(chset, channel, oper_bw, oper_offset));
5244 }
5245
5246 if (oper_bw == CHANNEL_WIDTH_40) {
5247 ht_capie.cap_info |= IEEE80211_HT_CAP_SUP_WIDTH;
5248 if (phtpriv->sgi_40m)
5249 ht_capie.cap_info |= IEEE80211_HT_CAP_SGI_40;
5250 }
5251
5252 cbw40_enable = oper_bw == CHANNEL_WIDTH_40 ? 1 : 0;
5253 }
5254
5255 /* todo: disable SM power save mode */
5256 ht_capie.cap_info |= IEEE80211_HT_CAP_SM_PS;
5257
5258 /* RX LDPC */
5259 if (TEST_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_RX)) {
5260 ht_capie.cap_info |= IEEE80211_HT_CAP_LDPC_CODING;
5261 RTW_INFO("[HT] Declare supporting RX LDPC\n");
5262 }
5263
5264 /* TX STBC */
5265 if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX)) {
5266 ht_capie.cap_info |= IEEE80211_HT_CAP_TX_STBC;
5267 RTW_INFO("[HT] Declare supporting TX STBC\n");
5268 }
5269
5270 /* RX STBC */
5271 if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX)) {
5272 if ((pregistrypriv->rx_stbc == 0x3) || /* enable for 2.4/5 GHz */
5273 ((channel <= 14) && (pregistrypriv->rx_stbc == 0x1)) || /* enable for 2.4GHz */
5274 ((channel > 14) && (pregistrypriv->rx_stbc == 0x2)) || /* enable for 5GHz */
5275 (pregistrypriv->wifi_spec == 1)) {
5276 /* HAL_DEF_RX_STBC means STBC RX spatial stream, todo: VHT 4 streams */
5277 rtw_hal_get_def_var(padapter, HAL_DEF_RX_STBC, (u8 *)(&rx_stbc_nss));
5278 SET_HT_CAP_ELE_RX_STBC(&ht_capie, rx_stbc_nss);
5279 RTW_INFO("[HT] Declare supporting RX STBC = %d\n", rx_stbc_nss);
5280 }
5281 }
5282
5283 /* fill default supported_mcs_set */
5284 _rtw_memcpy(ht_capie.supp_mcs_set, pmlmeext->default_supported_mcs_set, 16);
5285
5286 /* update default supported_mcs_set */
5287 rx_nss = GET_HAL_RX_NSS(padapter);
5288
5289 switch (rx_nss) {
5290 case 1:
5291 set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_1R);
5292 break;
5293 case 2:
5294 #ifdef CONFIG_DISABLE_MCS13TO15
5295 if (cbw40_enable && pregistrypriv->wifi_spec != 1)
5296 set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_2R_13TO15_OFF);
5297 else
5298 #endif
5299 set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_2R);
5300 break;
5301 case 3:
5302 set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_3R);
5303 break;
5304 case 4:
5305 set_mcs_rate_by_mask(ht_capie.supp_mcs_set, MCS_RATE_4R);
5306 break;
5307 default:
5308 RTW_WARN("rf_type:%d or rx_nss:%u is not expected\n", GET_HAL_RFPATH(padapter), rx_nss);
5309 }
5310
5311 {
5312 rtw_hal_get_def_var(padapter, HAL_DEF_RX_PACKET_OFFSET, &rx_packet_offset);
5313 rtw_hal_get_def_var(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz);
5314 if (max_recvbuf_sz - rx_packet_offset >= (8191 - 256)) {
5315 RTW_INFO("%s IEEE80211_HT_CAP_MAX_AMSDU is set\n", __FUNCTION__);
5316 ht_capie.cap_info = ht_capie.cap_info | IEEE80211_HT_CAP_MAX_AMSDU;
5317 }
5318 }
5319 /*
5320 AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
5321 AMPDU_para [4:2]:Min MPDU Start Spacing
5322 */
5323
5324 /*
5325 #if defined(CONFIG_RTL8188E) && defined(CONFIG_SDIO_HCI)
5326 ht_capie.ampdu_params_info = 2;
5327 #else
5328 ht_capie.ampdu_params_info = (IEEE80211_HT_CAP_AMPDU_FACTOR&0x03);
5329 #endif
5330 */
5331
5332 if (padapter->driver_rx_ampdu_factor != 0xFF)
5333 max_rx_ampdu_factor = (HT_CAP_AMPDU_FACTOR)padapter->driver_rx_ampdu_factor;
5334 else
5335 rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
5336
5337 /* rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor); */
5338 ht_capie.ampdu_params_info = (max_rx_ampdu_factor & 0x03);
5339
5340 if (padapter->driver_rx_ampdu_spacing != 0xFF)
5341 ht_capie.ampdu_params_info |= ((padapter->driver_rx_ampdu_spacing & 0x07) << 2);
5342 else {
5343 if (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_) {
5344 /*
5345 * Todo : Each chip must to ask DD , this chip best ampdu_density setting
5346 * By yiwei.sun
5347 */
5348 rtw_hal_get_def_var(padapter, HW_VAR_BEST_AMPDU_DENSITY, &best_ampdu_density);
5349
5350 ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & (best_ampdu_density << 2));
5351
5352 } else
5353 ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & 0x00);
5354 }
5355 #ifdef CONFIG_BEAMFORMING
5356 ht_capie.tx_BF_cap_info = 0;
5357
5358 /* HT Beamformer*/
5359 if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMER_ENABLE)) {
5360 /* Transmit NDP Capable */
5361 SET_HT_CAP_TXBF_TRANSMIT_NDP_CAP(&ht_capie, 1);
5362 /* Explicit Compressed Steering Capable */
5363 SET_HT_CAP_TXBF_EXPLICIT_COMP_STEERING_CAP(&ht_capie, 1);
5364 /* Compressed Steering Number Antennas */
5365 SET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(&ht_capie, 1);
5366 rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMER_CAP, (u8 *)&rf_num);
5367 SET_HT_CAP_TXBF_CHNL_ESTIMATION_NUM_ANTENNAS(&ht_capie, rf_num);
5368 }
5369
5370 /* HT Beamformee */
5371 if (TEST_FLAG(phtpriv->beamform_cap, BEAMFORMING_HT_BEAMFORMEE_ENABLE)) {
5372 /* Receive NDP Capable */
5373 SET_HT_CAP_TXBF_RECEIVE_NDP_CAP(&ht_capie, 1);
5374 /* Explicit Compressed Beamforming Feedback Capable */
5375 SET_HT_CAP_TXBF_EXPLICIT_COMP_FEEDBACK_CAP(&ht_capie, 2);
5376
5377 rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMEE_CAP, (u8 *)&rf_num);
5378 #ifdef CONFIG_80211AC_VHT
5379 /* IOT action suggested by Yu Chen 2017/3/3 */
5380 if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM) &&
5381 !pvhtpriv->ap_bf_cap.is_mu_bfer &&
5382 pvhtpriv->ap_bf_cap.su_sound_dim == 2)
5383 rf_num = (rf_num >= 2 ? 2 : rf_num);
5384 #endif
5385 SET_HT_CAP_TXBF_COMP_STEERING_NUM_ANTENNAS(&ht_capie, rf_num);
5386 }
5387 #endif/*CONFIG_BEAMFORMING*/
5388
5389 pframe = rtw_set_ie(out_ie + out_len, _HT_CAPABILITY_IE_,
5390 sizeof(struct rtw_ieee80211_ht_cap), (unsigned char *)&ht_capie, pout_len);
5391
5392 phtpriv->ht_option = _TRUE;
5393
5394 if (in_ie != NULL) {
5395 p = rtw_get_ie(in_ie, _HT_ADD_INFO_IE_, &ielen, in_len);
5396 if (p && (ielen == sizeof(struct ieee80211_ht_addt_info))) {
5397 out_len = *pout_len;
5398 pframe = rtw_set_ie(out_ie + out_len, _HT_ADD_INFO_IE_, ielen, p + 2 , pout_len);
5399 }
5400 }
5401
5402 return phtpriv->ht_option;
5403
5404 }
5405
5406 /* the fucntion is > passive_level (in critical_section) */
5407 void rtw_update_ht_cap(_adapter *padapter, u8 *pie, uint ie_len, u8 channel)
5408 {
5409 u8 *p, max_ampdu_sz;
5410 int len;
5411 /* struct sta_info *bmc_sta, *psta; */
5412 struct rtw_ieee80211_ht_cap *pht_capie;
5413 struct ieee80211_ht_addt_info *pht_addtinfo;
5414 /* struct recv_reorder_ctrl *preorder_ctrl; */
5415 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5416 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
5417 /* struct recv_priv *precvpriv = &padapter->recvpriv; */
5418 struct registry_priv *pregistrypriv = &padapter->registrypriv;
5419 /* struct wlan_network *pcur_network = &(pmlmepriv->cur_network);; */
5420 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5421 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5422 u8 cbw40_enable = 0;
5423
5424
5425 if (!phtpriv->ht_option)
5426 return;
5427
5428 if ((!pmlmeinfo->HT_info_enable) || (!pmlmeinfo->HT_caps_enable))
5429 return;
5430
5431 RTW_INFO("+rtw_update_ht_cap()\n");
5432
5433 /* maybe needs check if ap supports rx ampdu. */
5434 if ((phtpriv->ampdu_enable == _FALSE) && (pregistrypriv->ampdu_enable == 1)) {
5435 if (pregistrypriv->wifi_spec == 1) {
5436 /* remove this part because testbed AP should disable RX AMPDU */
5437 /* phtpriv->ampdu_enable = _FALSE; */
5438 phtpriv->ampdu_enable = _TRUE;
5439 } else
5440 phtpriv->ampdu_enable = _TRUE;
5441 }
5442
5443
5444 /* check Max Rx A-MPDU Size */
5445 len = 0;
5446 p = rtw_get_ie(pie + sizeof(NDIS_802_11_FIXED_IEs), _HT_CAPABILITY_IE_, &len, ie_len - sizeof(NDIS_802_11_FIXED_IEs));
5447 if (p && len > 0) {
5448 pht_capie = (struct rtw_ieee80211_ht_cap *)(p + 2);
5449 max_ampdu_sz = (pht_capie->ampdu_params_info & IEEE80211_HT_CAP_AMPDU_FACTOR);
5450 max_ampdu_sz = 1 << (max_ampdu_sz + 3); /* max_ampdu_sz (kbytes); */
5451
5452 /* RTW_INFO("rtw_update_ht_cap(): max_ampdu_sz=%d\n", max_ampdu_sz); */
5453 phtpriv->rx_ampdu_maxlen = max_ampdu_sz;
5454
5455 }
5456
5457
5458 len = 0;
5459 p = rtw_get_ie(pie + sizeof(NDIS_802_11_FIXED_IEs), _HT_ADD_INFO_IE_, &len, ie_len - sizeof(NDIS_802_11_FIXED_IEs));
5460 if (p && len > 0) {
5461 pht_addtinfo = (struct ieee80211_ht_addt_info *)(p + 2);
5462 /* todo: */
5463 }
5464
5465 if (hal_chk_bw_cap(padapter, BW_CAP_40M)) {
5466 if (channel > 14) {
5467 if (REGSTY_IS_BW_5G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
5468 cbw40_enable = 1;
5469 } else {
5470 if (REGSTY_IS_BW_2G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_40))
5471 cbw40_enable = 1;
5472 }
5473 }
5474
5475 /* update cur_bwmode & cur_ch_offset */
5476 if ((cbw40_enable) &&
5477 (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & BIT(1)) &&
5478 (pmlmeinfo->HT_info.infos[0] & BIT(2))) {
5479 int i;
5480 u8 rx_nss = 0;
5481
5482 rx_nss = GET_HAL_RX_NSS(padapter);
5483
5484 /* update the MCS set */
5485 for (i = 0; i < 16; i++)
5486 pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate[i] &= pmlmeext->default_supported_mcs_set[i];
5487
5488 /* update the MCS rates */
5489 switch (rx_nss) {
5490 case 1:
5491 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_1R);
5492 break;
5493 case 2:
5494 #ifdef CONFIG_DISABLE_MCS13TO15
5495 if (pmlmeext->cur_bwmode == CHANNEL_WIDTH_40 && pregistrypriv->wifi_spec != 1)
5496 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R_13TO15_OFF);
5497 else
5498 #endif
5499 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_2R);
5500 break;
5501 case 3:
5502 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_3R);
5503 break;
5504 case 4:
5505 set_mcs_rate_by_mask(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_RATE_4R);
5506 break;
5507 default:
5508 RTW_WARN("rx_nss:%u is not expected\n", rx_nss);
5509 }
5510
5511 /* switch to the 40M Hz mode accoring to the AP */
5512 /* pmlmeext->cur_bwmode = CHANNEL_WIDTH_40; */
5513 switch ((pmlmeinfo->HT_info.infos[0] & 0x3)) {
5514 case EXTCHNL_OFFSET_UPPER:
5515 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
5516 break;
5517
5518 case EXTCHNL_OFFSET_LOWER:
5519 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
5520 break;
5521
5522 default:
5523 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
5524 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5525 RTW_INFO("%s : ch offset is not assigned for HT40 mod , update cur_bwmode=%u, cur_ch_offset=%u\n",
5526 __func__, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
5527 break;
5528 }
5529 }
5530
5531 /* */
5532 /* Config SM Power Save setting */
5533 /* */
5534 pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2;
5535 if (pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC) {
5536 #if 0
5537 u8 i;
5538 /* update the MCS rates */
5539 for (i = 0; i < 16; i++)
5540 pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
5541 #endif
5542 RTW_INFO("%s(): WLAN_HT_CAP_SM_PS_STATIC\n", __FUNCTION__);
5543 }
5544
5545 /* */
5546 /* Config current HT Protection mode. */
5547 /* */
5548 pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;
5549 }
5550 #endif
5551
5552 #ifdef CONFIG_TDLS
5553 void rtw_issue_addbareq_cmd_tdls(_adapter *padapter, struct xmit_frame *pxmitframe)
5554 {
5555 struct pkt_attrib *pattrib = &pxmitframe->attrib;
5556 struct sta_info *ptdls_sta = NULL;
5557 u8 issued;
5558 int priority;
5559 struct ht_priv *phtpriv;
5560
5561 priority = pattrib->priority;
5562
5563 if (pattrib->direct_link == _TRUE) {
5564 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->dst);
5565 if ((ptdls_sta != NULL) && (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE)) {
5566 phtpriv = &ptdls_sta->htpriv;
5567
5568 if ((phtpriv->ht_option == _TRUE) && (phtpriv->ampdu_enable == _TRUE)) {
5569 issued = (phtpriv->agg_enable_bitmap >> priority) & 0x1;
5570 issued |= (phtpriv->candidate_tid_bitmap >> priority) & 0x1;
5571
5572 if (0 == issued) {
5573 RTW_INFO("[%s], p=%d\n", __FUNCTION__, priority);
5574 ptdls_sta->htpriv.candidate_tid_bitmap |= BIT((u8)priority);
5575 rtw_addbareq_cmd(padapter, (u8)priority, pattrib->dst);
5576 }
5577 }
5578 }
5579 }
5580 }
5581 #endif /* CONFIG_TDLS */
5582
5583 #ifdef CONFIG_80211N_HT
5584 static u8 rtw_issue_addbareq_check(_adapter *padapter, struct xmit_frame *pxmitframe, u8 issue_when_busy)
5585 {
5586 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5587 struct registry_priv *pregistry = &padapter->registrypriv;
5588 struct pkt_attrib *pattrib = &pxmitframe->attrib;
5589 s32 bmcst = IS_MCAST(pattrib->ra);
5590
5591 if (bmcst)
5592 return _FALSE;
5593
5594 if (pregistry->tx_quick_addba_req == 0) {
5595 if ((issue_when_busy == _TRUE) && (pmlmepriv->LinkDetectInfo.bBusyTraffic == _FALSE))
5596 return _FALSE;
5597
5598 if (pmlmepriv->LinkDetectInfo.NumTxOkInPeriod < 100)
5599 return _FALSE;
5600 }
5601
5602 return _TRUE;
5603 }
5604
5605 void rtw_issue_addbareq_cmd(_adapter *padapter, struct xmit_frame *pxmitframe, u8 issue_when_busy)
5606 {
5607 u8 issued;
5608 int priority;
5609 struct sta_info *psta = NULL;
5610 struct ht_priv *phtpriv;
5611 struct pkt_attrib *pattrib = &pxmitframe->attrib;
5612
5613 if (rtw_issue_addbareq_check(padapter,pxmitframe, issue_when_busy) == _FALSE)
5614 return;
5615
5616 priority = pattrib->priority;
5617
5618 #ifdef CONFIG_TDLS
5619 rtw_issue_addbareq_cmd_tdls(padapter, pxmitframe);
5620 #endif /* CONFIG_TDLS */
5621
5622 psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
5623 if (pattrib->psta != psta) {
5624 RTW_INFO("%s, pattrib->psta(%p) != psta(%p)\n", __func__, pattrib->psta, psta);
5625 return;
5626 }
5627
5628 if (psta == NULL) {
5629 RTW_INFO("%s, psta==NUL\n", __func__);
5630 return;
5631 }
5632
5633 if (!(psta->state & WIFI_ASOC_STATE)) {
5634 RTW_INFO("%s, psta->state(0x%x) != WIFI_ASOC_STATE\n", __func__, psta->state);
5635 return;
5636 }
5637
5638
5639 phtpriv = &psta->htpriv;
5640
5641 if ((phtpriv->ht_option == _TRUE) && (phtpriv->ampdu_enable == _TRUE)) {
5642 issued = (phtpriv->agg_enable_bitmap >> priority) & 0x1;
5643 issued |= (phtpriv->candidate_tid_bitmap >> priority) & 0x1;
5644
5645 if (0 == issued) {
5646 RTW_INFO("rtw_issue_addbareq_cmd, p=%d\n", priority);
5647 psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority);
5648 rtw_addbareq_cmd(padapter, (u8) priority, pattrib->ra);
5649 }
5650 }
5651
5652 }
5653 #endif /* CONFIG_80211N_HT */
5654 void rtw_append_exented_cap(_adapter *padapter, u8 *out_ie, uint *pout_len)
5655 {
5656 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5657 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
5658 #ifdef CONFIG_80211AC_VHT
5659 struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv;
5660 #endif /* CONFIG_80211AC_VHT */
5661 u8 cap_content[8] = { 0 };
5662 u8 *pframe;
5663 u8 null_content[8] = {0};
5664
5665 if (phtpriv->bss_coexist)
5666 SET_EXT_CAPABILITY_ELE_BSS_COEXIST(cap_content, 1);
5667
5668 #ifdef CONFIG_80211AC_VHT
5669 if (pvhtpriv->vht_option)
5670 SET_EXT_CAPABILITY_ELE_OP_MODE_NOTIF(cap_content, 1);
5671 #endif /* CONFIG_80211AC_VHT */
5672 #ifdef CONFIG_RTW_WNM
5673 rtw_wnm_set_ext_cap_btm(cap_content, 1);
5674 #endif
5675
5676 #ifdef CONFIG_RTW_MBO
5677 rtw_mbo_set_ext_cap_internw(cap_content, 1);
5678 #endif
5679 /*
5680 From 802.11 specification,if a STA does not support any of capabilities defined
5681 in the Extended Capabilities element, then the STA is not required to
5682 transmit the Extended Capabilities element.
5683 */
5684 if (_FALSE == _rtw_memcmp(cap_content, null_content, 8))
5685 pframe = rtw_set_ie(out_ie + *pout_len, EID_EXTCapability, 8, cap_content , pout_len);
5686 }
5687 #endif
5688
5689 #ifdef CONFIG_LAYER2_ROAMING
5690 inline void rtw_set_to_roam(_adapter *adapter, u8 to_roam)
5691 {
5692 if (to_roam == 0)
5693 adapter->mlmepriv.to_join = _FALSE;
5694 adapter->mlmepriv.to_roam = to_roam;
5695 }
5696
5697 inline u8 rtw_dec_to_roam(_adapter *adapter)
5698 {
5699 adapter->mlmepriv.to_roam--;
5700 return adapter->mlmepriv.to_roam;
5701 }
5702
5703 inline u8 rtw_to_roam(_adapter *adapter)
5704 {
5705 return adapter->mlmepriv.to_roam;
5706 }
5707
5708 void rtw_roaming(_adapter *padapter, struct wlan_network *tgt_network)
5709 {
5710 _irqL irqL;
5711 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5712
5713 _enter_critical_bh(&pmlmepriv->lock, &irqL);
5714 _rtw_roaming(padapter, tgt_network);
5715 _exit_critical_bh(&pmlmepriv->lock, &irqL);
5716 }
5717 void _rtw_roaming(_adapter *padapter, struct wlan_network *tgt_network)
5718 {
5719 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5720 struct wlan_network *cur_network = &pmlmepriv->cur_network;
5721 int do_join_r;
5722
5723 if (0 < rtw_to_roam(padapter)) {
5724 RTW_INFO("roaming from %s("MAC_FMT"), length:%d\n",
5725 cur_network->network.Ssid.Ssid, MAC_ARG(cur_network->network.MacAddress),
5726 cur_network->network.Ssid.SsidLength);
5727 _rtw_memcpy(&pmlmepriv->assoc_ssid, &cur_network->network.Ssid, sizeof(NDIS_802_11_SSID));
5728 pmlmepriv->assoc_ch = 0;
5729 pmlmepriv->assoc_by_bssid = _FALSE;
5730
5731 #ifdef CONFIG_WAPI_SUPPORT
5732 rtw_wapi_return_all_sta_info(padapter);
5733 #endif
5734
5735 while (1) {
5736 do_join_r = rtw_do_join(padapter);
5737 if (_SUCCESS == do_join_r)
5738 break;
5739 else {
5740 RTW_INFO("roaming do_join return %d\n", do_join_r);
5741 rtw_dec_to_roam(padapter);
5742
5743 if (rtw_to_roam(padapter) > 0)
5744 continue;
5745 else {
5746 RTW_INFO("%s(%d) -to roaming fail, indicate_disconnect\n", __FUNCTION__, __LINE__);
5747 #ifdef CONFIG_RTW_80211R
5748 rtw_ft_clr_flags(padapter, RTW_FT_PEER_EN|RTW_FT_PEER_OTD_EN);
5749 rtw_ft_reset_status(padapter);
5750 #endif
5751 rtw_indicate_disconnect(padapter, 0, _FALSE);
5752 break;
5753 }
5754 }
5755 }
5756 }
5757
5758 }
5759 #endif /* CONFIG_LAYER2_ROAMING */
5760
5761 bool rtw_adjust_chbw(_adapter *adapter, u8 req_ch, u8 *req_bw, u8 *req_offset)
5762 {
5763 struct registry_priv *regsty = adapter_to_regsty(adapter);
5764 u8 allowed_bw;
5765
5766 if (req_ch < 14)
5767 allowed_bw = REGSTY_BW_2G(regsty);
5768 else if (req_ch == 14)
5769 allowed_bw = CHANNEL_WIDTH_20;
5770 else
5771 allowed_bw = REGSTY_BW_5G(regsty);
5772
5773 allowed_bw = hal_largest_bw(adapter, allowed_bw);
5774
5775 if (allowed_bw == CHANNEL_WIDTH_80 && *req_bw > CHANNEL_WIDTH_80)
5776 *req_bw = CHANNEL_WIDTH_80;
5777 else if (allowed_bw == CHANNEL_WIDTH_40 && *req_bw > CHANNEL_WIDTH_40)
5778 *req_bw = CHANNEL_WIDTH_40;
5779 else if (allowed_bw == CHANNEL_WIDTH_20 && *req_bw > CHANNEL_WIDTH_20) {
5780 *req_bw = CHANNEL_WIDTH_20;
5781 *req_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5782 } else
5783 return _FALSE;
5784
5785 return _TRUE;
5786 }
5787
5788 sint rtw_linked_check(_adapter *padapter)
5789 {
5790 if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)
5791 || MLME_IS_ADHOC(padapter) || MLME_IS_ADHOC_MASTER(padapter)
5792 ) {
5793 if (padapter->stapriv.asoc_sta_count > 2)
5794 return _TRUE;
5795 } else {
5796 /* Station mode */
5797 if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _TRUE)
5798 return _TRUE;
5799 }
5800 return _FALSE;
5801 }
5802 /*#define DBG_ADAPTER_STATE_CHK*/
5803 u8 rtw_is_adapter_up(_adapter *padapter)
5804 {
5805 if (padapter == NULL)
5806 return _FALSE;
5807
5808 if (RTW_CANNOT_RUN(padapter)) {
5809 #ifdef DBG_ADAPTER_STATE_CHK
5810 RTW_INFO(FUNC_ADPT_FMT " FALSE -bDriverStopped(%s) bSurpriseRemoved(%s)\n"
5811 , FUNC_ADPT_ARG(padapter)
5812 , rtw_is_drv_stopped(padapter) ? "True" : "False"
5813 , rtw_is_surprise_removed(padapter) ? "True" : "False");
5814 #endif
5815 return _FALSE;
5816 }
5817
5818 if (!rtw_is_hw_init_completed(padapter)) {
5819 #ifdef DBG_ADAPTER_STATE_CHK
5820 RTW_INFO(FUNC_ADPT_FMT " FALSE -(hw_init_completed == _FALSE)\n", FUNC_ADPT_ARG(padapter));
5821 #endif
5822 return _FALSE;
5823 }
5824
5825 if (padapter->bup == _FALSE) {
5826 #ifdef DBG_ADAPTER_STATE_CHK
5827 RTW_INFO(FUNC_ADPT_FMT " FALSE -(bup == _FALSE)\n", FUNC_ADPT_ARG(padapter));
5828 #endif
5829 return _FALSE;
5830 }
5831
5832 return _TRUE;
5833 }
5834
5835 bool is_miracast_enabled(_adapter *adapter)
5836 {
5837 bool enabled = 0;
5838 #ifdef CONFIG_WFD
5839 struct wifi_display_info *wfdinfo = &adapter->wfd_info;
5840
5841 enabled = (wfdinfo->stack_wfd_mode & (MIRACAST_SOURCE | MIRACAST_SINK))
5842 || (wfdinfo->op_wfd_mode & (MIRACAST_SOURCE | MIRACAST_SINK));
5843 #endif
5844
5845 return enabled;
5846 }
5847
5848 bool rtw_chk_miracast_mode(_adapter *adapter, u8 mode)
5849 {
5850 bool ret = 0;
5851 #ifdef CONFIG_WFD
5852 struct wifi_display_info *wfdinfo = &adapter->wfd_info;
5853
5854 ret = (wfdinfo->stack_wfd_mode & mode) || (wfdinfo->op_wfd_mode & mode);
5855 #endif
5856
5857 return ret;
5858 }
5859
5860 const char *get_miracast_mode_str(int mode)
5861 {
5862 if (mode == MIRACAST_SOURCE)
5863 return "SOURCE";
5864 else if (mode == MIRACAST_SINK)
5865 return "SINK";
5866 else if (mode == (MIRACAST_SOURCE | MIRACAST_SINK))
5867 return "SOURCE&SINK";
5868 else if (mode == MIRACAST_DISABLED)
5869 return "DISABLED";
5870 else
5871 return "INVALID";
5872 }
5873
5874 #ifdef CONFIG_WFD
5875 static bool wfd_st_match_rule(_adapter *adapter, u8 *local_naddr, u8 *local_port, u8 *remote_naddr, u8 *remote_port)
5876 {
5877 struct wifi_display_info *wfdinfo = &adapter->wfd_info;
5878
5879 if (ntohs(*((u16 *)local_port)) == wfdinfo->rtsp_ctrlport
5880 || ntohs(*((u16 *)local_port)) == wfdinfo->tdls_rtsp_ctrlport
5881 || ntohs(*((u16 *)remote_port)) == wfdinfo->peer_rtsp_ctrlport)
5882 return _TRUE;
5883 return _FALSE;
5884 }
5885
5886 static struct st_register wfd_st_reg = {
5887 .s_proto = 0x06,
5888 .rule = wfd_st_match_rule,
5889 };
5890 #endif /* CONFIG_WFD */
5891
5892 inline void rtw_wfd_st_switch(struct sta_info *sta, bool on)
5893 {
5894 #ifdef CONFIG_WFD
5895 if (on)
5896 rtw_st_ctl_register(&sta->st_ctl, SESSION_TRACKER_REG_ID_WFD, &wfd_st_reg);
5897 else
5898 rtw_st_ctl_unregister(&sta->st_ctl, SESSION_TRACKER_REG_ID_WFD);
5899 #endif
5900 }
5901
5902 void dump_arp_pkt(void *sel, u8 *da, u8 *sa, u8 *arp, bool tx)
5903 {
5904 RTW_PRINT_SEL(sel, "%s ARP da="MAC_FMT", sa="MAC_FMT"\n"
5905 , tx ? "send" : "recv", MAC_ARG(da), MAC_ARG(sa));
5906 RTW_PRINT_SEL(sel, "htype=%u, ptype=0x%04x, hlen=%u, plen=%u, oper=%u\n"
5907 , GET_ARP_HTYPE(arp), GET_ARP_PTYPE(arp), GET_ARP_HLEN(arp)
5908 , GET_ARP_PLEN(arp), GET_ARP_OPER(arp));
5909 RTW_PRINT_SEL(sel, "sha="MAC_FMT", spa="IP_FMT"\n"
5910 , MAC_ARG(ARP_SENDER_MAC_ADDR(arp)), IP_ARG(ARP_SENDER_IP_ADDR(arp)));
5911 RTW_PRINT_SEL(sel, "tha="MAC_FMT", tpa="IP_FMT"\n"
5912 , MAC_ARG(ARP_TARGET_MAC_ADDR(arp)), IP_ARG(ARP_TARGET_IP_ADDR(arp)));
5913 }
5914
5915