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_MI_C_
16
17 #include <drv_types.h>
18
rtw_mi_update_union_chan_inf(_adapter * adapter,u8 ch,u8 offset,u8 bw)19 void rtw_mi_update_union_chan_inf(_adapter *adapter, u8 ch, u8 offset , u8 bw)
20 {
21 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
22 struct mi_state *iface_state = &dvobj->iface_state;
23
24 iface_state->union_ch = ch;
25 iface_state->union_bw = bw;
26 iface_state->union_offset = offset;
27 }
28
rtw_mi_stayin_union_ch_chk(_adapter * adapter)29 u8 rtw_mi_stayin_union_ch_chk(_adapter *adapter)
30 {
31 u8 rst = _TRUE;
32 u8 u_ch, u_bw, u_offset;
33 u8 o_ch, o_bw, o_offset;
34
35 u_ch = rtw_mi_get_union_chan(adapter);
36 u_bw = rtw_mi_get_union_bw(adapter);
37 u_offset = rtw_mi_get_union_offset(adapter);
38
39 o_ch = rtw_get_oper_ch(adapter);
40 o_bw = rtw_get_oper_bw(adapter);
41 o_offset = rtw_get_oper_choffset(adapter);
42
43 if ((u_ch != o_ch) || (u_bw != o_bw) || (u_offset != o_offset))
44 rst = _FALSE;
45
46 #ifdef DBG_IFACE_STATUS
47 if (rst == _FALSE) {
48 RTW_ERR("%s Not stay in union channel\n", __func__);
49 if (GET_PHL_COM(adapter_to_dvobj(adapter))->bScanInProcess == _TRUE)
50 RTW_ERR("ScanInProcess\n");
51 #ifdef CONFIG_IOCTL_CFG80211
52 if (rtw_cfg80211_get_is_roch(adapter))
53 RTW_ERR("Doing remain on channel\n");
54 #endif
55 RTW_ERR("union ch, bw, offset: %u,%u,%u\n", u_ch, u_bw, u_offset);
56 RTW_ERR("oper ch, bw, offset: %u,%u,%u\n", o_ch, o_bw, o_offset);
57 RTW_ERR("=========================\n");
58 }
59 #endif
60 return rst;
61 }
62
rtw_mi_stayin_union_band_chk(_adapter * adapter)63 u8 rtw_mi_stayin_union_band_chk(_adapter *adapter)
64 {
65 u8 rst = _TRUE;
66 u8 u_ch, o_ch;
67 u8 u_band, o_band;
68
69 u_ch = rtw_mi_get_union_chan(adapter);
70 o_ch = rtw_get_oper_ch(adapter);
71 u_band = (u_ch > 14) ? BAND_ON_5G : BAND_ON_24G;
72 o_band = (o_ch > 14) ? BAND_ON_5G : BAND_ON_24G;
73
74 if (u_ch != o_ch)
75 if(u_band != o_band)
76 rst = _FALSE;
77
78 #ifdef DBG_IFACE_STATUS
79 if (rst == _FALSE)
80 RTW_ERR("%s Not stay in union band\n", __func__);
81 #endif
82
83 return rst;
84 }
85
86 /* Find union about ch, bw, ch_offset of all linked/linking interfaces */
rtw_mi_get_ch_setting_union_by_ifbmp(struct dvobj_priv * dvobj,u8 ifbmp,u8 * ch,u8 * bw,u8 * offset)87 int rtw_mi_get_ch_setting_union_by_ifbmp(struct dvobj_priv *dvobj, u8 ifbmp, u8 *ch, u8 *bw, u8 *offset)
88 {
89 _adapter *iface;
90 struct mlme_ext_priv *mlmeext;
91 int i;
92 u8 ch_ret = 0;
93 u8 bw_ret = CHANNEL_WIDTH_20;
94 u8 offset_ret = CHAN_OFFSET_NO_EXT;
95 int num = 0;
96
97 if (ch)
98 *ch = 0;
99 if (bw)
100 *bw = CHANNEL_WIDTH_20;
101 if (offset)
102 *offset = CHAN_OFFSET_NO_EXT;
103
104 for (i = 0; i < dvobj->iface_nums; i++) {
105 iface = dvobj->padapters[i];
106 if (!iface || !(ifbmp & BIT(iface->iface_id)))
107 continue;
108
109 mlmeext = &iface->mlmeextpriv;
110
111 if (!check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE | WIFI_UNDER_LINKING))
112 continue;
113
114 if (check_fwstate(&iface->mlmepriv, WIFI_OP_CH_SWITCHING))
115 continue;
116
117 if (num == 0) {
118 ch_ret = mlmeext->chandef.chan;
119 bw_ret = mlmeext->chandef.bw;
120 offset_ret = mlmeext->chandef.offset;
121 num++;
122 continue;
123 }
124
125 if (ch_ret != mlmeext->chandef.chan) {
126 num = 0;
127 break;
128 }
129
130 if (bw_ret < mlmeext->chandef.bw) {
131 bw_ret = mlmeext->chandef.bw;
132 offset_ret = mlmeext->chandef.offset;
133 } else if (bw_ret == mlmeext->chandef.bw && offset_ret != mlmeext->chandef.offset) {
134 num = 0;
135 break;
136 }
137
138 num++;
139 }
140
141 if (num) {
142 if (ch)
143 *ch = ch_ret;
144 if (bw)
145 *bw = bw_ret;
146 if (offset)
147 *offset = offset_ret;
148 }
149
150 return num;
151 }
152
rtw_mi_get_ch_setting_union(_adapter * adapter,u8 * ch,u8 * bw,u8 * offset)153 inline int rtw_mi_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
154 {
155 return rtw_mi_get_ch_setting_union_by_ifbmp(adapter_to_dvobj(adapter), 0xFF, ch, bw, offset);
156 }
157
rtw_mi_get_ch_setting_union_no_self(_adapter * adapter,u8 * ch,u8 * bw,u8 * offset)158 inline int rtw_mi_get_ch_setting_union_no_self(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
159 {
160 return rtw_mi_get_ch_setting_union_by_ifbmp(adapter_to_dvobj(adapter), 0xFF & ~BIT(adapter->iface_id), ch, bw, offset);
161 }
162
163 /* For now, not return union_ch/bw/offset */
rtw_mi_status_by_ifbmp(struct dvobj_priv * dvobj,u8 ifbmp,struct mi_state * mstate)164 void rtw_mi_status_by_ifbmp(struct dvobj_priv *dvobj, u8 ifbmp, struct mi_state *mstate)
165 {
166 _adapter *iface;
167 int i;
168
169 _rtw_memset(mstate, 0, sizeof(struct mi_state));
170
171 for (i = 0; i < dvobj->iface_nums; i++) {
172 iface = dvobj->padapters[i];
173 if (!iface || !(ifbmp & BIT(iface->iface_id)))
174 continue;
175
176 if (MLME_IS_STA(iface)) {
177 MSTATE_STA_NUM(mstate)++;
178 if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
179 MSTATE_STA_LD_NUM(mstate)++;
180
181 #ifdef CONFIG_TDLS
182 if (iface->tdlsinfo.link_established == _TRUE)
183 MSTATE_TDLS_LD_NUM(mstate)++;
184 #endif
185 #ifdef CONFIG_P2P
186 if (MLME_IS_GC(iface))
187 MSTATE_P2P_GC_NUM(mstate)++;
188 #endif
189 }
190 if (check_fwstate(&iface->mlmepriv, WIFI_UNDER_LINKING) == _TRUE)
191 MSTATE_STA_LG_NUM(mstate)++;
192
193 #ifdef CONFIG_AP_MODE
194 } else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {
195 if (check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
196 MSTATE_AP_NUM(mstate)++;
197 if (iface->stapriv.asoc_sta_count >= 2)
198 MSTATE_AP_LD_NUM(mstate)++;
199 #ifdef CONFIG_P2P
200 if (MLME_IS_GO(iface))
201 MSTATE_P2P_GO_NUM(mstate)++;
202 #endif
203 } else
204 MSTATE_AP_STARTING_NUM(mstate)++;
205 #endif
206
207 } else if (check_fwstate(&iface->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE
208 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
209 ) {
210 MSTATE_ADHOC_NUM(mstate)++;
211 if (iface->stapriv.asoc_sta_count > 2)
212 MSTATE_ADHOC_LD_NUM(mstate)++;
213
214 #ifdef CONFIG_RTW_MESH
215 } else if (check_fwstate(&iface->mlmepriv, WIFI_MESH_STATE) == _TRUE
216 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
217 ) {
218 MSTATE_MESH_NUM(mstate)++;
219 if (iface->stapriv.asoc_sta_count > 2)
220 MSTATE_MESH_LD_NUM(mstate)++;
221 #endif
222
223 }
224
225 if (check_fwstate(&iface->mlmepriv, WIFI_UNDER_WPS) == _TRUE)
226 MSTATE_WPS_NUM(mstate)++;
227
228 if (check_fwstate(&iface->mlmepriv, WIFI_UNDER_SURVEY) == _TRUE) {
229 MSTATE_SCAN_NUM(mstate)++;
230
231 if (mlmeext_scan_state(&iface->mlmeextpriv) != SCAN_DISABLE
232 && mlmeext_scan_state(&iface->mlmeextpriv) != SCAN_BACK_OP)
233 MSTATE_SCAN_ENTER_NUM(mstate)++;
234 }
235
236 #ifdef CONFIG_IOCTL_CFG80211
237 if (rtw_cfg80211_get_is_mgmt_tx(iface))
238 MSTATE_MGMT_TX_NUM(mstate)++;
239 #ifdef CONFIG_P2P
240 if (rtw_cfg80211_get_is_roch(iface) == _TRUE)
241 MSTATE_ROCH_NUM(mstate)++;
242 #endif
243 #endif /* CONFIG_IOCTL_CFG80211 */
244 #ifdef CONFIG_P2P
245 if (MLME_IS_PD(iface))
246 MSTATE_P2P_DV_NUM(mstate)++;
247 #endif
248 }
249 }
250
rtw_mi_status(_adapter * adapter,struct mi_state * mstate)251 inline void rtw_mi_status(_adapter *adapter, struct mi_state *mstate)
252 {
253 return rtw_mi_status_by_ifbmp(adapter_to_dvobj(adapter), 0xFF, mstate);
254 }
255
rtw_mi_status_no_self(_adapter * adapter,struct mi_state * mstate)256 inline void rtw_mi_status_no_self(_adapter *adapter, struct mi_state *mstate)
257 {
258 return rtw_mi_status_by_ifbmp(adapter_to_dvobj(adapter), 0xFF & ~BIT(adapter->iface_id), mstate);
259 }
260
rtw_mi_status_no_others(_adapter * adapter,struct mi_state * mstate)261 inline void rtw_mi_status_no_others(_adapter *adapter, struct mi_state *mstate)
262 {
263 return rtw_mi_status_by_ifbmp(adapter_to_dvobj(adapter), BIT(adapter->iface_id), mstate);
264 }
265
266 /* For now, not handle union_ch/bw/offset */
rtw_mi_status_merge(struct mi_state * d,struct mi_state * a)267 inline void rtw_mi_status_merge(struct mi_state *d, struct mi_state *a)
268 {
269 d->sta_num += a->sta_num;
270 d->ld_sta_num += a->ld_sta_num;
271 d->lg_sta_num += a->lg_sta_num;
272 #ifdef CONFIG_TDLS
273 d->ld_tdls_num += a->ld_tdls_num;
274 #endif
275 #ifdef CONFIG_AP_MODE
276 d->ap_num += a->ap_num;
277 d->ld_ap_num += a->ld_ap_num;
278 #endif
279 d->adhoc_num += a->adhoc_num;
280 d->ld_adhoc_num += a->ld_adhoc_num;
281 #ifdef CONFIG_RTW_MESH
282 d->mesh_num += a->mesh_num;
283 d->ld_mesh_num += a->ld_mesh_num;
284 #endif
285 d->scan_num += a->scan_num;
286 d->scan_enter_num += a->scan_enter_num;
287 d->uwps_num += a->uwps_num;
288 #ifdef CONFIG_IOCTL_CFG80211
289 #ifdef CONFIG_P2P
290 d->roch_num += a->roch_num;
291 #endif
292 d->mgmt_tx_num += a->mgmt_tx_num;
293 #endif
294 }
295
dump_mi_status(void * sel,struct dvobj_priv * dvobj)296 void dump_mi_status(void *sel, struct dvobj_priv *dvobj)
297 {
298 RTW_PRINT_SEL(sel, "== dvobj-iface_state ==\n");
299 RTW_PRINT_SEL(sel, "sta_num:%d\n", DEV_STA_NUM(dvobj));
300 RTW_PRINT_SEL(sel, "linking_sta_num:%d\n", DEV_STA_LG_NUM(dvobj));
301 RTW_PRINT_SEL(sel, "linked_sta_num:%d\n", DEV_STA_LD_NUM(dvobj));
302 #ifdef CONFIG_TDLS
303 RTW_PRINT_SEL(sel, "linked_tdls_num:%d\n", DEV_TDLS_LD_NUM(dvobj));
304 #endif
305 #ifdef CONFIG_AP_MODE
306 RTW_PRINT_SEL(sel, "ap_num:%d\n", DEV_AP_NUM(dvobj));
307 RTW_PRINT_SEL(sel, "starting_ap_num:%d\n", DEV_AP_STARTING_NUM(dvobj));
308 RTW_PRINT_SEL(sel, "linked_ap_num:%d\n", DEV_AP_LD_NUM(dvobj));
309 #endif
310 RTW_PRINT_SEL(sel, "adhoc_num:%d\n", DEV_ADHOC_NUM(dvobj));
311 RTW_PRINT_SEL(sel, "linked_adhoc_num:%d\n", DEV_ADHOC_LD_NUM(dvobj));
312 #ifdef CONFIG_RTW_MESH
313 RTW_PRINT_SEL(sel, "mesh_num:%d\n", DEV_MESH_NUM(dvobj));
314 RTW_PRINT_SEL(sel, "linked_mesh_num:%d\n", DEV_MESH_LD_NUM(dvobj));
315 #endif
316 #ifdef CONFIG_P2P
317 RTW_PRINT_SEL(sel, "p2p_device_num:%d\n", DEV_P2P_DV_NUM(dvobj));
318 RTW_PRINT_SEL(sel, "p2p_gc_num:%d\n", DEV_P2P_GC_NUM(dvobj));
319 RTW_PRINT_SEL(sel, "p2p_go_num:%d\n", DEV_P2P_GO_NUM(dvobj));
320 #endif
321 RTW_PRINT_SEL(sel, "scan_num:%d\n", DEV_SCAN_NUM(dvobj));
322 RTW_PRINT_SEL(sel, "under_wps_num:%d\n", DEV_WPS_NUM(dvobj));
323 #if defined(CONFIG_IOCTL_CFG80211)
324 #if defined(CONFIG_P2P)
325 RTW_PRINT_SEL(sel, "roch_num:%d\n", DEV_ROCH_NUM(dvobj));
326 #endif
327 RTW_PRINT_SEL(sel, "mgmt_tx_num:%d\n", DEV_MGMT_TX_NUM(dvobj));
328 #endif
329 RTW_PRINT_SEL(sel, "union_ch:%d\n", DEV_U_CH(dvobj));
330 RTW_PRINT_SEL(sel, "union_bw:%d\n", DEV_U_BW(dvobj));
331 RTW_PRINT_SEL(sel, "union_offset:%d\n", DEV_U_OFFSET(dvobj));
332 RTW_PRINT_SEL(sel, "================\n\n");
333 }
334
dump_dvobj_mi_status(void * sel,const char * fun_name,_adapter * adapter)335 void dump_dvobj_mi_status(void *sel, const char *fun_name, _adapter *adapter)
336 {
337 RTW_INFO("\n[ %s ] call %s\n", fun_name, __func__);
338 dump_mi_status(sel, adapter_to_dvobj(adapter));
339 }
340
rtw_mi_update_iface_status(struct mlme_priv * pmlmepriv,sint state)341 inline void rtw_mi_update_iface_status(struct mlme_priv *pmlmepriv, sint state)
342 {
343 _adapter *adapter = container_of(pmlmepriv, _adapter, mlmepriv);
344 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
345 struct mi_state *iface_state = &dvobj->iface_state;
346 struct mi_state tmp_mstate;
347 u8 u_ch, u_offset, u_bw;
348
349 if (state == WIFI_MONITOR_STATE
350 || state == 0xFFFFFFFF
351 )
352 return;
353
354 if (0)
355 RTW_INFO("%s => will change or clean state to 0x%08x\n", __func__, state);
356
357 rtw_mi_status(adapter, &tmp_mstate);
358 _rtw_memcpy(iface_state, &tmp_mstate, sizeof(struct mi_state));
359
360 if (rtw_mi_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset))
361 rtw_mi_update_union_chan_inf(adapter , u_ch, u_offset , u_bw);
362 else {
363 if (0) {
364 dump_adapters_status(RTW_DBGDUMP , dvobj);
365 RTW_INFO("%s-[ERROR] cannot get union channel\n", __func__);
366 rtw_warn_on(1);
367 }
368 }
369
370 #ifdef DBG_IFACE_STATUS
371 DBG_IFACE_STATUS_DUMP(adapter);
372 #endif
373 }
rtw_mi_check_status(_adapter * adapter,u8 type)374 u8 rtw_mi_check_status(_adapter *adapter, u8 type)
375 {
376 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
377 struct mi_state *iface_state = &dvobj->iface_state;
378 u8 ret = _FALSE;
379
380 #ifdef DBG_IFACE_STATUS
381 DBG_IFACE_STATUS_DUMP(adapter);
382 RTW_INFO("%s-"ADPT_FMT" check type:%d\n", __func__, ADPT_ARG(adapter), type);
383 #endif
384
385 switch (type) {
386 case MI_LINKED:
387 if (MSTATE_STA_LD_NUM(iface_state) || MSTATE_AP_NUM(iface_state) || MSTATE_ADHOC_NUM(iface_state) || MSTATE_MESH_NUM(iface_state)) /*check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE)*/
388 ret = _TRUE;
389 break;
390 case MI_ASSOC:
391 if (MSTATE_STA_LD_NUM(iface_state) || MSTATE_AP_LD_NUM(iface_state) || MSTATE_ADHOC_LD_NUM(iface_state) || MSTATE_MESH_LD_NUM(iface_state))
392 ret = _TRUE;
393 break;
394 case MI_UNDER_WPS:
395 if (MSTATE_WPS_NUM(iface_state))
396 ret = _TRUE;
397 break;
398
399 case MI_AP_MODE:
400 if (MSTATE_AP_NUM(iface_state))
401 ret = _TRUE;
402 break;
403 case MI_AP_ASSOC:
404 if (MSTATE_AP_LD_NUM(iface_state))
405 ret = _TRUE;
406 break;
407
408 case MI_ADHOC:
409 if (MSTATE_ADHOC_NUM(iface_state))
410 ret = _TRUE;
411 break;
412 case MI_ADHOC_ASSOC:
413 if (MSTATE_ADHOC_LD_NUM(iface_state))
414 ret = _TRUE;
415 break;
416
417 #ifdef CONFIG_RTW_MESH
418 case MI_MESH:
419 if (MSTATE_MESH_NUM(iface_state))
420 ret = _TRUE;
421 break;
422 case MI_MESH_ASSOC:
423 if (MSTATE_MESH_LD_NUM(iface_state))
424 ret = _TRUE;
425 break;
426 #endif
427
428 case MI_STA_NOLINK: /* this is misleading, but not used now */
429 if (MSTATE_STA_NUM(iface_state) && (!(MSTATE_STA_LD_NUM(iface_state) || MSTATE_STA_LG_NUM(iface_state))))
430 ret = _TRUE;
431 break;
432 case MI_STA_LINKED:
433 if (MSTATE_STA_LD_NUM(iface_state))
434 ret = _TRUE;
435 break;
436 case MI_STA_LINKING:
437 if (MSTATE_STA_LG_NUM(iface_state))
438 ret = _TRUE;
439 break;
440
441 default:
442 break;
443 }
444 return ret;
445 }
446
447 /*
448 * return value : 0 is failed or have not interface meet condition
449 * return value : !0 is success or interface numbers which meet condition
450 * return value of ops_func must be _TRUE or _FALSE
451 */
_rtw_mi_process(_adapter * padapter,bool exclude_self,void * data,u8 (* ops_func)(_adapter * padapter,void * data))452 static u8 _rtw_mi_process(_adapter *padapter, bool exclude_self,
453 void *data, u8(*ops_func)(_adapter *padapter, void *data))
454 {
455 int i;
456 _adapter *iface;
457 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
458
459 u8 ret = 0;
460
461 for (i = 0; i < dvobj->iface_nums; i++) {
462 iface = dvobj->padapters[i];
463 if ((iface) && rtw_is_adapter_up(iface)) {
464
465 if ((exclude_self) && (iface == padapter))
466 continue;
467
468 if (ops_func)
469 if (_TRUE == ops_func(iface, data))
470 ret++;
471 }
472 }
473 return ret;
474 }
_rtw_mi_process_without_schk(_adapter * padapter,bool exclude_self,void * data,u8 (* ops_func)(_adapter * padapter,void * data))475 static u8 _rtw_mi_process_without_schk(_adapter *padapter, bool exclude_self,
476 void *data, u8(*ops_func)(_adapter *padapter, void *data))
477 {
478 int i;
479 _adapter *iface;
480 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
481
482 u8 ret = 0;
483
484 for (i = 0; i < dvobj->iface_nums; i++) {
485 iface = dvobj->padapters[i];
486 if (iface) {
487 if ((exclude_self) && (iface == padapter))
488 continue;
489
490 if (ops_func)
491 if (ops_func(iface, data) == _TRUE)
492 ret++;
493 }
494 }
495 return ret;
496 }
497
_rtw_mi_netif_caroff_qstop(_adapter * padapter,void * data)498 static u8 _rtw_mi_netif_caroff_qstop(_adapter *padapter, void *data)
499 {
500 struct net_device *pnetdev = padapter->pnetdev;
501
502 rtw_netif_carrier_off(pnetdev);
503 rtw_netif_stop_queue(pnetdev);
504 return _TRUE;
505 }
rtw_mi_netif_caroff_qstop(_adapter * padapter)506 u8 rtw_mi_netif_caroff_qstop(_adapter *padapter)
507 {
508 return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_caroff_qstop);
509 }
rtw_mi_buddy_netif_caroff_qstop(_adapter * padapter)510 u8 rtw_mi_buddy_netif_caroff_qstop(_adapter *padapter)
511 {
512 return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_caroff_qstop);
513 }
514
_rtw_mi_disconnect(_adapter * adapter,void * data)515 static u8 _rtw_mi_disconnect(_adapter *adapter, void *data)
516 {
517 struct mlme_priv *mlme = &adapter->mlmepriv;
518 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
519 struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
520 Disconnect_type disc_code = DISCONNECTION_NOT_YET_OCCUR;
521
522 if (data)
523 disc_code = *(int *)data;
524
525 if ((MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))
526 && check_fwstate(mlme, WIFI_ASOC_STATE)) {
527 #ifdef CONFIG_SPCT_CH_SWITCH
528 if (1)
529 rtw_ap_inform_ch_switch(adapter, mlmeext->chandef.chan, mlmeext->chandef.offset);
530 else
531 #endif
532 #ifdef CONFIG_STA_CMD_DISPR
533 rtw_phl_cmd_stop_beacon(adapter_to_dvobj(adapter)->phl, adapter->phl_role, _TRUE, PHL_CMD_NO_WAIT, 0);
534 #else
535 rtw_phl_cmd_stop_beacon(adapter_to_dvobj(adapter)->phl, adapter->phl_role, _TRUE, PHL_CMD_DIRECTLY, 0);
536 #endif
537 rtw_sta_flush(adapter, _FALSE);
538
539 rtw_hal_set_hwreg(adapter, HW_VAR_CHECK_TXBUF, 0);
540 set_fwstate(mlme, WIFI_OP_CH_SWITCHING);
541 rtw_phl_chanctx_del(adapter_to_dvobj(adapter)->phl, adapter->phl_role, NULL);
542
543 } else if (MLME_IS_STA(adapter)
544 && check_fwstate(mlme, WIFI_ASOC_STATE)) {
545 rtw_disassoc_cmd(adapter, 500, RTW_CMDF_DIRECTLY);
546 #ifndef CONFIG_STA_CMD_DISPR
547 rtw_free_assoc_resources(adapter, _TRUE);
548 #endif /* !CONFIG_STA_CMD_DISPR */
549 rtw_indicate_disconnect(adapter, 0, _FALSE);
550
551 if (disc_code == DISCONNECTION_BY_DRIVER_DUE_TO_EACH_IFACE_CHBW_NOT_SYNC) {
552 mlmeinfo->disconnect_occurred_time = rtw_systime_to_ms(rtw_get_current_time());
553 mlmeinfo->disconnect_code = disc_code;
554 mlmeinfo->wifi_reason_code = WLAN_REASON_DEAUTH_LEAVING;
555 }
556 }
557 return _TRUE;
558 }
559
rtw_mi_disconnect(_adapter * adapter)560 u8 rtw_mi_disconnect(_adapter *adapter)
561 {
562 return _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_disconnect);
563 }
rtw_mi_buddy_disconnect(_adapter * adapter,Disconnect_type disc_code)564 u8 rtw_mi_buddy_disconnect(_adapter *adapter, Disconnect_type disc_code)
565 {
566 return _rtw_mi_process(adapter, _TRUE, (void *)&disc_code,
567 _rtw_mi_disconnect);
568 }
569
_rtw_mi_netif_caron_qstart(_adapter * padapter,void * data)570 static u8 _rtw_mi_netif_caron_qstart(_adapter *padapter, void *data)
571 {
572 struct net_device *pnetdev = padapter->pnetdev;
573
574 rtw_netif_carrier_on(pnetdev);
575 rtw_netif_start_queue(pnetdev);
576 return _TRUE;
577 }
rtw_mi_netif_caron_qstart(_adapter * padapter)578 u8 rtw_mi_netif_caron_qstart(_adapter *padapter)
579 {
580 return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_caron_qstart);
581 }
rtw_mi_buddy_netif_caron_qstart(_adapter * padapter)582 u8 rtw_mi_buddy_netif_caron_qstart(_adapter *padapter)
583 {
584 return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_caron_qstart);
585 }
586
_rtw_mi_netif_stop_queue(_adapter * padapter,void * data)587 static u8 _rtw_mi_netif_stop_queue(_adapter *padapter, void *data)
588 {
589 struct net_device *pnetdev = padapter->pnetdev;
590
591 rtw_netif_stop_queue(pnetdev);
592 return _TRUE;
593 }
rtw_mi_netif_stop_queue(_adapter * padapter)594 u8 rtw_mi_netif_stop_queue(_adapter *padapter)
595 {
596 return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_stop_queue);
597 }
rtw_mi_buddy_netif_stop_queue(_adapter * padapter)598 u8 rtw_mi_buddy_netif_stop_queue(_adapter *padapter)
599 {
600 return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_stop_queue);
601 }
602
_rtw_mi_netif_wake_queue(_adapter * padapter,void * data)603 static u8 _rtw_mi_netif_wake_queue(_adapter *padapter, void *data)
604 {
605 struct net_device *pnetdev = padapter->pnetdev;
606
607 if (pnetdev)
608 rtw_netif_wake_queue(pnetdev);
609 return _TRUE;
610 }
rtw_mi_netif_wake_queue(_adapter * padapter)611 u8 rtw_mi_netif_wake_queue(_adapter *padapter)
612 {
613 return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_wake_queue);
614 }
rtw_mi_buddy_netif_wake_queue(_adapter * padapter)615 u8 rtw_mi_buddy_netif_wake_queue(_adapter *padapter)
616 {
617 return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_wake_queue);
618 }
619
_rtw_mi_netif_carrier_on(_adapter * padapter,void * data)620 static u8 _rtw_mi_netif_carrier_on(_adapter *padapter, void *data)
621 {
622 struct net_device *pnetdev = padapter->pnetdev;
623
624 if (pnetdev)
625 rtw_netif_carrier_on(pnetdev);
626 return _TRUE;
627 }
rtw_mi_netif_carrier_on(_adapter * padapter)628 u8 rtw_mi_netif_carrier_on(_adapter *padapter)
629 {
630 return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_carrier_on);
631 }
rtw_mi_buddy_netif_carrier_on(_adapter * padapter)632 u8 rtw_mi_buddy_netif_carrier_on(_adapter *padapter)
633 {
634 return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_carrier_on);
635 }
636
_rtw_mi_netif_carrier_off(_adapter * padapter,void * data)637 static u8 _rtw_mi_netif_carrier_off(_adapter *padapter, void *data)
638 {
639 struct net_device *pnetdev = padapter->pnetdev;
640
641 if (pnetdev)
642 rtw_netif_carrier_off(pnetdev);
643 return _TRUE;
644 }
rtw_mi_netif_carrier_off(_adapter * padapter)645 u8 rtw_mi_netif_carrier_off(_adapter *padapter)
646 {
647 return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_carrier_off);
648 }
rtw_mi_buddy_netif_carrier_off(_adapter * padapter)649 u8 rtw_mi_buddy_netif_carrier_off(_adapter *padapter)
650 {
651 return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_carrier_off);
652 }
653
_rtw_mi_scan_abort(_adapter * adapter,void * data)654 static u8 _rtw_mi_scan_abort(_adapter *adapter, void *data)
655 {
656 bool bwait = *(bool *)data;
657
658 if (bwait)
659 rtw_scan_abort(adapter, 0);
660 else
661 rtw_scan_abort_no_wait(adapter);
662
663 return _TRUE;
664 }
rtw_mi_scan_abort(_adapter * adapter,bool bwait)665 void rtw_mi_scan_abort(_adapter *adapter, bool bwait)
666 {
667 bool in_data = bwait;
668
669 _rtw_mi_process(adapter, _FALSE, &in_data, _rtw_mi_scan_abort);
670
671 }
rtw_mi_buddy_scan_abort(_adapter * adapter,bool bwait)672 void rtw_mi_buddy_scan_abort(_adapter *adapter, bool bwait)
673 {
674 bool in_data = bwait;
675
676 _rtw_mi_process(adapter, _TRUE, &in_data, _rtw_mi_scan_abort);
677 }
678
679 #if 0 /*#ifdef CONFIG_CORE_CMD_THREAD*/
680 static u32 _rtw_mi_start_drv_threads(_adapter *adapter, bool exclude_self)
681 {
682 int i;
683 _adapter *iface = NULL;
684 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
685 u32 _status = _SUCCESS;
686
687 for (i = 0; i < dvobj->iface_nums; i++) {
688 iface = dvobj->padapters[i];
689 if (iface) {
690 if ((exclude_self) && (iface == adapter))
691 continue;
692 if (rtw_start_drv_threads(iface) == _FAIL) {
693 _status = _FAIL;
694 break;
695 }
696 }
697 }
698 return _status;
699 }
700 u32 rtw_mi_start_drv_threads(_adapter *adapter)
701 {
702 return _rtw_mi_start_drv_threads(adapter, _FALSE);
703 }
704 u32 rtw_mi_buddy_start_drv_threads(_adapter *adapter)
705 {
706 return _rtw_mi_start_drv_threads(adapter, _TRUE);
707 }
708
709 static void _rtw_mi_stop_drv_threads(_adapter *adapter, bool exclude_self)
710 {
711 int i;
712 _adapter *iface = NULL;
713 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
714
715 for (i = 0; i < dvobj->iface_nums; i++) {
716 iface = dvobj->padapters[i];
717 if (iface) {
718 if ((exclude_self) && (iface == adapter))
719 continue;
720 rtw_stop_drv_threads(iface);
721 }
722 }
723 }
724 void rtw_mi_stop_drv_threads(_adapter *adapter)
725 {
726 _rtw_mi_stop_drv_threads(adapter, _FALSE);
727 }
728 void rtw_mi_buddy_stop_drv_threads(_adapter *adapter)
729 {
730 _rtw_mi_stop_drv_threads(adapter, _TRUE);
731 }
732 #endif
733
_rtw_mi_cancel_all_timer(_adapter * adapter,void * data)734 static u8 _rtw_mi_cancel_all_timer(_adapter *adapter, void *data)
735 {
736 rtw_cancel_all_timer(adapter);
737 return _TRUE;
738 }
rtw_mi_cancel_all_timer(_adapter * adapter)739 void rtw_mi_cancel_all_timer(_adapter *adapter)
740 {
741 _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_cancel_all_timer);
742 }
rtw_mi_buddy_cancel_all_timer(_adapter * adapter)743 void rtw_mi_buddy_cancel_all_timer(_adapter *adapter)
744 {
745 _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_cancel_all_timer);
746 }
747
_rtw_mi_reset_drv_sw(_adapter * adapter,void * data)748 static u8 _rtw_mi_reset_drv_sw(_adapter *adapter, void *data)
749 {
750 rtw_reset_drv_sw(adapter);
751 return _TRUE;
752 }
rtw_mi_reset_drv_sw(_adapter * adapter)753 void rtw_mi_reset_drv_sw(_adapter *adapter)
754 {
755 _rtw_mi_process_without_schk(adapter, _FALSE, NULL, _rtw_mi_reset_drv_sw);
756 }
rtw_mi_buddy_reset_drv_sw(_adapter * adapter)757 void rtw_mi_buddy_reset_drv_sw(_adapter *adapter)
758 {
759 _rtw_mi_process_without_schk(adapter, _TRUE, NULL, _rtw_mi_reset_drv_sw);
760 }
761
rtw_mi_hal_iface_init(_adapter * padapter)762 u8 rtw_mi_hal_iface_init(_adapter *padapter)
763 {
764 int i;
765 _adapter *iface;
766 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
767 u8 ret = _SUCCESS;
768
769 for (i = 0; i < dvobj->iface_nums; i++) {
770 iface = dvobj->padapters[i];
771 if (iface && iface->netif_up) {
772 ret = rtw_hw_iface_init(iface);
773 if (ret == _FAIL)
774 break;
775 }
776 }
777 return ret;
778 }
779
780
_rtw_mi_suspend_free_assoc_resource(_adapter * padapter,void * data)781 static u8 _rtw_mi_suspend_free_assoc_resource(_adapter *padapter, void *data)
782 {
783 return rtw_suspend_free_assoc_resource(padapter);
784 }
rtw_mi_suspend_free_assoc_resource(_adapter * adapter)785 void rtw_mi_suspend_free_assoc_resource(_adapter *adapter)
786 {
787 _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_suspend_free_assoc_resource);
788 }
rtw_mi_buddy_suspend_free_assoc_resource(_adapter * adapter)789 void rtw_mi_buddy_suspend_free_assoc_resource(_adapter *adapter)
790 {
791 _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_suspend_free_assoc_resource);
792 }
793
_rtw_mi_is_scan_deny(_adapter * adapter,void * data)794 static u8 _rtw_mi_is_scan_deny(_adapter *adapter, void *data)
795 {
796 return rtw_is_scan_deny(adapter);
797 }
798
rtw_mi_is_scan_deny(_adapter * adapter)799 u8 rtw_mi_is_scan_deny(_adapter *adapter)
800 {
801 return _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_is_scan_deny);
802
803 }
rtw_mi_buddy_is_scan_deny(_adapter * adapter)804 u8 rtw_mi_buddy_is_scan_deny(_adapter *adapter)
805 {
806 return _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_is_scan_deny);
807 }
808
809 #ifdef CONFIG_SET_SCAN_DENY_TIMER
_rtw_mi_set_scan_deny(_adapter * adapter,void * data)810 static u8 _rtw_mi_set_scan_deny(_adapter *adapter, void *data)
811 {
812 u32 ms = *(u32 *)data;
813
814 rtw_set_scan_deny(adapter, ms);
815 return _TRUE;
816 }
rtw_mi_set_scan_deny(_adapter * adapter,u32 ms)817 void rtw_mi_set_scan_deny(_adapter *adapter, u32 ms)
818 {
819 u32 in_data = ms;
820
821 _rtw_mi_process(adapter, _FALSE, &in_data, _rtw_mi_set_scan_deny);
822 }
rtw_mi_buddy_set_scan_deny(_adapter * adapter,u32 ms)823 void rtw_mi_buddy_set_scan_deny(_adapter *adapter, u32 ms)
824 {
825 u32 in_data = ms;
826
827 _rtw_mi_process(adapter, _TRUE, &in_data, _rtw_mi_set_scan_deny);
828 }
829 #endif /*CONFIG_SET_SCAN_DENY_TIMER*/
830
_rtw_mi_beacon_update(_adapter * padapter,void * data)831 static u8 _rtw_mi_beacon_update(_adapter *padapter, void *data)
832 {
833 if (!MLME_IS_STA(padapter)
834 && check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == _TRUE) {
835 RTW_INFO(ADPT_FMT" - update_beacon\n", ADPT_ARG(padapter));
836 rtw_update_beacon(padapter, 0xFF, NULL, _TRUE, 0);
837 }
838 return _TRUE;
839 }
840
rtw_mi_beacon_update(_adapter * padapter)841 void rtw_mi_beacon_update(_adapter *padapter)
842 {
843 _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_beacon_update);
844 }
845
rtw_mi_buddy_beacon_update(_adapter * padapter)846 void rtw_mi_buddy_beacon_update(_adapter *padapter)
847 {
848 _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_beacon_update);
849 }
850
_rtw_mi_busy_traffic_check(_adapter * padapter,void * data)851 u8 _rtw_mi_busy_traffic_check(_adapter *padapter, void *data)
852 {
853 return padapter->mlmepriv.LinkDetectInfo.bBusyTraffic;
854 }
855
rtw_mi_busy_traffic_check(_adapter * padapter)856 u8 rtw_mi_busy_traffic_check(_adapter *padapter)
857 {
858 return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_busy_traffic_check);
859 }
rtw_mi_buddy_busy_traffic_check(_adapter * padapter)860 u8 rtw_mi_buddy_busy_traffic_check(_adapter *padapter)
861 {
862 return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_busy_traffic_check);
863 }
_rtw_mi_check_mlmeinfo_state(_adapter * padapter,void * data)864 static u8 _rtw_mi_check_mlmeinfo_state(_adapter *padapter, void *data)
865 {
866 u32 state = *(u32 *)data;
867 struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
868
869 /*if (mlmeext_msr(mlmeext) == state)*/
870 if (check_mlmeinfo_state(mlmeext, state))
871 return _TRUE;
872 else
873 return _FALSE;
874 }
875
rtw_mi_check_mlmeinfo_state(_adapter * padapter,u32 state)876 u8 rtw_mi_check_mlmeinfo_state(_adapter *padapter, u32 state)
877 {
878 u32 in_data = state;
879
880 return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_check_mlmeinfo_state);
881 }
882
rtw_mi_buddy_check_mlmeinfo_state(_adapter * padapter,u32 state)883 u8 rtw_mi_buddy_check_mlmeinfo_state(_adapter *padapter, u32 state)
884 {
885 u32 in_data = state;
886
887 return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_check_mlmeinfo_state);
888 }
889
890 /*#define DBG_DUMP_FW_STATE*/
891 #ifdef DBG_DUMP_FW_STATE
rtw_dbg_dump_fwstate(_adapter * padapter,sint state)892 static void rtw_dbg_dump_fwstate(_adapter *padapter, sint state)
893 {
894 u8 buf[32] = {0};
895
896 if (state & WIFI_FW_NULL_STATE) {
897 _rtw_memset(buf, 0, 32);
898 sprintf(buf, "WIFI_FW_NULL_STATE");
899 RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf);
900 }
901
902 if (state & WIFI_ASOC_STATE) {
903 _rtw_memset(buf, 0, 32);
904 sprintf(buf, "WIFI_ASOC_STATE");
905 RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf);
906 }
907
908 if (state & WIFI_UNDER_LINKING) {
909 _rtw_memset(buf, 0, 32);
910 sprintf(buf, "WIFI_UNDER_LINKING");
911 RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf);
912 }
913
914 if (state & WIFI_UNDER_SURVEY) {
915 _rtw_memset(buf, 0, 32);
916 sprintf(buf, "WIFI_UNDER_SURVEY");
917 RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf);
918 }
919 }
920 #endif
921
_rtw_mi_check_fwstate(_adapter * padapter,void * data)922 static u8 _rtw_mi_check_fwstate(_adapter *padapter, void *data)
923 {
924 u8 ret = _FALSE;
925
926 sint state = *(sint *)data;
927
928 if ((state == WIFI_FW_NULL_STATE) &&
929 (padapter->mlmepriv.fw_state == WIFI_FW_NULL_STATE))
930 ret = _TRUE;
931 else if (_TRUE == check_fwstate(&padapter->mlmepriv, state))
932 ret = _TRUE;
933 #ifdef DBG_DUMP_FW_STATE
934 if (ret)
935 rtw_dbg_dump_fwstate(padapter, state);
936 #endif
937 return ret;
938 }
rtw_mi_check_fwstate(_adapter * padapter,sint state)939 u8 rtw_mi_check_fwstate(_adapter *padapter, sint state)
940 {
941 sint in_data = state;
942
943 return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_check_fwstate);
944 }
rtw_mi_buddy_check_fwstate(_adapter * padapter,sint state)945 u8 rtw_mi_buddy_check_fwstate(_adapter *padapter, sint state)
946 {
947 sint in_data = state;
948
949 return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_check_fwstate);
950 }
951
_rtw_mi_traffic_statistics(_adapter * padapter,void * data)952 static u8 _rtw_mi_traffic_statistics(_adapter *padapter , void *data)
953 {
954 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
955
956 /* Tx */
957 pdvobjpriv->traffic_stat.tx_bytes += padapter->xmitpriv.tx_bytes;
958 pdvobjpriv->traffic_stat.tx_pkts += padapter->xmitpriv.tx_pkts;
959 pdvobjpriv->traffic_stat.tx_drop += padapter->xmitpriv.tx_drop;
960
961 /* Rx */
962 pdvobjpriv->traffic_stat.rx_bytes += padapter->recvinfo.rx_bytes;
963 pdvobjpriv->traffic_stat.rx_pkts += padapter->recvinfo.rx_pkts;
964 pdvobjpriv->traffic_stat.rx_drop += padapter->recvinfo.rx_drop;
965 return _TRUE;
966 }
rtw_mi_traffic_statistics(_adapter * padapter)967 u8 rtw_mi_traffic_statistics(_adapter *padapter)
968 {
969 return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_traffic_statistics);
970 }
971
_rtw_mi_check_miracast_enabled(_adapter * padapter,void * data)972 static u8 _rtw_mi_check_miracast_enabled(_adapter *padapter , void *data)
973 {
974 return is_miracast_enabled(padapter);
975 }
rtw_mi_check_miracast_enabled(_adapter * padapter)976 u8 rtw_mi_check_miracast_enabled(_adapter *padapter)
977 {
978 return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_check_miracast_enabled);
979 }
980
981 #if 0 /*def CONFIG_XMIT_THREAD_MODE*/
982 static u8 _rtw_mi_check_pending_xmitbuf(_adapter *padapter , void *data)
983 {
984 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
985
986 return check_pending_xmitbuf(pxmitpriv);
987 }
988 u8 rtw_mi_check_pending_xmitbuf(_adapter *padapter)
989 {
990 return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_check_pending_xmitbuf);
991 }
992 u8 rtw_mi_buddy_check_pending_xmitbuf(_adapter *padapter)
993 {
994 return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_check_pending_xmitbuf);
995 }
996 #endif
997
998 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
999 #include <rtw_trx_sdio.h>
_rtw_mi_dequeue_xmit(_adapter * padapter,bool exclude_self)1000 static u8 _rtw_mi_dequeue_xmit(_adapter *padapter , bool exclude_self)
1001 {
1002 int i;
1003 u8 queue_empty = _TRUE;
1004 _adapter *iface;
1005 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1006
1007 for (i = 0; i < dvobj->iface_nums; i++) {
1008 iface = dvobj->padapters[i];
1009 if ((iface) && rtw_is_adapter_up(iface)) {
1010
1011 if ((exclude_self) && (iface == padapter))
1012 continue;
1013
1014 queue_empty &= sdio_dequeue_xmit(iface);
1015 }
1016 }
1017 return queue_empty;
1018 }
rtw_mi_sdio_dequeue_xmit(_adapter * padapter)1019 u8 rtw_mi_sdio_dequeue_xmit(_adapter *padapter)
1020 {
1021 return _rtw_mi_dequeue_xmit(padapter, _FALSE);
1022 }
rtw_mi_sdio_buddy_dequeue_xmit(_adapter * padapter)1023 u8 rtw_mi_sdio_buddy_dequeue_xmit(_adapter *padapter)
1024 {
1025 return _rtw_mi_dequeue_xmit(padapter, _TRUE);
1026 }
1027 #endif
_rtw_mi_adapter_reset(_adapter * padapter,u8 exclude_self)1028 static void _rtw_mi_adapter_reset(_adapter *padapter , u8 exclude_self)
1029 {
1030 int i;
1031 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1032
1033 for (i = 0; i < dvobj->iface_nums; i++) {
1034 if (dvobj->padapters[i]) {
1035 if ((exclude_self) && (dvobj->padapters[i] == padapter))
1036 continue;
1037 dvobj->padapters[i] = NULL;
1038 }
1039 }
1040 }
1041
rtw_mi_adapter_reset(_adapter * padapter)1042 void rtw_mi_adapter_reset(_adapter *padapter)
1043 {
1044 _rtw_mi_adapter_reset(padapter, _FALSE);
1045 }
1046
rtw_mi_buddy_adapter_reset(_adapter * padapter)1047 void rtw_mi_buddy_adapter_reset(_adapter *padapter)
1048 {
1049 _rtw_mi_adapter_reset(padapter, _TRUE);
1050 }
1051
_rtw_mi_dynamic_check_handlder(struct _ADAPTER * a,void * data)1052 static u8 _rtw_mi_dynamic_check_handlder(struct _ADAPTER *a, void *data)
1053 {
1054 rtw_iface_dynamic_check_handlder(a);
1055 return _TRUE;
1056 }
1057
rtw_mi_dynamic_check_handlder(struct _ADAPTER * a)1058 u8 rtw_mi_dynamic_check_handlder(struct _ADAPTER *a)
1059 {
1060 return _rtw_mi_process(a, _FALSE, NULL, _rtw_mi_dynamic_check_handlder);
1061 }
1062
1063 #if 0 /*#ifdef CONFIG_CORE_DM_CHK_TIMER*/
1064 static u8 _rtw_mi_dynamic_check_timer_handlder(_adapter *adapter, void *data)
1065 {
1066 rtw_iface_dynamic_check_timer_handlder(adapter);
1067 return _TRUE;
1068 }
1069 u8 rtw_mi_dynamic_check_timer_handlder(_adapter *padapter)
1070 {
1071 return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_dynamic_check_timer_handlder);
1072 }
1073 u8 rtw_mi_buddy_dynamic_check_timer_handlder(_adapter *padapter)
1074 {
1075 return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_dynamic_check_timer_handlder);
1076 }
1077 #endif
1078
_rtw_mi_dynamic_chk_wk_hdl(_adapter * adapter,void * data)1079 static u8 _rtw_mi_dynamic_chk_wk_hdl(_adapter *adapter, void *data)
1080 {
1081 rtw_iface_dynamic_chk_wk_hdl(adapter);
1082 return _TRUE;
1083 }
rtw_mi_dynamic_chk_wk_hdl(_adapter * padapter)1084 u8 rtw_mi_dynamic_chk_wk_hdl(_adapter *padapter)
1085 {
1086 return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_dynamic_chk_wk_hdl);
1087 }
rtw_mi_buddy_dynamic_chk_wk_hdl(_adapter * padapter)1088 u8 rtw_mi_buddy_dynamic_chk_wk_hdl(_adapter *padapter)
1089 {
1090 return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_dynamic_chk_wk_hdl);
1091 }
1092
_rtw_mi_os_xmit_schedule(_adapter * adapter,void * data)1093 static u8 _rtw_mi_os_xmit_schedule(_adapter *adapter, void *data)
1094 {
1095 rtw_os_xmit_schedule(adapter);
1096 return _TRUE;
1097 }
rtw_mi_os_xmit_schedule(_adapter * padapter)1098 u8 rtw_mi_os_xmit_schedule(_adapter *padapter)
1099 {
1100 return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_os_xmit_schedule);
1101 }
rtw_mi_buddy_os_xmit_schedule(_adapter * padapter)1102 u8 rtw_mi_buddy_os_xmit_schedule(_adapter *padapter)
1103 {
1104 return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_os_xmit_schedule);
1105 }
1106
_rtw_mi_report_survey_event(_adapter * adapter,void * data)1107 static u8 _rtw_mi_report_survey_event(_adapter *adapter, void *data)
1108 {
1109 union recv_frame *precv_frame = (union recv_frame *)data;
1110
1111 report_survey_event(adapter, precv_frame);
1112 return _TRUE;
1113 }
rtw_mi_report_survey_event(_adapter * padapter,union recv_frame * precv_frame)1114 u8 rtw_mi_report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
1115 {
1116 return _rtw_mi_process(padapter, _FALSE, precv_frame, _rtw_mi_report_survey_event);
1117 }
rtw_mi_buddy_report_survey_event(_adapter * padapter,union recv_frame * precv_frame)1118 u8 rtw_mi_buddy_report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
1119 {
1120 return _rtw_mi_process(padapter, _TRUE, precv_frame, _rtw_mi_report_survey_event);
1121 }
1122
_rtw_mi_sreset_adapter_hdl(_adapter * adapter,void * data)1123 static u8 _rtw_mi_sreset_adapter_hdl(_adapter *adapter, void *data)
1124 {
1125 u8 bstart = *(u8 *)data;
1126
1127 if (bstart)
1128 sreset_start_adapter(adapter);
1129 else
1130 sreset_stop_adapter(adapter);
1131 return _TRUE;
1132 }
rtw_mi_sreset_adapter_hdl(_adapter * padapter,u8 bstart)1133 u8 rtw_mi_sreset_adapter_hdl(_adapter *padapter, u8 bstart)
1134 {
1135 u8 in_data = bstart;
1136
1137 return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_sreset_adapter_hdl);
1138 }
1139
1140 #if defined(DBG_CONFIG_ERROR_RESET) && defined(CONFIG_CONCURRENT_MODE)
rtw_mi_ap_info_restore(_adapter * adapter)1141 void rtw_mi_ap_info_restore(_adapter *adapter)
1142 {
1143 int i;
1144 _adapter *iface;
1145 struct mlme_priv *pmlmepriv;
1146 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1147
1148 for (i = 0; i < dvobj->iface_nums; i++) {
1149 iface = dvobj->padapters[i];
1150 if (iface) {
1151 pmlmepriv = &iface->mlmepriv;
1152
1153 if (MLME_IS_AP(iface) || MLME_IS_MESH(iface)) {
1154 RTW_INFO(FUNC_ADPT_FMT" %s\n", FUNC_ADPT_ARG(iface), MLME_IS_AP(iface) ? "AP" : "MESH");
1155 rtw_iface_bcmc_sec_cam_map_restore(iface);
1156 }
1157 }
1158 }
1159 }
1160 #endif /*#if defined(DBG_CONFIG_ERROR_RESET) && defined(CONFIG_CONCURRENT_MODE)*/
1161
rtw_mi_buddy_sreset_adapter_hdl(_adapter * padapter,u8 bstart)1162 u8 rtw_mi_buddy_sreset_adapter_hdl(_adapter *padapter, u8 bstart)
1163 {
1164 u8 in_data = bstart;
1165
1166 return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_sreset_adapter_hdl);
1167 }
_rtw_mi_tx_beacon_hdl(_adapter * adapter,void * data)1168 static u8 _rtw_mi_tx_beacon_hdl(_adapter *adapter, void *data)
1169 {
1170 if ((MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))
1171 && check_fwstate(&adapter->mlmepriv, WIFI_ASOC_STATE) == _TRUE
1172 ) {
1173 adapter->mlmepriv.update_bcn = _TRUE;
1174 #ifndef CONFIG_INTERRUPT_BASED_TXBCN
1175 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) || defined(CONFIG_PCI_BCN_POLLING)
1176 tx_beacon_hdl(adapter, NULL);
1177 #endif
1178 #endif
1179 }
1180 return _TRUE;
1181 }
rtw_mi_tx_beacon_hdl(_adapter * padapter)1182 u8 rtw_mi_tx_beacon_hdl(_adapter *padapter)
1183 {
1184 return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_tx_beacon_hdl);
1185 }
rtw_mi_buddy_tx_beacon_hdl(_adapter * padapter)1186 u8 rtw_mi_buddy_tx_beacon_hdl(_adapter *padapter)
1187 {
1188 return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_sreset_adapter_hdl);
1189 }
1190
_rtw_mi_set_tx_beacon_cmd(_adapter * adapter,void * data)1191 static u8 _rtw_mi_set_tx_beacon_cmd(_adapter *adapter, void *data)
1192 {
1193 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1194
1195 if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
1196 if (pmlmepriv->update_bcn == _TRUE)
1197 set_tx_beacon_cmd(adapter, 0);
1198 }
1199 return _TRUE;
1200 }
rtw_mi_set_tx_beacon_cmd(_adapter * padapter)1201 u8 rtw_mi_set_tx_beacon_cmd(_adapter *padapter)
1202 {
1203 return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_set_tx_beacon_cmd);
1204 }
rtw_mi_buddy_set_tx_beacon_cmd(_adapter * padapter)1205 u8 rtw_mi_buddy_set_tx_beacon_cmd(_adapter *padapter)
1206 {
1207 return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_set_tx_beacon_cmd);
1208 }
1209
1210 #ifdef CONFIG_P2P
_rtw_mi_stay_in_p2p_mode(_adapter * adapter,void * data)1211 static u8 _rtw_mi_stay_in_p2p_mode(_adapter *adapter, void *data)
1212 {
1213 struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
1214
1215 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) ||
1216 rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
1217 return _TRUE;
1218 return _FALSE;
1219 }
rtw_mi_stay_in_p2p_mode(_adapter * padapter)1220 u8 rtw_mi_stay_in_p2p_mode(_adapter *padapter)
1221 {
1222 return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_stay_in_p2p_mode);
1223 }
rtw_mi_buddy_stay_in_p2p_mode(_adapter * padapter)1224 u8 rtw_mi_buddy_stay_in_p2p_mode(_adapter *padapter)
1225 {
1226 return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_stay_in_p2p_mode);
1227 }
1228 #endif /*CONFIG_P2P*/
1229
rtw_get_iface_by_id(_adapter * padapter,u8 iface_id)1230 _adapter *rtw_get_iface_by_id(_adapter *padapter, u8 iface_id)
1231 {
1232 _adapter *iface = NULL;
1233 struct dvobj_priv *dvobj;
1234
1235 if ((padapter == NULL) || (iface_id >= CONFIG_IFACE_NUMBER)) {
1236 rtw_warn_on(1);
1237 return iface;
1238 }
1239 dvobj = adapter_to_dvobj(padapter);
1240
1241 dvobj = adapter_to_dvobj(padapter);
1242 return dvobj->padapters[iface_id];
1243 }
1244
rtw_get_iface_by_macddr(_adapter * padapter,const u8 * mac_addr)1245 _adapter *rtw_get_iface_by_macddr(_adapter *padapter, const u8 *mac_addr)
1246 {
1247 int i;
1248 _adapter *iface = NULL;
1249 u8 bmatch = _FALSE;
1250 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1251
1252 #ifdef RTW_PHL_TEST_FPGA
1253 return dvobj->padapters[0];
1254 #endif
1255
1256 for (i = 0; i < dvobj->iface_nums; i++) {
1257 iface = dvobj->padapters[i];
1258 if ((iface) && (_rtw_memcmp(mac_addr, adapter_mac_addr(iface), ETH_ALEN))) {
1259 bmatch = _TRUE;
1260 break;
1261 }
1262 }
1263 if (bmatch)
1264 return iface;
1265 else
1266 return NULL;
1267 }
1268
rtw_get_iface_by_hwport(_adapter * padapter,u8 hw_port)1269 _adapter *rtw_get_iface_by_hwport(_adapter *padapter, u8 hw_port)
1270 {
1271 int i;
1272 _adapter *iface = NULL;
1273 u8 bmatch = _FALSE;
1274 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1275
1276 for (i = 0; i < dvobj->iface_nums; i++) {
1277 iface = dvobj->padapters[i];
1278 if ((iface) && (hw_port == iface->hw_port)) {
1279 bmatch = _TRUE;
1280 break;
1281 }
1282 }
1283 if (bmatch)
1284 return iface;
1285 else
1286 return NULL;
1287 }
1288
1289 /*#define CONFIG_SKB_ALLOCATED*/
1290 #define DBG_SKB_PROCESS
1291 #ifdef DBG_SKB_PROCESS
rtw_dbg_skb_process(_adapter * padapter,union recv_frame * precvframe,union recv_frame * pcloneframe)1292 void rtw_dbg_skb_process(_adapter *padapter, union recv_frame *precvframe, union recv_frame *pcloneframe)
1293 {
1294 struct sk_buff *pkt_copy, *pkt_org;
1295
1296 pkt_org = precvframe->u.hdr.pkt;
1297 pkt_copy = pcloneframe->u.hdr.pkt;
1298 /*
1299 RTW_INFO("%s ===== ORG SKB =====\n", __func__);
1300 RTW_INFO(" SKB head(%p)\n", pkt_org->head);
1301 RTW_INFO(" SKB data(%p)\n", pkt_org->data);
1302 RTW_INFO(" SKB tail(%p)\n", pkt_org->tail);
1303 RTW_INFO(" SKB end(%p)\n", pkt_org->end);
1304
1305 RTW_INFO(" recv frame head(%p)\n", precvframe->u.hdr.rx_head);
1306 RTW_INFO(" recv frame data(%p)\n", precvframe->u.hdr.rx_data);
1307 RTW_INFO(" recv frame tail(%p)\n", precvframe->u.hdr.rx_tail);
1308 RTW_INFO(" recv frame end(%p)\n", precvframe->u.hdr.rx_end);
1309
1310 RTW_INFO("%s ===== COPY SKB =====\n", __func__);
1311 RTW_INFO(" SKB head(%p)\n", pkt_copy->head);
1312 RTW_INFO(" SKB data(%p)\n", pkt_copy->data);
1313 RTW_INFO(" SKB tail(%p)\n", pkt_copy->tail);
1314 RTW_INFO(" SKB end(%p)\n", pkt_copy->end);
1315
1316 RTW_INFO(" recv frame head(%p)\n", pcloneframe->u.hdr.rx_head);
1317 RTW_INFO(" recv frame data(%p)\n", pcloneframe->u.hdr.rx_data);
1318 RTW_INFO(" recv frame tail(%p)\n", pcloneframe->u.hdr.rx_tail);
1319 RTW_INFO(" recv frame end(%p)\n", pcloneframe->u.hdr.rx_end);
1320 */
1321 /*
1322 RTW_INFO("%s => recv_frame adapter(%p,%p)\n", __func__, precvframe->u.hdr.adapter, pcloneframe->u.hdr.adapter);
1323 RTW_INFO("%s => recv_frame dev(%p,%p)\n", __func__, pkt_org->dev , pkt_copy->dev);
1324 RTW_INFO("%s => recv_frame len(%d,%d)\n", __func__, precvframe->u.hdr.len, pcloneframe->u.hdr.len);
1325 */
1326 if (precvframe->u.hdr.len != pcloneframe->u.hdr.len)
1327 RTW_INFO("%s [WARN] recv_frame length(%d:%d) compare failed\n", __func__, precvframe->u.hdr.len, pcloneframe->u.hdr.len);
1328
1329 if (_rtw_memcmp(&precvframe->u.hdr.attrib, &pcloneframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib)) == _FALSE)
1330 RTW_INFO("%s [WARN] recv_frame attrib compare failed\n", __func__);
1331
1332 if (_rtw_memcmp(precvframe->u.hdr.rx_data, pcloneframe->u.hdr.rx_data, precvframe->u.hdr.len) == _FALSE)
1333 RTW_INFO("%s [WARN] recv_frame rx_data compare failed\n", __func__);
1334
1335 }
1336 #endif
1337
_rtw_mi_buddy_clone_bcmc_packet(_adapter * adapter,union recv_frame * precvframe,union recv_frame * pcloneframe)1338 static s32 _rtw_mi_buddy_clone_bcmc_packet(_adapter *adapter,
1339 union recv_frame *precvframe, union recv_frame *pcloneframe)
1340 {
1341 s32 ret = _SUCCESS;
1342 #ifdef CONFIG_SKB_ALLOCATED
1343 u8 *pbuf = precvframe->u.hdr.rx_data;
1344 #endif
1345 struct rx_pkt_attrib *pattrib = NULL;
1346
1347 if (pcloneframe) {
1348 pcloneframe->u.hdr.adapter = adapter;
1349
1350 _rtw_init_listhead(&pcloneframe->u.hdr.list);
1351 pcloneframe->u.hdr.precvbuf = NULL; /*can't access the precvbuf for new arch.*/
1352 pcloneframe->u.hdr.len = 0;
1353
1354 _rtw_memcpy(&pcloneframe->u.hdr.attrib, &precvframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib));
1355
1356 pattrib = &pcloneframe->u.hdr.attrib;
1357 #ifdef CONFIG_SKB_ALLOCATED
1358 if (rtw_os_alloc_recvframe(adapter, pcloneframe, pbuf, NULL) == _SUCCESS)
1359 #else
1360 if (rtw_os_recvframe_duplicate_skb(adapter, pcloneframe, precvframe->u.hdr.pkt) == _SUCCESS)
1361 #endif
1362 {
1363 #ifdef CONFIG_SKB_ALLOCATED
1364 recvframe_put(pcloneframe, pattrib->pkt_len);
1365 #endif
1366
1367 #ifdef DBG_SKB_PROCESS
1368 rtw_dbg_skb_process(adapter, precvframe, pcloneframe);
1369 #endif
1370 validate_recv_frame(adapter, pcloneframe);
1371
1372 } else {
1373 ret = _FAIL;
1374 RTW_ERR("%s()-%d: rtw_os_alloc_recvframe() failed!\n", __func__, __LINE__);
1375 }
1376 }
1377 return ret;
1378 }
1379
1380
rtw_mi_buddy_clone_bcmc_packet(_adapter * padapter,union recv_frame * precvframe)1381 void rtw_mi_buddy_clone_bcmc_packet(_adapter *padapter,
1382 union recv_frame *precvframe)
1383 {
1384 int i;
1385 s32 ret = _SUCCESS;
1386 _adapter *iface = NULL;
1387 union recv_frame *pcloneframe = NULL;
1388 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1389 struct recv_priv *precvpriv = &dvobj->recvpriv;
1390 _queue *pfree_recv_queue = &precvpriv->free_recv_queue;
1391 u8 *fhead = get_recvframe_data(precvframe);
1392 u8 type = GetFrameType(fhead);
1393
1394 for (i = 0; i < dvobj->iface_nums; i++) {
1395 iface = dvobj->padapters[i];
1396 if (!iface || iface == padapter)
1397 continue;
1398 if (rtw_is_adapter_up(iface) == _FALSE || iface->registered == 0)
1399 continue;
1400 if (type == WIFI_DATA_TYPE && !adapter_allow_bmc_data_rx(iface))
1401 continue;
1402
1403 pcloneframe = rtw_alloc_recvframe(pfree_recv_queue);
1404 if (pcloneframe) {
1405 ret = _rtw_mi_buddy_clone_bcmc_packet(iface, precvframe, pcloneframe);
1406 if (ret == _FAIL)
1407 RTW_ERR("_rtw_mi_buddy_clone_bcmc_packet failed!\n");
1408
1409 rtw_free_recvframe(pcloneframe);
1410 } else {
1411 RTW_ERR("%s rtw_alloc_recvframe failed\n", __func__);
1412 rtw_warn_on(1);
1413 }
1414 }
1415 }
1416
1417 #ifdef CONFIG_PCI_HCI
1418 /*API be created temporary for MI, caller is interrupt-handler, PCIE's interrupt handler cannot apply to multi-AP*/
rtw_mi_get_ap_adapter(_adapter * padapter)1419 _adapter *rtw_mi_get_ap_adapter(_adapter *padapter)
1420 {
1421 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1422 int i;
1423 _adapter *iface = NULL;
1424
1425 for (i = 0; i < dvobj->iface_nums; i++) {
1426 iface = dvobj->padapters[i];
1427 if (!iface)
1428 continue;
1429
1430 if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE
1431 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE)
1432 break;
1433
1434 }
1435 return iface;
1436 }
1437 #endif
1438
rtw_mi_get_ld_sta_ifbmp(_adapter * adapter)1439 u8 rtw_mi_get_ld_sta_ifbmp(_adapter *adapter)
1440 {
1441 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1442 int i;
1443 _adapter *iface = NULL;
1444 u8 ifbmp = 0;
1445
1446 for (i = 0; i < dvobj->iface_nums; i++) {
1447 iface = dvobj->padapters[i];
1448 if (!iface)
1449 continue;
1450
1451 if (MLME_IS_STA(iface) && MLME_IS_ASOC(iface))
1452 ifbmp |= BIT(i);
1453 }
1454
1455 return ifbmp;
1456 }
1457
rtw_mi_get_ap_mesh_ifbmp(_adapter * adapter)1458 u8 rtw_mi_get_ap_mesh_ifbmp(_adapter *adapter)
1459 {
1460 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1461 int i;
1462 _adapter *iface = NULL;
1463 u8 ifbmp = 0;
1464
1465 for (i = 0; i < dvobj->iface_nums; i++) {
1466 iface = dvobj->padapters[i];
1467 if (!iface)
1468 continue;
1469
1470 if (CHK_MLME_STATE(iface, WIFI_AP_STATE | WIFI_MESH_STATE)
1471 && MLME_IS_ASOC(iface))
1472 ifbmp |= BIT(i);
1473 }
1474
1475 return ifbmp;
1476 }
1477
rtw_mi_get_assoc_if_num(_adapter * adapter)1478 u8 rtw_mi_get_assoc_if_num(_adapter *adapter)
1479 {
1480 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
1481 u8 n_assoc_iface = 0;
1482 #if 1
1483 u8 i;
1484
1485 for (i = 0; i < dvobj->iface_nums; i++) {
1486 if (check_fwstate(&(dvobj->padapters[i]->mlmepriv), WIFI_ASOC_STATE))
1487 n_assoc_iface++;
1488 }
1489 #else
1490 n_assoc_iface = DEV_STA_LD_NUM(dvobj) + DEV_AP_NUM(dvobj) + DEV_ADHOC_NUM(dvobj) + DEV_MESH_NUM(dvobj);
1491 #endif
1492 return n_assoc_iface;
1493 }
1494