phy.c 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2009-2012 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. * You should have received a copy of the GNU General Public License along with
  15. * this program; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  17. *
  18. * The full GNU General Public License is included in this distribution in the
  19. * file called LICENSE.
  20. *
  21. * Contact Information:
  22. * wlanfae <wlanfae@realtek.com>
  23. * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
  24. * Hsinchu 300, Taiwan.
  25. *
  26. * Larry Finger <Larry.Finger@lwfinger.net>
  27. *
  28. *****************************************************************************/
  29. #include "../wifi.h"
  30. #include "../pci.h"
  31. #include "../ps.h"
  32. #include "../core.h"
  33. #include "reg.h"
  34. #include "def.h"
  35. #include "phy.h"
  36. #include "rf.h"
  37. #include "dm.h"
  38. #include "table.h"
  39. #include "../rtl8723com/phy_common.h"
  40. /* static forward definitions */
  41. static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw,
  42. enum radio_path rfpath, u32 offset);
  43. static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw,
  44. enum radio_path rfpath,
  45. u32 offset, u32 data);
  46. static bool _phy_bb8192c_config_parafile(struct ieee80211_hw *hw);
  47. static bool _phy_cfg_mac_w_header(struct ieee80211_hw *hw);
  48. static bool _phy_cfg_bb_w_header(struct ieee80211_hw *hw, u8 configtype);
  49. static bool _phy_cfg_bb_w_pgheader(struct ieee80211_hw *hw, u8 configtype);
  50. static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel,
  51. u8 *stage, u8 *step, u32 *delay);
  52. static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
  53. enum wireless_mode wirelessmode,
  54. long power_indbm);
  55. static void rtl8723ae_phy_set_io(struct ieee80211_hw *hw);
  56. u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw,
  57. enum radio_path rfpath, u32 regaddr, u32 bitmask)
  58. {
  59. struct rtl_priv *rtlpriv = rtl_priv(hw);
  60. u32 original_value, readback_value, bitshift;
  61. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  62. unsigned long flags;
  63. RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  64. "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
  65. regaddr, rfpath, bitmask);
  66. spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
  67. if (rtlphy->rf_mode != RF_OP_BY_FW)
  68. original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr);
  69. else
  70. original_value = _phy_fw_rf_serial_read(hw, rfpath, regaddr);
  71. bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
  72. readback_value = (original_value & bitmask) >> bitshift;
  73. spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
  74. RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  75. "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
  76. regaddr, rfpath, bitmask, original_value);
  77. return readback_value;
  78. }
  79. void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw,
  80. enum radio_path rfpath,
  81. u32 regaddr, u32 bitmask, u32 data)
  82. {
  83. struct rtl_priv *rtlpriv = rtl_priv(hw);
  84. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  85. u32 original_value, bitshift;
  86. unsigned long flags;
  87. RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  88. "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
  89. regaddr, bitmask, data, rfpath);
  90. spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
  91. if (rtlphy->rf_mode != RF_OP_BY_FW) {
  92. if (bitmask != RFREG_OFFSET_MASK) {
  93. original_value = rtl8723_phy_rf_serial_read(hw, rfpath,
  94. regaddr);
  95. bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
  96. data = ((original_value & (~bitmask)) |
  97. (data << bitshift));
  98. }
  99. rtl8723_phy_rf_serial_write(hw, rfpath, regaddr, data);
  100. } else {
  101. if (bitmask != RFREG_OFFSET_MASK) {
  102. original_value = _phy_fw_rf_serial_read(hw, rfpath,
  103. regaddr);
  104. bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
  105. data = ((original_value & (~bitmask)) |
  106. (data << bitshift));
  107. }
  108. _phy_fw_rf_serial_write(hw, rfpath, regaddr, data);
  109. }
  110. spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
  111. RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  112. "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
  113. regaddr, bitmask, data, rfpath);
  114. }
  115. static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw,
  116. enum radio_path rfpath, u32 offset)
  117. {
  118. RT_ASSERT(false, "deprecated!\n");
  119. return 0;
  120. }
  121. static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw,
  122. enum radio_path rfpath,
  123. u32 offset, u32 data)
  124. {
  125. RT_ASSERT(false, "deprecated!\n");
  126. }
  127. static void _rtl8723ae_phy_bb_config_1t(struct ieee80211_hw *hw)
  128. {
  129. rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2);
  130. rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022);
  131. rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45);
  132. rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23);
  133. rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1);
  134. rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2);
  135. rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2);
  136. rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2);
  137. rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2);
  138. rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2);
  139. }
  140. bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw)
  141. {
  142. struct rtl_priv *rtlpriv = rtl_priv(hw);
  143. bool rtstatus = _phy_cfg_mac_w_header(hw);
  144. rtl_write_byte(rtlpriv, 0x04CA, 0x0A);
  145. return rtstatus;
  146. }
  147. bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw)
  148. {
  149. bool rtstatus = true;
  150. struct rtl_priv *rtlpriv = rtl_priv(hw);
  151. u8 tmpu1b;
  152. u8 reg_hwparafile = 1;
  153. rtl8723_phy_init_bb_rf_reg_def(hw);
  154. /* 1. 0x28[1] = 1 */
  155. tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_PLL_CTRL);
  156. udelay(2);
  157. rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, (tmpu1b|BIT(1)));
  158. udelay(2);
  159. /* 2. 0x29[7:0] = 0xFF */
  160. rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL+1, 0xff);
  161. udelay(2);
  162. /* 3. 0x02[1:0] = 2b'11 */
  163. tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN);
  164. rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, (tmpu1b |
  165. FEN_BB_GLB_RSTn | FEN_BBRSTB));
  166. /* 4. 0x25[6] = 0 */
  167. tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+1);
  168. rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+1, (tmpu1b&(~BIT(6))));
  169. /* 5. 0x24[20] = 0 Advised by SD3 Alex Wang. 2011.02.09. */
  170. tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+2);
  171. rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+2, (tmpu1b&(~BIT(4))));
  172. /* 6. 0x1f[7:0] = 0x07 */
  173. rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x07);
  174. if (reg_hwparafile == 1)
  175. rtstatus = _phy_bb8192c_config_parafile(hw);
  176. return rtstatus;
  177. }
  178. bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw)
  179. {
  180. return rtl8723ae_phy_rf6052_config(hw);
  181. }
  182. static bool _phy_bb8192c_config_parafile(struct ieee80211_hw *hw)
  183. {
  184. struct rtl_priv *rtlpriv = rtl_priv(hw);
  185. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  186. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  187. bool rtstatus;
  188. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n");
  189. rtstatus = _phy_cfg_bb_w_header(hw, BASEBAND_CONFIG_PHY_REG);
  190. if (rtstatus != true) {
  191. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
  192. return false;
  193. }
  194. if (rtlphy->rf_type == RF_1T2R) {
  195. _rtl8723ae_phy_bb_config_1t(hw);
  196. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n");
  197. }
  198. if (rtlefuse->autoload_failflag == false) {
  199. rtlphy->pwrgroup_cnt = 0;
  200. rtstatus = _phy_cfg_bb_w_pgheader(hw, BASEBAND_CONFIG_PHY_REG);
  201. }
  202. if (rtstatus != true) {
  203. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
  204. return false;
  205. }
  206. rtstatus = _phy_cfg_bb_w_header(hw, BASEBAND_CONFIG_AGC_TAB);
  207. if (rtstatus != true) {
  208. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
  209. return false;
  210. }
  211. rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
  212. RFPGA0_XA_HSSIPARAMETER2, 0x200));
  213. return true;
  214. }
  215. static bool _phy_cfg_mac_w_header(struct ieee80211_hw *hw)
  216. {
  217. struct rtl_priv *rtlpriv = rtl_priv(hw);
  218. u32 i;
  219. u32 arraylength;
  220. u32 *ptrarray;
  221. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl723MACPHY_Array\n");
  222. arraylength = RTL8723E_MACARRAYLENGTH;
  223. ptrarray = RTL8723EMAC_ARRAY;
  224. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  225. "Img:RTL8192CEMAC_2T_ARRAY\n");
  226. for (i = 0; i < arraylength; i = i + 2)
  227. rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
  228. return true;
  229. }
  230. static bool _phy_cfg_bb_w_header(struct ieee80211_hw *hw, u8 configtype)
  231. {
  232. int i;
  233. u32 *phy_regarray_table;
  234. u32 *agctab_array_table;
  235. u16 phy_reg_arraylen, agctab_arraylen;
  236. struct rtl_priv *rtlpriv = rtl_priv(hw);
  237. agctab_arraylen = RTL8723E_AGCTAB_1TARRAYLENGTH;
  238. agctab_array_table = RTL8723EAGCTAB_1TARRAY;
  239. phy_reg_arraylen = RTL8723E_PHY_REG_1TARRAY_LENGTH;
  240. phy_regarray_table = RTL8723EPHY_REG_1TARRAY;
  241. if (configtype == BASEBAND_CONFIG_PHY_REG) {
  242. for (i = 0; i < phy_reg_arraylen; i = i + 2) {
  243. rtl_addr_delay(phy_regarray_table[i]);
  244. rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,
  245. phy_regarray_table[i + 1]);
  246. udelay(1);
  247. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  248. "The phy_regarray_table[0] is %x"
  249. " Rtl819XPHY_REGArray[1] is %x\n",
  250. phy_regarray_table[i],
  251. phy_regarray_table[i + 1]);
  252. }
  253. } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
  254. for (i = 0; i < agctab_arraylen; i = i + 2) {
  255. rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD,
  256. agctab_array_table[i + 1]);
  257. udelay(1);
  258. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  259. "The agctab_array_table[0] is "
  260. "%x Rtl819XPHY_REGArray[1] is %x\n",
  261. agctab_array_table[i],
  262. agctab_array_table[i + 1]);
  263. }
  264. }
  265. return true;
  266. }
  267. static void _st_pwrIdx_dfrate_off(struct ieee80211_hw *hw, u32 regaddr,
  268. u32 bitmask, u32 data)
  269. {
  270. struct rtl_priv *rtlpriv = rtl_priv(hw);
  271. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  272. switch (regaddr) {
  273. case RTXAGC_A_RATE18_06:
  274. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][0] = data;
  275. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  276. "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",
  277. rtlphy->pwrgroup_cnt,
  278. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][0]);
  279. break;
  280. case RTXAGC_A_RATE54_24:
  281. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][1] = data;
  282. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  283. "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",
  284. rtlphy->pwrgroup_cnt,
  285. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][1]);
  286. break;
  287. case RTXAGC_A_CCK1_MCS32:
  288. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][6] = data;
  289. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  290. "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",
  291. rtlphy->pwrgroup_cnt,
  292. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][6]);
  293. break;
  294. case RTXAGC_B_CCK11_A_CCK2_11:
  295. if (bitmask == 0xffffff00) {
  296. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][7] = data;
  297. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  298. "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",
  299. rtlphy->pwrgroup_cnt,
  300. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][7]);
  301. }
  302. if (bitmask == 0x000000ff) {
  303. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][15] = data;
  304. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  305. "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
  306. rtlphy->pwrgroup_cnt,
  307. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][15]);
  308. }
  309. break;
  310. case RTXAGC_A_MCS03_MCS00:
  311. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][2] = data;
  312. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  313. "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",
  314. rtlphy->pwrgroup_cnt,
  315. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][2]);
  316. break;
  317. case RTXAGC_A_MCS07_MCS04:
  318. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][3] = data;
  319. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  320. "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",
  321. rtlphy->pwrgroup_cnt,
  322. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][3]);
  323. break;
  324. case RTXAGC_A_MCS11_MCS08:
  325. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][4] = data;
  326. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  327. "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",
  328. rtlphy->pwrgroup_cnt,
  329. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][4]);
  330. break;
  331. case RTXAGC_A_MCS15_MCS12:
  332. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][5] = data;
  333. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  334. "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",
  335. rtlphy->pwrgroup_cnt,
  336. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][5]);
  337. break;
  338. case RTXAGC_B_RATE18_06:
  339. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][8] = data;
  340. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  341. "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",
  342. rtlphy->pwrgroup_cnt,
  343. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][8]);
  344. break;
  345. case RTXAGC_B_RATE54_24:
  346. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][9] = data;
  347. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  348. "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
  349. rtlphy->pwrgroup_cnt,
  350. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][9]);
  351. break;
  352. case RTXAGC_B_CCK1_55_MCS32:
  353. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][14] = data;
  354. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  355. "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
  356. rtlphy->pwrgroup_cnt,
  357. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][14]);
  358. break;
  359. case RTXAGC_B_MCS03_MCS00:
  360. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][10] = data;
  361. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  362. "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
  363. rtlphy->pwrgroup_cnt,
  364. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][10]);
  365. break;
  366. case RTXAGC_B_MCS07_MCS04:
  367. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][11] = data;
  368. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  369. "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
  370. rtlphy->pwrgroup_cnt,
  371. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][11]);
  372. break;
  373. case RTXAGC_B_MCS11_MCS08:
  374. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][12] = data;
  375. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  376. "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
  377. rtlphy->pwrgroup_cnt,
  378. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][12]);
  379. break;
  380. case RTXAGC_B_MCS15_MCS12:
  381. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][13] = data;
  382. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  383. "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
  384. rtlphy->pwrgroup_cnt,
  385. rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][13]);
  386. rtlphy->pwrgroup_cnt++;
  387. break;
  388. }
  389. }
  390. static bool _phy_cfg_bb_w_pgheader(struct ieee80211_hw *hw, u8 configtype)
  391. {
  392. struct rtl_priv *rtlpriv = rtl_priv(hw);
  393. int i;
  394. u32 *phy_regarray_table_pg;
  395. u16 phy_regarray_pg_len;
  396. phy_regarray_pg_len = RTL8723E_PHY_REG_ARRAY_PGLENGTH;
  397. phy_regarray_table_pg = RTL8723EPHY_REG_ARRAY_PG;
  398. if (configtype == BASEBAND_CONFIG_PHY_REG) {
  399. for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
  400. rtl_addr_delay(phy_regarray_table_pg[i]);
  401. _st_pwrIdx_dfrate_off(hw, phy_regarray_table_pg[i],
  402. phy_regarray_table_pg[i + 1],
  403. phy_regarray_table_pg[i + 2]);
  404. }
  405. } else {
  406. RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
  407. "configtype != BaseBand_Config_PHY_REG\n");
  408. }
  409. return true;
  410. }
  411. bool rtl8723ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
  412. enum radio_path rfpath)
  413. {
  414. struct rtl_priv *rtlpriv = rtl_priv(hw);
  415. int i;
  416. u32 *radioa_array_table;
  417. u16 radioa_arraylen;
  418. radioa_arraylen = Rtl8723ERADIOA_1TARRAYLENGTH;
  419. radioa_array_table = RTL8723E_RADIOA_1TARRAY;
  420. switch (rfpath) {
  421. case RF90_PATH_A:
  422. for (i = 0; i < radioa_arraylen; i = i + 2) {
  423. rtl_rfreg_delay(hw, rfpath, radioa_array_table[i],
  424. RFREG_OFFSET_MASK,
  425. radioa_array_table[i + 1]);
  426. }
  427. break;
  428. case RF90_PATH_B:
  429. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  430. "switch case not process\n");
  431. break;
  432. case RF90_PATH_C:
  433. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  434. "switch case not process\n");
  435. break;
  436. case RF90_PATH_D:
  437. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  438. "switch case not process\n");
  439. break;
  440. }
  441. return true;
  442. }
  443. void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
  444. {
  445. struct rtl_priv *rtlpriv = rtl_priv(hw);
  446. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  447. rtlphy->default_initialgain[0] =
  448. (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
  449. rtlphy->default_initialgain[1] =
  450. (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
  451. rtlphy->default_initialgain[2] =
  452. (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
  453. rtlphy->default_initialgain[3] =
  454. (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
  455. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  456. "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
  457. rtlphy->default_initialgain[0],
  458. rtlphy->default_initialgain[1],
  459. rtlphy->default_initialgain[2],
  460. rtlphy->default_initialgain[3]);
  461. rtlphy->framesync = (u8) rtl_get_bbreg(hw,
  462. ROFDM0_RXDETECTOR3, MASKBYTE0);
  463. rtlphy->framesync_c34 = rtl_get_bbreg(hw,
  464. ROFDM0_RXDETECTOR2, MASKDWORD);
  465. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  466. "Default framesync (0x%x) = 0x%x\n",
  467. ROFDM0_RXDETECTOR3, rtlphy->framesync);
  468. }
  469. void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
  470. {
  471. struct rtl_priv *rtlpriv = rtl_priv(hw);
  472. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  473. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  474. u8 txpwr_level;
  475. long txpwr_dbm;
  476. txpwr_level = rtlphy->cur_cck_txpwridx;
  477. txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B, txpwr_level);
  478. txpwr_level = rtlphy->cur_ofdm24g_txpwridx +
  479. rtlefuse->legacy_ht_txpowerdiff;
  480. if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) > txpwr_dbm)
  481. txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
  482. txpwr_level);
  483. txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
  484. if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, txpwr_level) >
  485. txpwr_dbm)
  486. txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
  487. txpwr_level);
  488. *powerlevel = txpwr_dbm;
  489. }
  490. static void _rtl8723ae_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
  491. u8 *cckpowerlevel, u8 *ofdmpowerlevel)
  492. {
  493. struct rtl_priv *rtlpriv = rtl_priv(hw);
  494. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  495. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  496. u8 index = (channel - 1);
  497. cckpowerlevel[RF90_PATH_A] =
  498. rtlefuse->txpwrlevel_cck[RF90_PATH_A][index];
  499. cckpowerlevel[RF90_PATH_B] =
  500. rtlefuse->txpwrlevel_cck[RF90_PATH_B][index];
  501. if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) {
  502. ofdmpowerlevel[RF90_PATH_A] =
  503. rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index];
  504. ofdmpowerlevel[RF90_PATH_B] =
  505. rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index];
  506. } else if (get_rf_type(rtlphy) == RF_2T2R) {
  507. ofdmpowerlevel[RF90_PATH_A] =
  508. rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index];
  509. ofdmpowerlevel[RF90_PATH_B] =
  510. rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index];
  511. }
  512. }
  513. static void _rtl8723ae_ccxpower_index_check(struct ieee80211_hw *hw,
  514. u8 channel, u8 *cckpowerlevel,
  515. u8 *ofdmpowerlevel)
  516. {
  517. struct rtl_priv *rtlpriv = rtl_priv(hw);
  518. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  519. rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
  520. rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
  521. }
  522. void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
  523. {
  524. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  525. u8 cckpowerlevel[2], ofdmpowerlevel[2];
  526. if (rtlefuse->txpwr_fromeprom == false)
  527. return;
  528. _rtl8723ae_get_txpower_index(hw, channel, &cckpowerlevel[0],
  529. &ofdmpowerlevel[0]);
  530. _rtl8723ae_ccxpower_index_check(hw, channel, &cckpowerlevel[0],
  531. &ofdmpowerlevel[0]);
  532. rtl8723ae_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]);
  533. rtl8723ae_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel);
  534. }
  535. bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm)
  536. {
  537. struct rtl_priv *rtlpriv = rtl_priv(hw);
  538. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  539. struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  540. u8 idx;
  541. u8 rf_path;
  542. u8 ccktxpwridx = _phy_dbm_to_txpwr_Idx(hw, WIRELESS_MODE_B,
  543. power_indbm);
  544. u8 ofdmtxpwridx = _phy_dbm_to_txpwr_Idx(hw, WIRELESS_MODE_N_24G,
  545. power_indbm);
  546. if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0)
  547. ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff;
  548. else
  549. ofdmtxpwridx = 0;
  550. RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE,
  551. "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n",
  552. power_indbm, ccktxpwridx, ofdmtxpwridx);
  553. for (idx = 0; idx < 14; idx++) {
  554. for (rf_path = 0; rf_path < 2; rf_path++) {
  555. rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx;
  556. rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] =
  557. ofdmtxpwridx;
  558. rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] =
  559. ofdmtxpwridx;
  560. }
  561. }
  562. rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel);
  563. return true;
  564. }
  565. static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
  566. enum wireless_mode wirelessmode,
  567. long power_indbm)
  568. {
  569. u8 txpwridx;
  570. long offset;
  571. switch (wirelessmode) {
  572. case WIRELESS_MODE_B:
  573. offset = -7;
  574. break;
  575. case WIRELESS_MODE_G:
  576. case WIRELESS_MODE_N_24G:
  577. offset = -8;
  578. break;
  579. default:
  580. offset = -8;
  581. break;
  582. }
  583. if ((power_indbm - offset) > 0)
  584. txpwridx = (u8) ((power_indbm - offset) * 2);
  585. else
  586. txpwridx = 0;
  587. if (txpwridx > MAX_TXPWR_IDX_NMODE_92S)
  588. txpwridx = MAX_TXPWR_IDX_NMODE_92S;
  589. return txpwridx;
  590. }
  591. void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
  592. {
  593. struct rtl_priv *rtlpriv = rtl_priv(hw);
  594. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  595. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  596. struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
  597. u8 reg_bw_opmode;
  598. u8 reg_prsr_rsc;
  599. RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
  600. "Switch to %s bandwidth\n",
  601. rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
  602. "20MHz" : "40MHz");
  603. if (is_hal_stop(rtlhal)) {
  604. rtlphy->set_bwmode_inprogress = false;
  605. return;
  606. }
  607. reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
  608. reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
  609. switch (rtlphy->current_chan_bw) {
  610. case HT_CHANNEL_WIDTH_20:
  611. reg_bw_opmode |= BW_OPMODE_20MHZ;
  612. rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
  613. break;
  614. case HT_CHANNEL_WIDTH_20_40:
  615. reg_bw_opmode &= ~BW_OPMODE_20MHZ;
  616. rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
  617. reg_prsr_rsc =
  618. (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
  619. rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
  620. break;
  621. default:
  622. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  623. "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
  624. break;
  625. }
  626. switch (rtlphy->current_chan_bw) {
  627. case HT_CHANNEL_WIDTH_20:
  628. rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
  629. rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
  630. rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
  631. break;
  632. case HT_CHANNEL_WIDTH_20_40:
  633. rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
  634. rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
  635. rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
  636. (mac->cur_40_prime_sc >> 1));
  637. rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
  638. rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);
  639. rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
  640. (mac->cur_40_prime_sc ==
  641. HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
  642. break;
  643. default:
  644. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  645. "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
  646. break;
  647. }
  648. rtl8723ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
  649. rtlphy->set_bwmode_inprogress = false;
  650. RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
  651. }
  652. void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw,
  653. enum nl80211_channel_type ch_type)
  654. {
  655. struct rtl_priv *rtlpriv = rtl_priv(hw);
  656. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  657. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  658. u8 tmp_bw = rtlphy->current_chan_bw;
  659. if (rtlphy->set_bwmode_inprogress)
  660. return;
  661. rtlphy->set_bwmode_inprogress = true;
  662. if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
  663. rtl8723ae_phy_set_bw_mode_callback(hw);
  664. } else {
  665. RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
  666. "FALSE driver sleep or unload\n");
  667. rtlphy->set_bwmode_inprogress = false;
  668. rtlphy->current_chan_bw = tmp_bw;
  669. }
  670. }
  671. void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw)
  672. {
  673. struct rtl_priv *rtlpriv = rtl_priv(hw);
  674. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  675. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  676. u32 delay;
  677. RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
  678. "switch to channel%d\n", rtlphy->current_channel);
  679. if (is_hal_stop(rtlhal))
  680. return;
  681. do {
  682. if (!rtlphy->sw_chnl_inprogress)
  683. break;
  684. if (!_phy_sw_chnl_step_by_step
  685. (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage,
  686. &rtlphy->sw_chnl_step, &delay)) {
  687. if (delay > 0)
  688. mdelay(delay);
  689. else
  690. continue;
  691. } else {
  692. rtlphy->sw_chnl_inprogress = false;
  693. }
  694. break;
  695. } while (true);
  696. RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
  697. }
  698. u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw)
  699. {
  700. struct rtl_priv *rtlpriv = rtl_priv(hw);
  701. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  702. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  703. if (rtlphy->sw_chnl_inprogress)
  704. return 0;
  705. if (rtlphy->set_bwmode_inprogress)
  706. return 0;
  707. RT_ASSERT((rtlphy->current_channel <= 14),
  708. "WIRELESS_MODE_G but channel>14");
  709. rtlphy->sw_chnl_inprogress = true;
  710. rtlphy->sw_chnl_stage = 0;
  711. rtlphy->sw_chnl_step = 0;
  712. if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
  713. rtl8723ae_phy_sw_chnl_callback(hw);
  714. RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
  715. "sw_chnl_inprogress false schedule workitem\n");
  716. rtlphy->sw_chnl_inprogress = false;
  717. } else {
  718. RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
  719. "sw_chnl_inprogress false driver sleep or unload\n");
  720. rtlphy->sw_chnl_inprogress = false;
  721. }
  722. return 1;
  723. }
  724. static void _rtl8723ae_phy_sw_rf_seting(struct ieee80211_hw *hw, u8 channel)
  725. {
  726. struct rtl_priv *rtlpriv = rtl_priv(hw);
  727. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  728. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  729. if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) {
  730. if (channel == 6 && rtlphy->current_chan_bw ==
  731. HT_CHANNEL_WIDTH_20)
  732. rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD,
  733. 0x00255);
  734. else{
  735. u32 backupRF0x1A = (u32)rtl_get_rfreg(hw, RF90_PATH_A,
  736. RF_RX_G1, RFREG_OFFSET_MASK);
  737. rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD,
  738. backupRF0x1A);
  739. }
  740. }
  741. }
  742. static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel,
  743. u8 *stage, u8 *step, u32 *delay)
  744. {
  745. struct rtl_priv *rtlpriv = rtl_priv(hw);
  746. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  747. struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
  748. u32 precommoncmdcnt;
  749. struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
  750. u32 postcommoncmdcnt;
  751. struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
  752. u32 rfdependcmdcnt;
  753. struct swchnlcmd *currentcmd = NULL;
  754. u8 rfpath;
  755. u8 num_total_rfpath = rtlphy->num_total_rfpath;
  756. precommoncmdcnt = 0;
  757. rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
  758. MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL,
  759. 0, 0, 0);
  760. rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
  761. MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
  762. postcommoncmdcnt = 0;
  763. rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
  764. MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
  765. rfdependcmdcnt = 0;
  766. RT_ASSERT((channel >= 1 && channel <= 14),
  767. "illegal channel for Zebra: %d\n", channel);
  768. rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
  769. MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
  770. RF_CHNLBW, channel, 10);
  771. rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
  772. MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0);
  773. do {
  774. switch (*stage) {
  775. case 0:
  776. currentcmd = &precommoncmd[*step];
  777. break;
  778. case 1:
  779. currentcmd = &rfdependcmd[*step];
  780. break;
  781. case 2:
  782. currentcmd = &postcommoncmd[*step];
  783. break;
  784. }
  785. if (currentcmd->cmdid == CMDID_END) {
  786. if ((*stage) == 2) {
  787. return true;
  788. } else {
  789. (*stage)++;
  790. (*step) = 0;
  791. continue;
  792. }
  793. }
  794. switch (currentcmd->cmdid) {
  795. case CMDID_SET_TXPOWEROWER_LEVEL:
  796. rtl8723ae_phy_set_txpower_level(hw, channel);
  797. break;
  798. case CMDID_WRITEPORT_ULONG:
  799. rtl_write_dword(rtlpriv, currentcmd->para1,
  800. currentcmd->para2);
  801. break;
  802. case CMDID_WRITEPORT_USHORT:
  803. rtl_write_word(rtlpriv, currentcmd->para1,
  804. (u16) currentcmd->para2);
  805. break;
  806. case CMDID_WRITEPORT_UCHAR:
  807. rtl_write_byte(rtlpriv, currentcmd->para1,
  808. (u8) currentcmd->para2);
  809. break;
  810. case CMDID_RF_WRITEREG:
  811. for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
  812. rtlphy->rfreg_chnlval[rfpath] =
  813. ((rtlphy->rfreg_chnlval[rfpath] &
  814. 0xfffffc00) | currentcmd->para2);
  815. rtl_set_rfreg(hw, (enum radio_path)rfpath,
  816. currentcmd->para1,
  817. RFREG_OFFSET_MASK,
  818. rtlphy->rfreg_chnlval[rfpath]);
  819. }
  820. _rtl8723ae_phy_sw_rf_seting(hw, channel);
  821. break;
  822. default:
  823. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  824. "switch case not process\n");
  825. break;
  826. }
  827. break;
  828. } while (true);
  829. (*delay) = currentcmd->msdelay;
  830. (*step)++;
  831. return false;
  832. }
  833. static u8 _rtl8723ae_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
  834. {
  835. u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
  836. u8 result = 0x00;
  837. rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f);
  838. rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f);
  839. rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102);
  840. rtl_set_bbreg(hw, 0xe3c, MASKDWORD,
  841. config_pathb ? 0x28160202 : 0x28160502);
  842. if (config_pathb) {
  843. rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22);
  844. rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22);
  845. rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102);
  846. rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202);
  847. }
  848. rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1);
  849. rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
  850. rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
  851. mdelay(IQK_DELAY_TIME);
  852. reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
  853. reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
  854. reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
  855. reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
  856. if (!(reg_eac & BIT(28)) &&
  857. (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
  858. (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
  859. result |= 0x01;
  860. else
  861. return result;
  862. if (!(reg_eac & BIT(27)) &&
  863. (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
  864. (((reg_eac & 0x03FF0000) >> 16) != 0x36))
  865. result |= 0x02;
  866. return result;
  867. }
  868. static u8 _rtl8723ae_phy_path_b_iqk(struct ieee80211_hw *hw)
  869. {
  870. u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;
  871. u8 result = 0x00;
  872. rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002);
  873. rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000);
  874. mdelay(IQK_DELAY_TIME);
  875. reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
  876. reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
  877. reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
  878. reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
  879. reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
  880. if (!(reg_eac & BIT(31)) &&
  881. (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
  882. (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
  883. result |= 0x01;
  884. else
  885. return result;
  886. if (!(reg_eac & BIT(30)) &&
  887. (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
  888. (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
  889. result |= 0x02;
  890. return result;
  891. }
  892. static bool phy_simularity_comp(struct ieee80211_hw *hw, long result[][8],
  893. u8 c1, u8 c2)
  894. {
  895. u32 i, j, diff, simularity_bitmap, bound;
  896. u8 final_candidate[2] = { 0xFF, 0xFF };
  897. bool bresult = true;
  898. bound = 4;
  899. simularity_bitmap = 0;
  900. for (i = 0; i < bound; i++) {
  901. diff = (result[c1][i] > result[c2][i]) ?
  902. (result[c1][i] - result[c2][i]) :
  903. (result[c2][i] - result[c1][i]);
  904. if (diff > MAX_TOLERANCE) {
  905. if ((i == 2 || i == 6) && !simularity_bitmap) {
  906. if (result[c1][i] + result[c1][i + 1] == 0)
  907. final_candidate[(i / 4)] = c2;
  908. else if (result[c2][i] + result[c2][i + 1] == 0)
  909. final_candidate[(i / 4)] = c1;
  910. else
  911. simularity_bitmap = simularity_bitmap |
  912. (1 << i);
  913. } else
  914. simularity_bitmap =
  915. simularity_bitmap | (1 << i);
  916. }
  917. }
  918. if (simularity_bitmap == 0) {
  919. for (i = 0; i < (bound / 4); i++) {
  920. if (final_candidate[i] != 0xFF) {
  921. for (j = i * 4; j < (i + 1) * 4 - 2; j++)
  922. result[3][j] =
  923. result[final_candidate[i]][j];
  924. bresult = false;
  925. }
  926. }
  927. return bresult;
  928. } else if (!(simularity_bitmap & 0x0F)) {
  929. for (i = 0; i < 4; i++)
  930. result[3][i] = result[c1][i];
  931. return false;
  932. } else {
  933. return false;
  934. }
  935. }
  936. static void _rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw,
  937. long result[][8], u8 t, bool is2t)
  938. {
  939. struct rtl_priv *rtlpriv = rtl_priv(hw);
  940. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  941. u32 i;
  942. u8 patha_ok, pathb_ok;
  943. u32 adda_reg[IQK_ADDA_REG_NUM] = {
  944. 0x85c, 0xe6c, 0xe70, 0xe74,
  945. 0xe78, 0xe7c, 0xe80, 0xe84,
  946. 0xe88, 0xe8c, 0xed0, 0xed4,
  947. 0xed8, 0xedc, 0xee0, 0xeec
  948. };
  949. u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
  950. 0x522, 0x550, 0x551, 0x040
  951. };
  952. const u32 retrycount = 2;
  953. if (t == 0) {
  954. rtl8723_save_adda_registers(hw, adda_reg, rtlphy->adda_backup,
  955. 16);
  956. rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,
  957. rtlphy->iqk_mac_backup);
  958. }
  959. rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);
  960. if (t == 0) {
  961. rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
  962. RFPGA0_XA_HSSIPARAMETER1,
  963. BIT(8));
  964. }
  965. if (!rtlphy->rfpi_enable)
  966. rtl8723_phy_pi_mode_switch(hw, true);
  967. if (t == 0) {
  968. rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD);
  969. rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD);
  970. rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD);
  971. }
  972. rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
  973. rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
  974. rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
  975. if (is2t) {
  976. rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
  977. rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
  978. }
  979. rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,
  980. rtlphy->iqk_mac_backup);
  981. rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000);
  982. if (is2t)
  983. rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000);
  984. rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
  985. rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
  986. rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800);
  987. for (i = 0; i < retrycount; i++) {
  988. patha_ok = _rtl8723ae_phy_path_a_iqk(hw, is2t);
  989. if (patha_ok == 0x03) {
  990. result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
  991. 0x3FF0000) >> 16;
  992. result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
  993. 0x3FF0000) >> 16;
  994. result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
  995. 0x3FF0000) >> 16;
  996. result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
  997. 0x3FF0000) >> 16;
  998. break;
  999. } else if (i == (retrycount - 1) && patha_ok == 0x01)
  1000. result[t][0] = (rtl_get_bbreg(hw, 0xe94,
  1001. MASKDWORD) & 0x3FF0000) >> 16;
  1002. result[t][1] =
  1003. (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16;
  1004. }
  1005. if (is2t) {
  1006. rtl8723_phy_path_a_standby(hw);
  1007. rtl8723_phy_path_adda_on(hw, adda_reg, false, is2t);
  1008. for (i = 0; i < retrycount; i++) {
  1009. pathb_ok = _rtl8723ae_phy_path_b_iqk(hw);
  1010. if (pathb_ok == 0x03) {
  1011. result[t][4] =
  1012. (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) &
  1013. 0x3FF0000) >> 16;
  1014. result[t][5] =
  1015. (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
  1016. 0x3FF0000) >> 16;
  1017. result[t][6] =
  1018. (rtl_get_bbreg(hw, 0xec4, MASKDWORD) &
  1019. 0x3FF0000) >> 16;
  1020. result[t][7] =
  1021. (rtl_get_bbreg(hw, 0xecc, MASKDWORD) &
  1022. 0x3FF0000) >> 16;
  1023. break;
  1024. } else if (i == (retrycount - 1) && pathb_ok == 0x01) {
  1025. result[t][4] =
  1026. (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) &
  1027. 0x3FF0000) >> 16;
  1028. }
  1029. result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
  1030. 0x3FF0000) >> 16;
  1031. }
  1032. }
  1033. rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04);
  1034. rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874);
  1035. rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08);
  1036. rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
  1037. rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
  1038. if (is2t)
  1039. rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
  1040. if (t != 0) {
  1041. if (!rtlphy->rfpi_enable)
  1042. rtl8723_phy_pi_mode_switch(hw, false);
  1043. rtl8723_phy_reload_adda_registers(hw, adda_reg,
  1044. rtlphy->adda_backup, 16);
  1045. rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,
  1046. rtlphy->iqk_mac_backup);
  1047. }
  1048. }
  1049. static void _rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
  1050. {
  1051. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1052. u8 tmpreg;
  1053. u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
  1054. tmpreg = rtl_read_byte(rtlpriv, 0xd03);
  1055. if ((tmpreg & 0x70) != 0)
  1056. rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
  1057. else
  1058. rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
  1059. if ((tmpreg & 0x70) != 0) {
  1060. rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
  1061. if (is2t)
  1062. rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
  1063. MASK12BITS);
  1064. rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
  1065. (rf_a_mode & 0x8FFFF) | 0x10000);
  1066. if (is2t)
  1067. rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
  1068. (rf_b_mode & 0x8FFFF) | 0x10000);
  1069. }
  1070. lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
  1071. rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
  1072. mdelay(100);
  1073. if ((tmpreg & 0x70) != 0) {
  1074. rtl_write_byte(rtlpriv, 0xd03, tmpreg);
  1075. rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
  1076. if (is2t)
  1077. rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
  1078. rf_b_mode);
  1079. } else {
  1080. rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
  1081. }
  1082. }
  1083. static void _rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw,
  1084. bool bmain, bool is2t)
  1085. {
  1086. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  1087. if (is_hal_stop(rtlhal)) {
  1088. rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01);
  1089. rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
  1090. }
  1091. if (is2t) {
  1092. if (bmain)
  1093. rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
  1094. BIT(5) | BIT(6), 0x1);
  1095. else
  1096. rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
  1097. BIT(5) | BIT(6), 0x2);
  1098. } else {
  1099. if (bmain)
  1100. rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2);
  1101. else
  1102. rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1);
  1103. }
  1104. }
  1105. #undef IQK_ADDA_REG_NUM
  1106. #undef IQK_DELAY_TIME
  1107. void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
  1108. {
  1109. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1110. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  1111. long result[4][8];
  1112. u8 i, final_candidate;
  1113. bool patha_ok, pathb_ok;
  1114. long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_tmp = 0;
  1115. bool is12simular, is13simular, is23simular;
  1116. bool start_conttx = false, singletone = false;
  1117. u32 iqk_bb_reg[10] = {
  1118. ROFDM0_XARXIQIMBALANCE,
  1119. ROFDM0_XBRXIQIMBALANCE,
  1120. ROFDM0_ECCATHRESHOLD,
  1121. ROFDM0_AGCRSSITABLE,
  1122. ROFDM0_XATXIQIMBALANCE,
  1123. ROFDM0_XBTXIQIMBALANCE,
  1124. ROFDM0_XCTXIQIMBALANCE,
  1125. ROFDM0_XCTXAFE,
  1126. ROFDM0_XDTXAFE,
  1127. ROFDM0_RXIQEXTANTA
  1128. };
  1129. if (recovery) {
  1130. rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
  1131. rtlphy->iqk_bb_backup, 10);
  1132. return;
  1133. }
  1134. if (start_conttx || singletone)
  1135. return;
  1136. for (i = 0; i < 8; i++) {
  1137. result[0][i] = 0;
  1138. result[1][i] = 0;
  1139. result[2][i] = 0;
  1140. result[3][i] = 0;
  1141. }
  1142. final_candidate = 0xff;
  1143. patha_ok = false;
  1144. pathb_ok = false;
  1145. is12simular = false;
  1146. is23simular = false;
  1147. is13simular = false;
  1148. for (i = 0; i < 3; i++) {
  1149. _rtl8723ae_phy_iq_calibrate(hw, result, i, false);
  1150. if (i == 1) {
  1151. is12simular = phy_simularity_comp(hw, result, 0, 1);
  1152. if (is12simular) {
  1153. final_candidate = 0;
  1154. break;
  1155. }
  1156. }
  1157. if (i == 2) {
  1158. is13simular = phy_simularity_comp(hw, result, 0, 2);
  1159. if (is13simular) {
  1160. final_candidate = 0;
  1161. break;
  1162. }
  1163. is23simular = phy_simularity_comp(hw, result, 1, 2);
  1164. if (is23simular) {
  1165. final_candidate = 1;
  1166. } else {
  1167. for (i = 0; i < 8; i++)
  1168. reg_tmp += result[3][i];
  1169. if (reg_tmp != 0)
  1170. final_candidate = 3;
  1171. else
  1172. final_candidate = 0xFF;
  1173. }
  1174. }
  1175. }
  1176. for (i = 0; i < 4; i++) {
  1177. reg_e94 = result[i][0];
  1178. reg_e9c = result[i][1];
  1179. reg_ea4 = result[i][2];
  1180. reg_eb4 = result[i][4];
  1181. reg_ebc = result[i][5];
  1182. }
  1183. if (final_candidate != 0xff) {
  1184. rtlphy->reg_e94 = reg_e94 = result[final_candidate][0];
  1185. rtlphy->reg_e9c = reg_e9c = result[final_candidate][1];
  1186. reg_ea4 = result[final_candidate][2];
  1187. rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4];
  1188. rtlphy->reg_ebc = reg_ebc = result[final_candidate][5];
  1189. patha_ok = pathb_ok = true;
  1190. } else {
  1191. rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100;
  1192. rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0;
  1193. }
  1194. if (reg_e94 != 0) /*&&(reg_ea4 != 0) */
  1195. rtl8723_phy_path_a_fill_iqk_matrix(hw, patha_ok, result,
  1196. final_candidate,
  1197. (reg_ea4 == 0));
  1198. rtl8723_save_adda_registers(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 10);
  1199. }
  1200. void rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw)
  1201. {
  1202. bool start_conttx = false, singletone = false;
  1203. if (start_conttx || singletone)
  1204. return;
  1205. _rtl8723ae_phy_lc_calibrate(hw, false);
  1206. }
  1207. void rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
  1208. {
  1209. _rtl8723ae_phy_set_rfpath_switch(hw, bmain, false);
  1210. }
  1211. bool rtl8723ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
  1212. {
  1213. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1214. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  1215. bool postprocessing = false;
  1216. RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
  1217. "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
  1218. iotype, rtlphy->set_io_inprogress);
  1219. do {
  1220. switch (iotype) {
  1221. case IO_CMD_RESUME_DM_BY_SCAN:
  1222. RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
  1223. "[IO CMD] Resume DM after scan.\n");
  1224. postprocessing = true;
  1225. break;
  1226. case IO_CMD_PAUSE_DM_BY_SCAN:
  1227. RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
  1228. "[IO CMD] Pause DM before scan.\n");
  1229. postprocessing = true;
  1230. break;
  1231. default:
  1232. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  1233. "switch case not process\n");
  1234. break;
  1235. }
  1236. } while (false);
  1237. if (postprocessing && !rtlphy->set_io_inprogress) {
  1238. rtlphy->set_io_inprogress = true;
  1239. rtlphy->current_io_type = iotype;
  1240. } else {
  1241. return false;
  1242. }
  1243. rtl8723ae_phy_set_io(hw);
  1244. RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype);
  1245. return true;
  1246. }
  1247. static void rtl8723ae_phy_set_io(struct ieee80211_hw *hw)
  1248. {
  1249. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1250. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  1251. struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
  1252. RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
  1253. "--->Cmd(%#x), set_io_inprogress(%d)\n",
  1254. rtlphy->current_io_type, rtlphy->set_io_inprogress);
  1255. switch (rtlphy->current_io_type) {
  1256. case IO_CMD_RESUME_DM_BY_SCAN:
  1257. dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;
  1258. rtl8723ae_dm_write_dig(hw);
  1259. rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel);
  1260. break;
  1261. case IO_CMD_PAUSE_DM_BY_SCAN:
  1262. rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
  1263. dm_digtable->cur_igvalue = 0x17;
  1264. rtl8723ae_dm_write_dig(hw);
  1265. break;
  1266. default:
  1267. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  1268. "switch case not process\n");
  1269. break;
  1270. }
  1271. rtlphy->set_io_inprogress = false;
  1272. RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
  1273. "<---(%#x)\n", rtlphy->current_io_type);
  1274. }
  1275. static void rtl8723ae_phy_set_rf_on(struct ieee80211_hw *hw)
  1276. {
  1277. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1278. rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
  1279. rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
  1280. rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
  1281. rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
  1282. rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
  1283. rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
  1284. }
  1285. static void _rtl8723ae_phy_set_rf_sleep(struct ieee80211_hw *hw)
  1286. {
  1287. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1288. u32 u4b_tmp;
  1289. u8 delay = 5;
  1290. rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
  1291. rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
  1292. rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
  1293. u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
  1294. while (u4b_tmp != 0 && delay > 0) {
  1295. rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
  1296. rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
  1297. rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
  1298. u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
  1299. delay--;
  1300. }
  1301. if (delay == 0) {
  1302. rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
  1303. rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
  1304. rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
  1305. rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
  1306. RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
  1307. "Switch RF timeout !!!.\n");
  1308. return;
  1309. }
  1310. rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
  1311. rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
  1312. }
  1313. static bool _rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
  1314. enum rf_pwrstate rfpwr_state)
  1315. {
  1316. struct rtl_priv *rtlpriv = rtl_priv(hw);
  1317. struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
  1318. struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
  1319. struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
  1320. struct rtl8192_tx_ring *ring = NULL;
  1321. bool bresult = true;
  1322. u8 i, queue_id;
  1323. switch (rfpwr_state) {
  1324. case ERFON:
  1325. if ((ppsc->rfpwr_state == ERFOFF) &&
  1326. RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
  1327. bool rtstatus;
  1328. u32 InitializeCount = 0;
  1329. do {
  1330. InitializeCount++;
  1331. RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
  1332. "IPS Set eRf nic enable\n");
  1333. rtstatus = rtl_ps_enable_nic(hw);
  1334. } while ((rtstatus != true) && (InitializeCount < 10));
  1335. RT_CLEAR_PS_LEVEL(ppsc,
  1336. RT_RF_OFF_LEVL_HALT_NIC);
  1337. } else {
  1338. RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
  1339. "Set ERFON sleeped:%d ms\n",
  1340. jiffies_to_msecs(jiffies -
  1341. ppsc->last_sleep_jiffies));
  1342. ppsc->last_awake_jiffies = jiffies;
  1343. rtl8723ae_phy_set_rf_on(hw);
  1344. }
  1345. if (mac->link_state == MAC80211_LINKED) {
  1346. rtlpriv->cfg->ops->led_control(hw,
  1347. LED_CTL_LINK);
  1348. } else {
  1349. rtlpriv->cfg->ops->led_control(hw,
  1350. LED_CTL_NO_LINK);
  1351. }
  1352. break;
  1353. case ERFOFF:
  1354. if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
  1355. RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
  1356. "IPS Set eRf nic disable\n");
  1357. rtl_ps_disable_nic(hw);
  1358. RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
  1359. } else {
  1360. if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
  1361. rtlpriv->cfg->ops->led_control(hw,
  1362. LED_CTL_NO_LINK);
  1363. } else {
  1364. rtlpriv->cfg->ops->led_control(hw,
  1365. LED_CTL_POWER_OFF);
  1366. }
  1367. }
  1368. break;
  1369. case ERFSLEEP:
  1370. if (ppsc->rfpwr_state == ERFOFF)
  1371. break;
  1372. for (queue_id = 0, i = 0;
  1373. queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
  1374. ring = &pcipriv->dev.tx_ring[queue_id];
  1375. if (skb_queue_len(&ring->queue) == 0) {
  1376. queue_id++;
  1377. continue;
  1378. } else {
  1379. RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
  1380. "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
  1381. (i + 1), queue_id,
  1382. skb_queue_len(&ring->queue));
  1383. udelay(10);
  1384. i++;
  1385. }
  1386. if (i >= MAX_DOZE_WAITING_TIMES_9x) {
  1387. RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
  1388. "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
  1389. MAX_DOZE_WAITING_TIMES_9x,
  1390. queue_id,
  1391. skb_queue_len(&ring->queue));
  1392. break;
  1393. }
  1394. }
  1395. RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
  1396. "Set ERFSLEEP awaked:%d ms\n",
  1397. jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies));
  1398. ppsc->last_sleep_jiffies = jiffies;
  1399. _rtl8723ae_phy_set_rf_sleep(hw);
  1400. break;
  1401. default:
  1402. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  1403. "switch case not processed\n");
  1404. bresult = false;
  1405. break;
  1406. }
  1407. if (bresult)
  1408. ppsc->rfpwr_state = rfpwr_state;
  1409. return bresult;
  1410. }
  1411. bool rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
  1412. enum rf_pwrstate rfpwr_state)
  1413. {
  1414. struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
  1415. bool bresult = false;
  1416. if (rfpwr_state == ppsc->rfpwr_state)
  1417. return bresult;
  1418. bresult = _rtl8723ae_phy_set_rf_power_state(hw, rfpwr_state);
  1419. return bresult;
  1420. }