phy.c 19 KB

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