cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

phy_common.c (13667B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Copyright(c) 2009-2014  Realtek Corporation.*/
      3
      4#include "../wifi.h"
      5#include "phy_common.h"
      6#include "../rtl8723ae/reg.h"
      7#include <linux/module.h>
      8
      9/* These routines are common to RTL8723AE and RTL8723bE */
     10
     11u32 rtl8723_phy_query_bb_reg(struct ieee80211_hw *hw,
     12			     u32 regaddr, u32 bitmask)
     13{
     14	struct rtl_priv *rtlpriv = rtl_priv(hw);
     15	u32 returnvalue, originalvalue, bitshift;
     16
     17	rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
     18		"regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask);
     19	originalvalue = rtl_read_dword(rtlpriv, regaddr);
     20	bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
     21	returnvalue = (originalvalue & bitmask) >> bitshift;
     22
     23	rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
     24		"BBR MASK=0x%x Addr[0x%x]=0x%x\n", bitmask,
     25		regaddr, originalvalue);
     26	return returnvalue;
     27}
     28EXPORT_SYMBOL_GPL(rtl8723_phy_query_bb_reg);
     29
     30void rtl8723_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
     31			      u32 bitmask, u32 data)
     32{
     33	struct rtl_priv *rtlpriv = rtl_priv(hw);
     34	u32 originalvalue, bitshift;
     35
     36	rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
     37		"regaddr(%#x), bitmask(%#x), data(%#x)\n", regaddr, bitmask,
     38		data);
     39
     40	if (bitmask != MASKDWORD) {
     41		originalvalue = rtl_read_dword(rtlpriv, regaddr);
     42		bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
     43		data = ((originalvalue & (~bitmask)) | (data << bitshift));
     44	}
     45
     46	rtl_write_dword(rtlpriv, regaddr, data);
     47
     48	rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
     49		"regaddr(%#x), bitmask(%#x), data(%#x)\n",
     50		regaddr, bitmask, data);
     51}
     52EXPORT_SYMBOL_GPL(rtl8723_phy_set_bb_reg);
     53
     54u32 rtl8723_phy_calculate_bit_shift(u32 bitmask)
     55{
     56	u32 i = ffs(bitmask);
     57
     58	return i ? i - 1 : 32;
     59}
     60EXPORT_SYMBOL_GPL(rtl8723_phy_calculate_bit_shift);
     61
     62u32 rtl8723_phy_rf_serial_read(struct ieee80211_hw *hw,
     63			       enum radio_path rfpath, u32 offset)
     64{
     65	struct rtl_priv *rtlpriv = rtl_priv(hw);
     66	struct rtl_phy *rtlphy = &(rtlpriv->phy);
     67	struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
     68	u32 newoffset;
     69	u32 tmplong, tmplong2;
     70	u8 rfpi_enable = 0;
     71	u32 retvalue;
     72
     73	offset &= 0xff;
     74	newoffset = offset;
     75	if (RT_CANNOT_IO(hw)) {
     76		pr_err("return all one\n");
     77		return 0xFFFFFFFF;
     78	}
     79	tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
     80	if (rfpath == RF90_PATH_A)
     81		tmplong2 = tmplong;
     82	else
     83		tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
     84	tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
     85	    (newoffset << 23) | BLSSIREADEDGE;
     86	rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
     87		      tmplong & (~BLSSIREADEDGE));
     88	rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
     89	rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
     90		      tmplong | BLSSIREADEDGE);
     91	udelay(120);
     92	if (rfpath == RF90_PATH_A)
     93		rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
     94						 BIT(8));
     95	else if (rfpath == RF90_PATH_B)
     96		rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
     97						 BIT(8));
     98	if (rfpi_enable)
     99		retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi,
    100					 BLSSIREADBACKDATA);
    101	else
    102		retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb,
    103					 BLSSIREADBACKDATA);
    104	rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
    105		"RFR-%d Addr[0x%x]=0x%x\n",
    106		rfpath, pphyreg->rf_rb, retvalue);
    107	return retvalue;
    108}
    109EXPORT_SYMBOL_GPL(rtl8723_phy_rf_serial_read);
    110
    111void rtl8723_phy_rf_serial_write(struct ieee80211_hw *hw,
    112				 enum radio_path rfpath,
    113				 u32 offset, u32 data)
    114{
    115	u32 data_and_addr;
    116	u32 newoffset;
    117	struct rtl_priv *rtlpriv = rtl_priv(hw);
    118	struct rtl_phy *rtlphy = &(rtlpriv->phy);
    119	struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
    120
    121	if (RT_CANNOT_IO(hw)) {
    122		pr_err("stop\n");
    123		return;
    124	}
    125	offset &= 0xff;
    126	newoffset = offset;
    127	data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
    128	rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
    129	rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
    130		"RFW-%d Addr[0x%x]=0x%x\n",
    131		rfpath, pphyreg->rf3wire_offset,
    132		data_and_addr);
    133}
    134EXPORT_SYMBOL_GPL(rtl8723_phy_rf_serial_write);
    135
    136long rtl8723_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
    137				  enum wireless_mode wirelessmode,
    138				  u8 txpwridx)
    139{
    140	long offset;
    141	long pwrout_dbm;
    142
    143	switch (wirelessmode) {
    144	case WIRELESS_MODE_B:
    145		offset = -7;
    146		break;
    147	case WIRELESS_MODE_G:
    148	case WIRELESS_MODE_N_24G:
    149		offset = -8;
    150		break;
    151	default:
    152		offset = -8;
    153		break;
    154	}
    155	pwrout_dbm = txpwridx / 2 + offset;
    156	return pwrout_dbm;
    157}
    158EXPORT_SYMBOL_GPL(rtl8723_phy_txpwr_idx_to_dbm);
    159
    160void rtl8723_phy_init_bb_rf_reg_def(struct ieee80211_hw *hw)
    161{
    162	struct rtl_priv *rtlpriv = rtl_priv(hw);
    163	struct rtl_phy *rtlphy = &(rtlpriv->phy);
    164
    165	rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
    166	rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
    167	rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
    168	rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
    169
    170	rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
    171	rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
    172	rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
    173	rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
    174
    175	rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
    176	rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
    177
    178	rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
    179	rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
    180
    181	rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
    182	    RFPGA0_XA_LSSIPARAMETER;
    183	rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
    184	    RFPGA0_XB_LSSIPARAMETER;
    185
    186	rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER;
    187	rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER;
    188	rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER;
    189	rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER;
    190
    191	rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
    192	rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
    193	rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
    194	rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
    195
    196	rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
    197	rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
    198
    199	rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
    200	rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
    201
    202	rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
    203	rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
    204	rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
    205	rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
    206
    207	rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
    208	rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
    209	rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
    210	rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
    211
    212	rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
    213	rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
    214	rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
    215	rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
    216
    217	rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE;
    218	rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE;
    219	rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBANLANCE;
    220	rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE;
    221
    222	rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
    223	rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
    224	rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
    225	rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
    226
    227	rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE;
    228	rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE;
    229	rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE;
    230	rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE;
    231
    232	rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
    233	rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
    234	rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
    235	rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
    236
    237	rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK;
    238	rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK;
    239	rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK;
    240	rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK;
    241
    242	rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK;
    243	rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK;
    244
    245}
    246EXPORT_SYMBOL_GPL(rtl8723_phy_init_bb_rf_reg_def);
    247
    248bool rtl8723_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
    249				      u32 cmdtableidx,
    250				      u32 cmdtablesz,
    251				      enum swchnlcmd_id cmdid,
    252				      u32 para1, u32 para2,
    253				      u32 msdelay)
    254{
    255	struct swchnlcmd *pcmd;
    256
    257	if (cmdtable == NULL) {
    258		WARN_ONCE(true, "rtl8723-common: cmdtable cannot be NULL.\n");
    259		return false;
    260	}
    261
    262	if (cmdtableidx >= cmdtablesz)
    263		return false;
    264
    265	pcmd = cmdtable + cmdtableidx;
    266	pcmd->cmdid = cmdid;
    267	pcmd->para1 = para1;
    268	pcmd->para2 = para2;
    269	pcmd->msdelay = msdelay;
    270	return true;
    271}
    272EXPORT_SYMBOL_GPL(rtl8723_phy_set_sw_chnl_cmdarray);
    273
    274void rtl8723_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw,
    275					bool iqk_ok,
    276					long result[][8],
    277					u8 final_candidate,
    278					bool btxonly)
    279{
    280	u32 oldval_0, x, tx0_a, reg;
    281	long y, tx0_c;
    282
    283	if (final_candidate == 0xFF) {
    284		return;
    285	} else if (iqk_ok) {
    286		oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
    287					  MASKDWORD) >> 22) & 0x3FF;
    288		x = result[final_candidate][0];
    289		if ((x & 0x00000200) != 0)
    290			x = x | 0xFFFFFC00;
    291		tx0_a = (x * oldval_0) >> 8;
    292		rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a);
    293		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31),
    294			      ((x * oldval_0 >> 7) & 0x1));
    295		y = result[final_candidate][1];
    296		if ((y & 0x00000200) != 0)
    297			y = y | 0xFFFFFC00;
    298		tx0_c = (y * oldval_0) >> 8;
    299		rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000,
    300			      ((tx0_c & 0x3C0) >> 6));
    301		rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000,
    302			      (tx0_c & 0x3F));
    303		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29),
    304			      ((y * oldval_0 >> 7) & 0x1));
    305		if (btxonly)
    306			return;
    307		reg = result[final_candidate][2];
    308		rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
    309		reg = result[final_candidate][3] & 0x3F;
    310		rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
    311		reg = (result[final_candidate][3] >> 6) & 0xF;
    312		rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg);
    313	}
    314}
    315EXPORT_SYMBOL_GPL(rtl8723_phy_path_a_fill_iqk_matrix);
    316
    317void rtl8723_save_adda_registers(struct ieee80211_hw *hw, u32 *addareg,
    318				 u32 *addabackup, u32 registernum)
    319{
    320	u32 i;
    321
    322	for (i = 0; i < registernum; i++)
    323		addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD);
    324}
    325EXPORT_SYMBOL_GPL(rtl8723_save_adda_registers);
    326
    327void rtl8723_phy_save_mac_registers(struct ieee80211_hw *hw,
    328				    u32 *macreg, u32 *macbackup)
    329{
    330	struct rtl_priv *rtlpriv = rtl_priv(hw);
    331	u32 i;
    332
    333	for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
    334		macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
    335	macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
    336}
    337EXPORT_SYMBOL_GPL(rtl8723_phy_save_mac_registers);
    338
    339void rtl8723_phy_reload_adda_registers(struct ieee80211_hw *hw,
    340				       u32 *addareg, u32 *addabackup,
    341				       u32 regiesternum)
    342{
    343	u32 i;
    344
    345	for (i = 0; i < regiesternum; i++)
    346		rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]);
    347}
    348EXPORT_SYMBOL_GPL(rtl8723_phy_reload_adda_registers);
    349
    350void rtl8723_phy_reload_mac_registers(struct ieee80211_hw *hw,
    351				      u32 *macreg, u32 *macbackup)
    352{
    353	struct rtl_priv *rtlpriv = rtl_priv(hw);
    354	u32 i;
    355
    356	for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
    357		rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]);
    358	rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
    359}
    360EXPORT_SYMBOL_GPL(rtl8723_phy_reload_mac_registers);
    361
    362void rtl8723_phy_path_adda_on(struct ieee80211_hw *hw, u32 *addareg,
    363			      bool is_patha_on, bool is2t)
    364{
    365	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
    366	u32 pathon;
    367	u32 i;
    368
    369	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723AE) {
    370		pathon = is_patha_on ? 0x04db25a4 : 0x0b1b25a4;
    371		if (!is2t) {
    372			pathon = 0x0bdb25a0;
    373			rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0);
    374		} else {
    375			rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathon);
    376		}
    377	} else {
    378		/* rtl8723be */
    379		pathon = 0x01c00014;
    380		rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathon);
    381	}
    382
    383	for (i = 1; i < IQK_ADDA_REG_NUM; i++)
    384		rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathon);
    385}
    386EXPORT_SYMBOL_GPL(rtl8723_phy_path_adda_on);
    387
    388void rtl8723_phy_mac_setting_calibration(struct ieee80211_hw *hw,
    389					 u32 *macreg, u32 *macbackup)
    390{
    391	struct rtl_priv *rtlpriv = rtl_priv(hw);
    392	u32 i = 0;
    393
    394	rtl_write_byte(rtlpriv, macreg[i], 0x3F);
    395
    396	for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
    397		rtl_write_byte(rtlpriv, macreg[i],
    398			       (u8) (macbackup[i] & (~BIT(3))));
    399	rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5))));
    400}
    401EXPORT_SYMBOL_GPL(rtl8723_phy_mac_setting_calibration);
    402
    403void rtl8723_phy_path_a_standby(struct ieee80211_hw *hw)
    404{
    405	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
    406	rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
    407	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
    408}
    409EXPORT_SYMBOL_GPL(rtl8723_phy_path_a_standby);
    410
    411void rtl8723_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode)
    412{
    413	u32 mode;
    414
    415	mode = pi_mode ? 0x01000100 : 0x01000000;
    416	rtl_set_bbreg(hw, 0x820, MASKDWORD, mode);
    417	rtl_set_bbreg(hw, 0x828, MASKDWORD, mode);
    418}
    419EXPORT_SYMBOL_GPL(rtl8723_phy_pi_mode_switch);