Path: blob/master/ALFA-W1F1/RTL8814AU/core/rtw_mi.c
1307 views
/******************************************************************************1*2* Copyright(c) 2007 - 2017 Realtek Corporation.3*4* This program is free software; you can redistribute it and/or modify it5* under the terms of version 2 of the GNU General Public License as6* published by the Free Software Foundation.7*8* This program is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for11* more details.12*13*****************************************************************************/14#define _RTW_MI_C_1516#include <drv_types.h>17#include <hal_data.h>1819void rtw_mi_update_union_chan_inf(_adapter *adapter, u8 ch, u8 offset , u8 bw)20{21struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);22struct mi_state *iface_state = &dvobj->iface_state;2324iface_state->union_ch = ch;25iface_state->union_bw = bw;26iface_state->union_offset = offset;27}2829#ifdef DBG_IFACE_STATUS30#ifdef CONFIG_P2P31static u8 _rtw_mi_p2p_listen_scan_chk(_adapter *adapter)32{33int i;34_adapter *iface;35struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);36u8 p2p_listen_scan_state = _FALSE;3738for (i = 0; i < dvobj->iface_nums; i++) {39iface = dvobj->padapters[i];40if (rtw_p2p_chk_state(&iface->wdinfo, P2P_STATE_LISTEN) ||41rtw_p2p_chk_state(&iface->wdinfo, P2P_STATE_SCAN)) {42p2p_listen_scan_state = _TRUE;43break;44}45}46return p2p_listen_scan_state;47}48#endif49#endif5051u8 rtw_mi_stayin_union_ch_chk(_adapter *adapter)52{53u8 rst = _TRUE;54u8 u_ch, u_bw, u_offset;55u8 o_ch, o_bw, o_offset;5657u_ch = rtw_mi_get_union_chan(adapter);58u_bw = rtw_mi_get_union_bw(adapter);59u_offset = rtw_mi_get_union_offset(adapter);6061o_ch = rtw_get_oper_ch(adapter);62o_bw = rtw_get_oper_bw(adapter);63o_offset = rtw_get_oper_choffset(adapter);6465if ((u_ch != o_ch) || (u_bw != o_bw) || (u_offset != o_offset))66rst = _FALSE;6768#ifdef DBG_IFACE_STATUS69if (rst == _FALSE) {70RTW_ERR("%s Not stay in union channel\n", __func__);71if (GET_HAL_DATA(adapter)->bScanInProcess == _TRUE)72RTW_ERR("ScanInProcess\n");73#ifdef CONFIG_P2P74if (_rtw_mi_p2p_listen_scan_chk(adapter))75RTW_ERR("P2P in listen or scan state\n");76#endif77RTW_ERR("union ch, bw, offset: %u,%u,%u\n", u_ch, u_bw, u_offset);78RTW_ERR("oper ch, bw, offset: %u,%u,%u\n", o_ch, o_bw, o_offset);79RTW_ERR("=========================\n");80}81#endif82return rst;83}8485u8 rtw_mi_stayin_union_band_chk(_adapter *adapter)86{87u8 rst = _TRUE;88u8 u_ch, o_ch;89u8 u_band, o_band;9091u_ch = rtw_mi_get_union_chan(adapter);92o_ch = rtw_get_oper_ch(adapter);93u_band = (u_ch > 14) ? BAND_ON_5G : BAND_ON_2_4G;94o_band = (o_ch > 14) ? BAND_ON_5G : BAND_ON_2_4G;9596if (u_ch != o_ch)97if(u_band != o_band)98rst = _FALSE;99100#ifdef DBG_IFACE_STATUS101if (rst == _FALSE)102RTW_ERR("%s Not stay in union band\n", __func__);103#endif104105return rst;106}107108/* Find union about ch, bw, ch_offset of all linked/linking interfaces */109int rtw_mi_get_ch_setting_union_by_ifbmp(struct dvobj_priv *dvobj, u8 ifbmp, u8 *ch, u8 *bw, u8 *offset)110{111_adapter *iface;112struct mlme_ext_priv *mlmeext;113int i;114u8 ch_ret = 0;115u8 bw_ret = CHANNEL_WIDTH_20;116u8 offset_ret = HAL_PRIME_CHNL_OFFSET_DONT_CARE;117int num = 0;118119if (ch)120*ch = 0;121if (bw)122*bw = CHANNEL_WIDTH_20;123if (offset)124*offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;125126for (i = 0; i < dvobj->iface_nums; i++) {127iface = dvobj->padapters[i];128if (!iface || !(ifbmp & BIT(iface->iface_id)))129continue;130131mlmeext = &iface->mlmeextpriv;132133if (!check_fwstate(&iface->mlmepriv, _FW_LINKED | _FW_UNDER_LINKING))134continue;135136if (check_fwstate(&iface->mlmepriv, WIFI_OP_CH_SWITCHING))137continue;138139if (num == 0) {140ch_ret = mlmeext->cur_channel;141bw_ret = mlmeext->cur_bwmode;142offset_ret = mlmeext->cur_ch_offset;143num++;144continue;145}146147if (ch_ret != mlmeext->cur_channel) {148num = 0;149break;150}151152if (bw_ret < mlmeext->cur_bwmode) {153bw_ret = mlmeext->cur_bwmode;154offset_ret = mlmeext->cur_ch_offset;155} else if (bw_ret == mlmeext->cur_bwmode && offset_ret != mlmeext->cur_ch_offset) {156num = 0;157break;158}159160num++;161}162163if (num) {164if (ch)165*ch = ch_ret;166if (bw)167*bw = bw_ret;168if (offset)169*offset = offset_ret;170}171172return num;173}174175inline int rtw_mi_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)176{177return rtw_mi_get_ch_setting_union_by_ifbmp(adapter_to_dvobj(adapter), 0xFF, ch, bw, offset);178}179180inline int rtw_mi_get_ch_setting_union_no_self(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)181{182return rtw_mi_get_ch_setting_union_by_ifbmp(adapter_to_dvobj(adapter), 0xFF & ~BIT(adapter->iface_id), ch, bw, offset);183}184185/* For now, not return union_ch/bw/offset */186void rtw_mi_status_by_ifbmp(struct dvobj_priv *dvobj, u8 ifbmp, struct mi_state *mstate)187{188_adapter *iface;189int i;190191_rtw_memset(mstate, 0, sizeof(struct mi_state));192193for (i = 0; i < dvobj->iface_nums; i++) {194iface = dvobj->padapters[i];195if (!iface || !(ifbmp & BIT(iface->iface_id)))196continue;197198if (check_fwstate(&iface->mlmepriv, WIFI_STATION_STATE) == _TRUE) {199MSTATE_STA_NUM(mstate)++;200if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE) {201MSTATE_STA_LD_NUM(mstate)++;202203#ifdef CONFIG_TDLS204if (iface->tdlsinfo.link_established == _TRUE)205MSTATE_TDLS_LD_NUM(mstate)++;206#endif207#ifdef CONFIG_P2P208if (MLME_IS_GC(iface))209MSTATE_P2P_GC_NUM(mstate)++;210#endif211}212if (check_fwstate(&iface->mlmepriv, _FW_UNDER_LINKING) == _TRUE)213MSTATE_STA_LG_NUM(mstate)++;214215#ifdef CONFIG_AP_MODE216} else if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE ) {217if (check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE) {218MSTATE_AP_NUM(mstate)++;219if (iface->stapriv.asoc_sta_count > 2)220MSTATE_AP_LD_NUM(mstate)++;221#ifdef CONFIG_P2P222if (MLME_IS_GO(iface))223MSTATE_P2P_GO_NUM(mstate)++;224#endif225} else226MSTATE_AP_STARTING_NUM(mstate)++;227#endif228229} else if (check_fwstate(&iface->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE) == _TRUE230&& check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE231) {232MSTATE_ADHOC_NUM(mstate)++;233if (iface->stapriv.asoc_sta_count > 2)234MSTATE_ADHOC_LD_NUM(mstate)++;235236#ifdef CONFIG_RTW_MESH237} else if (check_fwstate(&iface->mlmepriv, WIFI_MESH_STATE) == _TRUE238&& check_fwstate(&iface->mlmepriv, _FW_LINKED) == _TRUE239) {240MSTATE_MESH_NUM(mstate)++;241if (iface->stapriv.asoc_sta_count > 2)242MSTATE_MESH_LD_NUM(mstate)++;243#endif244245}246247if (check_fwstate(&iface->mlmepriv, WIFI_UNDER_WPS) == _TRUE)248MSTATE_WPS_NUM(mstate)++;249250if (check_fwstate(&iface->mlmepriv, WIFI_SITE_MONITOR) == _TRUE) {251MSTATE_SCAN_NUM(mstate)++;252253if (mlmeext_scan_state(&iface->mlmeextpriv) != SCAN_DISABLE254&& mlmeext_scan_state(&iface->mlmeextpriv) != SCAN_BACK_OP)255MSTATE_SCAN_ENTER_NUM(mstate)++;256}257258#ifdef CONFIG_IOCTL_CFG80211259if (rtw_cfg80211_get_is_mgmt_tx(iface))260MSTATE_MGMT_TX_NUM(mstate)++;261#ifdef CONFIG_P2P262if (rtw_cfg80211_get_is_roch(iface) == _TRUE)263MSTATE_ROCH_NUM(mstate)++;264#endif265#endif /* CONFIG_IOCTL_CFG80211 */266#ifdef CONFIG_P2P267if (MLME_IS_PD(iface))268MSTATE_P2P_DV_NUM(mstate)++;269#endif270}271}272273inline void rtw_mi_status(_adapter *adapter, struct mi_state *mstate)274{275return rtw_mi_status_by_ifbmp(adapter_to_dvobj(adapter), 0xFF, mstate);276}277278inline void rtw_mi_status_no_self(_adapter *adapter, struct mi_state *mstate)279{280return rtw_mi_status_by_ifbmp(adapter_to_dvobj(adapter), 0xFF & ~BIT(adapter->iface_id), mstate);281}282283inline void rtw_mi_status_no_others(_adapter *adapter, struct mi_state *mstate)284{285return rtw_mi_status_by_ifbmp(adapter_to_dvobj(adapter), BIT(adapter->iface_id), mstate);286}287288/* For now, not handle union_ch/bw/offset */289inline void rtw_mi_status_merge(struct mi_state *d, struct mi_state *a)290{291d->sta_num += a->sta_num;292d->ld_sta_num += a->ld_sta_num;293d->lg_sta_num += a->lg_sta_num;294#ifdef CONFIG_TDLS295d->ld_tdls_num += a->ld_tdls_num;296#endif297#ifdef CONFIG_AP_MODE298d->ap_num += a->ap_num;299d->ld_ap_num += a->ld_ap_num;300#endif301d->adhoc_num += a->adhoc_num;302d->ld_adhoc_num += a->ld_adhoc_num;303#ifdef CONFIG_RTW_MESH304d->mesh_num += a->mesh_num;305d->ld_mesh_num += a->ld_mesh_num;306#endif307d->scan_num += a->scan_num;308d->scan_enter_num += a->scan_enter_num;309d->uwps_num += a->uwps_num;310#ifdef CONFIG_IOCTL_CFG80211311#ifdef CONFIG_P2P312d->roch_num += a->roch_num;313#endif314d->mgmt_tx_num += a->mgmt_tx_num;315#endif316}317318void dump_mi_status(void *sel, struct dvobj_priv *dvobj)319{320RTW_PRINT_SEL(sel, "== dvobj-iface_state ==\n");321RTW_PRINT_SEL(sel, "sta_num:%d\n", DEV_STA_NUM(dvobj));322RTW_PRINT_SEL(sel, "linking_sta_num:%d\n", DEV_STA_LG_NUM(dvobj));323RTW_PRINT_SEL(sel, "linked_sta_num:%d\n", DEV_STA_LD_NUM(dvobj));324#ifdef CONFIG_TDLS325RTW_PRINT_SEL(sel, "linked_tdls_num:%d\n", DEV_TDLS_LD_NUM(dvobj));326#endif327#ifdef CONFIG_AP_MODE328RTW_PRINT_SEL(sel, "ap_num:%d\n", DEV_AP_NUM(dvobj));329RTW_PRINT_SEL(sel, "starting_ap_num:%d\n", DEV_AP_STARTING_NUM(dvobj));330RTW_PRINT_SEL(sel, "linked_ap_num:%d\n", DEV_AP_LD_NUM(dvobj));331#endif332RTW_PRINT_SEL(sel, "adhoc_num:%d\n", DEV_ADHOC_NUM(dvobj));333RTW_PRINT_SEL(sel, "linked_adhoc_num:%d\n", DEV_ADHOC_LD_NUM(dvobj));334#ifdef CONFIG_RTW_MESH335RTW_PRINT_SEL(sel, "mesh_num:%d\n", DEV_MESH_NUM(dvobj));336RTW_PRINT_SEL(sel, "linked_mesh_num:%d\n", DEV_MESH_LD_NUM(dvobj));337#endif338#ifdef CONFIG_P2P339RTW_PRINT_SEL(sel, "p2p_device_num:%d\n", DEV_P2P_DV_NUM(dvobj));340RTW_PRINT_SEL(sel, "p2p_gc_num:%d\n", DEV_P2P_GC_NUM(dvobj));341RTW_PRINT_SEL(sel, "p2p_go_num:%d\n", DEV_P2P_GO_NUM(dvobj));342#endif343RTW_PRINT_SEL(sel, "scan_num:%d\n", DEV_SCAN_NUM(dvobj));344RTW_PRINT_SEL(sel, "under_wps_num:%d\n", DEV_WPS_NUM(dvobj));345#if defined(CONFIG_IOCTL_CFG80211)346#if defined(CONFIG_P2P)347RTW_PRINT_SEL(sel, "roch_num:%d\n", DEV_ROCH_NUM(dvobj));348#endif349RTW_PRINT_SEL(sel, "mgmt_tx_num:%d\n", DEV_MGMT_TX_NUM(dvobj));350#endif351RTW_PRINT_SEL(sel, "union_ch:%d\n", DEV_U_CH(dvobj));352RTW_PRINT_SEL(sel, "union_bw:%d\n", DEV_U_BW(dvobj));353RTW_PRINT_SEL(sel, "union_offset:%d\n", DEV_U_OFFSET(dvobj));354RTW_PRINT_SEL(sel, "================\n\n");355}356357void dump_dvobj_mi_status(void *sel, const char *fun_name, _adapter *adapter)358{359RTW_INFO("\n[ %s ] call %s\n", fun_name, __func__);360dump_mi_status(sel, adapter_to_dvobj(adapter));361}362363inline void rtw_mi_update_iface_status(struct mlme_priv *pmlmepriv, sint state)364{365_adapter *adapter = container_of(pmlmepriv, _adapter, mlmepriv);366struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);367struct mi_state *iface_state = &dvobj->iface_state;368struct mi_state tmp_mstate;369u8 u_ch, u_offset, u_bw;370371if (state == WIFI_MONITOR_STATE372|| state == 0xFFFFFFFF373)374return;375376if (0)377RTW_INFO("%s => will change or clean state to 0x%08x\n", __func__, state);378379rtw_mi_status(adapter, &tmp_mstate);380_rtw_memcpy(iface_state, &tmp_mstate, sizeof(struct mi_state));381382if (rtw_mi_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset))383rtw_mi_update_union_chan_inf(adapter , u_ch, u_offset , u_bw);384else {385if (0) {386dump_adapters_status(RTW_DBGDUMP , dvobj);387RTW_INFO("%s-[ERROR] cannot get union channel\n", __func__);388rtw_warn_on(1);389}390}391392#ifdef DBG_IFACE_STATUS393DBG_IFACE_STATUS_DUMP(adapter);394#endif395}396u8 rtw_mi_check_status(_adapter *adapter, u8 type)397{398struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);399struct mi_state *iface_state = &dvobj->iface_state;400u8 ret = _FALSE;401402#ifdef DBG_IFACE_STATUS403DBG_IFACE_STATUS_DUMP(adapter);404RTW_INFO("%s-"ADPT_FMT" check type:%d\n", __func__, ADPT_ARG(adapter), type);405#endif406407switch (type) {408case MI_LINKED:409if (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, _FW_LINKED)*/410ret = _TRUE;411break;412case MI_ASSOC:413if (MSTATE_STA_LD_NUM(iface_state) || MSTATE_AP_LD_NUM(iface_state) || MSTATE_ADHOC_LD_NUM(iface_state) || MSTATE_MESH_LD_NUM(iface_state))414ret = _TRUE;415break;416case MI_UNDER_WPS:417if (MSTATE_WPS_NUM(iface_state))418ret = _TRUE;419break;420421case MI_AP_MODE:422if (MSTATE_AP_NUM(iface_state))423ret = _TRUE;424break;425case MI_AP_ASSOC:426if (MSTATE_AP_LD_NUM(iface_state))427ret = _TRUE;428break;429430case MI_ADHOC:431if (MSTATE_ADHOC_NUM(iface_state))432ret = _TRUE;433break;434case MI_ADHOC_ASSOC:435if (MSTATE_ADHOC_LD_NUM(iface_state))436ret = _TRUE;437break;438439#ifdef CONFIG_RTW_MESH440case MI_MESH:441if (MSTATE_MESH_NUM(iface_state))442ret = _TRUE;443break;444case MI_MESH_ASSOC:445if (MSTATE_MESH_LD_NUM(iface_state))446ret = _TRUE;447break;448#endif449450case MI_STA_NOLINK: /* this is misleading, but not used now */451if (MSTATE_STA_NUM(iface_state) && (!(MSTATE_STA_LD_NUM(iface_state) || MSTATE_STA_LG_NUM(iface_state))))452ret = _TRUE;453break;454case MI_STA_LINKED:455if (MSTATE_STA_LD_NUM(iface_state))456ret = _TRUE;457break;458case MI_STA_LINKING:459if (MSTATE_STA_LG_NUM(iface_state))460ret = _TRUE;461break;462463default:464break;465}466return ret;467}468469/*470* return value : 0 is failed or have not interface meet condition471* return value : !0 is success or interface numbers which meet condition472* return value of ops_func must be _TRUE or _FALSE473*/474static u8 _rtw_mi_process(_adapter *padapter, bool exclude_self,475void *data, u8(*ops_func)(_adapter *padapter, void *data))476{477int i;478_adapter *iface;479struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);480481u8 ret = 0;482483for (i = 0; i < dvobj->iface_nums; i++) {484iface = dvobj->padapters[i];485if ((iface) && rtw_is_adapter_up(iface)) {486487if ((exclude_self) && (iface == padapter))488continue;489490if (ops_func)491if (_TRUE == ops_func(iface, data))492ret++;493}494}495return ret;496}497static u8 _rtw_mi_process_without_schk(_adapter *padapter, bool exclude_self,498void *data, u8(*ops_func)(_adapter *padapter, void *data))499{500int i;501_adapter *iface;502struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);503504u8 ret = 0;505506for (i = 0; i < dvobj->iface_nums; i++) {507iface = dvobj->padapters[i];508if (iface) {509if ((exclude_self) && (iface == padapter))510continue;511512if (ops_func)513if (ops_func(iface, data) == _TRUE)514ret++;515}516}517return ret;518}519520static u8 _rtw_mi_netif_caroff_qstop(_adapter *padapter, void *data)521{522struct net_device *pnetdev = padapter->pnetdev;523524rtw_netif_carrier_off(pnetdev);525rtw_netif_stop_queue(pnetdev);526return _TRUE;527}528u8 rtw_mi_netif_caroff_qstop(_adapter *padapter)529{530return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_caroff_qstop);531}532u8 rtw_mi_buddy_netif_caroff_qstop(_adapter *padapter)533{534return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_caroff_qstop);535}536537static u8 _rtw_mi_netif_caron_qstart(_adapter *padapter, void *data)538{539struct net_device *pnetdev = padapter->pnetdev;540541rtw_netif_carrier_on(pnetdev);542rtw_netif_start_queue(pnetdev);543return _TRUE;544}545u8 rtw_mi_netif_caron_qstart(_adapter *padapter)546{547return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_caron_qstart);548}549u8 rtw_mi_buddy_netif_caron_qstart(_adapter *padapter)550{551return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_caron_qstart);552}553554static u8 _rtw_mi_netif_stop_queue(_adapter *padapter, void *data)555{556struct net_device *pnetdev = padapter->pnetdev;557558rtw_netif_stop_queue(pnetdev);559return _TRUE;560}561u8 rtw_mi_netif_stop_queue(_adapter *padapter)562{563return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_stop_queue);564}565u8 rtw_mi_buddy_netif_stop_queue(_adapter *padapter)566{567return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_stop_queue);568}569570static u8 _rtw_mi_netif_wake_queue(_adapter *padapter, void *data)571{572struct net_device *pnetdev = padapter->pnetdev;573574if (pnetdev)575rtw_netif_wake_queue(pnetdev);576return _TRUE;577}578u8 rtw_mi_netif_wake_queue(_adapter *padapter)579{580return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_wake_queue);581}582u8 rtw_mi_buddy_netif_wake_queue(_adapter *padapter)583{584return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_wake_queue);585}586587static u8 _rtw_mi_netif_carrier_on(_adapter *padapter, void *data)588{589struct net_device *pnetdev = padapter->pnetdev;590591if (pnetdev)592rtw_netif_carrier_on(pnetdev);593return _TRUE;594}595u8 rtw_mi_netif_carrier_on(_adapter *padapter)596{597return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_carrier_on);598}599u8 rtw_mi_buddy_netif_carrier_on(_adapter *padapter)600{601return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_carrier_on);602}603604static u8 _rtw_mi_netif_carrier_off(_adapter *padapter, void *data)605{606struct net_device *pnetdev = padapter->pnetdev;607608if (pnetdev)609rtw_netif_carrier_off(pnetdev);610return _TRUE;611}612u8 rtw_mi_netif_carrier_off(_adapter *padapter)613{614return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_netif_carrier_off);615}616u8 rtw_mi_buddy_netif_carrier_off(_adapter *padapter)617{618return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_netif_carrier_off);619}620621static u8 _rtw_mi_scan_abort(_adapter *adapter, void *data)622{623bool bwait = *(bool *)data;624625if (bwait)626rtw_scan_abort(adapter);627else628rtw_scan_abort_no_wait(adapter);629630return _TRUE;631}632void rtw_mi_scan_abort(_adapter *adapter, bool bwait)633{634bool in_data = bwait;635636_rtw_mi_process(adapter, _FALSE, &in_data, _rtw_mi_scan_abort);637638}639void rtw_mi_buddy_scan_abort(_adapter *adapter, bool bwait)640{641bool in_data = bwait;642643_rtw_mi_process(adapter, _TRUE, &in_data, _rtw_mi_scan_abort);644}645646static u32 _rtw_mi_start_drv_threads(_adapter *adapter, bool exclude_self)647{648int i;649_adapter *iface = NULL;650struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);651u32 _status = _SUCCESS;652653for (i = 0; i < dvobj->iface_nums; i++) {654iface = dvobj->padapters[i];655if (iface) {656if ((exclude_self) && (iface == adapter))657continue;658if (rtw_start_drv_threads(iface) == _FAIL) {659_status = _FAIL;660break;661}662}663}664return _status;665}666u32 rtw_mi_start_drv_threads(_adapter *adapter)667{668return _rtw_mi_start_drv_threads(adapter, _FALSE);669}670u32 rtw_mi_buddy_start_drv_threads(_adapter *adapter)671{672return _rtw_mi_start_drv_threads(adapter, _TRUE);673}674675static void _rtw_mi_stop_drv_threads(_adapter *adapter, bool exclude_self)676{677int i;678_adapter *iface = NULL;679struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);680681for (i = 0; i < dvobj->iface_nums; i++) {682iface = dvobj->padapters[i];683if (iface) {684if ((exclude_self) && (iface == adapter))685continue;686rtw_stop_drv_threads(iface);687}688}689}690void rtw_mi_stop_drv_threads(_adapter *adapter)691{692_rtw_mi_stop_drv_threads(adapter, _FALSE);693}694void rtw_mi_buddy_stop_drv_threads(_adapter *adapter)695{696_rtw_mi_stop_drv_threads(adapter, _TRUE);697}698699static u8 _rtw_mi_cancel_all_timer(_adapter *adapter, void *data)700{701rtw_cancel_all_timer(adapter);702return _TRUE;703}704void rtw_mi_cancel_all_timer(_adapter *adapter)705{706_rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_cancel_all_timer);707}708void rtw_mi_buddy_cancel_all_timer(_adapter *adapter)709{710_rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_cancel_all_timer);711}712713static u8 _rtw_mi_reset_drv_sw(_adapter *adapter, void *data)714{715rtw_reset_drv_sw(adapter);716return _TRUE;717}718void rtw_mi_reset_drv_sw(_adapter *adapter)719{720_rtw_mi_process_without_schk(adapter, _FALSE, NULL, _rtw_mi_reset_drv_sw);721}722void rtw_mi_buddy_reset_drv_sw(_adapter *adapter)723{724_rtw_mi_process_without_schk(adapter, _TRUE, NULL, _rtw_mi_reset_drv_sw);725}726727static u8 _rtw_mi_intf_start(_adapter *adapter, void *data)728{729rtw_intf_start(adapter);730return _TRUE;731}732void rtw_mi_intf_start(_adapter *adapter)733{734_rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_intf_start);735}736void rtw_mi_buddy_intf_start(_adapter *adapter)737{738_rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_intf_start);739}740741static u8 _rtw_mi_intf_stop(_adapter *adapter, void *data)742{743rtw_intf_stop(adapter);744return _TRUE;745}746void rtw_mi_intf_stop(_adapter *adapter)747{748_rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_intf_stop);749}750void rtw_mi_buddy_intf_stop(_adapter *adapter)751{752_rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_intf_stop);753}754755#ifdef CONFIG_NEW_NETDEV_HDL756u8 rtw_mi_hal_iface_init(_adapter *padapter)757{758int i;759_adapter *iface;760struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);761762u8 ret = _TRUE;763764for (i = 0; i < dvobj->iface_nums; i++) {765iface = dvobj->padapters[i];766if (iface && iface->netif_up)767rtw_hal_iface_init(padapter);768}769return ret;770}771#endif772773static u8 _rtw_mi_suspend_free_assoc_resource(_adapter *padapter, void *data)774{775return rtw_suspend_free_assoc_resource(padapter);776}777void rtw_mi_suspend_free_assoc_resource(_adapter *adapter)778{779_rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_suspend_free_assoc_resource);780}781void rtw_mi_buddy_suspend_free_assoc_resource(_adapter *adapter)782{783_rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_suspend_free_assoc_resource);784}785786static u8 _rtw_mi_is_scan_deny(_adapter *adapter, void *data)787{788return rtw_is_scan_deny(adapter);789}790791u8 rtw_mi_is_scan_deny(_adapter *adapter)792{793return _rtw_mi_process(adapter, _FALSE, NULL, _rtw_mi_is_scan_deny);794795}796u8 rtw_mi_buddy_is_scan_deny(_adapter *adapter)797{798return _rtw_mi_process(adapter, _TRUE, NULL, _rtw_mi_is_scan_deny);799}800801#ifdef CONFIG_SET_SCAN_DENY_TIMER802static u8 _rtw_mi_set_scan_deny(_adapter *adapter, void *data)803{804u32 ms = *(u32 *)data;805806rtw_set_scan_deny(adapter, ms);807return _TRUE;808}809void rtw_mi_set_scan_deny(_adapter *adapter, u32 ms)810{811u32 in_data = ms;812813_rtw_mi_process(adapter, _FALSE, &in_data, _rtw_mi_set_scan_deny);814}815void rtw_mi_buddy_set_scan_deny(_adapter *adapter, u32 ms)816{817u32 in_data = ms;818819_rtw_mi_process(adapter, _TRUE, &in_data, _rtw_mi_set_scan_deny);820}821#endif /*CONFIG_SET_SCAN_DENY_TIMER*/822823static u8 _rtw_mi_beacon_update(_adapter *padapter, void *data)824{825if (!MLME_IS_STA(padapter)826&& check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _TRUE) {827RTW_INFO(ADPT_FMT" - update_beacon\n", ADPT_ARG(padapter));828update_beacon(padapter, 0xFF, NULL, _TRUE, 0);829}830return _TRUE;831}832833void rtw_mi_beacon_update(_adapter *padapter)834{835_rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_beacon_update);836}837838void rtw_mi_buddy_beacon_update(_adapter *padapter)839{840_rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_beacon_update);841}842843static u8 _rtw_mi_hal_dump_macaddr(_adapter *padapter, void *data)844{845u8 mac_addr[ETH_ALEN] = {0};846847rtw_hal_get_hwreg(padapter, HW_VAR_MAC_ADDR, mac_addr);848RTW_INFO(ADPT_FMT"MAC Address ="MAC_FMT"\n", ADPT_ARG(padapter), MAC_ARG(mac_addr));849return _TRUE;850}851void rtw_mi_hal_dump_macaddr(_adapter *padapter)852{853_rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_hal_dump_macaddr);854}855void rtw_mi_buddy_hal_dump_macaddr(_adapter *padapter)856{857_rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_hal_dump_macaddr);858}859860#ifdef CONFIG_PCI_HCI861static u8 _rtw_mi_xmit_tasklet_schedule(_adapter *padapter, void *data)862{863if (rtw_txframes_pending(padapter)) {864/* try to deal with the pending packets */865tasklet_hi_schedule(&(padapter->xmitpriv.xmit_tasklet));866}867return _TRUE;868}869void rtw_mi_xmit_tasklet_schedule(_adapter *padapter)870{871_rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_xmit_tasklet_schedule);872}873void rtw_mi_buddy_xmit_tasklet_schedule(_adapter *padapter)874{875_rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_xmit_tasklet_schedule);876}877#endif878879u8 _rtw_mi_busy_traffic_check(_adapter *padapter, void *data)880{881u32 passtime;882struct mlme_priv *pmlmepriv = &padapter->mlmepriv;883bool check_sc_interval = *(bool *)data;884885if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE) {886if (check_sc_interval) {887/* Miracast can't do AP scan*/888passtime = rtw_get_passing_time_ms(pmlmepriv->lastscantime);889if (passtime > BUSY_TRAFFIC_SCAN_DENY_PERIOD) {890RTW_INFO(ADPT_FMT" bBusyTraffic == _TRUE\n", ADPT_ARG(padapter));891return _TRUE;892}893} else894return _TRUE;895}896897return _FALSE;898}899900u8 rtw_mi_busy_traffic_check(_adapter *padapter, bool check_sc_interval)901{902bool in_data = check_sc_interval;903904return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_busy_traffic_check);905}906u8 rtw_mi_buddy_busy_traffic_check(_adapter *padapter, bool check_sc_interval)907{908bool in_data = check_sc_interval;909910return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_busy_traffic_check);911}912static u8 _rtw_mi_check_mlmeinfo_state(_adapter *padapter, void *data)913{914u32 state = *(u32 *)data;915struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;916917/*if (mlmeext_msr(mlmeext) == state)*/918if (check_mlmeinfo_state(mlmeext, state))919return _TRUE;920else921return _FALSE;922}923924u8 rtw_mi_check_mlmeinfo_state(_adapter *padapter, u32 state)925{926u32 in_data = state;927928return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_check_mlmeinfo_state);929}930931u8 rtw_mi_buddy_check_mlmeinfo_state(_adapter *padapter, u32 state)932{933u32 in_data = state;934935return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_check_mlmeinfo_state);936}937938/*#define DBG_DUMP_FW_STATE*/939#ifdef DBG_DUMP_FW_STATE940static void rtw_dbg_dump_fwstate(_adapter *padapter, sint state)941{942u8 buf[32] = {0};943944if (state & WIFI_FW_NULL_STATE) {945_rtw_memset(buf, 0, 32);946sprintf(buf, "WIFI_FW_NULL_STATE");947RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf);948}949950if (state & _FW_LINKED) {951_rtw_memset(buf, 0, 32);952sprintf(buf, "_FW_LINKED");953RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf);954}955956if (state & _FW_UNDER_LINKING) {957_rtw_memset(buf, 0, 32);958sprintf(buf, "_FW_UNDER_LINKING");959RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf);960}961962if (state & _FW_UNDER_SURVEY) {963_rtw_memset(buf, 0, 32);964sprintf(buf, "_FW_UNDER_SURVEY");965RTW_INFO(FUNC_ADPT_FMT"fwstate-%s\n", FUNC_ADPT_ARG(padapter), buf);966}967}968#endif969970static u8 _rtw_mi_check_fwstate(_adapter *padapter, void *data)971{972u8 ret = _FALSE;973974sint state = *(sint *)data;975976if ((state == WIFI_FW_NULL_STATE) &&977(padapter->mlmepriv.fw_state == WIFI_FW_NULL_STATE))978ret = _TRUE;979else if (_TRUE == check_fwstate(&padapter->mlmepriv, state))980ret = _TRUE;981#ifdef DBG_DUMP_FW_STATE982if (ret)983rtw_dbg_dump_fwstate(padapter, state);984#endif985return ret;986}987u8 rtw_mi_check_fwstate(_adapter *padapter, sint state)988{989sint in_data = state;990991return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_check_fwstate);992}993u8 rtw_mi_buddy_check_fwstate(_adapter *padapter, sint state)994{995sint in_data = state;996997return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_check_fwstate);998}9991000static u8 _rtw_mi_traffic_statistics(_adapter *padapter , void *data)1001{1002struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);10031004/* Tx */1005pdvobjpriv->traffic_stat.tx_bytes += padapter->xmitpriv.tx_bytes;1006pdvobjpriv->traffic_stat.tx_pkts += padapter->xmitpriv.tx_pkts;1007pdvobjpriv->traffic_stat.tx_drop += padapter->xmitpriv.tx_drop;10081009/* Rx */1010pdvobjpriv->traffic_stat.rx_bytes += padapter->recvpriv.rx_bytes;1011pdvobjpriv->traffic_stat.rx_pkts += padapter->recvpriv.rx_pkts;1012pdvobjpriv->traffic_stat.rx_drop += padapter->recvpriv.rx_drop;1013return _TRUE;1014}1015u8 rtw_mi_traffic_statistics(_adapter *padapter)1016{1017return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_traffic_statistics);1018}10191020static u8 _rtw_mi_check_miracast_enabled(_adapter *padapter , void *data)1021{1022return is_miracast_enabled(padapter);1023}1024u8 rtw_mi_check_miracast_enabled(_adapter *padapter)1025{1026return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_check_miracast_enabled);1027}10281029#ifdef CONFIG_XMIT_THREAD_MODE1030static u8 _rtw_mi_check_pending_xmitbuf(_adapter *padapter , void *data)1031{1032struct xmit_priv *pxmitpriv = &padapter->xmitpriv;10331034return check_pending_xmitbuf(pxmitpriv);1035}1036u8 rtw_mi_check_pending_xmitbuf(_adapter *padapter)1037{1038return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_check_pending_xmitbuf);1039}1040u8 rtw_mi_buddy_check_pending_xmitbuf(_adapter *padapter)1041{1042return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_check_pending_xmitbuf);1043}1044#endif10451046#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)1047static u8 _rtw_mi_dequeue_writeport(_adapter *padapter , bool exclude_self)1048{1049int i;1050u8 queue_empty = _TRUE;1051_adapter *iface;1052struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);10531054for (i = 0; i < dvobj->iface_nums; i++) {1055iface = dvobj->padapters[i];1056if ((iface) && rtw_is_adapter_up(iface)) {10571058if ((exclude_self) && (iface == padapter))1059continue;10601061queue_empty &= _dequeue_writeport(iface);1062}1063}1064return queue_empty;1065}1066u8 rtw_mi_dequeue_writeport(_adapter *padapter)1067{1068return _rtw_mi_dequeue_writeport(padapter, _FALSE);1069}1070u8 rtw_mi_buddy_dequeue_writeport(_adapter *padapter)1071{1072return _rtw_mi_dequeue_writeport(padapter, _TRUE);1073}1074#endif1075static void _rtw_mi_adapter_reset(_adapter *padapter , u8 exclude_self)1076{1077int i;1078struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);10791080for (i = 0; i < dvobj->iface_nums; i++) {1081if (dvobj->padapters[i]) {1082if ((exclude_self) && (dvobj->padapters[i] == padapter))1083continue;1084dvobj->padapters[i] = NULL;1085}1086}1087}10881089void rtw_mi_adapter_reset(_adapter *padapter)1090{1091_rtw_mi_adapter_reset(padapter, _FALSE);1092}10931094void rtw_mi_buddy_adapter_reset(_adapter *padapter)1095{1096_rtw_mi_adapter_reset(padapter, _TRUE);1097}10981099static u8 _rtw_mi_dynamic_check_timer_handlder(_adapter *adapter, void *data)1100{1101rtw_iface_dynamic_check_timer_handlder(adapter);1102return _TRUE;1103}1104u8 rtw_mi_dynamic_check_timer_handlder(_adapter *padapter)1105{1106return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_dynamic_check_timer_handlder);1107}1108u8 rtw_mi_buddy_dynamic_check_timer_handlder(_adapter *padapter)1109{1110return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_dynamic_check_timer_handlder);1111}11121113static u8 _rtw_mi_dynamic_chk_wk_hdl(_adapter *adapter, void *data)1114{1115rtw_iface_dynamic_chk_wk_hdl(adapter);1116return _TRUE;1117}1118u8 rtw_mi_dynamic_chk_wk_hdl(_adapter *padapter)1119{1120return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_dynamic_chk_wk_hdl);1121}1122u8 rtw_mi_buddy_dynamic_chk_wk_hdl(_adapter *padapter)1123{1124return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_dynamic_chk_wk_hdl);1125}11261127static u8 _rtw_mi_os_xmit_schedule(_adapter *adapter, void *data)1128{1129rtw_os_xmit_schedule(adapter);1130return _TRUE;1131}1132u8 rtw_mi_os_xmit_schedule(_adapter *padapter)1133{1134return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_os_xmit_schedule);1135}1136u8 rtw_mi_buddy_os_xmit_schedule(_adapter *padapter)1137{1138return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_os_xmit_schedule);1139}11401141static u8 _rtw_mi_report_survey_event(_adapter *adapter, void *data)1142{1143union recv_frame *precv_frame = (union recv_frame *)data;11441145report_survey_event(adapter, precv_frame);1146return _TRUE;1147}1148u8 rtw_mi_report_survey_event(_adapter *padapter, union recv_frame *precv_frame)1149{1150return _rtw_mi_process(padapter, _FALSE, precv_frame, _rtw_mi_report_survey_event);1151}1152u8 rtw_mi_buddy_report_survey_event(_adapter *padapter, union recv_frame *precv_frame)1153{1154return _rtw_mi_process(padapter, _TRUE, precv_frame, _rtw_mi_report_survey_event);1155}11561157static u8 _rtw_mi_sreset_adapter_hdl(_adapter *adapter, void *data)1158{1159u8 bstart = *(u8 *)data;11601161if (bstart)1162sreset_start_adapter(adapter);1163else1164sreset_stop_adapter(adapter);1165return _TRUE;1166}1167u8 rtw_mi_sreset_adapter_hdl(_adapter *padapter, u8 bstart)1168{1169u8 in_data = bstart;11701171return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_sreset_adapter_hdl);1172}11731174#if defined(DBG_CONFIG_ERROR_RESET) && defined(CONFIG_CONCURRENT_MODE)1175void rtw_mi_ap_info_restore(_adapter *adapter)1176{1177int i;1178_adapter *iface;1179struct mlme_priv *pmlmepriv;1180struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);11811182for (i = 0; i < dvobj->iface_nums; i++) {1183iface = dvobj->padapters[i];1184if (iface) {1185pmlmepriv = &iface->mlmepriv;11861187if (MLME_IS_AP(iface) || MLME_IS_MESH(iface)) {1188RTW_INFO(FUNC_ADPT_FMT" %s\n", FUNC_ADPT_ARG(iface), MLME_IS_AP(iface) ? "AP" : "MESH");1189rtw_iface_bcmc_sec_cam_map_restore(iface);1190}1191}1192}1193}1194#endif /*#if defined(DBG_CONFIG_ERROR_RESET) && defined(CONFIG_CONCURRENT_MODE)*/11951196u8 rtw_mi_buddy_sreset_adapter_hdl(_adapter *padapter, u8 bstart)1197{1198u8 in_data = bstart;11991200return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_sreset_adapter_hdl);1201}1202static u8 _rtw_mi_tx_beacon_hdl(_adapter *adapter, void *data)1203{1204if ((MLME_IS_AP(adapter) || MLME_IS_MESH(adapter))1205&& check_fwstate(&adapter->mlmepriv, WIFI_ASOC_STATE) == _TRUE1206) {1207adapter->mlmepriv.update_bcn = _TRUE;1208#ifndef CONFIG_INTERRUPT_BASED_TXBCN1209#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) || defined(CONFIG_PCI_BCN_POLLING)1210tx_beacon_hdl(adapter, NULL);1211#endif1212#endif1213}1214return _TRUE;1215}1216u8 rtw_mi_tx_beacon_hdl(_adapter *padapter)1217{1218return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_tx_beacon_hdl);1219}1220u8 rtw_mi_buddy_tx_beacon_hdl(_adapter *padapter)1221{1222return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_sreset_adapter_hdl);1223}12241225static u8 _rtw_mi_set_tx_beacon_cmd(_adapter *adapter, void *data)1226{1227struct mlme_priv *pmlmepriv = &adapter->mlmepriv;12281229if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {1230if (pmlmepriv->update_bcn == _TRUE)1231set_tx_beacon_cmd(adapter, 0);1232}1233return _TRUE;1234}1235u8 rtw_mi_set_tx_beacon_cmd(_adapter *padapter)1236{1237return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_set_tx_beacon_cmd);1238}1239u8 rtw_mi_buddy_set_tx_beacon_cmd(_adapter *padapter)1240{1241return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_set_tx_beacon_cmd);1242}12431244#ifdef CONFIG_P2P1245static u8 _rtw_mi_p2p_chk_state(_adapter *adapter, void *data)1246{1247struct wifidirect_info *pwdinfo = &(adapter->wdinfo);1248enum P2P_STATE state = *(enum P2P_STATE *)data;12491250return rtw_p2p_chk_state(pwdinfo, state);1251}1252u8 rtw_mi_p2p_chk_state(_adapter *padapter, enum P2P_STATE p2p_state)1253{1254u8 in_data = p2p_state;12551256return _rtw_mi_process(padapter, _FALSE, &in_data, _rtw_mi_p2p_chk_state);1257}1258u8 rtw_mi_buddy_p2p_chk_state(_adapter *padapter, enum P2P_STATE p2p_state)1259{1260u8 in_data = p2p_state;12611262return _rtw_mi_process(padapter, _TRUE, &in_data, _rtw_mi_p2p_chk_state);1263}1264static u8 _rtw_mi_stay_in_p2p_mode(_adapter *adapter, void *data)1265{1266struct wifidirect_info *pwdinfo = &(adapter->wdinfo);12671268if (rtw_p2p_role(pwdinfo) != P2P_ROLE_DISABLE)1269return _TRUE;1270return _FALSE;1271}1272u8 rtw_mi_stay_in_p2p_mode(_adapter *padapter)1273{1274return _rtw_mi_process(padapter, _FALSE, NULL, _rtw_mi_stay_in_p2p_mode);1275}1276u8 rtw_mi_buddy_stay_in_p2p_mode(_adapter *padapter)1277{1278return _rtw_mi_process(padapter, _TRUE, NULL, _rtw_mi_stay_in_p2p_mode);1279}1280#endif /*CONFIG_P2P*/12811282_adapter *rtw_get_iface_by_id(_adapter *padapter, u8 iface_id)1283{1284_adapter *iface = NULL;1285struct dvobj_priv *dvobj;12861287if ((padapter == NULL) || (iface_id >= CONFIG_IFACE_NUMBER)) {1288rtw_warn_on(1);1289return iface;1290}12911292dvobj = adapter_to_dvobj(padapter);1293return dvobj->padapters[iface_id];1294}12951296_adapter *rtw_get_iface_by_macddr(_adapter *padapter, const u8 *mac_addr)1297{1298int i;1299_adapter *iface = NULL;1300u8 bmatch = _FALSE;1301struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);13021303for (i = 0; i < dvobj->iface_nums; i++) {1304iface = dvobj->padapters[i];1305if ((iface) && (_rtw_memcmp(mac_addr, adapter_mac_addr(iface), ETH_ALEN))) {1306bmatch = _TRUE;1307break;1308}1309}1310if (bmatch)1311return iface;1312else1313return NULL;1314}13151316_adapter *rtw_get_iface_by_hwport(_adapter *padapter, u8 hw_port)1317{1318int i;1319_adapter *iface = NULL;1320u8 bmatch = _FALSE;1321struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);13221323for (i = 0; i < dvobj->iface_nums; i++) {1324iface = dvobj->padapters[i];1325if ((iface) && (hw_port == iface->hw_port)) {1326bmatch = _TRUE;1327break;1328}1329}1330if (bmatch)1331return iface;1332else1333return NULL;1334}13351336/*#define CONFIG_SKB_ALLOCATED*/1337#define DBG_SKB_PROCESS1338#ifdef DBG_SKB_PROCESS1339void rtw_dbg_skb_process(_adapter *padapter, union recv_frame *precvframe, union recv_frame *pcloneframe)1340{1341_pkt *pkt_copy, *pkt_org;13421343pkt_org = precvframe->u.hdr.pkt;1344pkt_copy = pcloneframe->u.hdr.pkt;1345/*1346RTW_INFO("%s ===== ORG SKB =====\n", __func__);1347RTW_INFO(" SKB head(%p)\n", pkt_org->head);1348RTW_INFO(" SKB data(%p)\n", pkt_org->data);1349RTW_INFO(" SKB tail(%p)\n", pkt_org->tail);1350RTW_INFO(" SKB end(%p)\n", pkt_org->end);13511352RTW_INFO(" recv frame head(%p)\n", precvframe->u.hdr.rx_head);1353RTW_INFO(" recv frame data(%p)\n", precvframe->u.hdr.rx_data);1354RTW_INFO(" recv frame tail(%p)\n", precvframe->u.hdr.rx_tail);1355RTW_INFO(" recv frame end(%p)\n", precvframe->u.hdr.rx_end);13561357RTW_INFO("%s ===== COPY SKB =====\n", __func__);1358RTW_INFO(" SKB head(%p)\n", pkt_copy->head);1359RTW_INFO(" SKB data(%p)\n", pkt_copy->data);1360RTW_INFO(" SKB tail(%p)\n", pkt_copy->tail);1361RTW_INFO(" SKB end(%p)\n", pkt_copy->end);13621363RTW_INFO(" recv frame head(%p)\n", pcloneframe->u.hdr.rx_head);1364RTW_INFO(" recv frame data(%p)\n", pcloneframe->u.hdr.rx_data);1365RTW_INFO(" recv frame tail(%p)\n", pcloneframe->u.hdr.rx_tail);1366RTW_INFO(" recv frame end(%p)\n", pcloneframe->u.hdr.rx_end);1367*/1368/*1369RTW_INFO("%s => recv_frame adapter(%p,%p)\n", __func__, precvframe->u.hdr.adapter, pcloneframe->u.hdr.adapter);1370RTW_INFO("%s => recv_frame dev(%p,%p)\n", __func__, pkt_org->dev , pkt_copy->dev);1371RTW_INFO("%s => recv_frame len(%d,%d)\n", __func__, precvframe->u.hdr.len, pcloneframe->u.hdr.len);1372*/1373if (precvframe->u.hdr.len != pcloneframe->u.hdr.len)1374RTW_INFO("%s [WARN] recv_frame length(%d:%d) compare failed\n", __func__, precvframe->u.hdr.len, pcloneframe->u.hdr.len);13751376if (_rtw_memcmp(&precvframe->u.hdr.attrib, &pcloneframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib)) == _FALSE)1377RTW_INFO("%s [WARN] recv_frame attrib compare failed\n", __func__);13781379if (_rtw_memcmp(precvframe->u.hdr.rx_data, pcloneframe->u.hdr.rx_data, precvframe->u.hdr.len) == _FALSE)1380RTW_INFO("%s [WARN] recv_frame rx_data compare failed\n", __func__);13811382}1383#endif13841385static s32 _rtw_mi_buddy_clone_bcmc_packet(_adapter *adapter, union recv_frame *precvframe, u8 *pphy_status, union recv_frame *pcloneframe)1386{1387s32 ret = _SUCCESS;1388#ifdef CONFIG_SKB_ALLOCATED1389u8 *pbuf = precvframe->u.hdr.rx_data;1390#endif1391struct rx_pkt_attrib *pattrib = NULL;13921393if (pcloneframe) {1394pcloneframe->u.hdr.adapter = adapter;13951396_rtw_init_listhead(&pcloneframe->u.hdr.list);1397pcloneframe->u.hdr.precvbuf = NULL; /*can't access the precvbuf for new arch.*/1398pcloneframe->u.hdr.len = 0;13991400_rtw_memcpy(&pcloneframe->u.hdr.attrib, &precvframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib));14011402pattrib = &pcloneframe->u.hdr.attrib;1403#ifdef CONFIG_SKB_ALLOCATED1404if (rtw_os_alloc_recvframe(adapter, pcloneframe, pbuf, NULL) == _SUCCESS)1405#else1406if (rtw_os_recvframe_duplicate_skb(adapter, pcloneframe, precvframe->u.hdr.pkt) == _SUCCESS)1407#endif1408{1409#ifdef CONFIG_SKB_ALLOCATED1410recvframe_put(pcloneframe, pattrib->pkt_len);1411#endif14121413#ifdef DBG_SKB_PROCESS1414rtw_dbg_skb_process(adapter, precvframe, pcloneframe);1415#endif14161417if (pphy_status)1418rx_query_phy_status(pcloneframe, pphy_status);14191420ret = rtw_recv_entry(pcloneframe);1421} else {1422ret = -1;1423RTW_INFO("%s()-%d: rtw_os_alloc_recvframe() failed!\n", __func__, __LINE__);1424}14251426}1427return ret;1428}14291430void rtw_mi_buddy_clone_bcmc_packet(_adapter *padapter, union recv_frame *precvframe, u8 *pphy_status)1431{1432int i;1433s32 ret = _SUCCESS;1434_adapter *iface = NULL;1435union recv_frame *pcloneframe = NULL;1436struct recv_priv *precvpriv = &padapter->recvpriv;/*primary_padapter*/1437_queue *pfree_recv_queue = &precvpriv->free_recv_queue;1438struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);1439u8 *fhead = get_recvframe_data(precvframe);1440u8 type = GetFrameType(fhead);14411442for (i = 0; i < dvobj->iface_nums; i++) {1443iface = dvobj->padapters[i];1444if (!iface || iface == padapter)1445continue;1446if (rtw_is_adapter_up(iface) == _FALSE || iface->registered == 0)1447continue;1448if (type == WIFI_DATA_TYPE && !adapter_allow_bmc_data_rx(iface))1449continue;14501451pcloneframe = rtw_alloc_recvframe(pfree_recv_queue);1452if (pcloneframe) {1453ret = _rtw_mi_buddy_clone_bcmc_packet(iface, precvframe, pphy_status, pcloneframe);1454if (_SUCCESS != ret) {1455if (ret == -1)1456rtw_free_recvframe(pcloneframe, pfree_recv_queue);1457/*RTW_INFO(ADPT_FMT"-clone BC/MC frame failed\n", ADPT_ARG(iface));*/1458}1459}1460}14611462}14631464#ifdef CONFIG_PCI_HCI1465/*API be created temporary for MI, caller is interrupt-handler, PCIE's interrupt handler cannot apply to multi-AP*/1466_adapter *rtw_mi_get_ap_adapter(_adapter *padapter)1467{1468struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);1469int i;1470_adapter *iface = NULL;14711472for (i = 0; i < dvobj->iface_nums; i++) {1473iface = dvobj->padapters[i];1474if (!iface)1475continue;14761477if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE1478&& check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE)1479break;14801481}1482return iface;1483}1484#endif14851486u8 rtw_mi_get_ld_sta_ifbmp(_adapter *adapter)1487{1488struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);1489int i;1490_adapter *iface = NULL;1491u8 ifbmp = 0;14921493for (i = 0; i < dvobj->iface_nums; i++) {1494iface = dvobj->padapters[i];1495if (!iface)1496continue;14971498if (MLME_IS_STA(iface) && MLME_IS_ASOC(iface))1499ifbmp |= BIT(i);1500}15011502return ifbmp;1503}15041505u8 rtw_mi_get_ap_mesh_ifbmp(_adapter *adapter)1506{1507struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);1508int i;1509_adapter *iface = NULL;1510u8 ifbmp = 0;15111512for (i = 0; i < dvobj->iface_nums; i++) {1513iface = dvobj->padapters[i];1514if (!iface)1515continue;15161517if (CHK_MLME_STATE(iface, WIFI_AP_STATE | WIFI_MESH_STATE)1518&& MLME_IS_ASOC(iface))1519ifbmp |= BIT(i);1520}15211522return ifbmp;1523}15241525void rtw_mi_update_ap_bmc_camid(_adapter *padapter, u8 camid_a, u8 camid_b)1526{1527#ifdef CONFIG_CONCURRENT_MODE1528struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);1529struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);15301531int i;1532_adapter *iface = NULL;15331534for (i = 0; i < dvobj->iface_nums; i++) {1535iface = dvobj->padapters[i];1536if (!iface)1537continue;15381539if (macid_ctl->iface_bmc[iface->iface_id] != INVALID_SEC_MAC_CAM_ID) {1540if (macid_ctl->iface_bmc[iface->iface_id] == camid_a)1541macid_ctl->iface_bmc[iface->iface_id] = camid_b;1542else if (macid_ctl->iface_bmc[iface->iface_id] == camid_b)1543macid_ctl->iface_bmc[iface->iface_id] = camid_a;1544iface->securitypriv.dot118021x_bmc_cam_id = macid_ctl->iface_bmc[iface->iface_id];1545}1546}1547#endif1548}15491550u8 rtw_mi_get_assoc_if_num(_adapter *adapter)1551{1552struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);1553u8 n_assoc_iface = 0;1554#if 11555u8 i;15561557for (i = 0; i < dvobj->iface_nums; i++) {1558if (check_fwstate(&(dvobj->padapters[i]->mlmepriv), WIFI_ASOC_STATE))1559n_assoc_iface++;1560}1561#else1562n_assoc_iface = DEV_STA_LD_NUM(dvobj) + DEV_AP_NUM(dvobj) + DEV_ADHOC_NUM(dvobj) + DEV_MESH_NUM(dvobj);1563#endif1564return n_assoc_iface;1565}156615671568