phy.c 17 KB

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