blob: 285818df149b9ee4d07784b610f969e646a756d8 [file] [log] [blame]
Larry Fingera619d1a2014-02-28 15:16:50 -06001/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 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 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../pci.h"
28#include "../ps.h"
29#include "reg.h"
30#include "def.h"
31#include "phy.h"
32#include "../rtl8723com/phy_common.h"
33#include "rf.h"
34#include "dm.h"
Larry Finger5c99f042014-09-26 16:40:25 -050035#include "../rtl8723com/dm_common.h"
Larry Fingera619d1a2014-02-28 15:16:50 -060036#include "table.h"
37#include "trx.h"
38
39static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw);
Larry Finger5c99f042014-09-26 16:40:25 -050040static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
41static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
42 u8 configtype);
Larry Fingera619d1a2014-02-28 15:16:50 -060043static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
44 u8 configtype);
Larry Finger5c99f042014-09-26 16:40:25 -050045static bool _rtl8723be_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
46 u8 channel, u8 *stage,
47 u8 *step, u32 *delay);
Larry Fingera619d1a2014-02-28 15:16:50 -060048
Larry Finger5c99f042014-09-26 16:40:25 -050049static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw);
50static void rtl8723be_phy_set_io(struct ieee80211_hw *hw);
Larry Fingera619d1a2014-02-28 15:16:50 -060051
52u32 rtl8723be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
53 u32 regaddr, u32 bitmask)
54{
55 struct rtl_priv *rtlpriv = rtl_priv(hw);
56 u32 original_value, readback_value, bitshift;
57 unsigned long flags;
58
59 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
60 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
61 regaddr, rfpath, bitmask);
62
63 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
64
65 original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr);
66 bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
67 readback_value = (original_value & bitmask) >> bitshift;
68
69 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
70
71 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
Larry Finger5c99f042014-09-26 16:40:25 -050072 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
73 regaddr, rfpath, bitmask, original_value);
Larry Fingera619d1a2014-02-28 15:16:50 -060074
75 return readback_value;
76}
77
78void rtl8723be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path path,
79 u32 regaddr, u32 bitmask, u32 data)
80{
81 struct rtl_priv *rtlpriv = rtl_priv(hw);
82 u32 original_value, bitshift;
83 unsigned long flags;
84
85 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
86 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
87 regaddr, bitmask, data, path);
88
89 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
90
91 if (bitmask != RFREG_OFFSET_MASK) {
92 original_value = rtl8723_phy_rf_serial_read(hw, path,
93 regaddr);
94 bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
95 data = ((original_value & (~bitmask)) |
96 (data << bitshift));
97 }
98
99 rtl8723_phy_rf_serial_write(hw, path, regaddr, data);
100
101 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
102
103 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
104 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
105 regaddr, bitmask, data, path);
Larry Finger5c99f042014-09-26 16:40:25 -0500106
Larry Fingera619d1a2014-02-28 15:16:50 -0600107}
108
109bool rtl8723be_phy_mac_config(struct ieee80211_hw *hw)
110{
111 struct rtl_priv *rtlpriv = rtl_priv(hw);
112 bool rtstatus = _rtl8723be_phy_config_mac_with_headerfile(hw);
113
114 rtl_write_byte(rtlpriv, 0x04CA, 0x0B);
115 return rtstatus;
116}
117
118bool rtl8723be_phy_bb_config(struct ieee80211_hw *hw)
119{
120 bool rtstatus = true;
121 struct rtl_priv *rtlpriv = rtl_priv(hw);
122 u16 regval;
Larry Finger5c99f042014-09-26 16:40:25 -0500123 u8 b_reg_hwparafile = 1;
Larry Fingera619d1a2014-02-28 15:16:50 -0600124 u32 tmp;
125 u8 crystalcap = rtlpriv->efuse.crystalcap;
126 rtl8723_phy_init_bb_rf_reg_def(hw);
127 regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
128 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
129 regval | BIT(13) | BIT(0) | BIT(1));
130
131 rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
132 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
133 FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
134 FEN_BB_GLB_RSTN | FEN_BBRSTB);
135 tmp = rtl_read_dword(rtlpriv, 0x4c);
136 rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23));
137
138 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
139
Larry Finger5c99f042014-09-26 16:40:25 -0500140 if (b_reg_hwparafile == 1)
Larry Fingera619d1a2014-02-28 15:16:50 -0600141 rtstatus = _rtl8723be_phy_bb8723b_config_parafile(hw);
142
143 crystalcap = crystalcap & 0x3F;
144 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
145 (crystalcap | crystalcap << 6));
146
147 return rtstatus;
148}
149
150bool rtl8723be_phy_rf_config(struct ieee80211_hw *hw)
151{
152 return rtl8723be_phy_rf6052_config(hw);
153}
154
Larry Finger5c99f042014-09-26 16:40:25 -0500155static bool _rtl8723be_check_condition(struct ieee80211_hw *hw,
156 const u32 condition)
157{
158 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
159 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
160 u32 _board = rtlefuse->board_type; /*need efuse define*/
161 u32 _interface = rtlhal->interface;
162 u32 _platform = 0x08;/*SupportPlatform */
163 u32 cond = condition;
164
165 if (condition == 0xCDCDCDCD)
166 return true;
167
168 cond = condition & 0xFF;
169 if ((_board & cond) == 0 && cond != 0x1F)
170 return false;
171
172 cond = condition & 0xFF00;
173 cond = cond >> 8;
174 if ((_interface & cond) == 0 && cond != 0x07)
175 return false;
176
177 cond = condition & 0xFF0000;
178 cond = cond >> 16;
179 if ((_platform & cond) == 0 && cond != 0x0F)
180 return false;
181 return true;
182}
183
Larry Fingera619d1a2014-02-28 15:16:50 -0600184static void _rtl8723be_config_rf_reg(struct ieee80211_hw *hw, u32 addr,
185 u32 data, enum radio_path rfpath,
186 u32 regaddr)
187{
188 if (addr == 0xfe || addr == 0xffe) {
Larry Finger5c99f042014-09-26 16:40:25 -0500189 /* In order not to disturb BT music
190 * when wifi init.(1ant NIC only)
191 */
Larry Fingera619d1a2014-02-28 15:16:50 -0600192 mdelay(50);
193 } else {
194 rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
195 udelay(1);
196 }
197}
Larry Fingera619d1a2014-02-28 15:16:50 -0600198static void _rtl8723be_config_rf_radio_a(struct ieee80211_hw *hw,
199 u32 addr, u32 data)
200{
201 u32 content = 0x1000; /*RF Content: radio_a_txt*/
202 u32 maskforphyset = (u32)(content & 0xE000);
203
204 _rtl8723be_config_rf_reg(hw, addr, data, RF90_PATH_A,
205 addr | maskforphyset);
Larry Finger5c99f042014-09-26 16:40:25 -0500206
Larry Fingera619d1a2014-02-28 15:16:50 -0600207}
208
209static void _rtl8723be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
210{
211 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500212 struct rtl_phy *rtlphy = &rtlpriv->phy;
Larry Fingera619d1a2014-02-28 15:16:50 -0600213
214 u8 band, path, txnum, section;
215
216 for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
217 for (path = 0; path < TX_PWR_BY_RATE_NUM_RF; ++path)
218 for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
219 for (section = 0;
220 section < TX_PWR_BY_RATE_NUM_SECTION;
221 ++section)
Larry Finger5c99f042014-09-26 16:40:25 -0500222 rtlphy->tx_power_by_rate_offset
223 [band][path][txnum][section] = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -0600224}
225
Larry Finger5c99f042014-09-26 16:40:25 -0500226static void _rtl8723be_config_bb_reg(struct ieee80211_hw *hw,
227 u32 addr, u32 data)
228{
229 if (addr == 0xfe) {
230 mdelay(50);
231 } else if (addr == 0xfd) {
232 mdelay(5);
233 } else if (addr == 0xfc) {
234 mdelay(1);
235 } else if (addr == 0xfb) {
236 udelay(50);
237 } else if (addr == 0xfa) {
238 udelay(5);
239 } else if (addr == 0xf9) {
240 udelay(1);
241 } else {
242 rtl_set_bbreg(hw, addr, MASKDWORD, data);
243 udelay(1);
244 }
245}
246
247static void _rtl8723be_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
248 u8 band,
249 u8 path, u8 rate_section,
250 u8 txnum, u8 value)
Larry Fingera619d1a2014-02-28 15:16:50 -0600251{
252 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500253 struct rtl_phy *rtlphy = &rtlpriv->phy;
Larry Fingera619d1a2014-02-28 15:16:50 -0600254
255 if (path > RF90_PATH_D) {
256 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
257 "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n",
258 path);
259 return;
260 }
261
262 if (band == BAND_ON_2_4G) {
263 switch (rate_section) {
264 case CCK:
265 rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
266 break;
267 case OFDM:
268 rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
269 break;
270 case HT_MCS0_MCS7:
271 rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
272 break;
273 case HT_MCS8_MCS15:
274 rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
275 break;
276 default:
277 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Larry Finger5c99f042014-09-26 16:40:25 -0500278 "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
279 rate_section, path, txnum);
Larry Fingera619d1a2014-02-28 15:16:50 -0600280 break;
281 };
282 } else {
283 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
284 "Invalid Band %d in PHY_SetTxPowerByRateBase()\n",
Larry Finger5c99f042014-09-26 16:40:25 -0500285 band);
Larry Fingera619d1a2014-02-28 15:16:50 -0600286 }
Larry Finger5c99f042014-09-26 16:40:25 -0500287
Larry Fingera619d1a2014-02-28 15:16:50 -0600288}
289
Larry Finger5c99f042014-09-26 16:40:25 -0500290static u8 _rtl8723be_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
291 u8 band, u8 path, u8 txnum,
292 u8 rate_section)
Larry Fingera619d1a2014-02-28 15:16:50 -0600293{
294 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500295 struct rtl_phy *rtlphy = &rtlpriv->phy;
Larry Fingera619d1a2014-02-28 15:16:50 -0600296 u8 value = 0;
297 if (path > RF90_PATH_D) {
298 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
299 "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n",
300 path);
301 return 0;
302 }
303
304 if (band == BAND_ON_2_4G) {
305 switch (rate_section) {
306 case CCK:
307 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
308 break;
309 case OFDM:
310 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
311 break;
312 case HT_MCS0_MCS7:
313 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
314 break;
315 case HT_MCS8_MCS15:
316 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
317 break;
318 default:
319 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Larry Finger5c99f042014-09-26 16:40:25 -0500320 "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
321 rate_section, path, txnum);
Larry Fingera619d1a2014-02-28 15:16:50 -0600322 break;
323 };
324 } else {
325 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
326 "Invalid Band %d in PHY_GetTxPowerByRateBase()\n",
Larry Finger5c99f042014-09-26 16:40:25 -0500327 band);
Larry Fingera619d1a2014-02-28 15:16:50 -0600328 }
329
330 return value;
331}
332
333static void _rtl8723be_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
334{
335 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500336 struct rtl_phy *rtlphy = &rtlpriv->phy;
337 u16 rawvalue = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -0600338 u8 base = 0, path = 0;
339
340 for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
341 if (path == RF90_PATH_A) {
Larry Finger5c99f042014-09-26 16:40:25 -0500342 rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
Larry Fingera619d1a2014-02-28 15:16:50 -0600343 [BAND_ON_2_4G][path][RF_1TX][3] >> 24) & 0xFF;
Larry Finger5c99f042014-09-26 16:40:25 -0500344 base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
345 _rtl8723be_phy_set_txpower_by_rate_base(hw,
346 BAND_ON_2_4G, path, CCK, RF_1TX, base);
Larry Fingera619d1a2014-02-28 15:16:50 -0600347 } else if (path == RF90_PATH_B) {
Larry Finger5c99f042014-09-26 16:40:25 -0500348 rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
Larry Fingera619d1a2014-02-28 15:16:50 -0600349 [BAND_ON_2_4G][path][RF_1TX][3] >> 0) & 0xFF;
Larry Finger5c99f042014-09-26 16:40:25 -0500350 base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
351 _rtl8723be_phy_set_txpower_by_rate_base(hw,
352 BAND_ON_2_4G,
353 path, CCK,
354 RF_1TX, base);
Larry Fingera619d1a2014-02-28 15:16:50 -0600355 }
Larry Finger5c99f042014-09-26 16:40:25 -0500356 rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
357 [BAND_ON_2_4G][path][RF_1TX][1] >> 24) & 0xFF;
358 base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
359 _rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
360 path, OFDM, RF_1TX,
361 base);
Larry Fingera619d1a2014-02-28 15:16:50 -0600362
Larry Finger5c99f042014-09-26 16:40:25 -0500363 rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
364 [BAND_ON_2_4G][path][RF_1TX][5] >> 24) & 0xFF;
365 base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
366 _rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
367 path, HT_MCS0_MCS7,
368 RF_1TX, base);
Larry Fingera619d1a2014-02-28 15:16:50 -0600369
Larry Finger5c99f042014-09-26 16:40:25 -0500370 rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
371 [BAND_ON_2_4G][path][RF_2TX][7] >> 24) & 0xFF;
372 base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
373 _rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
374 path, HT_MCS8_MCS15,
375 RF_2TX, base);
Larry Fingera619d1a2014-02-28 15:16:50 -0600376 }
377}
378
Larry Finger5c99f042014-09-26 16:40:25 -0500379static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start,
380 u8 end, u8 base_val)
Larry Fingera619d1a2014-02-28 15:16:50 -0600381{
Arnd Bergmann08aba422016-06-15 23:30:43 +0200382 s8 i = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -0600383 u8 temp_value = 0;
384 u32 temp_data = 0;
385
386 for (i = 3; i >= 0; --i) {
387 if (i >= start && i <= end) {
388 /* Get the exact value */
Larry Finger5c99f042014-09-26 16:40:25 -0500389 temp_value = (u8)(*data >> (i * 8)) & 0xF;
390 temp_value += ((u8)((*data >> (i*8 + 4)) & 0xF)) * 10;
Larry Fingera619d1a2014-02-28 15:16:50 -0600391
392 /* Change the value to a relative value */
393 temp_value = (temp_value > base_val) ?
394 temp_value - base_val :
395 base_val - temp_value;
396 } else {
Larry Finger5c99f042014-09-26 16:40:25 -0500397 temp_value = (u8)(*data >> (i * 8)) & 0xFF;
Larry Fingera619d1a2014-02-28 15:16:50 -0600398 }
399 temp_data <<= 8;
400 temp_data |= temp_value;
401 }
402 *data = temp_data;
403}
404
Larry Finger5c99f042014-09-26 16:40:25 -0500405static void _rtl8723be_phy_convert_txpower_dbm_to_relative_value(
Larry Fingera619d1a2014-02-28 15:16:50 -0600406 struct ieee80211_hw *hw)
407{
Larry Finger5c99f042014-09-26 16:40:25 -0500408 struct rtl_priv *rtlpriv = rtl_priv(hw);
409 struct rtl_phy *rtlphy = &rtlpriv->phy;
410 u8 base = 0, rfpath = RF90_PATH_A;
411
412 base = _rtl8723be_phy_get_txpower_by_rate_base(hw,
413 BAND_ON_2_4G, rfpath, RF_1TX, CCK);
414 _phy_convert_txpower_dbm_to_relative_value(
415 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][2],
416 1, 1, base);
417 _phy_convert_txpower_dbm_to_relative_value(
418 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][3],
419 1, 3, base);
420
421 base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfpath,
422 RF_1TX, OFDM);
423 _phy_convert_txpower_dbm_to_relative_value(
424 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][0],
425 0, 3, base);
426 _phy_convert_txpower_dbm_to_relative_value(
427 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][1],
428 0, 3, base);
429
430 base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G,
431 rfpath, RF_1TX, HT_MCS0_MCS7);
432 _phy_convert_txpower_dbm_to_relative_value(
433 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][4],
434 0, 3, base);
435 _phy_convert_txpower_dbm_to_relative_value(
436 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][5],
437 0, 3, base);
438
439 base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G,
440 rfpath, RF_2TX,
441 HT_MCS8_MCS15);
442 _phy_convert_txpower_dbm_to_relative_value(
443 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][6],
444 0, 3, base);
445
446 _phy_convert_txpower_dbm_to_relative_value(
447 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][7],
448 0, 3, base);
449
450 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
451 "<===_rtl8723be_phy_convert_txpower_dbm_to_relative_value()\n");
452}
453
454static void phy_txpower_by_rate_config(struct ieee80211_hw *hw)
455{
Larry Fingera619d1a2014-02-28 15:16:50 -0600456 _rtl8723be_phy_store_txpower_by_rate_base(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500457 _rtl8723be_phy_convert_txpower_dbm_to_relative_value(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -0600458}
459
460static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw)
461{
462 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500463 struct rtl_phy *rtlphy = &rtlpriv->phy;
Larry Fingera619d1a2014-02-28 15:16:50 -0600464 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
465 bool rtstatus;
466
467 rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
468 BASEBAND_CONFIG_PHY_REG);
469 if (!rtstatus) {
Joe Perches4713bd12016-06-26 12:34:30 -0700470 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!\n");
Larry Fingera619d1a2014-02-28 15:16:50 -0600471 return false;
472 }
473 _rtl8723be_phy_init_tx_power_by_rate(hw);
474 if (!rtlefuse->autoload_failflag) {
475 rtlphy->pwrgroup_cnt = 0;
476 rtstatus = _rtl8723be_phy_config_bb_with_pgheaderfile(hw,
477 BASEBAND_CONFIG_PHY_REG);
478 }
Larry Finger5c99f042014-09-26 16:40:25 -0500479 phy_txpower_by_rate_config(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -0600480 if (!rtstatus) {
Joe Perches4713bd12016-06-26 12:34:30 -0700481 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!\n");
Larry Fingera619d1a2014-02-28 15:16:50 -0600482 return false;
483 }
484 rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
485 BASEBAND_CONFIG_AGC_TAB);
486 if (!rtstatus) {
487 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
488 return false;
489 }
Larry Finger5c99f042014-09-26 16:40:25 -0500490 rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw,
491 RFPGA0_XA_HSSIPARAMETER2,
492 0x200));
Larry Fingera619d1a2014-02-28 15:16:50 -0600493 return true;
494}
495
Larry Finger5c99f042014-09-26 16:40:25 -0500496static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
497{
498 struct rtl_priv *rtlpriv = rtl_priv(hw);
499 u32 i;
500 u32 arraylength;
501 u32 *ptrarray;
502
503 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read rtl8723beMACPHY_Array\n");
504 arraylength = RTL8723BEMAC_1T_ARRAYLEN;
505 ptrarray = RTL8723BEMAC_1T_ARRAY;
506 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
507 "Img:RTL8723bEMAC_1T_ARRAY LEN %d\n", arraylength);
508 for (i = 0; i < arraylength; i = i + 2)
509 rtl_write_byte(rtlpriv, ptrarray[i], (u8)ptrarray[i + 1]);
510 return true;
511}
512
513static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
514 u8 configtype)
515{
516 #define READ_NEXT_PAIR(v1, v2, i) \
517 do { \
518 i += 2; \
519 v1 = array_table[i];\
520 v2 = array_table[i+1]; \
521 } while (0)
522
523 int i;
524 u32 *array_table;
525 u16 arraylen;
526 struct rtl_priv *rtlpriv = rtl_priv(hw);
527 u32 v1 = 0, v2 = 0;
528
529 if (configtype == BASEBAND_CONFIG_PHY_REG) {
530 arraylen = RTL8723BEPHY_REG_1TARRAYLEN;
531 array_table = RTL8723BEPHY_REG_1TARRAY;
532
533 for (i = 0; i < arraylen; i = i + 2) {
534 v1 = array_table[i];
535 v2 = array_table[i+1];
536 if (v1 < 0xcdcdcdcd) {
537 _rtl8723be_config_bb_reg(hw, v1, v2);
538 } else {/*This line is the start line of branch.*/
539 /* to protect READ_NEXT_PAIR not overrun */
540 if (i >= arraylen - 2)
541 break;
542
543 if (!_rtl8723be_check_condition(hw,
544 array_table[i])) {
545 /*Discard the following
546 *(offset, data) pairs
547 */
548 READ_NEXT_PAIR(v1, v2, i);
549 while (v2 != 0xDEAD &&
550 v2 != 0xCDEF &&
551 v2 != 0xCDCD &&
552 i < arraylen - 2) {
553 READ_NEXT_PAIR(v1, v2, i);
554 }
555 i -= 2; /* prevent from for-loop += 2*/
556 /*Configure matched pairs and
557 *skip to end of if-else.
558 */
559 } else {
560 READ_NEXT_PAIR(v1, v2, i);
561 while (v2 != 0xDEAD &&
562 v2 != 0xCDEF &&
563 v2 != 0xCDCD &&
564 i < arraylen - 2) {
565 _rtl8723be_config_bb_reg(hw,
566 v1, v2);
567 READ_NEXT_PAIR(v1, v2, i);
568 }
569
570 while (v2 != 0xDEAD && i < arraylen - 2)
571 READ_NEXT_PAIR(v1, v2, i);
572 }
573 }
574 }
575 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
576 arraylen = RTL8723BEAGCTAB_1TARRAYLEN;
577 array_table = RTL8723BEAGCTAB_1TARRAY;
578
579 for (i = 0; i < arraylen; i = i + 2) {
580 v1 = array_table[i];
581 v2 = array_table[i+1];
582 if (v1 < 0xCDCDCDCD) {
583 rtl_set_bbreg(hw, array_table[i],
584 MASKDWORD,
585 array_table[i + 1]);
586 udelay(1);
587 continue;
588 } else {/*This line is the start line of branch.*/
589 /* to protect READ_NEXT_PAIR not overrun */
590 if (i >= arraylen - 2)
591 break;
592
593 if (!_rtl8723be_check_condition(hw,
594 array_table[i])) {
595 /*Discard the following
596 *(offset, data) pairs
597 */
598 READ_NEXT_PAIR(v1, v2, i);
599 while (v2 != 0xDEAD &&
600 v2 != 0xCDEF &&
601 v2 != 0xCDCD &&
602 i < arraylen - 2) {
603 READ_NEXT_PAIR(v1, v2, i);
604 }
605 i -= 2; /* prevent from for-loop += 2*/
606 /*Configure matched pairs and
607 *skip to end of if-else.
608 */
609 } else {
610 READ_NEXT_PAIR(v1, v2, i);
611 while (v2 != 0xDEAD &&
612 v2 != 0xCDEF &&
613 v2 != 0xCDCD &&
614 i < arraylen - 2) {
615 rtl_set_bbreg(hw, array_table[i],
616 MASKDWORD,
617 array_table[i + 1]);
618 udelay(1);
619 READ_NEXT_PAIR(v1, v2, i);
620 }
621
622 while (v2 != 0xDEAD && i < arraylen - 2)
623 READ_NEXT_PAIR(v1, v2, i);
624 }
625 }
626 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
627 "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n",
628 array_table[i], array_table[i + 1]);
629 }
630 }
631 return true;
632}
633
634static u8 _rtl8723be_get_rate_section_index(u32 regaddr)
635{
636 u8 index = 0;
637
638 switch (regaddr) {
639 case RTXAGC_A_RATE18_06:
640 index = 0;
641 break;
642 case RTXAGC_A_RATE54_24:
643 index = 1;
644 break;
645 case RTXAGC_A_CCK1_MCS32:
646 index = 2;
647 break;
648 case RTXAGC_B_CCK11_A_CCK2_11:
649 index = 3;
650 break;
651 case RTXAGC_A_MCS03_MCS00:
652 index = 4;
653 break;
654 case RTXAGC_A_MCS07_MCS04:
655 index = 5;
656 break;
657 case RTXAGC_A_MCS11_MCS08:
658 index = 6;
659 break;
660 case RTXAGC_A_MCS15_MCS12:
661 index = 7;
662 break;
663 case RTXAGC_B_RATE18_06:
664 index = 0;
665 break;
666 case RTXAGC_B_RATE54_24:
667 index = 1;
668 break;
669 case RTXAGC_B_CCK1_55_MCS32:
670 index = 2;
671 break;
672 case RTXAGC_B_MCS03_MCS00:
673 index = 4;
674 break;
675 case RTXAGC_B_MCS07_MCS04:
676 index = 5;
677 break;
678 case RTXAGC_B_MCS11_MCS08:
679 index = 6;
680 break;
681 case RTXAGC_B_MCS15_MCS12:
682 index = 7;
683 break;
684 default:
685 regaddr &= 0xFFF;
686 if (regaddr >= 0xC20 && regaddr <= 0xC4C)
687 index = (u8)((regaddr - 0xC20) / 4);
688 else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
689 index = (u8)((regaddr - 0xE20) / 4);
690 break;
691 };
692 return index;
693}
694
Larry Fingera619d1a2014-02-28 15:16:50 -0600695static void _rtl8723be_store_tx_power_by_rate(struct ieee80211_hw *hw,
696 u32 band, u32 rfpath,
697 u32 txnum, u32 regaddr,
698 u32 bitmask, u32 data)
699{
700 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500701 struct rtl_phy *rtlphy = &rtlpriv->phy;
Larry Fingera619d1a2014-02-28 15:16:50 -0600702 u8 rate_section = _rtl8723be_get_rate_section_index(regaddr);
703
Larry Finger4e3b3bc2014-03-10 18:53:10 -0500704 if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
Larry Finger5c99f042014-09-26 16:40:25 -0500705 RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid Band %d\n", band);
Larry Finger4e3b3bc2014-03-10 18:53:10 -0500706 return;
707 }
Larry Finger5c99f042014-09-26 16:40:25 -0500708 if (rfpath > MAX_RF_PATH - 1) {
709 RT_TRACE(rtlpriv, FPHY, PHY_TXPWR,
Larry Fingera619d1a2014-02-28 15:16:50 -0600710 "Invalid RfPath %d\n", rfpath);
Larry Finger4e3b3bc2014-03-10 18:53:10 -0500711 return;
712 }
Larry Finger5c99f042014-09-26 16:40:25 -0500713 if (txnum > MAX_RF_PATH - 1) {
714 RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid TxNum %d\n", txnum);
Larry Finger4e3b3bc2014-03-10 18:53:10 -0500715 return;
716 }
Larry Finger5c99f042014-09-26 16:40:25 -0500717
Larry Fingera619d1a2014-02-28 15:16:50 -0600718 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] =
719 data;
Larry Finger5c99f042014-09-26 16:40:25 -0500720
Larry Fingera619d1a2014-02-28 15:16:50 -0600721}
722
723static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
724 u8 configtype)
725{
726 struct rtl_priv *rtlpriv = rtl_priv(hw);
727 int i;
728 u32 *phy_regarray_table_pg;
729 u16 phy_regarray_pg_len;
730 u32 v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0;
731
732 phy_regarray_pg_len = RTL8723BEPHY_REG_ARRAY_PGLEN;
733 phy_regarray_table_pg = RTL8723BEPHY_REG_ARRAY_PG;
734
735 if (configtype == BASEBAND_CONFIG_PHY_REG) {
736 for (i = 0; i < phy_regarray_pg_len; i = i + 6) {
737 v1 = phy_regarray_table_pg[i];
738 v2 = phy_regarray_table_pg[i+1];
739 v3 = phy_regarray_table_pg[i+2];
740 v4 = phy_regarray_table_pg[i+3];
741 v5 = phy_regarray_table_pg[i+4];
742 v6 = phy_regarray_table_pg[i+5];
743
744 if (v1 < 0xcdcdcdcd) {
745 if (phy_regarray_table_pg[i] == 0xfe ||
746 phy_regarray_table_pg[i] == 0xffe)
747 mdelay(50);
748 else
749 _rtl8723be_store_tx_power_by_rate(hw,
750 v1, v2, v3, v4, v5, v6);
751 continue;
Larry Fingera619d1a2014-02-28 15:16:50 -0600752 }
753 }
754 } else {
755 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
756 "configtype != BaseBand_Config_PHY_REG\n");
757 }
758 return true;
759}
760
761bool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
762 enum radio_path rfpath)
763{
764 #define READ_NEXT_RF_PAIR(v1, v2, i) \
765 do { \
766 i += 2; \
767 v1 = radioa_array_table[i]; \
768 v2 = radioa_array_table[i+1]; \
769 } while (0)
770
771 int i;
772 bool rtstatus = true;
773 u32 *radioa_array_table;
774 u16 radioa_arraylen;
775 struct rtl_priv *rtlpriv = rtl_priv(hw);
776 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
777 u32 v1 = 0, v2 = 0;
778
779 radioa_arraylen = RTL8723BE_RADIOA_1TARRAYLEN;
780 radioa_array_table = RTL8723BE_RADIOA_1TARRAY;
781 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
782 "Radio_A:RTL8723BE_RADIOA_1TARRAY %d\n", radioa_arraylen);
783 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
784 rtstatus = true;
785 switch (rfpath) {
786 case RF90_PATH_A:
787 for (i = 0; i < radioa_arraylen; i = i + 2) {
788 v1 = radioa_array_table[i];
789 v2 = radioa_array_table[i+1];
790 if (v1 < 0xcdcdcdcd) {
791 _rtl8723be_config_rf_radio_a(hw, v1, v2);
Larry Finger5c99f042014-09-26 16:40:25 -0500792 } else {/*This line is the start line of branch.*/
793 /* to protect READ_NEXT_PAIR not overrun */
794 if (i >= radioa_arraylen - 2)
795 break;
796
Larry Fingera619d1a2014-02-28 15:16:50 -0600797 if (!_rtl8723be_check_condition(hw,
798 radioa_array_table[i])) {
Larry Finger5c99f042014-09-26 16:40:25 -0500799 /*Discard the following
800 *(offset, data) pairs
Larry Fingera619d1a2014-02-28 15:16:50 -0600801 */
802 READ_NEXT_RF_PAIR(v1, v2, i);
803 while (v2 != 0xDEAD &&
804 v2 != 0xCDEF &&
805 v2 != 0xCDCD &&
Larry Finger5c99f042014-09-26 16:40:25 -0500806 i < radioa_arraylen - 2) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600807 READ_NEXT_RF_PAIR(v1, v2, i);
Larry Finger5c99f042014-09-26 16:40:25 -0500808 }
Larry Fingera619d1a2014-02-28 15:16:50 -0600809 i -= 2; /* prevent from for-loop += 2*/
810 } else {
Larry Finger5c99f042014-09-26 16:40:25 -0500811 /*Configure matched pairs
812 *and skip to end of if-else.
Larry Fingera619d1a2014-02-28 15:16:50 -0600813 */
814 READ_NEXT_RF_PAIR(v1, v2, i);
815 while (v2 != 0xDEAD &&
816 v2 != 0xCDEF &&
817 v2 != 0xCDCD &&
818 i < radioa_arraylen - 2) {
819 _rtl8723be_config_rf_radio_a(hw,
820 v1, v2);
821 READ_NEXT_RF_PAIR(v1, v2, i);
822 }
823
824 while (v2 != 0xDEAD &&
825 i < radioa_arraylen - 2) {
826 READ_NEXT_RF_PAIR(v1, v2, i);
827 }
828 }
829 }
830 }
831
832 if (rtlhal->oem_id == RT_CID_819X_HP)
833 _rtl8723be_config_rf_radio_a(hw, 0x52, 0x7E4BD);
Larry Fingera619d1a2014-02-28 15:16:50 -0600834 break;
835 case RF90_PATH_B:
Larry Fingera619d1a2014-02-28 15:16:50 -0600836 case RF90_PATH_C:
Larry Fingera619d1a2014-02-28 15:16:50 -0600837 break;
838 case RF90_PATH_D:
Larry Finger5c99f042014-09-26 16:40:25 -0500839 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Larry Fingera619d1a2014-02-28 15:16:50 -0600840 "switch case not process\n");
841 break;
842 }
843 return true;
844}
845
846void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
847{
848 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500849 struct rtl_phy *rtlphy = &rtlpriv->phy;
Larry Fingera619d1a2014-02-28 15:16:50 -0600850
851 rtlphy->default_initialgain[0] =
Larry Finger5c99f042014-09-26 16:40:25 -0500852 (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
Larry Fingera619d1a2014-02-28 15:16:50 -0600853 rtlphy->default_initialgain[1] =
Larry Finger5c99f042014-09-26 16:40:25 -0500854 (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
Larry Fingera619d1a2014-02-28 15:16:50 -0600855 rtlphy->default_initialgain[2] =
Larry Finger5c99f042014-09-26 16:40:25 -0500856 (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
Larry Fingera619d1a2014-02-28 15:16:50 -0600857 rtlphy->default_initialgain[3] =
Larry Finger5c99f042014-09-26 16:40:25 -0500858 (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
Larry Fingera619d1a2014-02-28 15:16:50 -0600859
860 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Larry Finger5c99f042014-09-26 16:40:25 -0500861 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
862 rtlphy->default_initialgain[0],
863 rtlphy->default_initialgain[1],
864 rtlphy->default_initialgain[2],
865 rtlphy->default_initialgain[3]);
Larry Fingera619d1a2014-02-28 15:16:50 -0600866
Larry Finger5c99f042014-09-26 16:40:25 -0500867 rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3,
Larry Fingera619d1a2014-02-28 15:16:50 -0600868 MASKBYTE0);
869 rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
870 MASKDWORD);
871
872 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
873 "Default framesync (0x%x) = 0x%x\n",
874 ROFDM0_RXDETECTOR3, rtlphy->framesync);
875}
876
Larry Fingera619d1a2014-02-28 15:16:50 -0600877static u8 _rtl8723be_phy_get_ratesection_intxpower_byrate(enum radio_path path,
878 u8 rate)
879{
880 u8 rate_section = 0;
881
882 switch (rate) {
883 case DESC92C_RATE1M:
884 rate_section = 2;
885 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500886
Larry Fingera619d1a2014-02-28 15:16:50 -0600887 case DESC92C_RATE2M:
888 case DESC92C_RATE5_5M:
889 if (path == RF90_PATH_A)
890 rate_section = 3;
891 else if (path == RF90_PATH_B)
892 rate_section = 2;
893 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500894
Larry Fingera619d1a2014-02-28 15:16:50 -0600895 case DESC92C_RATE11M:
896 rate_section = 3;
897 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500898
Larry Fingera619d1a2014-02-28 15:16:50 -0600899 case DESC92C_RATE6M:
900 case DESC92C_RATE9M:
901 case DESC92C_RATE12M:
902 case DESC92C_RATE18M:
903 rate_section = 0;
904 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500905
Larry Fingera619d1a2014-02-28 15:16:50 -0600906 case DESC92C_RATE24M:
907 case DESC92C_RATE36M:
908 case DESC92C_RATE48M:
909 case DESC92C_RATE54M:
910 rate_section = 1;
911 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500912
Larry Fingera619d1a2014-02-28 15:16:50 -0600913 case DESC92C_RATEMCS0:
914 case DESC92C_RATEMCS1:
915 case DESC92C_RATEMCS2:
916 case DESC92C_RATEMCS3:
917 rate_section = 4;
918 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500919
Larry Fingera619d1a2014-02-28 15:16:50 -0600920 case DESC92C_RATEMCS4:
921 case DESC92C_RATEMCS5:
922 case DESC92C_RATEMCS6:
923 case DESC92C_RATEMCS7:
924 rate_section = 5;
925 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500926
Larry Fingera619d1a2014-02-28 15:16:50 -0600927 case DESC92C_RATEMCS8:
928 case DESC92C_RATEMCS9:
929 case DESC92C_RATEMCS10:
930 case DESC92C_RATEMCS11:
931 rate_section = 6;
932 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500933
Larry Fingera619d1a2014-02-28 15:16:50 -0600934 case DESC92C_RATEMCS12:
935 case DESC92C_RATEMCS13:
936 case DESC92C_RATEMCS14:
937 case DESC92C_RATEMCS15:
938 rate_section = 7;
939 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500940
Larry Fingera619d1a2014-02-28 15:16:50 -0600941 default:
942 RT_ASSERT(true, "Rate_Section is Illegal\n");
943 break;
944 }
Larry Finger5c99f042014-09-26 16:40:25 -0500945
Larry Fingera619d1a2014-02-28 15:16:50 -0600946 return rate_section;
947}
948
949static u8 _rtl8723be_get_txpower_by_rate(struct ieee80211_hw *hw,
950 enum band_type band,
951 enum radio_path rfpath, u8 rate)
952{
953 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500954 struct rtl_phy *rtlphy = &rtlpriv->phy;
Larry Fingera619d1a2014-02-28 15:16:50 -0600955 u8 shift = 0, rate_section, tx_num;
Arnd Bergmann08aba422016-06-15 23:30:43 +0200956 s8 tx_pwr_diff = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -0600957
958 rate_section = _rtl8723be_phy_get_ratesection_intxpower_byrate(rfpath,
959 rate);
960 tx_num = RF_TX_NUM_NONIMPLEMENT;
961
962 if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
963 if (rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15)
964 tx_num = RF_2TX;
965 else
966 tx_num = RF_1TX;
967 }
968
969 switch (rate) {
970 case DESC92C_RATE6M:
971 case DESC92C_RATE24M:
972 case DESC92C_RATEMCS0:
973 case DESC92C_RATEMCS4:
974 case DESC92C_RATEMCS8:
975 case DESC92C_RATEMCS12:
976 shift = 0;
977 break;
978 case DESC92C_RATE1M:
979 case DESC92C_RATE2M:
980 case DESC92C_RATE9M:
981 case DESC92C_RATE36M:
982 case DESC92C_RATEMCS1:
983 case DESC92C_RATEMCS5:
984 case DESC92C_RATEMCS9:
985 case DESC92C_RATEMCS13:
986 shift = 8;
987 break;
988 case DESC92C_RATE5_5M:
989 case DESC92C_RATE12M:
990 case DESC92C_RATE48M:
991 case DESC92C_RATEMCS2:
992 case DESC92C_RATEMCS6:
993 case DESC92C_RATEMCS10:
994 case DESC92C_RATEMCS14:
995 shift = 16;
996 break;
997 case DESC92C_RATE11M:
998 case DESC92C_RATE18M:
999 case DESC92C_RATE54M:
1000 case DESC92C_RATEMCS3:
1001 case DESC92C_RATEMCS7:
1002 case DESC92C_RATEMCS11:
1003 case DESC92C_RATEMCS15:
1004 shift = 24;
1005 break;
1006 default:
1007 RT_ASSERT(true, "Rate_Section is Illegal\n");
1008 break;
1009 }
1010 tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rfpath][tx_num]
1011 [rate_section] >> shift) & 0xff;
1012
1013 return tx_pwr_diff;
1014}
1015
1016static u8 _rtl8723be_get_txpower_index(struct ieee80211_hw *hw, u8 path,
1017 u8 rate, u8 bandwidth, u8 channel)
1018{
1019 struct rtl_priv *rtlpriv = rtl_priv(hw);
1020 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1021 u8 index = (channel - 1);
Heinrich Schuchardt6b3c33e2016-05-18 00:46:23 +02001022 u8 txpower = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06001023 u8 power_diff_byrate = 0;
1024
1025 if (channel > 14 || channel < 1) {
1026 index = 0;
1027 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1028 "Illegal channel!\n");
1029 }
Larry Finger5c99f042014-09-26 16:40:25 -05001030 if (RX_HAL_IS_CCK_RATE(rate))
Larry Fingera619d1a2014-02-28 15:16:50 -06001031 txpower = rtlefuse->txpwrlevel_cck[path][index];
1032 else if (DESC92C_RATE6M <= rate)
1033 txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
1034 else
1035 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1036 "invalid rate\n");
1037
1038 if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M &&
Larry Finger5c99f042014-09-26 16:40:25 -05001039 !RX_HAL_IS_CCK_RATE(rate))
Larry Fingera619d1a2014-02-28 15:16:50 -06001040 txpower += rtlefuse->txpwr_legacyhtdiff[0][TX_1S];
1041
1042 if (bandwidth == HT_CHANNEL_WIDTH_20) {
1043 if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1044 txpower += rtlefuse->txpwr_ht20diff[0][TX_1S];
1045 if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1046 txpower += rtlefuse->txpwr_ht20diff[0][TX_2S];
1047 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
1048 if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1049 txpower += rtlefuse->txpwr_ht40diff[0][TX_1S];
1050 if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1051 txpower += rtlefuse->txpwr_ht40diff[0][TX_2S];
1052 }
Larry Finger5c99f042014-09-26 16:40:25 -05001053
Larry Fingera619d1a2014-02-28 15:16:50 -06001054 if (rtlefuse->eeprom_regulatory != 2)
1055 power_diff_byrate = _rtl8723be_get_txpower_by_rate(hw,
1056 BAND_ON_2_4G,
1057 path, rate);
1058
1059 txpower += power_diff_byrate;
1060
1061 if (txpower > MAX_POWER_INDEX)
1062 txpower = MAX_POWER_INDEX;
1063
1064 return txpower;
1065}
1066
1067static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw,
1068 u8 power_index, u8 path, u8 rate)
1069{
1070 struct rtl_priv *rtlpriv = rtl_priv(hw);
1071 if (path == RF90_PATH_A) {
1072 switch (rate) {
1073 case DESC92C_RATE1M:
1074 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_CCK1_MCS32,
1075 MASKBYTE1, power_index);
1076 break;
1077 case DESC92C_RATE2M:
1078 rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1079 MASKBYTE1, power_index);
1080 break;
1081 case DESC92C_RATE5_5M:
1082 rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1083 MASKBYTE2, power_index);
1084 break;
1085 case DESC92C_RATE11M:
1086 rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1087 MASKBYTE3, power_index);
1088 break;
Larry Finger5c99f042014-09-26 16:40:25 -05001089
Larry Fingera619d1a2014-02-28 15:16:50 -06001090 case DESC92C_RATE6M:
1091 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1092 MASKBYTE0, power_index);
1093 break;
1094 case DESC92C_RATE9M:
1095 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1096 MASKBYTE1, power_index);
1097 break;
1098 case DESC92C_RATE12M:
1099 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1100 MASKBYTE2, power_index);
1101 break;
1102 case DESC92C_RATE18M:
1103 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1104 MASKBYTE3, power_index);
1105 break;
Larry Finger5c99f042014-09-26 16:40:25 -05001106
Larry Fingera619d1a2014-02-28 15:16:50 -06001107 case DESC92C_RATE24M:
1108 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1109 MASKBYTE0, power_index);
1110 break;
1111 case DESC92C_RATE36M:
1112 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1113 MASKBYTE1, power_index);
1114 break;
1115 case DESC92C_RATE48M:
1116 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1117 MASKBYTE2, power_index);
1118 break;
1119 case DESC92C_RATE54M:
1120 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1121 MASKBYTE3, power_index);
1122 break;
Larry Finger5c99f042014-09-26 16:40:25 -05001123
Larry Fingera619d1a2014-02-28 15:16:50 -06001124 case DESC92C_RATEMCS0:
1125 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1126 MASKBYTE0, power_index);
1127 break;
1128 case DESC92C_RATEMCS1:
1129 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1130 MASKBYTE1, power_index);
1131 break;
1132 case DESC92C_RATEMCS2:
1133 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1134 MASKBYTE2, power_index);
1135 break;
1136 case DESC92C_RATEMCS3:
1137 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1138 MASKBYTE3, power_index);
1139 break;
Larry Finger5c99f042014-09-26 16:40:25 -05001140
Larry Fingera619d1a2014-02-28 15:16:50 -06001141 case DESC92C_RATEMCS4:
1142 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1143 MASKBYTE0, power_index);
1144 break;
1145 case DESC92C_RATEMCS5:
1146 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1147 MASKBYTE1, power_index);
1148 break;
1149 case DESC92C_RATEMCS6:
1150 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1151 MASKBYTE2, power_index);
1152 break;
1153 case DESC92C_RATEMCS7:
1154 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1155 MASKBYTE3, power_index);
1156 break;
Larry Finger5c99f042014-09-26 16:40:25 -05001157
Larry Fingera619d1a2014-02-28 15:16:50 -06001158 case DESC92C_RATEMCS8:
1159 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1160 MASKBYTE0, power_index);
1161 break;
1162 case DESC92C_RATEMCS9:
1163 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1164 MASKBYTE1, power_index);
1165 break;
1166 case DESC92C_RATEMCS10:
1167 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1168 MASKBYTE2, power_index);
1169 break;
1170 case DESC92C_RATEMCS11:
1171 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1172 MASKBYTE3, power_index);
1173 break;
Larry Finger5c99f042014-09-26 16:40:25 -05001174
Larry Fingera619d1a2014-02-28 15:16:50 -06001175 default:
Larry Finger5c99f042014-09-26 16:40:25 -05001176 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Rate!!\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06001177 break;
1178 }
1179 } else {
1180 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n");
1181 }
1182}
1183
1184void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1185{
1186 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1187 u8 cck_rates[] = {DESC92C_RATE1M, DESC92C_RATE2M,
1188 DESC92C_RATE5_5M, DESC92C_RATE11M};
1189 u8 ofdm_rates[] = {DESC92C_RATE6M, DESC92C_RATE9M,
1190 DESC92C_RATE12M, DESC92C_RATE18M,
1191 DESC92C_RATE24M, DESC92C_RATE36M,
1192 DESC92C_RATE48M, DESC92C_RATE54M};
1193 u8 ht_rates_1t[] = {DESC92C_RATEMCS0, DESC92C_RATEMCS1,
1194 DESC92C_RATEMCS2, DESC92C_RATEMCS3,
1195 DESC92C_RATEMCS4, DESC92C_RATEMCS5,
1196 DESC92C_RATEMCS6, DESC92C_RATEMCS7};
1197 u8 i, size;
1198 u8 power_index;
1199
1200 if (!rtlefuse->txpwr_fromeprom)
1201 return;
1202
1203 size = sizeof(cck_rates) / sizeof(u8);
1204 for (i = 0; i < size; i++) {
1205 power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1206 cck_rates[i],
1207 rtl_priv(hw)->phy.current_chan_bw,
1208 channel);
1209 _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1210 cck_rates[i]);
1211 }
1212 size = sizeof(ofdm_rates) / sizeof(u8);
1213 for (i = 0; i < size; i++) {
1214 power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1215 ofdm_rates[i],
1216 rtl_priv(hw)->phy.current_chan_bw,
1217 channel);
1218 _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1219 ofdm_rates[i]);
1220 }
1221 size = sizeof(ht_rates_1t) / sizeof(u8);
1222 for (i = 0; i < size; i++) {
1223 power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1224 ht_rates_1t[i],
1225 rtl_priv(hw)->phy.current_chan_bw,
1226 channel);
1227 _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1228 ht_rates_1t[i]);
1229 }
1230}
1231
1232void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1233{
1234 struct rtl_priv *rtlpriv = rtl_priv(hw);
1235 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1236 enum io_type iotype;
1237
1238 if (!is_hal_stop(rtlhal)) {
1239 switch (operation) {
Larry Finger5c99f042014-09-26 16:40:25 -05001240 case SCAN_OPT_BACKUP_BAND0:
1241 iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
Larry Fingera619d1a2014-02-28 15:16:50 -06001242 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1243 (u8 *)&iotype);
Larry Finger5c99f042014-09-26 16:40:25 -05001244
Larry Fingera619d1a2014-02-28 15:16:50 -06001245 break;
1246 case SCAN_OPT_RESTORE:
1247 iotype = IO_CMD_RESUME_DM_BY_SCAN;
1248 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1249 (u8 *)&iotype);
1250 break;
1251 default:
1252 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1253 "Unknown Scan Backup operation.\n");
1254 break;
1255 }
1256 }
1257}
1258
1259void rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
1260{
1261 struct rtl_priv *rtlpriv = rtl_priv(hw);
1262 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
Larry Finger5c99f042014-09-26 16:40:25 -05001263 struct rtl_phy *rtlphy = &rtlpriv->phy;
Larry Fingera619d1a2014-02-28 15:16:50 -06001264 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1265 u8 reg_bw_opmode;
1266 u8 reg_prsr_rsc;
1267
1268 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1269 "Switch to %s bandwidth\n",
Larry Finger5c99f042014-09-26 16:40:25 -05001270 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1271 "20MHz" : "40MHz");
Larry Fingera619d1a2014-02-28 15:16:50 -06001272
1273 if (is_hal_stop(rtlhal)) {
1274 rtlphy->set_bwmode_inprogress = false;
1275 return;
1276 }
1277
1278 reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1279 reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1280
1281 switch (rtlphy->current_chan_bw) {
1282 case HT_CHANNEL_WIDTH_20:
1283 reg_bw_opmode |= BW_OPMODE_20MHZ;
1284 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1285 break;
1286 case HT_CHANNEL_WIDTH_20_40:
1287 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1288 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1289 reg_prsr_rsc = (reg_prsr_rsc & 0x90) |
1290 (mac->cur_40_prime_sc << 5);
1291 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1292 break;
1293 default:
1294 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1295 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1296 break;
1297 }
1298
1299 switch (rtlphy->current_chan_bw) {
1300 case HT_CHANNEL_WIDTH_20:
1301 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1302 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
Larry Finger5c99f042014-09-26 16:40:25 -05001303 /* rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);*/
Larry Fingera619d1a2014-02-28 15:16:50 -06001304 break;
1305 case HT_CHANNEL_WIDTH_20_40:
1306 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1307 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
Larry Finger5c99f042014-09-26 16:40:25 -05001308
Larry Fingera619d1a2014-02-28 15:16:50 -06001309 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1310 (mac->cur_40_prime_sc >> 1));
1311 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
Larry Finger5c99f042014-09-26 16:40:25 -05001312 /*rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);*/
1313
Larry Fingera619d1a2014-02-28 15:16:50 -06001314 rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1315 (mac->cur_40_prime_sc ==
1316 HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1317 break;
1318 default:
1319 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1320 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1321 break;
1322 }
1323 rtl8723be_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1324 rtlphy->set_bwmode_inprogress = false;
1325 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
1326}
1327
1328void rtl8723be_phy_set_bw_mode(struct ieee80211_hw *hw,
1329 enum nl80211_channel_type ch_type)
1330{
1331 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -05001332 struct rtl_phy *rtlphy = &rtlpriv->phy;
Larry Fingera619d1a2014-02-28 15:16:50 -06001333 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1334 u8 tmp_bw = rtlphy->current_chan_bw;
1335
1336 if (rtlphy->set_bwmode_inprogress)
1337 return;
1338 rtlphy->set_bwmode_inprogress = true;
1339 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1340 rtl8723be_phy_set_bw_mode_callback(hw);
1341 } else {
1342 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1343 "false driver sleep or unload\n");
1344 rtlphy->set_bwmode_inprogress = false;
1345 rtlphy->current_chan_bw = tmp_bw;
1346 }
1347}
1348
1349void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1350{
1351 struct rtl_priv *rtlpriv = rtl_priv(hw);
1352 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
Larry Finger5c99f042014-09-26 16:40:25 -05001353 struct rtl_phy *rtlphy = &rtlpriv->phy;
Larry Fingera619d1a2014-02-28 15:16:50 -06001354 u32 delay;
1355
1356 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1357 "switch to channel%d\n", rtlphy->current_channel);
1358 if (is_hal_stop(rtlhal))
1359 return;
1360 do {
1361 if (!rtlphy->sw_chnl_inprogress)
1362 break;
Larry Finger5c99f042014-09-26 16:40:25 -05001363 if (!_rtl8723be_phy_sw_chnl_step_by_step(hw,
1364 rtlphy->current_channel,
1365 &rtlphy->sw_chnl_stage,
1366 &rtlphy->sw_chnl_step,
1367 &delay)) {
Larry Fingera619d1a2014-02-28 15:16:50 -06001368 if (delay > 0)
1369 mdelay(delay);
1370 else
1371 continue;
1372 } else {
1373 rtlphy->sw_chnl_inprogress = false;
1374 }
1375 break;
1376 } while (true);
1377 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
1378}
1379
1380u8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw)
1381{
1382 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -05001383 struct rtl_phy *rtlphy = &rtlpriv->phy;
Larry Fingera619d1a2014-02-28 15:16:50 -06001384 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1385
1386 if (rtlphy->sw_chnl_inprogress)
1387 return 0;
1388 if (rtlphy->set_bwmode_inprogress)
1389 return 0;
1390 RT_ASSERT((rtlphy->current_channel <= 14),
1391 "WIRELESS_MODE_G but channel>14");
1392 rtlphy->sw_chnl_inprogress = true;
1393 rtlphy->sw_chnl_stage = 0;
1394 rtlphy->sw_chnl_step = 0;
1395 if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1396 rtl8723be_phy_sw_chnl_callback(hw);
1397 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
Masanari Iida8a190232016-06-29 12:37:19 +09001398 "sw_chnl_inprogress false schedule workitem current channel %d\n",
Larry Finger5c99f042014-09-26 16:40:25 -05001399 rtlphy->current_channel);
Larry Fingera619d1a2014-02-28 15:16:50 -06001400 rtlphy->sw_chnl_inprogress = false;
1401 } else {
1402 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
Larry Finger5c99f042014-09-26 16:40:25 -05001403 "sw_chnl_inprogress false driver sleep or unload\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06001404 rtlphy->sw_chnl_inprogress = false;
1405 }
1406 return 1;
1407}
1408
Larry Finger5c99f042014-09-26 16:40:25 -05001409static bool _rtl8723be_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
1410 u8 channel, u8 *stage,
1411 u8 *step, u32 *delay)
Larry Fingera619d1a2014-02-28 15:16:50 -06001412{
1413 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -05001414 struct rtl_phy *rtlphy = &rtlpriv->phy;
Larry Fingera619d1a2014-02-28 15:16:50 -06001415 struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
1416 u32 precommoncmdcnt;
1417 struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
1418 u32 postcommoncmdcnt;
1419 struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
1420 u32 rfdependcmdcnt;
1421 struct swchnlcmd *currentcmd = NULL;
1422 u8 rfpath;
1423 u8 num_total_rfpath = rtlphy->num_total_rfpath;
1424
1425 precommoncmdcnt = 0;
1426 rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1427 MAX_PRECMD_CNT,
1428 CMDID_SET_TXPOWEROWER_LEVEL,
1429 0, 0, 0);
1430 rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1431 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
Larry Finger5c99f042014-09-26 16:40:25 -05001432
Larry Fingera619d1a2014-02-28 15:16:50 -06001433 postcommoncmdcnt = 0;
Larry Finger5c99f042014-09-26 16:40:25 -05001434
Larry Fingera619d1a2014-02-28 15:16:50 -06001435 rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1436 MAX_POSTCMD_CNT, CMDID_END,
Larry Finger5c99f042014-09-26 16:40:25 -05001437 0, 0, 0);
1438
Larry Fingera619d1a2014-02-28 15:16:50 -06001439 rfdependcmdcnt = 0;
1440
1441 RT_ASSERT((channel >= 1 && channel <= 14),
1442 "illegal channel for Zebra: %d\n", channel);
1443
1444 rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1445 MAX_RFDEPENDCMD_CNT,
1446 CMDID_RF_WRITEREG,
1447 RF_CHNLBW, channel, 10);
1448
1449 rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1450 MAX_RFDEPENDCMD_CNT,
Larry Finger5c99f042014-09-26 16:40:25 -05001451 CMDID_END, 0, 0, 0);
Larry Fingera619d1a2014-02-28 15:16:50 -06001452
1453 do {
1454 switch (*stage) {
1455 case 0:
1456 currentcmd = &precommoncmd[*step];
1457 break;
1458 case 1:
1459 currentcmd = &rfdependcmd[*step];
1460 break;
1461 case 2:
1462 currentcmd = &postcommoncmd[*step];
1463 break;
Larry Finger5c99f042014-09-26 16:40:25 -05001464 default:
1465 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1466 "Invalid 'stage' = %d, Check it!\n", *stage);
1467 return true;
Larry Fingera619d1a2014-02-28 15:16:50 -06001468 }
1469
1470 if (currentcmd->cmdid == CMDID_END) {
1471 if ((*stage) == 2) {
1472 return true;
1473 } else {
1474 (*stage)++;
1475 (*step) = 0;
1476 continue;
1477 }
1478 }
1479
1480 switch (currentcmd->cmdid) {
1481 case CMDID_SET_TXPOWEROWER_LEVEL:
1482 rtl8723be_phy_set_txpower_level(hw, channel);
1483 break;
1484 case CMDID_WRITEPORT_ULONG:
1485 rtl_write_dword(rtlpriv, currentcmd->para1,
1486 currentcmd->para2);
1487 break;
1488 case CMDID_WRITEPORT_USHORT:
1489 rtl_write_word(rtlpriv, currentcmd->para1,
Larry Finger5c99f042014-09-26 16:40:25 -05001490 (u16)currentcmd->para2);
Larry Fingera619d1a2014-02-28 15:16:50 -06001491 break;
1492 case CMDID_WRITEPORT_UCHAR:
1493 rtl_write_byte(rtlpriv, currentcmd->para1,
Larry Finger5c99f042014-09-26 16:40:25 -05001494 (u8)currentcmd->para2);
Larry Fingera619d1a2014-02-28 15:16:50 -06001495 break;
1496 case CMDID_RF_WRITEREG:
1497 for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
1498 rtlphy->rfreg_chnlval[rfpath] =
1499 ((rtlphy->rfreg_chnlval[rfpath] &
1500 0xfffffc00) | currentcmd->para2);
1501
1502 rtl_set_rfreg(hw, (enum radio_path)rfpath,
1503 currentcmd->para1,
1504 RFREG_OFFSET_MASK,
1505 rtlphy->rfreg_chnlval[rfpath]);
1506 }
1507 break;
1508 default:
Larry Finger5c99f042014-09-26 16:40:25 -05001509 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Larry Fingera619d1a2014-02-28 15:16:50 -06001510 "switch case not process\n");
1511 break;
1512 }
1513
1514 break;
1515 } while (true);
1516
1517 (*delay) = currentcmd->msdelay;
1518 (*step)++;
1519 return false;
1520}
1521
Larry Finger5c99f042014-09-26 16:40:25 -05001522static u8 _rtl8723be_phy_path_a_iqk(struct ieee80211_hw *hw)
Larry Fingera619d1a2014-02-28 15:16:50 -06001523{
Larry Finger5c99f042014-09-26 16:40:25 -05001524 u32 reg_eac, reg_e94, reg_e9c, tmp;
Larry Fingera619d1a2014-02-28 15:16:50 -06001525 u8 result = 0x00;
1526
Larry Finger5c99f042014-09-26 16:40:25 -05001527 /* leave IQK mode */
1528 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1529 /* switch to path A */
1530 rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000);
1531 /* enable path A PA in TXIQK mode */
1532 rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1533 rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x20000);
1534 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0003f);
1535 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xc7f87);
Larry Fingera619d1a2014-02-28 15:16:50 -06001536
Larry Finger5c99f042014-09-26 16:40:25 -05001537 /* 1. TX IQK */
1538 /* path-A IQK setting */
1539 /* IQK setting */
1540 rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1541 rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1542 /* path-A IQK setting */
1543 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1544 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1545 rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1546 rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1547
1548 rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea);
1549 rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160000);
1550 rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1551 rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1552 /* LO calibration setting */
1553 rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1554 /* enter IQK mode */
1555 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1556
1557 /* One shot, path A LOK & IQK */
1558 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1559 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
Larry Fingera619d1a2014-02-28 15:16:50 -06001560
1561 mdelay(IQK_DELAY_TIME);
1562
Larry Finger5c99f042014-09-26 16:40:25 -05001563 /* leave IQK mode */
1564 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1565
1566 /* Check failed */
Larry Fingera619d1a2014-02-28 15:16:50 -06001567 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1568 reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1569 reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
Larry Fingera619d1a2014-02-28 15:16:50 -06001570
1571 if (!(reg_eac & BIT(28)) &&
1572 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1573 (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1574 result |= 0x01;
Larry Finger5c99f042014-09-26 16:40:25 -05001575 else /* if Tx not OK, ignore Rx */
1576 return result;
1577
1578 /* Allen 20131125 */
1579 tmp = (reg_e9c & 0x03FF0000) >> 16;
1580 if ((tmp & 0x200) > 0)
1581 tmp = 0x400 - tmp;
1582
1583 if (!(reg_eac & BIT(28)) &&
1584 (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1585 (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1586 (tmp < 0xf))
1587 result |= 0x01;
1588 else /* if Tx not OK, ignore Rx */
1589 return result;
1590
Larry Fingera619d1a2014-02-28 15:16:50 -06001591 return result;
1592}
1593
Larry Finger5c99f042014-09-26 16:40:25 -05001594/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1595static u8 _rtl8723be_phy_path_a_rx_iqk(struct ieee80211_hw *hw)
Larry Fingera619d1a2014-02-28 15:16:50 -06001596{
Larry Finger5c99f042014-09-26 16:40:25 -05001597 u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u32tmp, tmp;
1598 u8 result = 0x00;
Larry Fingera619d1a2014-02-28 15:16:50 -06001599
Larry Finger5c99f042014-09-26 16:40:25 -05001600 /* leave IQK mode */
1601 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
Larry Fingera619d1a2014-02-28 15:16:50 -06001602
Larry Finger5c99f042014-09-26 16:40:25 -05001603 /* switch to path A */
1604 rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000);
1605
1606 /* 1 Get TXIMR setting */
1607 /* modify RXIQK mode table */
1608 rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1609 rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1610 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1611 /* LNA2 off, PA on for Dcut */
1612 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7fb7);
1613 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1614
1615 /* IQK setting */
1616 rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1617 rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1618
1619 /* path-A IQK setting */
1620 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1621 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1622 rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1623 rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1624
1625 rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0);
1626 rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1627 rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1628 rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1629
1630 /* LO calibration setting */
1631 rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1632
1633 /* enter IQK mode */
1634 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1635
1636 /* One shot, path A LOK & IQK */
1637 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1638 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1639
1640 mdelay(IQK_DELAY_TIME);
1641
1642 /* leave IQK mode */
1643 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1644
1645 /* Check failed */
1646 reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1647 reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1648 reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1649
1650 if (!(reg_eac & BIT(28)) &&
1651 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1652 (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1653 result |= 0x01;
1654 else /* if Tx not OK, ignore Rx */
1655 return result;
1656
1657 /* Allen 20131125 */
1658 tmp = (reg_e9c & 0x03FF0000) >> 16;
1659 if ((tmp & 0x200) > 0)
1660 tmp = 0x400 - tmp;
1661
1662 if (!(reg_eac & BIT(28)) &&
1663 (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1664 (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1665 (tmp < 0xf))
1666 result |= 0x01;
1667 else /* if Tx not OK, ignore Rx */
1668 return result;
1669
1670 u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000) |
1671 ((reg_e9c & 0x3FF0000) >> 16);
1672 rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp);
1673
1674 /* 1 RX IQK */
1675 /* modify RXIQK mode table */
1676 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1677 rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1678 rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1679 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1680 /* LAN2 on, PA off for Dcut */
1681 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77);
1682
1683 /* PA, PAD setting */
1684 rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0xf80);
1685 rtl_set_rfreg(hw, RF90_PATH_A, 0x55, RFREG_OFFSET_MASK, 0x4021f);
1686
1687 /* IQK setting */
1688 rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1689
1690 /* path-A IQK setting */
1691 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1692 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1693 rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1694 rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1695
1696 rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000);
1697 rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f);
1698 rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1699 rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1700
1701 /* LO calibration setting */
1702 rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1);
1703
1704 /* enter IQK mode */
1705 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1706
1707 /* One shot, path A LOK & IQK */
1708 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1709 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1710
1711 mdelay(IQK_DELAY_TIME);
1712
1713 /* leave IQK mode */
1714 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1715
1716 /* Check failed */
1717 reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1718 reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1719
1720 /* leave IQK mode */
1721 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1722 rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x780);
1723
1724 /* Allen 20131125 */
1725 tmp = (reg_eac & 0x03FF0000) >> 16;
Larry Fingerb3c42012016-03-17 13:41:03 -05001726 if ((tmp & 0x200) > 0)
1727 tmp = 0x400 - tmp;
Larry Finger5c99f042014-09-26 16:40:25 -05001728 /* if Tx is OK, check whether Rx is OK */
1729 if (!(reg_eac & BIT(27)) &&
1730 (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1731 (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1732 result |= 0x02;
1733 else if (!(reg_eac & BIT(27)) &&
1734 (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) &&
1735 (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) &&
1736 (tmp < 0xf))
1737 result |= 0x02;
1738
1739 return result;
1740}
1741
1742static u8 _rtl8723be_phy_path_b_iqk(struct ieee80211_hw *hw)
1743{
1744 u32 reg_eac, reg_e94, reg_e9c, tmp;
1745 u8 result = 0x00;
1746
1747 /* leave IQK mode */
1748 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1749 /* switch to path B */
1750 rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280);
1751
1752 /* enable path B PA in TXIQK mode */
1753 rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1754 rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x40fc1);
1755
1756 /* 1 Tx IQK */
1757 /* IQK setting */
1758 rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1759 rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1760 /* path-A IQK setting */
1761 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1762 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1763 rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1764 rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1765
1766 rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea);
1767 rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1768 rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1769 rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1770
1771 /* LO calibration setting */
1772 rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1773
1774 /* enter IQK mode */
1775 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1776
1777 /* One shot, path B LOK & IQK */
1778 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1779 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1780
1781 mdelay(IQK_DELAY_TIME);
1782
1783 /* leave IQK mode */
1784 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1785
1786 /* Check failed */
1787 reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1788 reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1789 reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1790
1791 if (!(reg_eac & BIT(28)) &&
1792 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1793 (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1794 result |= 0x01;
Larry Fingera619d1a2014-02-28 15:16:50 -06001795 else
Larry Finger5c99f042014-09-26 16:40:25 -05001796 return result;
1797
1798 /* Allen 20131125 */
1799 tmp = (reg_e9c & 0x03FF0000) >> 16;
1800 if ((tmp & 0x200) > 0)
1801 tmp = 0x400 - tmp;
1802
1803 if (!(reg_eac & BIT(28)) &&
1804 (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1805 (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1806 (tmp < 0xf))
1807 result |= 0x01;
1808 else
1809 return result;
1810
1811 return result;
1812}
1813
1814/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1815static u8 _rtl8723be_phy_path_b_rx_iqk(struct ieee80211_hw *hw)
1816{
1817 u32 reg_e94, reg_e9c, reg_ea4, reg_eac, u32tmp, tmp;
1818 u8 result = 0x00;
1819
1820 /* leave IQK mode */
1821 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1822 /* switch to path B */
1823 rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280);
1824
1825 /* 1 Get TXIMR setting */
1826 /* modify RXIQK mode table */
1827 rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1828 rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1829 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1830 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ff7);
1831
1832 /* open PA S1 & SMIXER */
1833 rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1834 rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fed);
1835
1836 /* IQK setting */
1837 rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1838 rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1839
1840 /* path-B IQK setting */
1841 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1842 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1843 rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1844 rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1845
1846 rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0);
1847 rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1848 rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1849 rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1850
1851 /* LO calibration setting */
1852 rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1853 /* enter IQK mode */
1854 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1855
1856 /* One shot, path B TXIQK @ RXIQK */
1857 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1858 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1859
1860 mdelay(IQK_DELAY_TIME);
1861
1862 /* leave IQK mode */
1863 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1864 /* Check failed */
1865 reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1866 reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1867 reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1868
1869 if (!(reg_eac & BIT(28)) &&
1870 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1871 (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1872 result |= 0x01;
1873 else /* if Tx not OK, ignore Rx */
1874 return result;
1875
1876 /* Allen 20131125 */
1877 tmp = (reg_e9c & 0x03FF0000) >> 16;
1878 if ((tmp & 0x200) > 0)
1879 tmp = 0x400 - tmp;
1880
1881 if (!(reg_eac & BIT(28)) &&
1882 (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1883 (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1884 (tmp < 0xf))
1885 result |= 0x01;
1886 else
1887 return result;
1888
1889 u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000) |
1890 ((reg_e9c & 0x3FF0000) >> 16);
1891 rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp);
1892
1893 /* 1 RX IQK */
1894
1895 /* <20121009, Kordan> RF Mode = 3 */
1896 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1897 rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1898 rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1899 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1900 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77);
1901 rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x0);
1902
1903 /* open PA S1 & close SMIXER */
1904 rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1905 rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fbd);
1906
1907 /* IQK setting */
1908 rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1909
1910 /* path-B IQK setting */
1911 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1912 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1913 rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1914 rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1915
1916 rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000);
1917 rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f);
1918 rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1919 rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1920
1921 /* LO calibration setting */
1922 rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1);
1923 /* enter IQK mode */
1924 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1925
1926 /* One shot, path B LOK & IQK */
1927 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1928 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1929
1930 mdelay(IQK_DELAY_TIME);
1931
1932 /* leave IQK mode */
1933 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1934 /* Check failed */
1935 reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1936 reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1937
1938 /* Allen 20131125 */
1939 tmp = (reg_eac & 0x03FF0000) >> 16;
1940 if ((tmp & 0x200) > 0)
1941 tmp = 0x400 - tmp;
1942
1943 /* if Tx is OK, check whether Rx is OK */
1944 if (!(reg_eac & BIT(27)) &&
1945 (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1946 (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1947 result |= 0x02;
1948 else if (!(reg_eac & BIT(27)) &&
1949 (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) &&
1950 (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) &&
1951 (tmp < 0xf))
1952 result |= 0x02;
1953 else
1954 return result;
1955
1956 return result;
1957}
1958
1959static void _rtl8723be_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,
1960 bool b_iqk_ok,
1961 long result[][8],
1962 u8 final_candidate,
1963 bool btxonly)
1964{
1965 u32 oldval_1, x, tx1_a, reg;
1966 long y, tx1_c;
1967
1968 if (final_candidate == 0xFF) {
1969 return;
1970 } else if (b_iqk_ok) {
1971 oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
1972 MASKDWORD) >> 22) & 0x3FF;
1973 x = result[final_candidate][4];
1974 if ((x & 0x00000200) != 0)
1975 x = x | 0xFFFFFC00;
1976 tx1_a = (x * oldval_1) >> 8;
1977 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a);
1978 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27),
1979 ((x * oldval_1 >> 7) & 0x1));
1980 y = result[final_candidate][5];
1981 if ((y & 0x00000200) != 0)
1982 y = y | 0xFFFFFC00;
1983 tx1_c = (y * oldval_1) >> 8;
1984 rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000,
1985 ((tx1_c & 0x3C0) >> 6));
1986 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000,
1987 (tx1_c & 0x3F));
1988 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25),
1989 ((y * oldval_1 >> 7) & 0x1));
1990 if (btxonly)
1991 return;
1992 reg = result[final_candidate][6];
1993 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
1994 reg = result[final_candidate][7] & 0x3F;
1995 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
1996 reg = (result[final_candidate][7] >> 6) & 0xF;
1997 /* rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); */
1998 }
1999}
2000
2001static bool _rtl8723be_phy_simularity_compare(struct ieee80211_hw *hw,
2002 long result[][8], u8 c1, u8 c2)
2003{
2004 u32 i, j, diff, simularity_bitmap, bound = 0;
2005
2006 u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */
2007 bool bresult = true; /* is2t = true*/
2008 s32 tmp1 = 0, tmp2 = 0;
2009
2010 bound = 8;
Larry Fingera619d1a2014-02-28 15:16:50 -06002011
2012 simularity_bitmap = 0;
2013
2014 for (i = 0; i < bound; i++) {
Larry Finger5c99f042014-09-26 16:40:25 -05002015 if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
2016 if ((result[c1][i] & 0x00000200) != 0)
2017 tmp1 = result[c1][i] | 0xFFFFFC00;
2018 else
2019 tmp1 = result[c1][i];
2020
2021 if ((result[c2][i] & 0x00000200) != 0)
2022 tmp2 = result[c2][i] | 0xFFFFFC00;
2023 else
2024 tmp2 = result[c2][i];
2025 } else {
2026 tmp1 = result[c1][i];
2027 tmp2 = result[c2][i];
2028 }
2029
2030 diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
Larry Fingera619d1a2014-02-28 15:16:50 -06002031
2032 if (diff > MAX_TOLERANCE) {
2033 if ((i == 2 || i == 6) && !simularity_bitmap) {
2034 if (result[c1][i] + result[c1][i + 1] == 0)
2035 final_candidate[(i / 4)] = c2;
2036 else if (result[c2][i] + result[c2][i + 1] == 0)
2037 final_candidate[(i / 4)] = c1;
2038 else
2039 simularity_bitmap |= (1 << i);
Larry Finger5c99f042014-09-26 16:40:25 -05002040 } else
Larry Fingera619d1a2014-02-28 15:16:50 -06002041 simularity_bitmap |= (1 << i);
Larry Fingera619d1a2014-02-28 15:16:50 -06002042 }
2043 }
2044
2045 if (simularity_bitmap == 0) {
2046 for (i = 0; i < (bound / 4); i++) {
2047 if (final_candidate[i] != 0xFF) {
2048 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
2049 result[3][j] =
2050 result[final_candidate[i]][j];
2051 bresult = false;
2052 }
2053 }
2054 return bresult;
Larry Fingera619d1a2014-02-28 15:16:50 -06002055 } else {
Larry Finger5c99f042014-09-26 16:40:25 -05002056 if (!(simularity_bitmap & 0x03)) { /* path A TX OK */
2057 for (i = 0; i < 2; i++)
2058 result[3][i] = result[c1][i];
2059 }
2060 if (!(simularity_bitmap & 0x0c)) { /* path A RX OK */
2061 for (i = 2; i < 4; i++)
2062 result[3][i] = result[c1][i];
2063 }
2064 if (!(simularity_bitmap & 0x30)) { /* path B TX OK */
2065 for (i = 4; i < 6; i++)
2066 result[3][i] = result[c1][i];
2067 }
2068 if (!(simularity_bitmap & 0xc0)) { /* path B RX OK */
2069 for (i = 6; i < 8; i++)
2070 result[3][i] = result[c1][i];
2071 }
Larry Fingera619d1a2014-02-28 15:16:50 -06002072 return false;
2073 }
2074}
2075
2076static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw,
2077 long result[][8], u8 t, bool is2t)
2078{
2079 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -05002080 struct rtl_phy *rtlphy = &rtlpriv->phy;
Larry Fingera619d1a2014-02-28 15:16:50 -06002081 u32 i;
Larry Finger5c99f042014-09-26 16:40:25 -05002082 u8 patha_ok, pathb_ok;
Larry Fingera619d1a2014-02-28 15:16:50 -06002083 u32 adda_reg[IQK_ADDA_REG_NUM] = {
2084 0x85c, 0xe6c, 0xe70, 0xe74,
2085 0xe78, 0xe7c, 0xe80, 0xe84,
2086 0xe88, 0xe8c, 0xed0, 0xed4,
2087 0xed8, 0xedc, 0xee0, 0xeec
2088 };
2089
2090 u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
2091 0x522, 0x550, 0x551, 0x040
2092 };
2093 u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
2094 ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR,
2095 RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c,
2096 0x870, 0x860,
Larry Finger5c99f042014-09-26 16:40:25 -05002097 0x864, 0xa04
Larry Fingera619d1a2014-02-28 15:16:50 -06002098 };
2099 const u32 retrycount = 2;
Larry Finger5c99f042014-09-26 16:40:25 -05002100
2101 u32 path_sel_bb;/* path_sel_rf */
2102
Larry Fingera619d1a2014-02-28 15:16:50 -06002103 u8 tmp_reg_c50, tmp_reg_c58;
2104
2105 tmp_reg_c50 = rtl_get_bbreg(hw, 0xc50, MASKBYTE0);
2106 tmp_reg_c58 = rtl_get_bbreg(hw, 0xc58, MASKBYTE0);
2107
2108 if (t == 0) {
2109 rtl8723_save_adda_registers(hw, adda_reg,
2110 rtlphy->adda_backup, 16);
2111 rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,
2112 rtlphy->iqk_mac_backup);
2113 rtl8723_save_adda_registers(hw, iqk_bb_reg,
2114 rtlphy->iqk_bb_backup,
2115 IQK_BB_REG_NUM);
2116 }
2117 rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);
2118 if (t == 0) {
Larry Finger5c99f042014-09-26 16:40:25 -05002119 rtlphy->rfpi_enable = (u8)rtl_get_bbreg(hw,
Larry Fingera619d1a2014-02-28 15:16:50 -06002120 RFPGA0_XA_HSSIPARAMETER1,
2121 BIT(8));
2122 }
Larry Fingera619d1a2014-02-28 15:16:50 -06002123
2124 path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
Larry Fingera619d1a2014-02-28 15:16:50 -06002125
Larry Finger5c99f042014-09-26 16:40:25 -05002126 rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,
2127 rtlphy->iqk_mac_backup);
Larry Fingera619d1a2014-02-28 15:16:50 -06002128 /*BB Setting*/
Larry Finger5c99f042014-09-26 16:40:25 -05002129 rtl_set_bbreg(hw, 0xa04, 0x0f000000, 0xf);
Larry Fingera619d1a2014-02-28 15:16:50 -06002130 rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
2131 rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
2132 rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
2133
Larry Finger5c99f042014-09-26 16:40:25 -05002134 /* path A TX IQK */
Larry Fingera619d1a2014-02-28 15:16:50 -06002135 for (i = 0; i < retrycount; i++) {
Larry Finger5c99f042014-09-26 16:40:25 -05002136 patha_ok = _rtl8723be_phy_path_a_iqk(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -06002137 if (patha_ok == 0x01) {
2138 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Larry Finger5c99f042014-09-26 16:40:25 -05002139 "Path A Tx IQK Success!!\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06002140 result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
2141 0x3FF0000) >> 16;
2142 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
2143 0x3FF0000) >> 16;
2144 break;
Larry Finger5c99f042014-09-26 16:40:25 -05002145 } else {
2146 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2147 "Path A Tx IQK Fail!!\n");
2148 }
2149 }
2150 /* path A RX IQK */
2151 for (i = 0; i < retrycount; i++) {
2152 patha_ok = _rtl8723be_phy_path_a_rx_iqk(hw);
2153 if (patha_ok == 0x03) {
2154 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2155 "Path A Rx IQK Success!!\n");
2156 result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
2157 0x3FF0000) >> 16;
2158 result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
2159 0x3FF0000) >> 16;
2160 break;
2161 }
2162 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2163 "Path A Rx IQK Fail!!\n");
2164 }
2165
2166 if (0x00 == patha_ok)
2167 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Path A IQK Fail!!\n");
2168
2169 if (is2t) {
2170 /* path B TX IQK */
2171 for (i = 0; i < retrycount; i++) {
2172 pathb_ok = _rtl8723be_phy_path_b_iqk(hw);
2173 if (pathb_ok == 0x01) {
2174 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2175 "Path B Tx IQK Success!!\n");
2176 result[t][4] = (rtl_get_bbreg(hw, 0xe94,
2177 MASKDWORD) &
2178 0x3FF0000) >> 16;
2179 result[t][5] = (rtl_get_bbreg(hw, 0xe9c,
2180 MASKDWORD) &
2181 0x3FF0000) >> 16;
2182 break;
2183 }
2184 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2185 "Path B Tx IQK Fail!!\n");
2186 }
2187 /* path B RX IQK */
2188 for (i = 0; i < retrycount; i++) {
2189 pathb_ok = _rtl8723be_phy_path_b_rx_iqk(hw);
2190 if (pathb_ok == 0x03) {
2191 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2192 "Path B Rx IQK Success!!\n");
2193 result[t][6] = (rtl_get_bbreg(hw, 0xea4,
2194 MASKDWORD) &
2195 0x3FF0000) >> 16;
2196 result[t][7] = (rtl_get_bbreg(hw, 0xeac,
2197 MASKDWORD) &
2198 0x3FF0000) >> 16;
2199 break;
2200 }
2201 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2202 "Path B Rx IQK Fail!!\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06002203 }
2204 }
2205
Larry Finger5c99f042014-09-26 16:40:25 -05002206 /* Back to BB mode, load original value */
2207 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0);
Larry Fingera619d1a2014-02-28 15:16:50 -06002208
2209 if (t != 0) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002210 rtl8723_phy_reload_adda_registers(hw, adda_reg,
2211 rtlphy->adda_backup, 16);
2212 rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,
2213 rtlphy->iqk_mac_backup);
2214 rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
2215 rtlphy->iqk_bb_backup,
2216 IQK_BB_REG_NUM);
2217
2218 rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
Larry Finger5c99f042014-09-26 16:40:25 -05002219 /*rtl_set_rfreg(hw, RF90_PATH_B, 0xb0, 0xfffff, path_sel_rf);*/
Larry Fingera619d1a2014-02-28 15:16:50 -06002220
2221 rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
2222 rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_reg_c50);
2223 if (is2t) {
2224 rtl_set_bbreg(hw, 0xc58, MASKBYTE0, 0x50);
2225 rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_reg_c58);
2226 }
2227 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
2228 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
2229 }
2230 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "8723be IQK Finish!!\n");
2231}
2232
Larry Finger5c99f042014-09-26 16:40:25 -05002233static u8 _get_right_chnl_place_for_iqk(u8 chnl)
2234{
2235 u8 channel_all[TARGET_CHNL_NUM_2G_5G] = {
2236 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
2237 13, 14, 36, 38, 40, 42, 44, 46,
2238 48, 50, 52, 54, 56, 58, 60, 62, 64,
2239 100, 102, 104, 106, 108, 110,
2240 112, 114, 116, 118, 120, 122,
2241 124, 126, 128, 130, 132, 134, 136,
2242 138, 140, 149, 151, 153, 155, 157,
2243 159, 161, 163, 165};
2244 u8 place = chnl;
2245
2246 if (chnl > 14) {
2247 for (place = 14; place < sizeof(channel_all); place++) {
2248 if (channel_all[place] == chnl)
2249 return place - 13;
2250 }
2251 }
2252 return 0;
2253}
2254
Larry Fingera619d1a2014-02-28 15:16:50 -06002255static void _rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
2256{
Larry Fingera619d1a2014-02-28 15:16:50 -06002257 u8 tmpreg;
2258 u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
Larry Finger5c99f042014-09-26 16:40:25 -05002259 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -06002260
2261 tmpreg = rtl_read_byte(rtlpriv, 0xd03);
2262
2263 if ((tmpreg & 0x70) != 0)
2264 rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
2265 else
2266 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2267
2268 if ((tmpreg & 0x70) != 0) {
2269 rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
2270
2271 if (is2t)
2272 rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
2273 MASK12BITS);
2274
2275 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
2276 (rf_a_mode & 0x8FFFF) | 0x10000);
2277
2278 if (is2t)
2279 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
2280 (rf_b_mode & 0x8FFFF) | 0x10000);
2281 }
2282 lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
2283
2284 rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdfbe0);
2285 rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, 0x8c0a);
2286
Larry Finger5c99f042014-09-26 16:40:25 -05002287 /* In order not to disturb BT music when wifi init.(1ant NIC only) */
2288 /*mdelay(100);*/
2289 /* In order not to disturb BT music when wifi init.(1ant NIC only) */
2290 mdelay(50);
Larry Fingera619d1a2014-02-28 15:16:50 -06002291
2292 rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdffe0);
2293
2294 if ((tmpreg & 0x70) != 0) {
2295 rtl_write_byte(rtlpriv, 0xd03, tmpreg);
2296 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
2297
2298 if (is2t)
2299 rtl_set_rfreg(hw, RF90_PATH_B, 0x00,
2300 MASK12BITS, rf_b_mode);
2301 } else {
2302 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2303 }
Larry Fingerb3c42012016-03-17 13:41:03 -05002304 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06002305}
2306
2307static void _rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw,
2308 bool bmain, bool is2t)
2309{
2310 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -06002311 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
2312
Larry Finger5c99f042014-09-26 16:40:25 -05002313 if (bmain) /* left antenna */
2314 rtl_set_bbreg(hw, 0x92C, MASKDWORD, 0x1);
2315 else
2316 rtl_set_bbreg(hw, 0x92C, MASKDWORD, 0x2);
Larry Fingera619d1a2014-02-28 15:16:50 -06002317}
2318
2319#undef IQK_ADDA_REG_NUM
2320#undef IQK_DELAY_TIME
Larry Finger5c99f042014-09-26 16:40:25 -05002321/* IQK is merge from Merge Temp */
2322void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
Larry Fingera619d1a2014-02-28 15:16:50 -06002323{
2324 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -05002325 struct rtl_phy *rtlphy = &rtlpriv->phy;
Larry Fingera619d1a2014-02-28 15:16:50 -06002326 long result[4][8];
Larry Finger5c99f042014-09-26 16:40:25 -05002327 u8 i, final_candidate, idx;
2328 bool b_patha_ok, b_pathb_ok;
2329 long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4;
2330 long reg_ecc, reg_tmp = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002331 bool is12simular, is13simular, is23simular;
2332 u32 iqk_bb_reg[9] = {
2333 ROFDM0_XARXIQIMBALANCE,
2334 ROFDM0_XBRXIQIMBALANCE,
2335 ROFDM0_ECCATHRESHOLD,
2336 ROFDM0_AGCRSSITABLE,
2337 ROFDM0_XATXIQIMBALANCE,
2338 ROFDM0_XBTXIQIMBALANCE,
2339 ROFDM0_XCTXAFE,
2340 ROFDM0_XDTXAFE,
2341 ROFDM0_RXIQEXTANTA
2342 };
Larry Finger5c99f042014-09-26 16:40:25 -05002343 u32 path_sel_bb = 0; /* path_sel_rf = 0 */
Larry Fingera619d1a2014-02-28 15:16:50 -06002344
Larry Finger5c99f042014-09-26 16:40:25 -05002345 if (rtlphy->lck_inprogress)
2346 return;
2347
2348 spin_lock(&rtlpriv->locks.iqk_lock);
2349 rtlphy->lck_inprogress = true;
2350 spin_unlock(&rtlpriv->locks.iqk_lock);
2351
2352 if (b_recovery) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002353 rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
2354 rtlphy->iqk_bb_backup, 9);
2355 return;
2356 }
Larry Finger5c99f042014-09-26 16:40:25 -05002357 /* Save RF Path */
2358 path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
2359 /* path_sel_rf = rtl_get_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff); */
Larry Fingera619d1a2014-02-28 15:16:50 -06002360
2361 for (i = 0; i < 8; i++) {
2362 result[0][i] = 0;
2363 result[1][i] = 0;
2364 result[2][i] = 0;
2365 result[3][i] = 0;
2366 }
2367 final_candidate = 0xff;
Larry Finger5c99f042014-09-26 16:40:25 -05002368 b_patha_ok = false;
2369 b_pathb_ok = false;
Larry Fingera619d1a2014-02-28 15:16:50 -06002370 is12simular = false;
2371 is23simular = false;
2372 is13simular = false;
2373 for (i = 0; i < 3; i++) {
Larry Finger5c99f042014-09-26 16:40:25 -05002374 _rtl8723be_phy_iq_calibrate(hw, result, i, true);
Larry Fingera619d1a2014-02-28 15:16:50 -06002375 if (i == 1) {
Larry Finger5c99f042014-09-26 16:40:25 -05002376 is12simular = _rtl8723be_phy_simularity_compare(hw,
2377 result,
2378 0, 1);
Larry Fingera619d1a2014-02-28 15:16:50 -06002379 if (is12simular) {
2380 final_candidate = 0;
2381 break;
2382 }
2383 }
2384 if (i == 2) {
Larry Finger5c99f042014-09-26 16:40:25 -05002385 is13simular = _rtl8723be_phy_simularity_compare(hw,
2386 result,
2387 0, 2);
Larry Fingera619d1a2014-02-28 15:16:50 -06002388 if (is13simular) {
2389 final_candidate = 0;
2390 break;
2391 }
Larry Finger5c99f042014-09-26 16:40:25 -05002392 is23simular = _rtl8723be_phy_simularity_compare(hw,
2393 result,
2394 1, 2);
Larry Fingera619d1a2014-02-28 15:16:50 -06002395 if (is23simular) {
2396 final_candidate = 1;
2397 } else {
2398 for (i = 0; i < 8; i++)
2399 reg_tmp += result[3][i];
2400
2401 if (reg_tmp != 0)
2402 final_candidate = 3;
2403 else
2404 final_candidate = 0xFF;
2405 }
2406 }
2407 }
2408 for (i = 0; i < 4; i++) {
2409 reg_e94 = result[i][0];
2410 reg_e9c = result[i][1];
2411 reg_ea4 = result[i][2];
2412 reg_eac = result[i][3];
2413 reg_eb4 = result[i][4];
2414 reg_ebc = result[i][5];
2415 reg_ec4 = result[i][6];
2416 reg_ecc = result[i][7];
2417 }
2418 if (final_candidate != 0xff) {
2419 reg_e94 = result[final_candidate][0];
2420 rtlphy->reg_e94 = reg_e94;
2421 reg_e9c = result[final_candidate][1];
2422 rtlphy->reg_e9c = reg_e9c;
2423 reg_ea4 = result[final_candidate][2];
2424 reg_eac = result[final_candidate][3];
2425 reg_eb4 = result[final_candidate][4];
2426 rtlphy->reg_eb4 = reg_eb4;
2427 reg_ebc = result[final_candidate][5];
2428 rtlphy->reg_ebc = reg_ebc;
2429 reg_ec4 = result[final_candidate][6];
2430 reg_ecc = result[final_candidate][7];
Larry Finger5c99f042014-09-26 16:40:25 -05002431 b_patha_ok = true;
2432 b_pathb_ok = true;
Larry Fingera619d1a2014-02-28 15:16:50 -06002433 } else {
2434 rtlphy->reg_e94 = 0x100;
2435 rtlphy->reg_eb4 = 0x100;
2436 rtlphy->reg_e9c = 0x0;
2437 rtlphy->reg_ebc = 0x0;
2438 }
Larry Finger5c99f042014-09-26 16:40:25 -05002439 if (reg_e94 != 0)
2440 rtl8723_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result,
Larry Fingera619d1a2014-02-28 15:16:50 -06002441 final_candidate,
2442 (reg_ea4 == 0));
Larry Finger5c99f042014-09-26 16:40:25 -05002443 if (reg_eb4 != 0)
2444 _rtl8723be_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, result,
2445 final_candidate,
2446 (reg_ec4 == 0));
2447
2448 idx = _get_right_chnl_place_for_iqk(rtlphy->current_channel);
2449
2450 if (final_candidate < 4) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002451 for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
Larry Finger5c99f042014-09-26 16:40:25 -05002452 rtlphy->iqk_matrix[idx].value[0][i] =
Larry Fingera619d1a2014-02-28 15:16:50 -06002453 result[final_candidate][i];
Larry Finger5c99f042014-09-26 16:40:25 -05002454 rtlphy->iqk_matrix[idx].iqk_done = true;
2455
Larry Fingera619d1a2014-02-28 15:16:50 -06002456 }
Larry Finger5c99f042014-09-26 16:40:25 -05002457 rtl8723_save_adda_registers(hw, iqk_bb_reg,
2458 rtlphy->iqk_bb_backup, 9);
2459
2460 rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
2461 /* rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff, path_sel_rf); */
2462
2463 spin_lock(&rtlpriv->locks.iqk_lock);
2464 rtlphy->lck_inprogress = false;
2465 spin_unlock(&rtlpriv->locks.iqk_lock);
Larry Fingera619d1a2014-02-28 15:16:50 -06002466}
2467
2468void rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw)
2469{
2470 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -05002471 struct rtl_phy *rtlphy = &rtlpriv->phy;
2472 struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
Larry Fingera619d1a2014-02-28 15:16:50 -06002473 u32 timeout = 2000, timecount = 0;
2474
2475 while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
2476 udelay(50);
2477 timecount += 50;
2478 }
2479
2480 rtlphy->lck_inprogress = true;
Larry Finger5c99f042014-09-26 16:40:25 -05002481 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Larry Fingera619d1a2014-02-28 15:16:50 -06002482 "LCK:Start!!! currentband %x delay %d ms\n",
Larry Finger5c99f042014-09-26 16:40:25 -05002483 rtlhal->current_bandtype, timecount);
Larry Fingera619d1a2014-02-28 15:16:50 -06002484
2485 _rtl8723be_phy_lc_calibrate(hw, false);
2486
2487 rtlphy->lck_inprogress = false;
2488}
2489
Larry Fingera619d1a2014-02-28 15:16:50 -06002490void rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
2491{
Larry Finger5c99f042014-09-26 16:40:25 -05002492 _rtl8723be_phy_set_rfpath_switch(hw, bmain, true);
Larry Fingera619d1a2014-02-28 15:16:50 -06002493}
2494
2495bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
2496{
2497 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -05002498 struct rtl_phy *rtlphy = &rtlpriv->phy;
2499 bool b_postprocessing = false;
Larry Fingera619d1a2014-02-28 15:16:50 -06002500
2501 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2502 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
2503 iotype, rtlphy->set_io_inprogress);
2504 do {
2505 switch (iotype) {
2506 case IO_CMD_RESUME_DM_BY_SCAN:
2507 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2508 "[IO CMD] Resume DM after scan.\n");
Larry Finger5c99f042014-09-26 16:40:25 -05002509 b_postprocessing = true;
Larry Fingera619d1a2014-02-28 15:16:50 -06002510 break;
Larry Finger5c99f042014-09-26 16:40:25 -05002511 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
Larry Fingera619d1a2014-02-28 15:16:50 -06002512 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2513 "[IO CMD] Pause DM before scan.\n");
Larry Finger5c99f042014-09-26 16:40:25 -05002514 b_postprocessing = true;
Larry Fingera619d1a2014-02-28 15:16:50 -06002515 break;
2516 default:
Larry Finger5c99f042014-09-26 16:40:25 -05002517 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Larry Fingera619d1a2014-02-28 15:16:50 -06002518 "switch case not process\n");
2519 break;
2520 }
2521 } while (false);
Larry Finger5c99f042014-09-26 16:40:25 -05002522 if (b_postprocessing && !rtlphy->set_io_inprogress) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002523 rtlphy->set_io_inprogress = true;
2524 rtlphy->current_io_type = iotype;
2525 } else {
2526 return false;
2527 }
2528 rtl8723be_phy_set_io(hw);
2529 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
2530 return true;
2531}
2532
Larry Finger5c99f042014-09-26 16:40:25 -05002533static void rtl8723be_phy_set_io(struct ieee80211_hw *hw)
2534{
2535 struct rtl_priv *rtlpriv = rtl_priv(hw);
2536 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
2537 struct rtl_phy *rtlphy = &rtlpriv->phy;
2538
2539 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2540 "--->Cmd(%#x), set_io_inprogress(%d)\n",
2541 rtlphy->current_io_type, rtlphy->set_io_inprogress);
2542 switch (rtlphy->current_io_type) {
2543 case IO_CMD_RESUME_DM_BY_SCAN:
2544 dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;
2545 /*rtl92c_dm_write_dig(hw);*/
2546 rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel);
2547 rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83);
2548 break;
2549 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2550 rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
2551 dm_digtable->cur_igvalue = 0x17;
2552 rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40);
2553 break;
2554 default:
2555 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
2556 "switch case not process\n");
2557 break;
2558 }
2559 rtlphy->set_io_inprogress = false;
2560 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2561 "(%#x)\n", rtlphy->current_io_type);
2562}
2563
Larry Fingera619d1a2014-02-28 15:16:50 -06002564static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw)
2565{
2566 struct rtl_priv *rtlpriv = rtl_priv(hw);
2567
2568 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
2569 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2570 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2571 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2572 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2573}
2574
2575static void _rtl8723be_phy_set_rf_sleep(struct ieee80211_hw *hw)
2576{
2577 struct rtl_priv *rtlpriv = rtl_priv(hw);
2578
2579 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2580 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2581 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2582 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2583}
2584
2585static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2586 enum rf_pwrstate rfpwr_state)
2587{
2588 struct rtl_priv *rtlpriv = rtl_priv(hw);
2589 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2590 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2591 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2592 bool bresult = true;
2593 u8 i, queue_id;
2594 struct rtl8192_tx_ring *ring = NULL;
2595
2596 switch (rfpwr_state) {
2597 case ERFON:
2598 if ((ppsc->rfpwr_state == ERFOFF) &&
Larry Finger5c99f042014-09-26 16:40:25 -05002599 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002600 bool rtstatus;
Larry Finger5c99f042014-09-26 16:40:25 -05002601 u32 initializecount = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002602 do {
Larry Finger5c99f042014-09-26 16:40:25 -05002603 initializecount++;
Larry Fingera619d1a2014-02-28 15:16:50 -06002604 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2605 "IPS Set eRf nic enable\n");
2606 rtstatus = rtl_ps_enable_nic(hw);
Larry Finger5c99f042014-09-26 16:40:25 -05002607 } while (!rtstatus && (initializecount < 10));
Larry Fingerb3c42012016-03-17 13:41:03 -05002608 RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
Larry Fingera619d1a2014-02-28 15:16:50 -06002609 } else {
2610 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2611 "Set ERFON sleeped:%d ms\n",
2612 jiffies_to_msecs(jiffies -
2613 ppsc->last_sleep_jiffies));
2614 ppsc->last_awake_jiffies = jiffies;
2615 rtl8723be_phy_set_rf_on(hw);
2616 }
2617 if (mac->link_state == MAC80211_LINKED)
2618 rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
2619 else
2620 rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
Larry Finger5c99f042014-09-26 16:40:25 -05002621
Larry Fingera619d1a2014-02-28 15:16:50 -06002622 break;
Larry Finger5c99f042014-09-26 16:40:25 -05002623
Larry Fingera619d1a2014-02-28 15:16:50 -06002624 case ERFOFF:
2625 for (queue_id = 0, i = 0;
2626 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2627 ring = &pcipriv->dev.tx_ring[queue_id];
Larry Finger5c99f042014-09-26 16:40:25 -05002628 /* Don't check BEACON Q.
2629 * BEACON Q is always not empty,
2630 * because '_rtl8723be_cmd_send_packet'
2631 */
2632 if (queue_id == BEACON_QUEUE ||
2633 skb_queue_len(&ring->queue) == 0) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002634 queue_id++;
2635 continue;
2636 } else {
2637 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
Larry Finger5c99f042014-09-26 16:40:25 -05002638 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2639 (i + 1), queue_id,
2640 skb_queue_len(&ring->queue));
Larry Fingera619d1a2014-02-28 15:16:50 -06002641
2642 udelay(10);
2643 i++;
2644 }
2645 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2646 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
Larry Finger5c99f042014-09-26 16:40:25 -05002647 "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
Larry Fingera619d1a2014-02-28 15:16:50 -06002648 MAX_DOZE_WAITING_TIMES_9x,
2649 queue_id,
2650 skb_queue_len(&ring->queue));
2651 break;
2652 }
2653 }
2654
2655 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
2656 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2657 "IPS Set eRf nic disable\n");
2658 rtl_ps_disable_nic(hw);
2659 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2660 } else {
2661 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
2662 rtlpriv->cfg->ops->led_control(hw,
2663 LED_CTL_NO_LINK);
2664 } else {
2665 rtlpriv->cfg->ops->led_control(hw,
2666 LED_CTL_POWER_OFF);
2667 }
2668 }
2669 break;
Larry Finger5c99f042014-09-26 16:40:25 -05002670
Larry Fingera619d1a2014-02-28 15:16:50 -06002671 case ERFSLEEP:
2672 if (ppsc->rfpwr_state == ERFOFF)
2673 break;
2674 for (queue_id = 0, i = 0;
2675 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2676 ring = &pcipriv->dev.tx_ring[queue_id];
2677 if (skb_queue_len(&ring->queue) == 0) {
2678 queue_id++;
2679 continue;
2680 } else {
2681 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
Larry Finger5c99f042014-09-26 16:40:25 -05002682 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2683 (i + 1), queue_id,
2684 skb_queue_len(&ring->queue));
Larry Fingera619d1a2014-02-28 15:16:50 -06002685
2686 udelay(10);
2687 i++;
2688 }
2689 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2690 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
Larry Finger5c99f042014-09-26 16:40:25 -05002691 "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2692 MAX_DOZE_WAITING_TIMES_9x,
2693 queue_id,
2694 skb_queue_len(&ring->queue));
Larry Fingera619d1a2014-02-28 15:16:50 -06002695 break;
2696 }
2697 }
2698 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2699 "Set ERFSLEEP awaked:%d ms\n",
2700 jiffies_to_msecs(jiffies -
2701 ppsc->last_awake_jiffies));
2702 ppsc->last_sleep_jiffies = jiffies;
2703 _rtl8723be_phy_set_rf_sleep(hw);
2704 break;
Larry Finger5c99f042014-09-26 16:40:25 -05002705
Larry Fingera619d1a2014-02-28 15:16:50 -06002706 default:
Larry Finger5c99f042014-09-26 16:40:25 -05002707 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Larry Fingera619d1a2014-02-28 15:16:50 -06002708 "switch case not process\n");
2709 bresult = false;
2710 break;
2711 }
2712 if (bresult)
2713 ppsc->rfpwr_state = rfpwr_state;
2714 return bresult;
2715}
2716
2717bool rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2718 enum rf_pwrstate rfpwr_state)
2719{
2720 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2721
2722 bool bresult = false;
2723
2724 if (rfpwr_state == ppsc->rfpwr_state)
2725 return bresult;
2726 bresult = _rtl8723be_phy_set_rf_power_state(hw, rfpwr_state);
2727 return bresult;
2728}