phy.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  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 "hw.h"
  36. #include "phy.h"
  37. #include "../rtl8192c/phy_common.h"
  38. #include "rf.h"
  39. #include "dm.h"
  40. #include "../rtl8192c/dm_common.h"
  41. #include "../rtl8192c/fw_common.h"
  42. #include "table.h"
  43. static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
  44. u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
  45. enum radio_path rfpath, u32 regaddr, u32 bitmask)
  46. {
  47. struct rtl_priv *rtlpriv = rtl_priv(hw);
  48. u32 original_value, readback_value, bitshift;
  49. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  50. RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  51. "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
  52. regaddr, rfpath, bitmask);
  53. spin_lock(&rtlpriv->locks.rf_lock);
  54. if (rtlphy->rf_mode != RF_OP_BY_FW) {
  55. original_value = _rtl92c_phy_rf_serial_read(hw,
  56. rfpath, regaddr);
  57. } else {
  58. original_value = _rtl92c_phy_fw_rf_serial_read(hw,
  59. rfpath, regaddr);
  60. }
  61. bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
  62. readback_value = (original_value & bitmask) >> bitshift;
  63. spin_unlock(&rtlpriv->locks.rf_lock);
  64. RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  65. "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
  66. regaddr, rfpath, bitmask, original_value);
  67. return readback_value;
  68. }
  69. bool rtl92c_phy_mac_config(struct ieee80211_hw *hw)
  70. {
  71. struct rtl_priv *rtlpriv = rtl_priv(hw);
  72. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  73. bool is92c = IS_92C_SERIAL(rtlhal->version);
  74. bool rtstatus = _rtl92c_phy_config_mac_with_headerfile(hw);
  75. if (is92c)
  76. rtl_write_byte(rtlpriv, 0x14, 0x71);
  77. else
  78. rtl_write_byte(rtlpriv, 0x04CA, 0x0A);
  79. return rtstatus;
  80. }
  81. bool rtl92c_phy_bb_config(struct ieee80211_hw *hw)
  82. {
  83. bool rtstatus = true;
  84. struct rtl_priv *rtlpriv = rtl_priv(hw);
  85. u16 regval;
  86. u32 regvaldw;
  87. u8 reg_hwparafile = 1;
  88. _rtl92c_phy_init_bb_rf_register_definition(hw);
  89. regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
  90. rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
  91. regval | BIT(13) | BIT(0) | BIT(1));
  92. rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83);
  93. rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb);
  94. rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
  95. rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
  96. FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
  97. FEN_BB_GLB_RSTn | FEN_BBRSTB);
  98. rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
  99. regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0);
  100. rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23));
  101. if (reg_hwparafile == 1)
  102. rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw);
  103. return rtstatus;
  104. }
  105. void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw,
  106. enum radio_path rfpath,
  107. u32 regaddr, u32 bitmask, u32 data)
  108. {
  109. struct rtl_priv *rtlpriv = rtl_priv(hw);
  110. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  111. u32 original_value, bitshift;
  112. RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  113. "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
  114. regaddr, bitmask, data, rfpath);
  115. spin_lock(&rtlpriv->locks.rf_lock);
  116. if (rtlphy->rf_mode != RF_OP_BY_FW) {
  117. if (bitmask != RFREG_OFFSET_MASK) {
  118. original_value = _rtl92c_phy_rf_serial_read(hw,
  119. rfpath,
  120. regaddr);
  121. bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
  122. data =
  123. ((original_value & (~bitmask)) |
  124. (data << bitshift));
  125. }
  126. _rtl92c_phy_rf_serial_write(hw, rfpath, regaddr, data);
  127. } else {
  128. if (bitmask != RFREG_OFFSET_MASK) {
  129. original_value = _rtl92c_phy_fw_rf_serial_read(hw,
  130. rfpath,
  131. regaddr);
  132. bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
  133. data =
  134. ((original_value & (~bitmask)) |
  135. (data << bitshift));
  136. }
  137. _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data);
  138. }
  139. spin_unlock(&rtlpriv->locks.rf_lock);
  140. RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  141. "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
  142. regaddr, bitmask, data, rfpath);
  143. }
  144. static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
  145. {
  146. struct rtl_priv *rtlpriv = rtl_priv(hw);
  147. u32 i;
  148. u32 arraylength;
  149. u32 *ptrarray;
  150. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n");
  151. arraylength = MAC_2T_ARRAYLENGTH;
  152. ptrarray = RTL8192CEMAC_2T_ARRAY;
  153. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CEMAC_2T_ARRAY\n");
  154. for (i = 0; i < arraylength; i = i + 2)
  155. rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
  156. return true;
  157. }
  158. bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
  159. u8 configtype)
  160. {
  161. int i;
  162. u32 *phy_regarray_table;
  163. u32 *agctab_array_table;
  164. u16 phy_reg_arraylen, agctab_arraylen;
  165. struct rtl_priv *rtlpriv = rtl_priv(hw);
  166. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  167. if (IS_92C_SERIAL(rtlhal->version)) {
  168. agctab_arraylen = AGCTAB_2TARRAYLENGTH;
  169. agctab_array_table = RTL8192CEAGCTAB_2TARRAY;
  170. phy_reg_arraylen = PHY_REG_2TARRAY_LENGTH;
  171. phy_regarray_table = RTL8192CEPHY_REG_2TARRAY;
  172. } else {
  173. agctab_arraylen = AGCTAB_1TARRAYLENGTH;
  174. agctab_array_table = RTL8192CEAGCTAB_1TARRAY;
  175. phy_reg_arraylen = PHY_REG_1TARRAY_LENGTH;
  176. phy_regarray_table = RTL8192CEPHY_REG_1TARRAY;
  177. }
  178. if (configtype == BASEBAND_CONFIG_PHY_REG) {
  179. for (i = 0; i < phy_reg_arraylen; i = i + 2) {
  180. rtl_addr_delay(phy_regarray_table[i]);
  181. rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,
  182. phy_regarray_table[i + 1]);
  183. udelay(1);
  184. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  185. "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
  186. phy_regarray_table[i],
  187. phy_regarray_table[i + 1]);
  188. }
  189. } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
  190. for (i = 0; i < agctab_arraylen; i = i + 2) {
  191. rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD,
  192. agctab_array_table[i + 1]);
  193. udelay(1);
  194. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  195. "The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
  196. agctab_array_table[i],
  197. agctab_array_table[i + 1]);
  198. }
  199. }
  200. return true;
  201. }
  202. bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
  203. u8 configtype)
  204. {
  205. struct rtl_priv *rtlpriv = rtl_priv(hw);
  206. int i;
  207. u32 *phy_regarray_table_pg;
  208. u16 phy_regarray_pg_len;
  209. phy_regarray_pg_len = PHY_REG_ARRAY_PGLENGTH;
  210. phy_regarray_table_pg = RTL8192CEPHY_REG_ARRAY_PG;
  211. if (configtype == BASEBAND_CONFIG_PHY_REG) {
  212. for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
  213. rtl_addr_delay(phy_regarray_table_pg[i]);
  214. _rtl92c_store_pwrIndex_diffrate_offset(hw,
  215. phy_regarray_table_pg[i],
  216. phy_regarray_table_pg[i + 1],
  217. phy_regarray_table_pg[i + 2]);
  218. }
  219. } else {
  220. RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
  221. "configtype != BaseBand_Config_PHY_REG\n");
  222. }
  223. return true;
  224. }
  225. bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
  226. enum radio_path rfpath)
  227. {
  228. int i;
  229. u32 *radioa_array_table;
  230. u32 *radiob_array_table;
  231. u16 radioa_arraylen, radiob_arraylen;
  232. struct rtl_priv *rtlpriv = rtl_priv(hw);
  233. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  234. if (IS_92C_SERIAL(rtlhal->version)) {
  235. radioa_arraylen = RADIOA_2TARRAYLENGTH;
  236. radioa_array_table = RTL8192CERADIOA_2TARRAY;
  237. radiob_arraylen = RADIOB_2TARRAYLENGTH;
  238. radiob_array_table = RTL8192CE_RADIOB_2TARRAY;
  239. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  240. "Radio_A:RTL8192CERADIOA_2TARRAY\n");
  241. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  242. "Radio_B:RTL8192CE_RADIOB_2TARRAY\n");
  243. } else {
  244. radioa_arraylen = RADIOA_1TARRAYLENGTH;
  245. radioa_array_table = RTL8192CE_RADIOA_1TARRAY;
  246. radiob_arraylen = RADIOB_1TARRAYLENGTH;
  247. radiob_array_table = RTL8192CE_RADIOB_1TARRAY;
  248. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  249. "Radio_A:RTL8192CE_RADIOA_1TARRAY\n");
  250. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
  251. "Radio_B:RTL8192CE_RADIOB_1TARRAY\n");
  252. }
  253. RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath);
  254. switch (rfpath) {
  255. case RF90_PATH_A:
  256. for (i = 0; i < radioa_arraylen; i = i + 2) {
  257. rtl_rfreg_delay(hw, rfpath, radioa_array_table[i],
  258. RFREG_OFFSET_MASK,
  259. radioa_array_table[i + 1]);
  260. }
  261. break;
  262. case RF90_PATH_B:
  263. for (i = 0; i < radiob_arraylen; i = i + 2) {
  264. rtl_rfreg_delay(hw, rfpath, radiob_array_table[i],
  265. RFREG_OFFSET_MASK,
  266. radiob_array_table[i + 1]);
  267. }
  268. break;
  269. case RF90_PATH_C:
  270. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  271. "switch case not processed\n");
  272. break;
  273. case RF90_PATH_D:
  274. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  275. "switch case not processed\n");
  276. break;
  277. default:
  278. break;
  279. }
  280. return true;
  281. }
  282. void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
  283. {
  284. struct rtl_priv *rtlpriv = rtl_priv(hw);
  285. struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  286. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  287. struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
  288. u8 reg_bw_opmode;
  289. u8 reg_prsr_rsc;
  290. RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n",
  291. rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
  292. "20MHz" : "40MHz");
  293. if (is_hal_stop(rtlhal)) {
  294. rtlphy->set_bwmode_inprogress = false;
  295. return;
  296. }
  297. reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
  298. reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
  299. switch (rtlphy->current_chan_bw) {
  300. case HT_CHANNEL_WIDTH_20:
  301. reg_bw_opmode |= BW_OPMODE_20MHZ;
  302. rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
  303. break;
  304. case HT_CHANNEL_WIDTH_20_40:
  305. reg_bw_opmode &= ~BW_OPMODE_20MHZ;
  306. rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
  307. reg_prsr_rsc =
  308. (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
  309. rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
  310. break;
  311. default:
  312. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  313. "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
  314. break;
  315. }
  316. switch (rtlphy->current_chan_bw) {
  317. case HT_CHANNEL_WIDTH_20:
  318. rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
  319. rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
  320. rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
  321. break;
  322. case HT_CHANNEL_WIDTH_20_40:
  323. rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
  324. rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
  325. rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
  326. (mac->cur_40_prime_sc >> 1));
  327. rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
  328. rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);
  329. rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
  330. (mac->cur_40_prime_sc ==
  331. HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
  332. break;
  333. default:
  334. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  335. "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
  336. break;
  337. }
  338. rtl92ce_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
  339. rtlphy->set_bwmode_inprogress = false;
  340. RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
  341. }
  342. void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
  343. {
  344. u8 tmpreg;
  345. u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
  346. struct rtl_priv *rtlpriv = rtl_priv(hw);
  347. tmpreg = rtl_read_byte(rtlpriv, 0xd03);
  348. if ((tmpreg & 0x70) != 0)
  349. rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
  350. else
  351. rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
  352. if ((tmpreg & 0x70) != 0) {
  353. rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
  354. if (is2t)
  355. rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
  356. MASK12BITS);
  357. rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
  358. (rf_a_mode & 0x8FFFF) | 0x10000);
  359. if (is2t)
  360. rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
  361. (rf_b_mode & 0x8FFFF) | 0x10000);
  362. }
  363. lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
  364. rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
  365. mdelay(100);
  366. if ((tmpreg & 0x70) != 0) {
  367. rtl_write_byte(rtlpriv, 0xd03, tmpreg);
  368. rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
  369. if (is2t)
  370. rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
  371. rf_b_mode);
  372. } else {
  373. rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
  374. }
  375. }
  376. static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw)
  377. {
  378. u32 u4b_tmp;
  379. u8 delay = 5;
  380. struct rtl_priv *rtlpriv = rtl_priv(hw);
  381. rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
  382. rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
  383. rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
  384. u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
  385. while (u4b_tmp != 0 && delay > 0) {
  386. rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
  387. rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
  388. rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
  389. u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
  390. delay--;
  391. }
  392. if (delay == 0) {
  393. rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
  394. rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
  395. rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
  396. rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
  397. RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
  398. "Switch RF timeout !!!\n");
  399. return;
  400. }
  401. rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
  402. rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
  403. }
  404. static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
  405. enum rf_pwrstate rfpwr_state)
  406. {
  407. struct rtl_priv *rtlpriv = rtl_priv(hw);
  408. struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
  409. struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
  410. struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
  411. bool bresult = true;
  412. u8 i, queue_id;
  413. struct rtl8192_tx_ring *ring = NULL;
  414. switch (rfpwr_state) {
  415. case ERFON:{
  416. if ((ppsc->rfpwr_state == ERFOFF) &&
  417. RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
  418. bool rtstatus;
  419. u32 InitializeCount = 0;
  420. do {
  421. InitializeCount++;
  422. RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
  423. "IPS Set eRf nic enable\n");
  424. rtstatus = rtl_ps_enable_nic(hw);
  425. } while (!rtstatus && (InitializeCount < 10));
  426. RT_CLEAR_PS_LEVEL(ppsc,
  427. RT_RF_OFF_LEVL_HALT_NIC);
  428. } else {
  429. RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
  430. "Set ERFON sleeped:%d ms\n",
  431. jiffies_to_msecs(jiffies -
  432. ppsc->
  433. last_sleep_jiffies));
  434. ppsc->last_awake_jiffies = jiffies;
  435. rtl92ce_phy_set_rf_on(hw);
  436. }
  437. if (mac->link_state == MAC80211_LINKED) {
  438. rtlpriv->cfg->ops->led_control(hw,
  439. LED_CTL_LINK);
  440. } else {
  441. rtlpriv->cfg->ops->led_control(hw,
  442. LED_CTL_NO_LINK);
  443. }
  444. break;
  445. }
  446. case ERFOFF:{
  447. if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
  448. RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
  449. "IPS Set eRf nic disable\n");
  450. rtl_ps_disable_nic(hw);
  451. RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
  452. } else {
  453. if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
  454. rtlpriv->cfg->ops->led_control(hw,
  455. LED_CTL_NO_LINK);
  456. } else {
  457. rtlpriv->cfg->ops->led_control(hw,
  458. LED_CTL_POWER_OFF);
  459. }
  460. }
  461. break;
  462. }
  463. case ERFSLEEP:{
  464. if (ppsc->rfpwr_state == ERFOFF)
  465. break;
  466. for (queue_id = 0, i = 0;
  467. queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
  468. ring = &pcipriv->dev.tx_ring[queue_id];
  469. if (queue_id == BEACON_QUEUE ||
  470. skb_queue_len(&ring->queue) == 0) {
  471. queue_id++;
  472. continue;
  473. } else {
  474. RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
  475. "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
  476. i + 1, queue_id,
  477. skb_queue_len(&ring->queue));
  478. udelay(10);
  479. i++;
  480. }
  481. if (i >= MAX_DOZE_WAITING_TIMES_9x) {
  482. RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
  483. "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
  484. MAX_DOZE_WAITING_TIMES_9x,
  485. queue_id,
  486. skb_queue_len(&ring->queue));
  487. break;
  488. }
  489. }
  490. RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
  491. "Set ERFSLEEP awaked:%d ms\n",
  492. jiffies_to_msecs(jiffies -
  493. ppsc->last_awake_jiffies));
  494. ppsc->last_sleep_jiffies = jiffies;
  495. _rtl92ce_phy_set_rf_sleep(hw);
  496. break;
  497. }
  498. default:
  499. RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
  500. "switch case not processed\n");
  501. bresult = false;
  502. break;
  503. }
  504. if (bresult)
  505. ppsc->rfpwr_state = rfpwr_state;
  506. return bresult;
  507. }
  508. bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,
  509. enum rf_pwrstate rfpwr_state)
  510. {
  511. struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
  512. bool bresult = false;
  513. if (rfpwr_state == ppsc->rfpwr_state)
  514. return bresult;
  515. bresult = _rtl92ce_phy_set_rf_power_state(hw, rfpwr_state);
  516. return bresult;
  517. }