phy.c 16 KB

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