phy_common.c 14 KB

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