net: wireless: rockchip_wlan: add rtl8723cs support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723cs / core / rtw_mi.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2015 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #define _RTW_MI_C_
21
22 #include <drv_types.h>
23 #include <hal_data.h>
24
25 void rtw_mi_update_union_chan_inf(_adapter *adapter, u8 ch, u8 offset , u8 bw)
26 {
27         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
28         struct mi_state *iface_state = &dvobj->iface_state;
29
30         iface_state->union_ch = ch;
31         iface_state->union_bw = bw;
32         iface_state->union_offset = offset;
33 }
34
35 /* Find union about ch, bw, ch_offset of all linked/linking interfaces */
36 int _rtw_mi_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset, bool include_self)
37 {
38         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
39         _adapter *iface;
40         struct mlme_ext_priv *mlmeext;
41         int i;
42         u8 ch_ret = 0;
43         u8 bw_ret = CHANNEL_WIDTH_20;
44         u8 offset_ret = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
45         int num = 0;
46
47         if (ch)
48                 *ch = 0;
49         if (bw)
50                 *bw = CHANNEL_WIDTH_20;
51         if (offset)
52                 *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
53
54         for (i = 0; i < dvobj->iface_nums; i++) {
55                 iface = dvobj->padapters[i];
56                 mlmeext = &iface->mlmeextpriv;
57
58                 if (!check_fwstate(&iface->mlmepriv, _FW_LINKED | _FW_UNDER_LINKING))
59                         continue;
60
61                 if (check_fwstate(&iface->mlmepriv, WIFI_OP_CH_SWITCHING))
62                         continue;
63
64                 if (include_self == _FALSE && adapter == iface)
65                         continue;
66
67                 if (num == 0) {
68                         ch_ret = mlmeext->cur_channel;
69                         bw_ret = mlmeext->cur_bwmode;
70                         offset_ret = mlmeext->cur_ch_offset;
71                         num++;
72                         continue;
73                 }
74
75                 if (ch_ret != mlmeext->cur_channel) {
76                         num = 0;
77                         break;
78                 }
79
80                 if (bw_ret < mlmeext->cur_bwmode) {
81                         bw_ret = mlmeext->cur_bwmode;
82                         offset_ret = mlmeext->cur_ch_offset;
83                 } else if (bw_ret == mlmeext->cur_bwmode && offset_ret != mlmeext->cur_ch_offset) {
84                         num = 0;
85                         break;
86                 }
87
88                 num++;
89         }
90
91         if (num) {
92                 if (ch)
93                         *ch = ch_ret;
94                 if (bw)
95                         *bw = bw_ret;
96                 if (offset)
97                         *offset = offset_ret;
98         }
99
100         return num;
101 }
102
103 inline int rtw_mi_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
104 {
105         return _rtw_mi_get_ch_setting_union(adapter, ch, bw, offset, 1);
106 }
107
108 inline int rtw_mi_get_ch_setting_union_no_self(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
109 {
110         return _rtw_mi_get_ch_setting_union(adapter, ch, bw, offset, 0);
111 }
112
113 /* For now, not return union_ch/bw/offset */
114 void _rtw_mi_status(_adapter *adapter, struct mi_state *mstate, bool include_self)
115 {
116         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
117         _adapter *iface;
118         int i;
119
120         _rtw_memset(mstate, 0, sizeof(struct mi_state));
121
122         for (i = 0; i < dvobj->iface_nums; i++) {
123                 iface = dvobj->padapters[i];
124
125                 if (include_self == _FALSE && iface == adapter)
126                         continue;
127
128                 if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {
129                         MSTATE_STA_NUM(mstate)++;
130                         if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE)
131                                 MSTATE_STA_LD_NUM(mstate)++;
132
133                         if (check_fwstate(&iface->mlmepriv, _FW_UNDER_LINKING) == _TRUE)
134                                 MSTATE_STA_LG_NUM(mstate)++;
135
136                 } else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE
137                         && check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE
138                 ) {
139                         MSTATE_AP_NUM(mstate)++;
140                         if (iface->stapriv.asoc_sta_count > 2)
141                                 MSTATE_AP_LD_NUM(mstate)++;
142
143                 } else if (check_fwstate(&iface->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE
144                         && check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE
145                 ) {
146                         MSTATE_ADHOC_NUM(mstate)++;
147                         if (iface->stapriv.asoc_sta_count > 2)
148                                 MSTATE_ADHOC_LD_NUM(mstate)++;
149                 }
150
151                 if (check_fwstate(&iface->mlmepriv, WIFI_UNDER_WPS) == _TRUE)
152                         MSTATE_WPS_NUM(mstate)++;
153
154 #ifdef CONFIG_IOCTL_CFG80211
155                 if (rtw_cfg80211_get_is_mgmt_tx(iface))
156                         MSTATE_MGMT_TX_NUM(mstate)++;
157                 #ifdef CONFIG_P2P
158                 if (rtw_cfg80211_get_is_roch(iface) == _TRUE)
159                         MSTATE_ROCH_NUM(mstate)++;
160                 #endif
161 #endif /* CONFIG_IOCTL_CFG80211 */
162
163         }
164 }
165
166 inline void rtw_mi_status(_adapter *adapter, struct mi_state *mstate)
167 {
168         return _rtw_mi_status(adapter, mstate, 1);
169 }
170 inline void rtw_mi_status_no_self(_adapter *adapter, struct mi_state *mstate)
171 {
172         return _rtw_mi_status(adapter, mstate, 0);
173 }
174 void dump_mi_status(void *sel, struct dvobj_priv *dvobj)
175 {
176         RTW_PRINT_SEL(sel, "== dvobj-iface_state ==\n");
177         RTW_PRINT_SEL(sel, "sta_num:%d\n", DEV_STA_NUM(dvobj));
178         RTW_PRINT_SEL(sel, "linking_sta_num:%d\n", DEV_STA_LG_NUM(dvobj));
179         RTW_PRINT_SEL(sel, "linked_sta_num:%d\n", DEV_STA_LD_NUM(dvobj));
180         RTW_PRINT_SEL(sel, "ap_num:%d\n", DEV_AP_NUM(dvobj));
181         RTW_PRINT_SEL(sel, "linked_ap_num:%d\n", DEV_AP_LD_NUM(dvobj));
182         RTW_PRINT_SEL(sel, "adhoc_num:%d\n", DEV_ADHOC_NUM(dvobj));
183         RTW_PRINT_SEL(sel, "linked_adhoc_num:%d\n", DEV_ADHOC_LD_NUM(dvobj));
184 #ifdef CONFIG_P2P
185         RTW_PRINT_SEL(sel, "p2p_device_num:%d\n", rtw_mi_stay_in_p2p_mode(dvobj->padapters[IFACE_ID0]));
186 #endif
187 #if defined(CONFIG_IOCTL_CFG80211)
188         #if defined(CONFIG_P2P)
189         RTW_PRINT_SEL(sel, "roch_num:%d\n", DEV_ROCH_NUM(dvobj));
190         #endif
191         RTW_PRINT_SEL(sel, "mgmt_tx_num:%d\n", DEV_MGMT_TX_NUM(dvobj));
192 #endif
193         RTW_PRINT_SEL(sel, "under_wps_num:%d\n", DEV_WPS_NUM(dvobj));
194         RTW_PRINT_SEL(sel, "union_ch:%d\n", DEV_U_CH(dvobj));
195         RTW_PRINT_SEL(sel, "union_bw:%d\n", DEV_U_BW(dvobj));
196         RTW_PRINT_SEL(sel, "union_offset:%d\n", DEV_U_OFFSET(dvobj));
197         RTW_PRINT_SEL(sel, "================\n\n");
198 }
199
200 void dump_dvobj_mi_status(void *sel, const char *fun_name, _adapter *adapter)
201 {
202         RTW_INFO("\n[ %s ] call %s\n", fun_name, __func__);
203         dump_mi_status(sel, adapter_to_dvobj(adapter));
204 }
205
206 inline void rtw_mi_update_iface_status(struct mlme_priv *pmlmepriv, sint state)
207 {
208         _adapter *adapter = container_of(pmlmepriv, _adapter, mlmepriv);
209         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
210         struct mi_state *iface_state = &dvobj->iface_state;
211         struct mi_state tmp_mstate;
212         u8 i;
213         u8 u_ch, u_offset, u_bw;
214         _adapter *iface;
215
216         if (state == WIFI_MONITOR_STATE
217                 || state == WIFI_SITE_MONITOR
218                 || state == 0xFFFFFFFF
219         )
220                 return;
221
222         if (0)
223                 RTW_INFO("%s => will change or clean state to 0x%08x\n", __func__, state);
224
225         rtw_mi_status(adapter, &tmp_mstate);
226         _rtw_memcpy(iface_state, &tmp_mstate, sizeof(struct mi_state));
227
228         if (rtw_mi_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset))
229                 rtw_mi_update_union_chan_inf(adapter , u_ch, u_offset , u_bw);
230         else {
231                 if (0) {
232                         dump_adapters_status(RTW_DBGDUMP , dvobj);
233                         RTW_INFO("%s-[ERROR] cannot get union channel\n", __func__);
234                         rtw_warn_on(1);
235                 }
236         }
237
238 #ifdef DBG_IFACE_STATUS
239         DBG_IFACE_STATUS_DUMP(adapter);
240 #endif
241 }
242 u8 rtw_mi_check_status(_adapter *adapter, u8 type)
243 {
244         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
245         struct mi_state *iface_state = &dvobj->iface_state;
246         u8 ret = _FALSE;
247
248 #ifdef DBG_IFACE_STATUS
249         DBG_IFACE_STATUS_DUMP(adapter);
250         RTW_INFO("%s-"ADPT_FMT" check type:%d\n", __func__, ADPT_ARG(adapter), type);
251 #endif
252
253         switch (type) {
254         case MI_LINKED:
255                 if (MSTATE_STA_LD_NUM(iface_state) || MSTATE_AP_NUM(iface_state) || MSTATE_ADHOC_NUM(iface_state)) /*check_fwstate(&iface->mlmepriv, _FW_LINKED)*/
256                         ret = _TRUE;
257                 break;
258         case MI_ASSOC:
259                 if (MSTATE_STA_LD_NUM(iface_state) || MSTATE_AP_LD_NUM(iface_state) || MSTATE_ADHOC_LD_NUM(iface_state))
260                         ret = _TRUE;
261                 break;
262         case MI_UNDER_WPS:
263                 if (MSTATE_WPS_NUM(iface_state))
264                         ret = _TRUE;
265                 break;
266
267         case MI_AP_MODE:
268                 if (MSTATE_AP_NUM(iface_state))
269                         ret = _TRUE;
270                 break;
271         case MI_AP_ASSOC:
272                 if (MSTATE_AP_LD_NUM(iface_state))
273                         ret = _TRUE;
274                 break;
275
276         case MI_ADHOC:
277                 if (MSTATE_ADHOC_NUM(iface_state))
278                         ret = _TRUE;
279                 break;
280         case MI_ADHOC_ASSOC:
281                 if (MSTATE_ADHOC_LD_NUM(iface_state))
282                         ret = _TRUE;
283                 break;
284
285         case MI_STA_NOLINK: /* this is misleading, but not used now */
286                 if (MSTATE_STA_NUM(iface_state) && (!(MSTATE_STA_LD_NUM(iface_state) || MSTATE_STA_LG_NUM(iface_state))))
287                         ret = _TRUE;
288                 break;
289         case MI_STA_LINKED:
290                 if (MSTATE_STA_LD_NUM(iface_state))
291                         ret = _TRUE;
292                 break;
293         case MI_STA_LINKING:
294                 if (MSTATE_STA_LG_NUM(iface_state))
295                         ret = _TRUE;
296                 break;
297
298         default:
299                 break;
300         }
301         return ret;
302 }
303
304 u8 rtw_mi_mp_mode_check(_adapter *padapter)
305 {
306 #ifdef CONFIG_MP_INCLUDED
307 #ifdef CONFIG_CONCURRENT_MODE
308         int i;
309         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
310         _adapter *iface = NULL;
311
312         for (i = 0; i < dvobj->iface_nums; i++) {
313                 iface = dvobj->padapters[i];
314
315                 if ((iface) && (iface->registrypriv.mp_mode == 1))
316                         return _TRUE;
317         }
318 #else
319         if (padapter->registrypriv.mp_mode == 1)
320                 return _TRUE;
321 #endif
322 #endif /* CONFIG_MP_INCLUDED */
323         return _FALSE;
324 }
325
326 /*
327 * return value : 0 is failed or have not interface meet condition
328 * return value : !0 is success or interface numbers which meet condition
329 * return value of ops_func must be _TRUE or _FALSE
330 */
331 static u8 _rtw_mi_process(_adapter *padapter, bool exclude_self,
332                   void *data, u8(*ops_func)(_adapter *padapter, void *data))
333 {
334         int i;
335         _adapter *iface;
336         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
337
338         u8 ret = 0;
339
340         for (i = 0; i < dvobj->iface_nums; i++) {
341                 iface = dvobj->padapters[i];
342                 if ((iface) && rtw_is_adapter_up(iface)) {
343
344                         if ((exclude_self) && (iface == padapter))
345                                 continue;
346
347                         if (ops_func)
348                                 if (_TRUE == ops_func(iface, data))
349                                         ret++;
350                 }
351         }
352         return ret;
353 }
354 static u8 _rtw_mi_netif_stop_queue(_adapter *padapter, void *data)
355 {
356         bool carrier_off = *(bool *)data;
357         struct net_device *pnetdev = padapter->pnetdev;
358
359         if (carrier_off)
360                 netif_carrier_off(pnetdev);
361         rtw_netif_stop_queue(pnetdev);
362         return _TRUE;
363 }
364 u8 rtw_mi_netif_stop_queue(_adapter *padapter, bool carrier_off)
365 {
366         bool in_data = carrier_off;
367
368         return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_netif_stop_queue);
369 }
370 u8 rtw_mi_buddy_netif_stop_queue(_adapter *padapter, bool carrier_off)
371 {
372         bool in_data = carrier_off;
373
374         return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_netif_stop_queue);
375 }
376
377 static u8 _rtw_mi_netif_wake_queue(_adapter *padapter, void *data)
378 {
379         struct net_device *pnetdev = padapter->pnetdev;
380
381         if (pnetdev)
382                 rtw_netif_wake_queue(pnetdev);
383         return _TRUE;
384 }
385 u8 rtw_mi_netif_wake_queue(_adapter *padapter)
386 {
387         return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_wake_queue);
388 }
389 u8 rtw_mi_buddy_netif_wake_queue(_adapter *padapter)
390 {
391         return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_wake_queue);
392 }
393
394 static u8 _rtw_mi_netif_carrier_on(_adapter *padapter, void *data)
395 {
396         struct net_device *pnetdev = padapter->pnetdev;
397
398         if (pnetdev)
399                 rtw_netif_carrier_on(pnetdev);
400         return _TRUE;
401 }
402 u8 rtw_mi_netif_carrier_on(_adapter *padapter)
403 {
404         return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_carrier_on);
405 }
406 u8 rtw_mi_buddy_netif_carrier_on(_adapter *padapter)
407 {
408         return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_carrier_on);
409 }
410
411 static u8 _rtw_mi_scan_abort(_adapter *adapter, void *data)
412 {
413         bool bwait = *(bool *)data;
414
415         if (bwait)
416                 rtw_scan_abort(adapter);
417         else
418                 rtw_scan_abort_no_wait(adapter);
419
420         return _TRUE;
421 }
422 void rtw_mi_scan_abort(_adapter *adapter, bool bwait)
423 {
424         bool in_data = bwait;
425
426         _rtw_mi_process(adapter, _FALSE, &in_data, _rtw_mi_scan_abort);
427
428 }
429 void rtw_mi_buddy_scan_abort(_adapter *adapter, bool bwait)
430 {
431         bool in_data = bwait;
432
433         _rtw_mi_process(adapter, _TRUE, &in_data, _rtw_mi_scan_abort);
434 }
435
436 static u8 _rtw_mi_start_drv_threads(_adapter *adapter, void *data)
437 {
438         rtw_start_drv_threads(adapter);
439         return _TRUE;
440 }
441 void rtw_mi_start_drv_threads(_adapter *adapter)
442 {
443         _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_start_drv_threads);
444 }
445 void rtw_mi_buddy_start_drv_threads(_adapter *adapter)
446 {
447         _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_start_drv_threads);
448 }
449
450 static u8 _rtw_mi_stop_drv_threads(_adapter *adapter, void *data)
451 {
452         rtw_stop_drv_threads(adapter);
453         return _TRUE;
454 }
455 void rtw_mi_stop_drv_threads(_adapter *adapter)
456 {
457         _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_stop_drv_threads);
458 }
459 void rtw_mi_buddy_stop_drv_threads(_adapter *adapter)
460 {
461         _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_stop_drv_threads);
462 }
463
464 static u8 _rtw_mi_cancel_all_timer(_adapter *adapter, void *data)
465 {
466         rtw_cancel_all_timer(adapter);
467         return _TRUE;
468 }
469 void rtw_mi_cancel_all_timer(_adapter *adapter)
470 {
471         _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_cancel_all_timer);
472 }
473 void rtw_mi_buddy_cancel_all_timer(_adapter *adapter)
474 {
475         _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_cancel_all_timer);
476 }
477
478 static u8 _rtw_mi_reset_drv_sw(_adapter *adapter, void *data)
479 {
480         rtw_reset_drv_sw(adapter);
481         return _TRUE;
482 }
483 void rtw_mi_reset_drv_sw(_adapter *adapter)
484 {
485         _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_reset_drv_sw);
486 }
487 void rtw_mi_buddy_reset_drv_sw(_adapter *adapter)
488 {
489         _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_reset_drv_sw);
490 }
491
492 static u8 _rtw_mi_intf_start(_adapter *adapter, void *data)
493 {
494         rtw_intf_start(adapter);
495         return _TRUE;
496 }
497 void rtw_mi_intf_start(_adapter *adapter)
498 {
499         _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_intf_start);
500 }
501 void rtw_mi_buddy_intf_start(_adapter *adapter)
502 {
503         _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_intf_start);
504 }
505
506 static u8 _rtw_mi_intf_stop(_adapter *adapter, void *data)
507 {
508         rtw_intf_stop(adapter);
509         return _TRUE;
510 }
511 void rtw_mi_intf_stop(_adapter *adapter)
512 {
513         _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_intf_stop);
514 }
515 void rtw_mi_buddy_intf_stop(_adapter *adapter)
516 {
517         _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_intf_stop);
518 }
519
520 static u8 _rtw_mi_suspend_free_assoc_resource(_adapter *padapter, void *data)
521 {
522         return rtw_suspend_free_assoc_resource(padapter);
523 }
524 void rtw_mi_suspend_free_assoc_resource(_adapter *adapter)
525 {
526         _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_suspend_free_assoc_resource);
527 }
528 void rtw_mi_buddy_suspend_free_assoc_resource(_adapter *adapter)
529 {
530         _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_suspend_free_assoc_resource);
531 }
532
533 static u8 _rtw_mi_is_scan_deny(_adapter *adapter, void *data)
534 {
535         return rtw_is_scan_deny(adapter);
536 }
537
538 u8 rtw_mi_is_scan_deny(_adapter *adapter)
539 {
540         return _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_is_scan_deny);
541
542 }
543 u8 rtw_mi_buddy_is_scan_deny(_adapter *adapter)
544 {
545         return _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_is_scan_deny);
546 }
547
548 #ifdef CONFIG_SET_SCAN_DENY_TIMER
549 static u8 _rtw_mi_set_scan_deny(_adapter *adapter, void *data)
550 {
551         u32 ms = *(u32 *)data;
552
553         rtw_set_scan_deny(adapter, ms);
554         return _TRUE;
555 }
556 void rtw_mi_set_scan_deny(_adapter *adapter, u32 ms)
557 {
558         u32 in_data = ms;
559
560         _rtw_mi_process(adapter, _FALSE, &in_data, _rtw_mi_set_scan_deny);
561 }
562 void rtw_mi_buddy_set_scan_deny(_adapter *adapter, u32 ms)
563 {
564         u32 in_data = ms;
565
566         _rtw_mi_process(adapter, _TRUE, &in_data, _rtw_mi_set_scan_deny);
567 }
568 #endif
569
570 struct nulldata_param {
571         unsigned char *da;
572         unsigned int power_mode;
573         int try_cnt;
574         int wait_ms;
575 };
576
577 static u8 _rtw_mi_issue_nulldata(_adapter *padapter, void *data)
578 {
579         struct nulldata_param *pnulldata_param = (struct nulldata_param *)data;
580
581         if (is_client_associated_to_ap(padapter) == _TRUE) {
582                 /* TODO: TDLS peers */
583                 issue_nulldata(padapter, pnulldata_param->da, pnulldata_param->power_mode, pnulldata_param->try_cnt, pnulldata_param->wait_ms);
584                 return _TRUE;
585         }
586         return _FALSE;
587 }
588
589 u8 rtw_mi_issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
590 {
591         struct nulldata_param nparam;
592
593         nparam.da = da;
594         nparam.power_mode = power_mode;/*0 or 1*/
595         nparam.try_cnt = try_cnt;
596         nparam.wait_ms = wait_ms;
597
598         return _rtw_mi_process(padapter, _FALSE, &nparam, _rtw_mi_issue_nulldata);
599 }
600 u8 rtw_mi_buddy_issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
601 {
602         struct nulldata_param nparam;
603
604         nparam.da = da;
605         nparam.power_mode = power_mode;
606         nparam.try_cnt = try_cnt;
607         nparam.wait_ms = wait_ms;
608
609         return _rtw_mi_process(padapter, _TRUE, &nparam, _rtw_mi_issue_nulldata);
610 }
611
612 static u8 _rtw_mi_beacon_update(_adapter *padapter, void *data)
613 {
614         struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
615
616         if (mlmeext_msr(mlmeext) == WIFI_FW_AP_STATE
617             && check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _TRUE) {
618                 RTW_INFO(ADPT_FMT"-WIFI_FW_AP_STATE - update_beacon\n", ADPT_ARG(padapter));
619                 update_beacon(padapter, 0, NULL, _TRUE);
620         }
621         return _TRUE;
622 }
623
624 void rtw_mi_beacon_update(_adapter *padapter)
625 {
626         _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_beacon_update);
627 }
628
629 void rtw_mi_buddy_beacon_update(_adapter *padapter)
630 {
631         _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_beacon_update);
632 }
633
634 static u8 _rtw_mi_hal_dump_macaddr(_adapter *padapter, void *data)
635 {
636         u8 mac_addr[ETH_ALEN] = {0};
637
638         rtw_hal_get_macaddr_port(padapter, mac_addr);
639         RTW_INFO(ADPT_FMT"MAC Address ="MAC_FMT"\n", ADPT_ARG(padapter), MAC_ARG(mac_addr));
640         return _TRUE;
641 }
642 void rtw_mi_hal_dump_macaddr(_adapter *padapter)
643 {
644         _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_hal_dump_macaddr);
645 }
646 void rtw_mi_buddy_hal_dump_macaddr(_adapter *padapter)
647 {
648         _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_hal_dump_macaddr);
649 }
650
651 #ifdef CONFIG_PCI_HCI
652 static u8 _rtw_mi_xmit_tasklet_schedule(_adapter *padapter, void *data)
653 {
654         if (rtw_txframes_pending(padapter)) {
655                 /* try to deal with the pending packets */
656                 tasklet_hi_schedule(&(padapter->xmitpriv.xmit_tasklet));
657         }
658         return _TRUE;
659 }
660 void rtw_mi_xmit_tasklet_schedule(_adapter *padapter)
661 {
662         _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_xmit_tasklet_schedule);
663 }
664 void rtw_mi_buddy_xmit_tasklet_schedule(_adapter *padapter)
665 {
666         _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_xmit_tasklet_schedule);
667 }
668 #endif
669
670 u8 _rtw_mi_busy_traffic_check(_adapter *padapter, void *data)
671 {
672         u32 passtime;
673         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
674         bool check_sc_interval = *(bool *)data;
675
676         if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE) {
677                 if (check_sc_interval) {
678                         /* Miracast can't do AP scan*/
679                         passtime = rtw_get_passing_time_ms(pmlmepriv->lastscantime);
680                         pmlmepriv->lastscantime = rtw_get_current_time();
681                         if (passtime > BUSY_TRAFFIC_SCAN_DENY_PERIOD) {
682                                 RTW_INFO(ADPT_FMT" bBusyTraffic == _TRUE\n", ADPT_ARG(padapter));
683                                 return _TRUE;
684                         }
685                 } else
686                         return _TRUE;
687         }
688
689         return _FALSE;
690 }
691
692 u8 rtw_mi_busy_traffic_check(_adapter *padapter, bool check_sc_interval)
693 {
694         bool in_data = check_sc_interval;
695
696         return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_busy_traffic_check);
697 }
698 u8 rtw_mi_buddy_busy_traffic_check(_adapter *padapter, bool check_sc_interval)
699 {
700         bool in_data = check_sc_interval;
701
702         return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_busy_traffic_check);
703 }
704 static u8 _rtw_mi_check_mlmeinfo_state(_adapter *padapter, void *data)
705 {
706         u32 state = *(u32 *)data;
707         struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
708
709         /*if (mlmeext_msr(mlmeext) == state)*/
710         if (check_mlmeinfo_state(mlmeext, state))
711                 return _TRUE;
712         else
713                 return _FALSE;
714 }
715
716 u8 rtw_mi_check_mlmeinfo_state(_adapter *padapter, u32 state)
717 {
718         u32 in_data = state;
719
720         return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_check_mlmeinfo_state);
721 }
722
723 u8 rtw_mi_buddy_check_mlmeinfo_state(_adapter *padapter, u32 state)
724 {
725         u32 in_data = state;
726
727         return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_check_mlmeinfo_state);
728 }
729
730 /*#define DBG_DUMP_FW_STATE*/
731 #ifdef DBG_DUMP_FW_STATE
732 static void rtw_dbg_dump_fwstate(_adapter *padapter, sint state)
733 {
734         u8 buf[32] = {0};
735
736         if (state & WIFI_FW_NULL_STATE) {
737                 _rtw_memset(buf, 0, 32);
738                 sprintf(buf, "WIFI_FW_NULL_STATE");
739                 RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf);
740         }
741
742         if (state & _FW_LINKED) {
743                 _rtw_memset(buf, 0, 32);
744                 sprintf(buf, "_FW_LINKED");
745                 RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf);
746         }
747
748         if (state & _FW_UNDER_LINKING) {
749                 _rtw_memset(buf, 0, 32);
750                 sprintf(buf, "_FW_UNDER_LINKING");
751                 RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf);
752         }
753
754         if (state & _FW_UNDER_SURVEY) {
755                 _rtw_memset(buf, 0, 32);
756                 sprintf(buf, "_FW_UNDER_SURVEY");
757                 RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf);
758         }
759 }
760 #endif
761
762 static u8 _rtw_mi_check_fwstate(_adapter *padapter, void *data)
763 {
764         u8 ret = _FALSE;
765
766         sint state = *(sint *)data;
767
768         if ((state == WIFI_FW_NULL_STATE) &&
769             (padapter->mlmepriv.fw_state == WIFI_FW_NULL_STATE))
770                 ret = _TRUE;
771         else if (_TRUE == check_fwstate(&padapter->mlmepriv, state))
772                 ret = _TRUE;
773 #ifdef DBG_DUMP_FW_STATE
774         if (ret)
775                 rtw_dbg_dump_fwstate(padapter, state);
776 #endif
777         return ret;
778 }
779 u8 rtw_mi_check_fwstate(_adapter *padapter, sint state)
780 {
781         sint in_data = state;
782
783         return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_check_fwstate);
784 }
785 u8 rtw_mi_buddy_check_fwstate(_adapter *padapter, sint state)
786 {
787         sint in_data = state;
788
789         return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_check_fwstate);
790 }
791
792 static u8 _rtw_mi_traffic_statistics(_adapter *padapter , void *data)
793 {
794         struct dvobj_priv       *pdvobjpriv = adapter_to_dvobj(padapter);
795
796         /* Tx */
797         pdvobjpriv->traffic_stat.tx_bytes += padapter->xmitpriv.tx_bytes;
798         pdvobjpriv->traffic_stat.tx_pkts += padapter->xmitpriv.tx_pkts;
799         pdvobjpriv->traffic_stat.tx_drop += padapter->xmitpriv.tx_drop;
800
801         /* Rx */
802         pdvobjpriv->traffic_stat.rx_bytes += padapter->recvpriv.rx_bytes;
803         pdvobjpriv->traffic_stat.rx_pkts += padapter->recvpriv.rx_pkts;
804         pdvobjpriv->traffic_stat.rx_drop += padapter->recvpriv.rx_drop;
805         return _TRUE;
806 }
807 u8 rtw_mi_traffic_statistics(_adapter *padapter)
808 {
809         return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_traffic_statistics);
810 }
811
812 static u8 _rtw_mi_check_miracast_enabled(_adapter *padapter , void *data)
813 {
814         return is_miracast_enabled(padapter);
815 }
816 u8 rtw_mi_check_miracast_enabled(_adapter *padapter)
817 {
818         return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_check_miracast_enabled);
819 }
820
821 #ifdef CONFIG_XMIT_THREAD_MODE
822 static u8 _rtw_mi_check_pending_xmitbuf(_adapter *padapter , void *data)
823 {
824         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
825
826         return check_pending_xmitbuf(pxmitpriv);
827 }
828 u8 rtw_mi_check_pending_xmitbuf(_adapter *padapter)
829 {
830         return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_check_pending_xmitbuf);
831 }
832 u8 rtw_mi_buddy_check_pending_xmitbuf(_adapter *padapter)
833 {
834         return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_check_pending_xmitbuf);
835 }
836 #endif
837
838 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
839 static u8 _rtw_mi_dequeue_writeport(_adapter *padapter , bool exclude_self)
840 {
841         int i;
842         u8      queue_empty = _TRUE;
843         _adapter *iface;
844         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
845
846         for (i = 0; i < dvobj->iface_nums; i++) {
847                 iface = dvobj->padapters[i];
848                 if ((iface) && rtw_is_adapter_up(iface)) {
849
850                         if ((exclude_self) && (iface == padapter))
851                                 continue;
852
853                         queue_empty &= _dequeue_writeport(iface);
854                 }
855         }
856         return queue_empty;
857 }
858 u8 rtw_mi_dequeue_writeport(_adapter *padapter)
859 {
860         return _rtw_mi_dequeue_writeport(padapter, _FALSE);
861 }
862 u8 rtw_mi_buddy_dequeue_writeport(_adapter *padapter)
863 {
864         return _rtw_mi_dequeue_writeport(padapter, _TRUE);
865 }
866 #endif
867 static void _rtw_mi_adapter_reset(_adapter *padapter , u8 exclude_self)
868 {
869         int i;
870         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
871
872         for (i = 0; i < dvobj->iface_nums; i++) {
873                 if (dvobj->padapters[i]) {
874                         if ((exclude_self) && (dvobj->padapters[i] == padapter))
875                                 continue;
876                         dvobj->padapters[i] = NULL;
877                 }
878         }
879 }
880
881 void rtw_mi_adapter_reset(_adapter *padapter)
882 {
883         _rtw_mi_adapter_reset(padapter, _FALSE);
884 }
885
886 void rtw_mi_buddy_adapter_reset(_adapter *padapter)
887 {
888         _rtw_mi_adapter_reset(padapter, _TRUE);
889 }
890
891 static u8 _rtw_mi_dynamic_check_timer_handlder(_adapter *adapter, void *data)
892 {
893         rtw_iface_dynamic_check_timer_handlder(adapter);
894         return _TRUE;
895 }
896 u8 rtw_mi_dynamic_check_timer_handlder(_adapter *padapter)
897 {
898         return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_dynamic_check_timer_handlder);
899 }
900 u8 rtw_mi_buddy_dynamic_check_timer_handlder(_adapter *padapter)
901 {
902         return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_dynamic_check_timer_handlder);
903 }
904
905 static u8 _rtw_mi_dev_unload(_adapter *adapter, void *data)
906 {
907         rtw_dev_unload(adapter);
908         return _TRUE;
909 }
910 u8 rtw_mi_dev_unload(_adapter *padapter)
911 {
912         return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_dev_unload);
913 }
914 u8 rtw_mi_buddy_dev_unload(_adapter *padapter)
915 {
916         return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_dev_unload);
917 }
918
919 static u8 _rtw_mi_dynamic_chk_wk_hdl(_adapter *adapter, void *data)
920 {
921         rtw_iface_dynamic_chk_wk_hdl(adapter);
922         return _TRUE;
923 }
924 u8 rtw_mi_dynamic_chk_wk_hdl(_adapter *padapter)
925 {
926         return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_dynamic_chk_wk_hdl);
927 }
928 u8 rtw_mi_buddy_dynamic_chk_wk_hdl(_adapter *padapter)
929 {
930         return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_dynamic_chk_wk_hdl);
931 }
932
933 static u8 _rtw_mi_os_xmit_schedule(_adapter *adapter, void *data)
934 {
935         rtw_os_xmit_schedule(adapter);
936         return _TRUE;
937 }
938 u8 rtw_mi_os_xmit_schedule(_adapter *padapter)
939 {
940         return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_os_xmit_schedule);
941 }
942 u8 rtw_mi_buddy_os_xmit_schedule(_adapter *padapter)
943 {
944         return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_os_xmit_schedule);
945 }
946
947 static u8 _rtw_mi_report_survey_event(_adapter *adapter, void *data)
948 {
949         union recv_frame *precv_frame = (union recv_frame *)data;
950
951         report_survey_event(adapter, precv_frame);
952         return _TRUE;
953 }
954 u8 rtw_mi_report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
955 {
956         return _rtw_mi_process(padapter, _FALSE, precv_frame, _rtw_mi_report_survey_event);
957 }
958 u8 rtw_mi_buddy_report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
959 {
960         return _rtw_mi_process(padapter, _TRUE, precv_frame, _rtw_mi_report_survey_event);
961 }
962
963 static u8 _rtw_mi_sreset_adapter_hdl(_adapter *adapter, void *data)
964 {
965         u8 bstart = *(u8 *)data;
966
967         if (bstart)
968                 sreset_start_adapter(adapter);
969         else
970                 sreset_stop_adapter(adapter);
971         return _TRUE;
972 }
973 u8 rtw_mi_sreset_adapter_hdl(_adapter *padapter, u8 bstart)
974 {
975         u8 in_data = bstart;
976
977         return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_sreset_adapter_hdl);
978 }
979 u8 rtw_mi_buddy_sreset_adapter_hdl(_adapter *padapter, u8 bstart)
980 {
981         u8 in_data = bstart;
982
983         return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_sreset_adapter_hdl);
984 }
985 static u8 _rtw_mi_tx_beacon_hdl(_adapter *adapter, void *data)
986 {
987         if (check_fwstate(&adapter->mlmepriv, WIFI_AP_STATE) == _TRUE
988             && check_fwstate(&adapter->mlmepriv, WIFI_ASOC_STATE) == _TRUE
989            ) {
990                 adapter->mlmepriv.update_bcn = _TRUE;
991 #ifndef CONFIG_INTERRUPT_BASED_TXBCN
992 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
993                 tx_beacon_hdl(adapter, NULL);
994 #endif
995 #endif
996         }
997         return _TRUE;
998 }
999 u8 rtw_mi_tx_beacon_hdl(_adapter *padapter)
1000 {
1001         return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_tx_beacon_hdl);
1002 }
1003 u8 rtw_mi_buddy_tx_beacon_hdl(_adapter *padapter)
1004 {
1005         return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_sreset_adapter_hdl);
1006 }
1007
1008 static u8 _rtw_mi_set_tx_beacon_cmd(_adapter *adapter, void *data)
1009 {
1010         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1011
1012         if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1013                 if (pmlmepriv->update_bcn == _TRUE)
1014                         set_tx_beacon_cmd(adapter);
1015         }
1016         return _TRUE;
1017 }
1018 u8 rtw_mi_set_tx_beacon_cmd(_adapter *padapter)
1019 {
1020         return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_set_tx_beacon_cmd);
1021 }
1022 u8 rtw_mi_buddy_set_tx_beacon_cmd(_adapter *padapter)
1023 {
1024         return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_set_tx_beacon_cmd);
1025 }
1026
1027 #ifdef CONFIG_P2P
1028 static u8 _rtw_mi_p2p_chk_state(_adapter *adapter, void *data)
1029 {
1030         struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
1031         enum P2P_STATE state = *(enum P2P_STATE *)data;
1032
1033         return rtw_p2p_chk_state(pwdinfo, state);
1034 }
1035 u8 rtw_mi_p2p_chk_state(_adapter *padapter, enum P2P_STATE p2p_state)
1036 {
1037         u8 in_data = p2p_state;
1038
1039         return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_p2p_chk_state);
1040 }
1041 u8 rtw_mi_buddy_p2p_chk_state(_adapter *padapter, enum P2P_STATE p2p_state)
1042 {
1043         u8 in_data  = p2p_state;
1044
1045         return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_p2p_chk_state);
1046 }
1047 static u8 _rtw_mi_stay_in_p2p_mode(_adapter *adapter, void *data)
1048 {
1049         struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
1050
1051         if (rtw_p2p_role(pwdinfo) != P2P_ROLE_DISABLE)
1052                 return _TRUE;
1053         return _FALSE;
1054 }
1055 u8 rtw_mi_stay_in_p2p_mode(_adapter *padapter)
1056 {
1057         return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_stay_in_p2p_mode);
1058 }
1059 u8 rtw_mi_buddy_stay_in_p2p_mode(_adapter *padapter)
1060 {
1061         return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_stay_in_p2p_mode);
1062 }
1063 #endif /*CONFIG_P2P*/
1064
1065 _adapter *rtw_get_iface_by_id(_adapter *padapter, u8 iface_id)
1066 {
1067         _adapter *iface = NULL;
1068         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1069
1070         if ((padapter == NULL) || (iface_id >= CONFIG_IFACE_NUMBER)) {
1071                 rtw_warn_on(1);
1072                 return iface;
1073         }
1074
1075         return  dvobj->padapters[iface_id];
1076 }
1077
1078 _adapter *rtw_get_iface_by_macddr(_adapter *padapter, u8 *mac_addr)
1079 {
1080         int i;
1081         _adapter *iface = NULL;
1082         u8 bmatch = _FALSE;
1083         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1084
1085         for (i = 0; i < dvobj->iface_nums; i++) {
1086                 iface = dvobj->padapters[i];
1087                 if ((iface) && (_rtw_memcmp(mac_addr, adapter_mac_addr(iface), ETH_ALEN))) {
1088                         bmatch = _TRUE;
1089                         break;
1090                 }
1091         }
1092         if (bmatch)
1093                 return iface;
1094         else
1095                 return NULL;
1096 }
1097
1098 _adapter *rtw_get_iface_by_hwport(_adapter *padapter, u8 hw_port)
1099 {
1100         int i;
1101         _adapter *iface = NULL;
1102         u8 bmatch = _FALSE;
1103         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1104
1105         for (i = 0; i < dvobj->iface_nums; i++) {
1106                 iface = dvobj->padapters[i];
1107                 if ((iface) && (hw_port == iface->hw_port)) {
1108                         bmatch = _TRUE;
1109                         break;
1110                 }
1111         }
1112         if (bmatch)
1113                 return iface;
1114         else
1115                 return NULL;
1116 }
1117
1118 /*#define CONFIG_SKB_ALLOCATED*/
1119 #define DBG_SKB_PROCESS
1120 #ifdef DBG_SKB_PROCESS
1121 void rtw_dbg_skb_process(_adapter *padapter, union recv_frame *precvframe, union recv_frame *pcloneframe)
1122 {
1123         _pkt *pkt_copy, *pkt_org;
1124
1125         pkt_org = precvframe->u.hdr.pkt;
1126         pkt_copy = pcloneframe->u.hdr.pkt;
1127         /*
1128                 RTW_INFO("%s ===== ORG SKB =====\n", __func__);
1129                 RTW_INFO(" SKB head(%p)\n", pkt_org->head);
1130                 RTW_INFO(" SKB data(%p)\n", pkt_org->data);
1131                 RTW_INFO(" SKB tail(%p)\n", pkt_org->tail);
1132                 RTW_INFO(" SKB end(%p)\n", pkt_org->end);
1133
1134                 RTW_INFO(" recv frame head(%p)\n", precvframe->u.hdr.rx_head);
1135                 RTW_INFO(" recv frame data(%p)\n", precvframe->u.hdr.rx_data);
1136                 RTW_INFO(" recv frame tail(%p)\n", precvframe->u.hdr.rx_tail);
1137                 RTW_INFO(" recv frame end(%p)\n", precvframe->u.hdr.rx_end);
1138
1139                 RTW_INFO("%s ===== COPY SKB =====\n", __func__);
1140                 RTW_INFO(" SKB head(%p)\n", pkt_copy->head);
1141                 RTW_INFO(" SKB data(%p)\n", pkt_copy->data);
1142                 RTW_INFO(" SKB tail(%p)\n", pkt_copy->tail);
1143                 RTW_INFO(" SKB end(%p)\n", pkt_copy->end);
1144
1145                 RTW_INFO(" recv frame head(%p)\n", pcloneframe->u.hdr.rx_head);
1146                 RTW_INFO(" recv frame data(%p)\n", pcloneframe->u.hdr.rx_data);
1147                 RTW_INFO(" recv frame tail(%p)\n", pcloneframe->u.hdr.rx_tail);
1148                 RTW_INFO(" recv frame end(%p)\n", pcloneframe->u.hdr.rx_end);
1149         */
1150         /*
1151                 RTW_INFO("%s => recv_frame adapter(%p,%p)\n", __func__, precvframe->u.hdr.adapter, pcloneframe->u.hdr.adapter);
1152                 RTW_INFO("%s => recv_frame dev(%p,%p)\n", __func__, pkt_org->dev , pkt_copy->dev);
1153                 RTW_INFO("%s => recv_frame len(%d,%d)\n", __func__, precvframe->u.hdr.len, pcloneframe->u.hdr.len);
1154         */
1155         if (precvframe->u.hdr.len != pcloneframe->u.hdr.len)
1156                 RTW_INFO("%s [WARN]  recv_frame length(%d:%d) compare failed\n", __func__, precvframe->u.hdr.len, pcloneframe->u.hdr.len);
1157
1158         if (_rtw_memcmp(&precvframe->u.hdr.attrib, &pcloneframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib)) == _FALSE)
1159                 RTW_INFO("%s [WARN]  recv_frame attrib compare failed\n", __func__);
1160
1161         if (_rtw_memcmp(precvframe->u.hdr.rx_data, pcloneframe->u.hdr.rx_data, precvframe->u.hdr.len) == _FALSE)
1162                 RTW_INFO("%s [WARN]  recv_frame rx_data compare failed\n", __func__);
1163
1164 }
1165 #endif
1166
1167 static s32 _rtw_mi_buddy_clone_bcmc_packet(_adapter *adapter, union recv_frame *precvframe, u8 *pphy_status, union recv_frame *pcloneframe)
1168 {
1169         s32 ret = _SUCCESS;
1170         u8 *pbuf = precvframe->u.hdr.rx_data;
1171         struct rx_pkt_attrib *pattrib = NULL;
1172         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(adapter);
1173
1174         if (pcloneframe) {
1175                 pcloneframe->u.hdr.adapter = adapter;
1176
1177                 _rtw_init_listhead(&pcloneframe->u.hdr.list);
1178                 pcloneframe->u.hdr.precvbuf = NULL;     /*can't access the precvbuf for new arch.*/
1179                 pcloneframe->u.hdr.len = 0;
1180
1181                 _rtw_memcpy(&pcloneframe->u.hdr.attrib, &precvframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib));
1182
1183                 pattrib = &pcloneframe->u.hdr.attrib;
1184 #ifdef CONFIG_SKB_ALLOCATED
1185                 if (rtw_os_alloc_recvframe(adapter, pcloneframe, pbuf, NULL) == _SUCCESS)
1186 #else
1187                 if (rtw_os_recvframe_duplicate_skb(adapter, pcloneframe, precvframe->u.hdr.pkt) == _SUCCESS)
1188 #endif
1189                 {
1190 #ifdef CONFIG_SKB_ALLOCATED
1191                         recvframe_put(pcloneframe, pattrib->pkt_len);
1192 #endif
1193
1194 #ifdef DBG_SKB_PROCESS
1195                         rtw_dbg_skb_process(adapter, precvframe, pcloneframe);
1196 #endif
1197
1198                         if (pattrib->physt && pphy_status)
1199                                 rx_query_phy_status(pcloneframe, pphy_status);
1200
1201                         ret = rtw_recv_entry(pcloneframe);
1202                 } else {
1203                         ret = -1;
1204                         RTW_INFO("%s()-%d: rtw_os_alloc_recvframe() failed!\n", __func__, __LINE__);
1205                 }
1206
1207         }
1208         return ret;
1209 }
1210
1211 void rtw_mi_buddy_clone_bcmc_packet(_adapter *padapter, union recv_frame *precvframe, u8 *pphy_status)
1212 {
1213         int i;
1214         s32 ret = _SUCCESS;
1215         _adapter *iface = NULL;
1216         union recv_frame *pcloneframe = NULL;
1217         struct recv_priv *precvpriv = &padapter->recvpriv;/*primary_padapter*/
1218         _queue *pfree_recv_queue = &precvpriv->free_recv_queue;
1219         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1220
1221         for (i = 0; i < dvobj->iface_nums; i++) {
1222                 iface = dvobj->padapters[i];
1223                 if (!iface || iface == padapter)
1224                         continue;
1225                 if (rtw_is_adapter_up(iface) == _FALSE || iface->registered == 0)
1226                         continue;
1227
1228                 pcloneframe = rtw_alloc_recvframe(pfree_recv_queue);
1229                 if (pcloneframe) {
1230                         ret = _rtw_mi_buddy_clone_bcmc_packet(iface, precvframe, pphy_status, pcloneframe);
1231                         if (_SUCCESS != ret) {
1232                                 if (ret == -1)
1233                                         rtw_free_recvframe(pcloneframe, pfree_recv_queue);
1234                                 /*RTW_INFO(ADPT_FMT"-clone BC/MC frame failed\n", ADPT_ARG(iface));*/
1235                         }
1236                 }
1237         }
1238
1239 }
1240
1241 #ifdef CONFIG_PCI_HCI
1242 /*API be created temporary for MI, caller is interrupt-handler, PCIE's interrupt handler cannot apply to multi-AP*/
1243 _adapter *rtw_mi_get_ap_adapter(_adapter *padapter)
1244 {
1245         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1246         int i;
1247         _adapter *iface = NULL;
1248
1249         for (i = 0; i < dvobj->iface_nums; i++) {
1250                 iface = dvobj->padapters[i];
1251                 if (!iface)
1252                         continue;
1253
1254                 if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE
1255                     && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE)
1256                         break;
1257
1258         }
1259         return iface;
1260 }
1261 #endif
1262
1263 void rtw_mi_update_ap_bmc_camid(_adapter *padapter, u8 camid_a, u8 camid_b)
1264 {
1265 #ifdef CONFIG_CONCURRENT_MODE
1266         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
1267         struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
1268
1269         int i;
1270         _adapter *iface = NULL;
1271
1272         for (i = 0; i < dvobj->iface_nums; i++) {
1273                 iface = dvobj->padapters[i];
1274                 if (!iface)
1275                         continue;
1276
1277                 if (macid_ctl->iface_bmc[iface->iface_id] != INVALID_SEC_MAC_CAM_ID) {
1278                         if (macid_ctl->iface_bmc[iface->iface_id] == camid_a)
1279                                 macid_ctl->iface_bmc[iface->iface_id] = camid_b;
1280                         else if (macid_ctl->iface_bmc[iface->iface_id] == camid_b)
1281                                 macid_ctl->iface_bmc[iface->iface_id] = camid_a;
1282                         iface->securitypriv.dot118021x_bmc_cam_id  = macid_ctl->iface_bmc[iface->iface_id];
1283                 }
1284         }
1285 #endif
1286 }