Path: blob/master/ALFA-W1F1/RTL8814AU/core/rtw_rson.c
1307 views
/******************************************************************************1*2* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.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* You should have received a copy of the GNU General Public License along with14* this program; if not, write to the Free Software Foundation, Inc.,15* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA16*17*18******************************************************************************/19#define _RTW_RSON_C_2021#include <drv_types.h>2223#ifdef CONFIG_RTW_REPEATER_SON2425/******** Custommize Part ***********************/2627unsigned char RTW_RSON_OUI[] = {0xFA, 0xFA, 0xFA};28#define RSON_SCORE_DIFF_TH 82930/*31Calculate the corresponding score.32*/33inline u8 rtw_cal_rson_score(struct rtw_rson_struct *cand_rson_data, NDIS_802_11_RSSI Rssi)34{35if ((cand_rson_data->hopcnt == RTW_RSON_HC_NOTREADY)36|| (cand_rson_data->connectible == RTW_RSON_DENYCONNECT))37return RTW_RSON_SCORE_NOTCNNT;3839return RTW_RSON_SCORE_MAX - (cand_rson_data->hopcnt * 10) + (Rssi/10);40}4142/*************************************************/434445static u8 rtw_rson_block_bssid_idx = 0;46u8 rtw_rson_block_bssid[10][6] = {47/*{0x02, 0xE0, 0x4C, 0x07, 0xC3, 0xF6}*/48};4950/* fake root, regard a real AP as a SO root */51static u8 rtw_rson_root_bssid_idx = 0;52u8 rtw_rson_root_bssid[10][6] = {53/*{0x1c, 0x5f, 0x2b, 0x5a, 0x60, 0x24}*/54};5556int is_match_bssid(u8 *mac, u8 bssid_array[][6], int num)57{58int i;5960for (i = 0; i < num; i++)61if (_rtw_memcmp(mac, bssid_array[i], 6) == _TRUE)62return _TRUE;63return _FALSE;64}6566void init_rtw_rson_data(struct dvobj_priv *dvobj)67{68/*Aries todo. if pdvobj->rson_data.ver == 1 */69dvobj->rson_data.ver = RTW_RSON_VER;70dvobj->rson_data.id = CONFIG_RTW_REPEATER_SON_ID;71#ifdef CONFIG_RTW_REPEATER_SON_ROOT72dvobj->rson_data.hopcnt = RTW_RSON_HC_ROOT;73dvobj->rson_data.connectible = RTW_RSON_ALLOWCONNECT;74#else75dvobj->rson_data.hopcnt = RTW_RSON_HC_NOTREADY;76dvobj->rson_data.connectible = RTW_RSON_DENYCONNECT;77#endif78dvobj->rson_data.loading = 0;79_rtw_memset(dvobj->rson_data.res, 0xAA, sizeof(dvobj->rson_data.res));80}8182void rtw_rson_get_property_str(_adapter *padapter, char *rson_data_str)83{84struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);8586sprintf(rson_data_str, "version : \t%d\nid : \t\t%08x\nhop count : \t%d\nconnectible : \t%s\nloading : \t%d\nreserve : \t%16ph\n",87pdvobj->rson_data.ver,88pdvobj->rson_data.id,89pdvobj->rson_data.hopcnt,90pdvobj->rson_data.connectible ? "connectable":"unconnectable",91pdvobj->rson_data.loading,92pdvobj->rson_data.res);93}9495int str2hexbuf(char *str, u8 *hexbuf, int len)96{97u8 *p;98int i, slen, idx = 0;99100p = (unsigned char *)str;101if ((*p != '0') || (*(p+1) != 'x'))102return _FALSE;103slen = strlen(str);104if (slen > (len*2) + 2)105return _FALSE;106p += 2;107for (i = 0 ; i < len; i++, idx = idx+2) {108hexbuf[i] = key_2char2num(p[idx], p[idx + 1]);109if (slen <= idx+2)110break;111}112return _TRUE;113}114115int rtw_rson_set_property(_adapter *padapter, char *field, char *value)116{117struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);118int num = 0;119120if (_rtw_memcmp(field, (u8 *)"ver", 3) == _TRUE)121pdvobj->rson_data.ver = rtw_atoi(value);122else if (_rtw_memcmp(field, (u8 *)"id", 2) == _TRUE)123num = sscanf(value, "%08x", &(pdvobj->rson_data.id));124else if (_rtw_memcmp(field, (u8 *)"hc", 2) == _TRUE)125num = sscanf(value, "%hhu", &(pdvobj->rson_data.hopcnt));126else if (_rtw_memcmp(field, (u8 *)"cnt", 3) == _TRUE)127num = sscanf(value, "%hhu", &(pdvobj->rson_data.connectible));128else if (_rtw_memcmp(field, (u8 *)"loading", 2) == _TRUE)129num = sscanf(value, "%hhu", &(pdvobj->rson_data.loading));130else if (_rtw_memcmp(field, (u8 *)"res", 2) == _TRUE) {131str2hexbuf(value, pdvobj->rson_data.res, 16);132return 1;133} else134return _FALSE;135return num;136}137138/*139return : TRUE -- competitor is taking advantage than condidate140FALSE -- we should continue keeping candidate141*/142int rtw_rson_choose(struct wlan_network **candidate, struct wlan_network *competitor)143{144s16 comp_score = 0, cand_score = 0;145struct rtw_rson_struct rson_cand, rson_comp;146147if (is_match_bssid(competitor->network.MacAddress, rtw_rson_block_bssid, rtw_rson_block_bssid_idx) == _TRUE)148return _FALSE;149150if ((competitor == NULL)151|| (rtw_get_rson_struct(&(competitor->network), &rson_comp) != _TRUE)152|| (rson_comp.id != CONFIG_RTW_REPEATER_SON_ID))153return _FALSE;154155comp_score = rtw_cal_rson_score(&rson_comp, competitor->network.Rssi);156if (comp_score == RTW_RSON_SCORE_NOTCNNT)157return _FALSE;158159if (*candidate == NULL)160return _TRUE;161if (rtw_get_rson_struct(&((*candidate)->network), &rson_cand) != _TRUE)162return _FALSE;163164cand_score = rtw_cal_rson_score(&rson_cand, (*candidate)->network.Rssi);165RTW_INFO("%s: competitor_score=%d, candidate_score=%d\n", __func__, comp_score, cand_score);166if (comp_score - cand_score > RSON_SCORE_DIFF_TH)167return _TRUE;168169return _FALSE;170}171172inline u8 rtw_rson_varify_ie(u8 *p)173{174u8 *ptr = NULL;175u8 ver;176u32 id;177u8 hopcnt;178u8 allcnnt;179180ptr = p + 2 + sizeof(RTW_RSON_OUI);181ver = *ptr;182183/* for (ver == 1) */184if (ver != 1)185return _FALSE;186187return _TRUE;188}189190/*191Parsing RTK self-organization vendor IE192*/193int rtw_get_rson_struct(WLAN_BSSID_EX *bssid, struct rtw_rson_struct *rson_data)194{195sint limit = 0;196u32 len;197u8 *p;198199if ((rson_data == NULL) || (bssid == NULL))200return -EINVAL;201202/* Default */203rson_data->id = 0;204rson_data->ver = 0;205rson_data->hopcnt = 0;206rson_data->connectible = 0;207rson_data->loading = 0;208/* fake root */209if (is_match_bssid(bssid->MacAddress, rtw_rson_root_bssid, rtw_rson_root_bssid_idx) == _TRUE) {210rson_data->id = CONFIG_RTW_REPEATER_SON_ID;211rson_data->ver = RTW_RSON_VER;212rson_data->hopcnt = RTW_RSON_HC_ROOT;213rson_data->connectible = RTW_RSON_ALLOWCONNECT;214rson_data->loading = 0;215return _TRUE;216}217limit = bssid->IELength - _BEACON_IE_OFFSET_;218219for (p = bssid->IEs + _BEACON_IE_OFFSET_; ; p += (len + 2)) {220p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &len, limit);221limit -= len;222if ((p == NULL) || (len == 0))223break;224if (p && (_rtw_memcmp(p + 2, RTW_RSON_OUI, sizeof(RTW_RSON_OUI)) == _TRUE)225&& rtw_rson_varify_ie(p)) {226p = p + 2 + sizeof(RTW_RSON_OUI);227rson_data->ver = *p;228/* for (ver == 1) */229p = p + 1;230rson_data->id = le32_to_cpup((__le32 *)p);231p = p + 4;232rson_data->hopcnt = *p;233p = p + 1;234rson_data->connectible = *p;235p = p + 1;236rson_data->loading = *p;237238return _TRUE;239}240}241return -EBADMSG;242}243244u32 rtw_rson_append_ie(_adapter *padapter, unsigned char *pframe, u32 *len)245{246u8 *ptr, *ori, ie_len = 0;247struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);248struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);249/* static int iii = 0;*/250251if ((!pdvobj) || (!pframe))252return 0;253ptr = ori = pframe;254*ptr++ = _VENDOR_SPECIFIC_IE_;255*ptr++ = ie_len = sizeof(RTW_RSON_OUI)+sizeof(pdvobj->rson_data);256_rtw_memcpy(ptr, RTW_RSON_OUI, sizeof(RTW_RSON_OUI));257ptr = ptr + sizeof(RTW_RSON_OUI);258*ptr++ = pdvobj->rson_data.ver;259*(s32 *)ptr = cpu_to_le32(pdvobj->rson_data.id);260ptr = ptr + sizeof(pdvobj->rson_data.id);261*ptr++ = pdvobj->rson_data.hopcnt;262*ptr++ = pdvobj->rson_data.connectible;263*ptr++ = pdvobj->rson_data.loading;264_rtw_memcpy(ptr, pdvobj->rson_data.res, sizeof(pdvobj->rson_data.res));265pframe = ptr;266/*267iii = iii % 20;268if (iii++ == 0)269RTW_INFO("%s : RTW RSON IE : %20ph\n", __func__, ori);270*/271*len += (ie_len+2);272return ie_len;273274}275276void rtw_rson_do_disconnect(_adapter *padapter)277{278struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);279280RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));281#ifndef CONFIG_RTW_REPEATER_SON_ROOT282pdvobj->rson_data.ver = RTW_RSON_VER;283pdvobj->rson_data.id = CONFIG_RTW_REPEATER_SON_ID;284pdvobj->rson_data.hopcnt = RTW_RSON_HC_NOTREADY;285pdvobj->rson_data.connectible = RTW_RSON_DENYCONNECT;286pdvobj->rson_data.loading = 0;287rtw_mi_tx_beacon_hdl(padapter);288#endif289}290291void rtw_rson_join_done(_adapter *padapter)292{293struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);294WLAN_BSSID_EX *cur_network = NULL;295struct rtw_rson_struct rson_data;296297RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));298if (!padapter->mlmepriv.cur_network_scanned)299return;300cur_network = &(padapter->mlmepriv.cur_network_scanned->network);301if (rtw_get_rson_struct(cur_network, &rson_data) != _TRUE) {302RTW_ERR("%s: try to join a improper network(%s)\n", __func__, cur_network->Ssid.Ssid);303return;304}305306#ifndef CONFIG_RTW_REPEATER_SON_ROOT307/* update rson_data */308pdvobj->rson_data.ver = RTW_RSON_VER;309pdvobj->rson_data.id = rson_data.id;310pdvobj->rson_data.hopcnt = rson_data.hopcnt + 1;311pdvobj->rson_data.connectible = RTW_RSON_ALLOWCONNECT;312pdvobj->rson_data.loading = 0;313rtw_mi_tx_beacon_hdl(padapter);314#endif315}316317int rtw_rson_isupdate_roamcan(struct mlme_priv *mlme318, struct wlan_network **candidate, struct wlan_network *competitor)319{320struct rtw_rson_struct rson_cand, rson_comp, rson_curr;321s16 comp_score, cand_score, curr_score;322323if ((competitor == NULL)324|| (rtw_get_rson_struct(&(competitor->network), &rson_comp) != _TRUE)325|| (rson_comp.id != CONFIG_RTW_REPEATER_SON_ID))326return _FALSE;327328if (is_match_bssid(competitor->network.MacAddress, rtw_rson_block_bssid, rtw_rson_block_bssid_idx) == _TRUE)329return _FALSE;330331if ((!mlme->cur_network_scanned)332|| (mlme->cur_network_scanned == competitor)333|| (rtw_get_rson_struct(&(mlme->cur_network_scanned->network), &rson_curr)) != _TRUE)334return _FALSE;335336if (rtw_get_passing_time_ms((u32)competitor->last_scanned) >= mlme->roam_scanr_exp_ms)337return _FALSE;338339comp_score = rtw_cal_rson_score(&rson_comp, competitor->network.Rssi);340curr_score = rtw_cal_rson_score(&rson_curr, mlme->cur_network_scanned->network.Rssi);341if (comp_score - curr_score < RSON_SCORE_DIFF_TH)342return _FALSE;343344if (*candidate == NULL)345return _TRUE;346347if (rtw_get_rson_struct(&((*candidate)->network), &rson_cand) != _TRUE) {348RTW_ERR("%s : Unable to get rson_struct from candidate(%s -- " MAC_FMT")\n",349__func__, (*candidate)->network.Ssid.Ssid, MAC_ARG((*candidate)->network.MacAddress));350return _FALSE;351}352cand_score = rtw_cal_rson_score(&rson_cand, (*candidate)->network.Rssi);353RTW_DBG("comp_score=%d , cand_score=%d , curr_score=%d\n", comp_score, cand_score, curr_score);354if (cand_score < comp_score)355return _TRUE;356357#if 0 /* Handle 11R protocol */358#ifdef CONFIG_RTW_80211R359if (rtw_chk_ft_flags(adapter, RTW_FT_SUPPORTED)) {360ptmp = rtw_get_ie(&competitor->network.IEs[12], _MDIE_, &mdie_len, competitor->network.IELength-12);361if (ptmp) {362if (!_rtw_memcmp(&pftpriv->mdid, ptmp+2, 2))363goto exit;364365/*The candidate don't support over-the-DS*/366if (rtw_chk_ft_flags(adapter, RTW_FT_STA_OVER_DS_SUPPORTED)) {367if ((rtw_chk_ft_flags(adapter, RTW_FT_OVER_DS_SUPPORTED) && !(*(ptmp+4) & 0x01)) ||368(!rtw_chk_ft_flags(adapter, RTW_FT_OVER_DS_SUPPORTED) && (*(ptmp+4) & 0x01))) {369RTW_INFO("FT: ignore the candidate(" MAC_FMT ") for over-the-DS\n", MAC_ARG(competitor->network.MacAddress));370rtw_clr_ft_flags(adapter, RTW_FT_OVER_DS_SUPPORTED);371goto exit;372}373}374} else375goto exit;376}377#endif378#endif379return _FALSE;380}381382void rtw_rson_show_survey_info(struct seq_file *m, _list *plist, _list *phead)383{384struct wlan_network *pnetwork = NULL;385struct rtw_rson_struct rson_data;386s16 rson_score;387u16 index = 0;388389RTW_PRINT_SEL(m, "%5s %-17s %3s %5s %14s %10s %-3s %5s %32s\n", "index", "bssid", "ch", "id", "hop_cnt", "loading", "RSSI", "score", "ssid");390while (1) {391if (rtw_end_of_queue_search(phead, plist) == _TRUE)392break;393394pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);395if (!pnetwork)396break;397398_rtw_memset(&rson_data, 0, sizeof(rson_data));399rson_score = 0;400if (rtw_get_rson_struct(&(pnetwork->network), &rson_data) == _TRUE)401rson_score = rtw_cal_rson_score(&rson_data, pnetwork->network.Rssi);402RTW_PRINT_SEL(m, "%5d "MAC_FMT" %3d 0x%08x %6d %10d %6d %6d %32s\n",403++index,404MAC_ARG(pnetwork->network.MacAddress),405pnetwork->network.Configuration.DSConfig,406rson_data.id,407rson_data.hopcnt,408rson_data.loading,409(int)pnetwork->network.Rssi,410rson_score,411pnetwork->network.Ssid.Ssid);412plist = get_next(plist);413}414415}416417/*418Description : As a AP role, We need to check the qualify of associating STA.419We also need to check if we are ready to be associated.420421return : TRUE -- AP REJECT this STA422FALSE -- AP ACCEPT this STA423*/424u8 rtw_rson_ap_check_sta(_adapter *padapter, u8 *pframe, uint pkt_len, unsigned short ie_offset)425{426struct wlan_network *pnetwork = NULL;427struct rtw_rson_struct rson_target;428struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);429int len = 0;430u8 ret = _FALSE;431u8 *p;432433#ifndef CONFIG_RTW_REPEATER_SON_ROOT434_rtw_memset(&rson_target, 0, sizeof(rson_target));435for (p = pframe + WLAN_HDR_A3_LEN + ie_offset; ; p += (len + 2)) {436p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);437438if ((p == NULL) || (len == 0))439break;440441if (p && (_rtw_memcmp(p + 2, RTW_RSON_OUI, sizeof(RTW_RSON_OUI)) == _TRUE)442&& rtw_rson_varify_ie(p)) {443p = p + 2 + sizeof(RTW_RSON_OUI);444rson_target.ver = *p;445/* for (ver == 1) */446p = p + 1;447rson_target.id = le32_to_cpup((__le32 *)p);448p = p + 4;449rson_target.hopcnt = *p;450p = p + 1;451rson_target.connectible = *p;452p = p + 1;453rson_target.loading = *p;454break;455}456}457458if (rson_target.id == 0) /* Normal STA, not a RSON STA */459ret = _FALSE;460else if (rson_target.id != pdvobj->rson_data.id) {461ret = _TRUE;462RTW_INFO("%s : Reject AssoReq because RSON ID not match, STA=%08x, our=%08x\n",463__func__, rson_target.id, pdvobj->rson_data.id);464} else if ((pdvobj->rson_data.hopcnt == RTW_RSON_HC_NOTREADY)465|| (pdvobj->rson_data.connectible == RTW_RSON_DENYCONNECT)) {466ret = _TRUE;467RTW_INFO("%s : Reject AssoReq becuase our hopcnt=%d or connectbile=%d\n",468__func__, pdvobj->rson_data.hopcnt, pdvobj->rson_data.connectible);469}470#endif471return ret;472}473474u8 rtw_rson_scan_wk_cmd(_adapter *padapter, int op)475{476struct cmd_obj *ph2c;477struct drvextra_cmd_parm *pdrvextra_cmd_parm;478struct cmd_priv *pcmdpriv = &padapter->cmdpriv;479u8 *extra_cmd_buf;480u8 res = _SUCCESS;481482ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));483if (ph2c == NULL) {484res = _FAIL;485goto exit;486}487488pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));489if (pdrvextra_cmd_parm == NULL) {490rtw_mfree((u8 *)ph2c, sizeof(struct cmd_obj));491res = _FAIL;492goto exit;493}494pdrvextra_cmd_parm->ec_id = RSON_SCAN_WK_CID;495pdrvextra_cmd_parm->type = op;496pdrvextra_cmd_parm->size = 0;497pdrvextra_cmd_parm->pbuf = NULL;498499init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));500501res = rtw_enqueue_cmd(pcmdpriv, ph2c);502503exit:504return res;505506}507508void rtw_rson_scan_cmd_hdl(_adapter *padapter, int op)509{510struct cmd_priv *pcmdpriv = &padapter->cmdpriv;511struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;512struct mlme_priv *pmlmepriv = &padapter->mlmepriv;513u8 val8;514515if (mlmeext_chk_scan_state(pmlmeext, SCAN_DISABLE) != _TRUE)516return;517if (op == RSON_SCAN_PROCESS) {518padapter->rtw_rson_scanstage = RSON_SCAN_PROCESS;519val8 = 0x1e;520rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &val8, _FALSE);521val8 = 1;522rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));523issue_probereq(padapter, NULL, NULL);524/* stop rson_scan after 100ms */525_set_timer(&(pmlmeext->rson_scan_timer), 100);526} else if (op == RSON_SCAN_DISABLE) {527padapter->rtw_rson_scanstage = RSON_SCAN_DISABLE;528val8 = 0;529rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));530val8 = 0xff;531rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &val8, _FALSE);532/* report_surveydone_event(padapter);*/533if (pmlmepriv->to_join == _TRUE) {534if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) != _TRUE) {535int s_ret;536537set_fwstate(pmlmepriv, _FW_UNDER_LINKING);538pmlmepriv->to_join = _FALSE;539s_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv);540if (s_ret == _SUCCESS)541_set_timer(&pmlmepriv->assoc_timer, MAX_JOIN_TIMEOUT);542else if (s_ret == 2) {543_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);544rtw_indicate_connect(padapter);545} else {546RTW_INFO("try_to_join, but select scanning queue fail, to_roam:%d\n", rtw_to_roam(padapter));547if (rtw_to_roam(padapter) != 0) {548if (rtw_dec_to_roam(padapter) == 0) {549rtw_set_to_roam(padapter, 0);550rtw_free_assoc_resources(padapter, _TRUE);551rtw_indicate_disconnect(padapter, 0, _FALSE);552} else553pmlmepriv->to_join = _TRUE;554} else555rtw_indicate_disconnect(padapter, 0, _FALSE);556_clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);557}558}559} else {560if (rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE)) {561if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)562&& check_fwstate(pmlmepriv, _FW_LINKED)) {563if (rtw_select_roaming_candidate(pmlmepriv) == _SUCCESS) {564#ifdef CONFIG_RTW_80211R565if (rtw_chk_ft_flags(padapter, RTW_FT_OVER_DS_SUPPORTED)) {566start_clnt_ft_action(adapter, (u8 *)pmlmepriv->roam_network->network.MacAddress);567} else {568/*wait a little time to retrieve packets buffered in the current ap while scan*/569_set_timer(&pmlmeext->ft_roam_timer, 30);570}571#else572receive_disconnect(padapter, pmlmepriv->cur_network.network.MacAddress573, WLAN_REASON_ACTIVE_ROAM, _FALSE);574#endif575}576}577}578issue_action_BSSCoexistPacket(padapter);579issue_action_BSSCoexistPacket(padapter);580issue_action_BSSCoexistPacket(padapter);581}582} else {583RTW_ERR("%s : improper parameter -- op = %d\n", __func__, op);584}585}586587#endif /* CONFIG_RTW_REPEATER_SON */588589590