blob: 5ad7e753c357f8671a9b5f518f1661205c57e898 [file] [log] [blame]
Larry Fingerb1a3bfc2014-09-26 16:40:23 -05001/******************************************************************************
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 "rf.h"
33#include "dm.h"
34#include "table.h"
35
36static u32 _rtl92ee_phy_rf_serial_read(struct ieee80211_hw *hw,
37 enum radio_path rfpath, u32 offset);
38static void _rtl92ee_phy_rf_serial_write(struct ieee80211_hw *hw,
39 enum radio_path rfpath, u32 offset,
40 u32 data);
41static u32 _rtl92ee_phy_calculate_bit_shift(u32 bitmask);
42static bool _rtl92ee_phy_bb8192ee_config_parafile(struct ieee80211_hw *hw);
43static bool _rtl92ee_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
44static bool phy_config_bb_with_hdr_file(struct ieee80211_hw *hw,
45 u8 configtype);
46static bool phy_config_bb_with_pghdrfile(struct ieee80211_hw *hw,
47 u8 configtype);
48static void phy_init_bb_rf_register_def(struct ieee80211_hw *hw);
49static bool _rtl92ee_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
50 u32 cmdtableidx, u32 cmdtablesz,
51 enum swchnlcmd_id cmdid,
52 u32 para1, u32 para2,
53 u32 msdelay);
54static bool _rtl92ee_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
55 u8 channel, u8 *stage,
56 u8 *step, u32 *delay);
57static long _rtl92ee_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
58 enum wireless_mode wirelessmode,
59 u8 txpwridx);
60static void rtl92ee_phy_set_rf_on(struct ieee80211_hw *hw);
61static void rtl92ee_phy_set_io(struct ieee80211_hw *hw);
62
63u32 rtl92ee_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
64{
65 struct rtl_priv *rtlpriv = rtl_priv(hw);
66 u32 returnvalue, originalvalue, bitshift;
67
68 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
69 "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask);
70 originalvalue = rtl_read_dword(rtlpriv, regaddr);
71 bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask);
72 returnvalue = (originalvalue & bitmask) >> bitshift;
73
74 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
75 "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
76 bitmask, regaddr, originalvalue);
77
78 return returnvalue;
79}
80
81void rtl92ee_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
82 u32 bitmask, u32 data)
83{
84 struct rtl_priv *rtlpriv = rtl_priv(hw);
85 u32 originalvalue, bitshift;
86
87 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
88 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
89 regaddr, bitmask, data);
90
91 if (bitmask != MASKDWORD) {
92 originalvalue = rtl_read_dword(rtlpriv, regaddr);
93 bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask);
94 data = ((originalvalue & (~bitmask)) | (data << bitshift));
95 }
96
97 rtl_write_dword(rtlpriv, regaddr, data);
98
99 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
100 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
101 regaddr, bitmask, data);
102}
103
104u32 rtl92ee_phy_query_rf_reg(struct ieee80211_hw *hw,
105 enum radio_path rfpath, u32 regaddr, u32 bitmask)
106{
107 struct rtl_priv *rtlpriv = rtl_priv(hw);
108 u32 original_value, readback_value, bitshift;
109 unsigned long flags;
110
111 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
112 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
113 regaddr, rfpath, bitmask);
114
115 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
116
117 original_value = _rtl92ee_phy_rf_serial_read(hw , rfpath, regaddr);
118 bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask);
119 readback_value = (original_value & bitmask) >> bitshift;
120
121 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
122
123 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
124 "regaddr(%#x),rfpath(%#x),bitmask(%#x),original_value(%#x)\n",
125 regaddr, rfpath, bitmask, original_value);
126
127 return readback_value;
128}
129
130void rtl92ee_phy_set_rf_reg(struct ieee80211_hw *hw,
131 enum radio_path rfpath,
132 u32 addr, u32 bitmask, u32 data)
133{
134 struct rtl_priv *rtlpriv = rtl_priv(hw);
135 u32 original_value, bitshift;
136 unsigned long flags;
137
138 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
139 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
140 addr, bitmask, data, rfpath);
141
142 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
143
144 if (bitmask != RFREG_OFFSET_MASK) {
145 original_value = _rtl92ee_phy_rf_serial_read(hw, rfpath, addr);
146 bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask);
147 data = (original_value & (~bitmask)) | (data << bitshift);
148 }
149
150 _rtl92ee_phy_rf_serial_write(hw, rfpath, addr, data);
151
152 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
153
154 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
155 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
156 addr, bitmask, data, rfpath);
157}
158
159static u32 _rtl92ee_phy_rf_serial_read(struct ieee80211_hw *hw,
160 enum radio_path rfpath, u32 offset)
161{
162 struct rtl_priv *rtlpriv = rtl_priv(hw);
163 struct rtl_phy *rtlphy = &rtlpriv->phy;
164 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
165 u32 newoffset;
166 u32 tmplong, tmplong2;
167 u8 rfpi_enable = 0;
168 u32 retvalue;
169
170 offset &= 0xff;
171 newoffset = offset;
172 if (RT_CANNOT_IO(hw)) {
173 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n");
174 return 0xFFFFFFFF;
175 }
176 tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
177 if (rfpath == RF90_PATH_A)
178 tmplong2 = tmplong;
179 else
180 tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
181 tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
182 (newoffset << 23) | BLSSIREADEDGE;
183 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
184 tmplong & (~BLSSIREADEDGE));
185 mdelay(1);
186 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
187 mdelay(2);
188 if (rfpath == RF90_PATH_A)
189 rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
190 BIT(8));
191 else if (rfpath == RF90_PATH_B)
192 rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
193 BIT(8));
194 if (rfpi_enable)
195 retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi,
196 BLSSIREADBACKDATA);
197 else
198 retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb,
199 BLSSIREADBACKDATA);
200 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
201 "RFR-%d Addr[0x%x]=0x%x\n",
202 rfpath, pphyreg->rf_rb, retvalue);
203 return retvalue;
204}
205
206static void _rtl92ee_phy_rf_serial_write(struct ieee80211_hw *hw,
207 enum radio_path rfpath, u32 offset,
208 u32 data)
209{
210 u32 data_and_addr;
211 u32 newoffset;
212 struct rtl_priv *rtlpriv = rtl_priv(hw);
213 struct rtl_phy *rtlphy = &rtlpriv->phy;
214 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
215
216 if (RT_CANNOT_IO(hw)) {
217 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n");
218 return;
219 }
220 offset &= 0xff;
221 newoffset = offset;
222 data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
223 rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
224 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
225 "RFW-%d Addr[0x%x]=0x%x\n", rfpath,
226 pphyreg->rf3wire_offset, data_and_addr);
227}
228
229static u32 _rtl92ee_phy_calculate_bit_shift(u32 bitmask)
230{
231 u32 i;
232
233 for (i = 0; i <= 31; i++) {
234 if (((bitmask >> i) & 0x1) == 1)
235 break;
236 }
237 return i;
238}
239
240bool rtl92ee_phy_mac_config(struct ieee80211_hw *hw)
241{
242 return _rtl92ee_phy_config_mac_with_headerfile(hw);
243}
244
245bool rtl92ee_phy_bb_config(struct ieee80211_hw *hw)
246{
247 struct rtl_priv *rtlpriv = rtl_priv(hw);
248 bool rtstatus = true;
249 u16 regval;
250 u32 tmp;
251 u8 crystal_cap;
252
253 phy_init_bb_rf_register_def(hw);
254 regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
255 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
256 regval | BIT(13) | BIT(0) | BIT(1));
257
258 rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
259 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
260 FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
261 FEN_BB_GLB_RSTN | FEN_BBRSTB);
262
263 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
264
265 tmp = rtl_read_dword(rtlpriv, 0x4c);
266 rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23));
267
268 rtstatus = _rtl92ee_phy_bb8192ee_config_parafile(hw);
269
270 crystal_cap = rtlpriv->efuse.eeprom_crystalcap & 0x3F;
271 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
272 (crystal_cap | (crystal_cap << 6)));
273 return rtstatus;
274}
275
276bool rtl92ee_phy_rf_config(struct ieee80211_hw *hw)
277{
278 return rtl92ee_phy_rf6052_config(hw);
279}
280
281static bool _check_condition(struct ieee80211_hw *hw,
282 const u32 condition)
283{
284 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
285 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
286 u32 _board = rtlefuse->board_type; /*need efuse define*/
287 u32 _interface = rtlhal->interface;
288 u32 _platform = 0x08;/*SupportPlatform */
289 u32 cond = condition;
290
291 if (condition == 0xCDCDCDCD)
292 return true;
293
294 cond = condition & 0xFF;
295 if ((_board != cond) && (cond != 0xFF))
296 return false;
297
298 cond = condition & 0xFF00;
299 cond = cond >> 8;
300 if ((_interface & cond) == 0 && cond != 0x07)
301 return false;
302
303 cond = condition & 0xFF0000;
304 cond = cond >> 16;
305 if ((_platform & cond) == 0 && cond != 0x0F)
306 return false;
307
308 return true;
309}
310
311static void _rtl92ee_config_rf_reg(struct ieee80211_hw *hw, u32 addr, u32 data,
312 enum radio_path rfpath, u32 regaddr)
313{
314 if (addr == 0xfe || addr == 0xffe) {
315 mdelay(50);
316 } else {
317 rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
318 udelay(1);
319
320 if (addr == 0xb6) {
321 u32 getvalue;
322 u8 count = 0;
323
324 getvalue = rtl_get_rfreg(hw, rfpath, addr, MASKDWORD);
325 udelay(1);
326
327 while ((getvalue >> 8) != (data >> 8)) {
328 count++;
329 rtl_set_rfreg(hw, rfpath, regaddr,
330 RFREG_OFFSET_MASK, data);
331 udelay(1);
332 getvalue = rtl_get_rfreg(hw, rfpath, addr,
333 MASKDWORD);
334 if (count > 5)
335 break;
336 }
337 }
338
339 if (addr == 0xb2) {
340 u32 getvalue;
341 u8 count = 0;
342
343 getvalue = rtl_get_rfreg(hw, rfpath, addr, MASKDWORD);
344 udelay(1);
345
346 while (getvalue != data) {
347 count++;
348 rtl_set_rfreg(hw, rfpath, regaddr,
349 RFREG_OFFSET_MASK, data);
350 udelay(1);
351 rtl_set_rfreg(hw, rfpath, 0x18,
352 RFREG_OFFSET_MASK, 0x0fc07);
353 udelay(1);
354 getvalue = rtl_get_rfreg(hw, rfpath, addr,
355 MASKDWORD);
356 if (count > 5)
357 break;
358 }
359 }
360 }
361}
362
363static void _rtl92ee_config_rf_radio_a(struct ieee80211_hw *hw,
364 u32 addr, u32 data)
365{
366 u32 content = 0x1000; /*RF Content: radio_a_txt*/
367 u32 maskforphyset = (u32)(content & 0xE000);
368
369 _rtl92ee_config_rf_reg(hw, addr, data, RF90_PATH_A,
370 addr | maskforphyset);
371}
372
373static void _rtl92ee_config_rf_radio_b(struct ieee80211_hw *hw,
374 u32 addr, u32 data)
375{
376 u32 content = 0x1001; /*RF Content: radio_b_txt*/
377 u32 maskforphyset = (u32)(content & 0xE000);
378
379 _rtl92ee_config_rf_reg(hw, addr, data, RF90_PATH_B,
380 addr | maskforphyset);
381}
382
383static void _rtl92ee_config_bb_reg(struct ieee80211_hw *hw,
384 u32 addr, u32 data)
385{
386 if (addr == 0xfe)
387 mdelay(50);
388 else if (addr == 0xfd)
389 mdelay(5);
390 else if (addr == 0xfc)
391 mdelay(1);
392 else if (addr == 0xfb)
393 udelay(50);
394 else if (addr == 0xfa)
395 udelay(5);
396 else if (addr == 0xf9)
397 udelay(1);
398 else
399 rtl_set_bbreg(hw, addr, MASKDWORD , data);
400
401 udelay(1);
402}
403
404static void _rtl92ee_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
405{
406 struct rtl_priv *rtlpriv = rtl_priv(hw);
407 struct rtl_phy *rtlphy = &rtlpriv->phy;
408
409 u8 band = BAND_ON_2_4G, rf = 0, txnum = 0, sec = 0;
410
411 for (; band <= BAND_ON_5G; ++band)
412 for (; rf < TX_PWR_BY_RATE_NUM_RF; ++rf)
413 for (; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
414 for (; sec < TX_PWR_BY_RATE_NUM_SECTION; ++sec)
415 rtlphy->tx_power_by_rate_offset
416 [band][rf][txnum][sec] = 0;
417}
418
419static void _rtl92ee_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
420 u8 band, u8 path,
421 u8 rate_section, u8 txnum,
422 u8 value)
423{
424 struct rtl_priv *rtlpriv = rtl_priv(hw);
425 struct rtl_phy *rtlphy = &rtlpriv->phy;
426
427 if (path > RF90_PATH_D) {
428 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
429 "Invalid Rf Path %d\n", path);
430 return;
431 }
432
433 if (band == BAND_ON_2_4G) {
434 switch (rate_section) {
435 case CCK:
436 rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
437 break;
438 case OFDM:
439 rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
440 break;
441 case HT_MCS0_MCS7:
442 rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
443 break;
444 case HT_MCS8_MCS15:
445 rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
446 break;
447 default:
448 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
449 "Invalid RateSection %d in 2.4G,Rf %d,%dTx\n",
450 rate_section, path, txnum);
451 break;
Wu Fengguang12ff7282015-08-15 18:36:37 +0800452 }
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500453 } else {
454 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
455 "Invalid Band %d\n", band);
456 }
457}
458
459static u8 _rtl92ee_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
460 u8 band, u8 path, u8 txnum,
461 u8 rate_section)
462{
463 struct rtl_priv *rtlpriv = rtl_priv(hw);
464 struct rtl_phy *rtlphy = &rtlpriv->phy;
465 u8 value = 0;
466
467 if (path > RF90_PATH_D) {
468 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
469 "Invalid Rf Path %d\n", path);
470 return 0;
471 }
472
473 if (band == BAND_ON_2_4G) {
474 switch (rate_section) {
475 case CCK:
476 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
477 break;
478 case OFDM:
479 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
480 break;
481 case HT_MCS0_MCS7:
482 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
483 break;
484 case HT_MCS8_MCS15:
485 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
486 break;
487 default:
488 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
489 "Invalid RateSection %d in 2.4G,Rf %d,%dTx\n",
490 rate_section, path, txnum);
491 break;
Wu Fengguang12ff7282015-08-15 18:36:37 +0800492 }
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500493 } else {
494 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
495 "Invalid Band %d()\n", band);
496 }
497 return value;
498}
499
500static void _rtl92ee_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
501{
502 struct rtl_priv *rtlpriv = rtl_priv(hw);
503 struct rtl_phy *rtlphy = &rtlpriv->phy;
504 u16 raw = 0;
505 u8 base = 0, path = 0;
506
507 for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
508 if (path == RF90_PATH_A) {
509 raw = (u16)(rtlphy->tx_power_by_rate_offset
510 [BAND_ON_2_4G][path][RF_1TX][3] >> 24) &
511 0xFF;
512 base = (raw >> 4) * 10 + (raw & 0xF);
513 _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
514 path, CCK, RF_1TX,
515 base);
516 } else if (path == RF90_PATH_B) {
517 raw = (u16)(rtlphy->tx_power_by_rate_offset
518 [BAND_ON_2_4G][path][RF_1TX][3] >> 0) &
519 0xFF;
520 base = (raw >> 4) * 10 + (raw & 0xF);
521 _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
522 path, CCK, RF_1TX,
523 base);
524 }
525 raw = (u16)(rtlphy->tx_power_by_rate_offset
526 [BAND_ON_2_4G][path][RF_1TX][1] >> 24) & 0xFF;
527 base = (raw >> 4) * 10 + (raw & 0xF);
528 _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path,
529 OFDM, RF_1TX, base);
530
531 raw = (u16)(rtlphy->tx_power_by_rate_offset
532 [BAND_ON_2_4G][path][RF_1TX][5] >> 24) & 0xFF;
533 base = (raw >> 4) * 10 + (raw & 0xF);
534 _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path,
535 HT_MCS0_MCS7, RF_1TX,
536 base);
537
538 raw = (u16)(rtlphy->tx_power_by_rate_offset
539 [BAND_ON_2_4G][path][RF_2TX][7] >> 24) & 0xFF;
540 base = (raw >> 4) * 10 + (raw & 0xF);
541 _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path,
542 HT_MCS8_MCS15, RF_2TX,
543 base);
544 }
545}
546
547static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start,
548 u8 end, u8 base)
549{
Arnd Bergmann08aba422016-06-15 23:30:43 +0200550 s8 i = 0;
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500551 u8 tmp = 0;
552 u32 temp_data = 0;
553
554 for (i = 3; i >= 0; --i) {
555 if (i >= start && i <= end) {
556 /* Get the exact value */
557 tmp = (u8)(*data >> (i * 8)) & 0xF;
558 tmp += ((u8)((*data >> (i * 8 + 4)) & 0xF)) * 10;
559
560 /* Change the value to a relative value */
561 tmp = (tmp > base) ? tmp - base : base - tmp;
562 } else {
563 tmp = (u8)(*data >> (i * 8)) & 0xFF;
564 }
565 temp_data <<= 8;
566 temp_data |= tmp;
567 }
568 *data = temp_data;
569}
570
571static void phy_convert_txpwr_dbm_to_rel_val(struct ieee80211_hw *hw)
572{
573 struct rtl_priv *rtlpriv = rtl_priv(hw);
574 struct rtl_phy *rtlphy = &rtlpriv->phy;
575 u8 base = 0, rf = 0, band = BAND_ON_2_4G;
576
577 for (rf = RF90_PATH_A; rf <= RF90_PATH_B; ++rf) {
578 if (rf == RF90_PATH_A) {
579 base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band,
580 rf, RF_1TX,
581 CCK);
582 _phy_convert_txpower_dbm_to_relative_value(
583 &rtlphy->tx_power_by_rate_offset
584 [band][rf][RF_1TX][2],
585 1, 1, base);
586 _phy_convert_txpower_dbm_to_relative_value(
587 &rtlphy->tx_power_by_rate_offset
588 [band][rf][RF_1TX][3],
589 1, 3, base);
590 } else if (rf == RF90_PATH_B) {
591 base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band,
592 rf, RF_1TX,
593 CCK);
594 _phy_convert_txpower_dbm_to_relative_value(
595 &rtlphy->tx_power_by_rate_offset
596 [band][rf][RF_1TX][3],
597 0, 0, base);
598 _phy_convert_txpower_dbm_to_relative_value(
599 &rtlphy->tx_power_by_rate_offset
600 [band][rf][RF_1TX][2],
601 1, 3, base);
602 }
603 base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, rf,
604 RF_1TX, OFDM);
605 _phy_convert_txpower_dbm_to_relative_value(
606 &rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][0],
607 0, 3, base);
608 _phy_convert_txpower_dbm_to_relative_value(
609 &rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][1],
610 0, 3, base);
611
612 base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, rf,
613 RF_1TX,
614 HT_MCS0_MCS7);
615 _phy_convert_txpower_dbm_to_relative_value(
616 &rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][4],
617 0, 3, base);
618 _phy_convert_txpower_dbm_to_relative_value(
619 &rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][5],
620 0, 3, base);
621
622 base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, rf,
623 RF_2TX,
624 HT_MCS8_MCS15);
625 _phy_convert_txpower_dbm_to_relative_value(
626 &rtlphy->tx_power_by_rate_offset[band][rf][RF_2TX][6],
627 0, 3, base);
628
629 _phy_convert_txpower_dbm_to_relative_value(
630 &rtlphy->tx_power_by_rate_offset[band][rf][RF_2TX][7],
631 0, 3, base);
632 }
633
634 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
635 "<==phy_convert_txpwr_dbm_to_rel_val()\n");
636}
637
638static void _rtl92ee_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw)
639{
640 _rtl92ee_phy_store_txpower_by_rate_base(hw);
641 phy_convert_txpwr_dbm_to_rel_val(hw);
642}
643
644static bool _rtl92ee_phy_bb8192ee_config_parafile(struct ieee80211_hw *hw)
645{
646 struct rtl_priv *rtlpriv = rtl_priv(hw);
647 struct rtl_phy *rtlphy = &rtlpriv->phy;
648 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
649 bool rtstatus;
650
651 rtstatus = phy_config_bb_with_hdr_file(hw, BASEBAND_CONFIG_PHY_REG);
652 if (!rtstatus) {
Joe Perches4713bd12016-06-26 12:34:30 -0700653 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!\n");
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500654 return false;
655 }
656
657 _rtl92ee_phy_init_tx_power_by_rate(hw);
658 if (!rtlefuse->autoload_failflag) {
659 rtlphy->pwrgroup_cnt = 0;
660 rtstatus =
661 phy_config_bb_with_pghdrfile(hw, BASEBAND_CONFIG_PHY_REG);
662 }
663 _rtl92ee_phy_txpower_by_rate_configuration(hw);
664 if (!rtstatus) {
Joe Perches4713bd12016-06-26 12:34:30 -0700665 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!\n");
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500666 return false;
667 }
668 rtstatus = phy_config_bb_with_hdr_file(hw, BASEBAND_CONFIG_AGC_TAB);
669 if (!rtstatus) {
670 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
671 return false;
672 }
673 rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw,
674 RFPGA0_XA_HSSIPARAMETER2,
675 0x200));
676
677 return true;
678}
679
680static bool _rtl92ee_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
681{
682 struct rtl_priv *rtlpriv = rtl_priv(hw);
683 u32 i;
684 u32 arraylength;
685 u32 *ptrarray;
686
687 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl8192EMACPHY_Array\n");
688 arraylength = RTL8192EE_MAC_ARRAY_LEN;
689 ptrarray = RTL8192EE_MAC_ARRAY;
690 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
691 "Img:RTL8192EE_MAC_ARRAY LEN %d\n" , arraylength);
692 for (i = 0; i < arraylength; i = i + 2)
693 rtl_write_byte(rtlpriv, ptrarray[i], (u8)ptrarray[i + 1]);
694 return true;
695}
696
697#define READ_NEXT_PAIR(v1, v2, i) \
698 do { \
699 i += 2; \
700 v1 = array[i]; \
701 v2 = array[i+1]; \
702 } while (0)
703
704static bool phy_config_bb_with_hdr_file(struct ieee80211_hw *hw,
705 u8 configtype)
706{
707 int i;
708 u32 *array;
709 u16 len;
710 struct rtl_priv *rtlpriv = rtl_priv(hw);
711 u32 v1 = 0, v2 = 0;
712
713 if (configtype == BASEBAND_CONFIG_PHY_REG) {
714 len = RTL8192EE_PHY_REG_ARRAY_LEN;
715 array = RTL8192EE_PHY_REG_ARRAY;
716
717 for (i = 0; i < len; i = i + 2) {
718 v1 = array[i];
719 v2 = array[i+1];
720 if (v1 < 0xcdcdcdcd) {
721 _rtl92ee_config_bb_reg(hw, v1, v2);
722 } else {/*This line is the start line of branch.*/
723 /* to protect READ_NEXT_PAIR not overrun */
724 if (i >= len - 2)
725 break;
726
727 if (!_check_condition(hw , array[i])) {
728 /*Discard the following pairs*/
729 READ_NEXT_PAIR(v1, v2, i);
730 while (v2 != 0xDEAD &&
731 v2 != 0xCDEF &&
732 v2 != 0xCDCD && i < len - 2) {
733 READ_NEXT_PAIR(v1, v2, i);
734 }
735 i -= 2; /* prevent from for-loop += 2*/
736 } else {
737 /* Configure matched pairs and
738 * skip to end of if-else.
739 */
740 READ_NEXT_PAIR(v1, v2, i);
741 while (v2 != 0xDEAD &&
742 v2 != 0xCDEF &&
743 v2 != 0xCDCD && i < len - 2) {
744 _rtl92ee_config_bb_reg(hw, v1,
745 v2);
746 READ_NEXT_PAIR(v1, v2, i);
747 }
748
749 while (v2 != 0xDEAD && i < len - 2)
750 READ_NEXT_PAIR(v1, v2, i);
751 }
752 }
753 }
754 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
755 len = RTL8192EE_AGC_TAB_ARRAY_LEN;
756 array = RTL8192EE_AGC_TAB_ARRAY;
757
758 for (i = 0; i < len; i = i + 2) {
759 v1 = array[i];
760 v2 = array[i+1];
761 if (v1 < 0xCDCDCDCD) {
762 rtl_set_bbreg(hw, array[i], MASKDWORD,
763 array[i + 1]);
764 udelay(1);
765 continue;
766 } else{/*This line is the start line of branch.*/
767 /* to protect READ_NEXT_PAIR not overrun */
768 if (i >= len - 2)
769 break;
770
771 if (!_check_condition(hw , array[i])) {
772 /*Discard the following pairs*/
773 READ_NEXT_PAIR(v1, v2, i);
774 while (v2 != 0xDEAD &&
775 v2 != 0xCDEF &&
776 v2 != 0xCDCD &&
777 i < len - 2) {
778 READ_NEXT_PAIR(v1, v2, i);
779 }
780 i -= 2; /* prevent from for-loop += 2*/
781 } else {
782 /* Configure matched pairs and
783 * skip to end of if-else.
784 */
785 READ_NEXT_PAIR(v1, v2, i);
786 while (v2 != 0xDEAD &&
787 v2 != 0xCDEF &&
788 v2 != 0xCDCD &&
789 i < len - 2) {
790 rtl_set_bbreg(hw,
791 array[i],
792 MASKDWORD,
793 array[i + 1]);
794 udelay(1);
795 READ_NEXT_PAIR(v1 , v2 , i);
796 }
797
798 while (v2 != 0xDEAD &&
799 i < len - 2) {
800 READ_NEXT_PAIR(v1 , v2 , i);
801 }
802 }
803 }
804 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
805 "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n",
806 array[i],
807 array[i + 1]);
808 }
809 }
810 return true;
811}
812
813static u8 _rtl92ee_get_rate_section_index(u32 regaddr)
814{
815 u8 index = 0;
816
817 switch (regaddr) {
818 case RTXAGC_A_RATE18_06:
819 case RTXAGC_B_RATE18_06:
820 index = 0;
821 break;
822 case RTXAGC_A_RATE54_24:
823 case RTXAGC_B_RATE54_24:
824 index = 1;
825 break;
826 case RTXAGC_A_CCK1_MCS32:
827 case RTXAGC_B_CCK1_55_MCS32:
828 index = 2;
829 break;
830 case RTXAGC_B_CCK11_A_CCK2_11:
831 index = 3;
832 break;
833 case RTXAGC_A_MCS03_MCS00:
834 case RTXAGC_B_MCS03_MCS00:
835 index = 4;
836 break;
837 case RTXAGC_A_MCS07_MCS04:
838 case RTXAGC_B_MCS07_MCS04:
839 index = 5;
840 break;
841 case RTXAGC_A_MCS11_MCS08:
842 case RTXAGC_B_MCS11_MCS08:
843 index = 6;
844 break;
845 case RTXAGC_A_MCS15_MCS12:
846 case RTXAGC_B_MCS15_MCS12:
847 index = 7;
848 break;
849 default:
850 regaddr &= 0xFFF;
851 if (regaddr >= 0xC20 && regaddr <= 0xC4C)
852 index = (u8)((regaddr - 0xC20) / 4);
853 else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
854 index = (u8)((regaddr - 0xE20) / 4);
855 break;
Wu Fengguang12ff7282015-08-15 18:36:37 +0800856 }
Larry Fingerb1a3bfc2014-09-26 16:40:23 -0500857 return index;
858}
859
860static void _rtl92ee_store_tx_power_by_rate(struct ieee80211_hw *hw,
861 enum band_type band,
862 enum radio_path rfpath,
863 u32 txnum, u32 regaddr,
864 u32 bitmask, u32 data)
865{
866 struct rtl_priv *rtlpriv = rtl_priv(hw);
867 struct rtl_phy *rtlphy = &rtlpriv->phy;
868 u8 section = _rtl92ee_get_rate_section_index(regaddr);
869
870 if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
871 RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid Band %d\n", band);
872 return;
873 }
874
875 if (rfpath > MAX_RF_PATH - 1) {
876 RT_TRACE(rtlpriv, FPHY, PHY_TXPWR,
877 "Invalid RfPath %d\n", rfpath);
878 return;
879 }
880 if (txnum > MAX_RF_PATH - 1) {
881 RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid TxNum %d\n", txnum);
882 return;
883 }
884
885 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][section] = data;
886}
887
888static bool phy_config_bb_with_pghdrfile(struct ieee80211_hw *hw,
889 u8 configtype)
890{
891 struct rtl_priv *rtlpriv = rtl_priv(hw);
892 int i;
893 u32 *phy_regarray_table_pg;
894 u16 phy_regarray_pg_len;
895 u32 v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0;
896
897 phy_regarray_pg_len = RTL8192EE_PHY_REG_ARRAY_PG_LEN;
898 phy_regarray_table_pg = RTL8192EE_PHY_REG_ARRAY_PG;
899
900 if (configtype == BASEBAND_CONFIG_PHY_REG) {
901 for (i = 0; i < phy_regarray_pg_len; i = i + 6) {
902 v1 = phy_regarray_table_pg[i];
903 v2 = phy_regarray_table_pg[i+1];
904 v3 = phy_regarray_table_pg[i+2];
905 v4 = phy_regarray_table_pg[i+3];
906 v5 = phy_regarray_table_pg[i+4];
907 v6 = phy_regarray_table_pg[i+5];
908
909 if (v1 < 0xcdcdcdcd) {
910 _rtl92ee_store_tx_power_by_rate(hw, v1, v2, v3,
911 v4, v5, v6);
912 continue;
913 }
914 }
915 } else {
916 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
917 "configtype != BaseBand_Config_PHY_REG\n");
918 }
919 return true;
920}
921
922#define READ_NEXT_RF_PAIR(v1, v2, i) \
923 do { \
924 i += 2; \
925 v1 = array[i]; \
926 v2 = array[i+1]; \
927 } while (0)
928
929bool rtl92ee_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
930 enum radio_path rfpath)
931{
932 struct rtl_priv *rtlpriv = rtl_priv(hw);
933 int i;
934 u32 *array;
935 u16 len;
936 u32 v1 = 0, v2 = 0;
937
938 switch (rfpath) {
939 case RF90_PATH_A:
940 len = RTL8192EE_RADIOA_ARRAY_LEN;
941 array = RTL8192EE_RADIOA_ARRAY;
942 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
943 "Radio_A:RTL8192EE_RADIOA_ARRAY %d\n" , len);
944 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
945 for (i = 0; i < len; i = i + 2) {
946 v1 = array[i];
947 v2 = array[i+1];
948 if (v1 < 0xcdcdcdcd) {
949 _rtl92ee_config_rf_radio_a(hw, v1, v2);
950 continue;
951 } else {/*This line is the start line of branch.*/
952 /* to protect READ_NEXT_PAIR not overrun */
953 if (i >= len - 2)
954 break;
955
956 if (!_check_condition(hw , array[i])) {
957 /*Discard the following pairs*/
958 READ_NEXT_RF_PAIR(v1, v2, i);
959 while (v2 != 0xDEAD &&
960 v2 != 0xCDEF &&
961 v2 != 0xCDCD && i < len - 2) {
962 READ_NEXT_RF_PAIR(v1, v2, i);
963 }
964 i -= 2; /* prevent from for-loop += 2*/
965 } else {
966 /* Configure matched pairs and
967 * skip to end of if-else.
968 */
969 READ_NEXT_RF_PAIR(v1, v2, i);
970 while (v2 != 0xDEAD &&
971 v2 != 0xCDEF &&
972 v2 != 0xCDCD && i < len - 2) {
973 _rtl92ee_config_rf_radio_a(hw,
974 v1,
975 v2);
976 READ_NEXT_RF_PAIR(v1, v2, i);
977 }
978
979 while (v2 != 0xDEAD && i < len - 2)
980 READ_NEXT_RF_PAIR(v1, v2, i);
981 }
982 }
983 }
984 break;
985
986 case RF90_PATH_B:
987 len = RTL8192EE_RADIOB_ARRAY_LEN;
988 array = RTL8192EE_RADIOB_ARRAY;
989 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
990 "Radio_A:RTL8192EE_RADIOB_ARRAY %d\n" , len);
991 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
992 for (i = 0; i < len; i = i + 2) {
993 v1 = array[i];
994 v2 = array[i+1];
995 if (v1 < 0xcdcdcdcd) {
996 _rtl92ee_config_rf_radio_b(hw, v1, v2);
997 continue;
998 } else {/*This line is the start line of branch.*/
999 /* to protect READ_NEXT_PAIR not overrun */
1000 if (i >= len - 2)
1001 break;
1002
1003 if (!_check_condition(hw , array[i])) {
1004 /*Discard the following pairs*/
1005 READ_NEXT_RF_PAIR(v1, v2, i);
1006 while (v2 != 0xDEAD &&
1007 v2 != 0xCDEF &&
1008 v2 != 0xCDCD && i < len - 2) {
1009 READ_NEXT_RF_PAIR(v1, v2, i);
1010 }
1011 i -= 2; /* prevent from for-loop += 2*/
1012 } else {
1013 /* Configure matched pairs and
1014 * skip to end of if-else.
1015 */
1016 READ_NEXT_RF_PAIR(v1, v2, i);
1017 while (v2 != 0xDEAD &&
1018 v2 != 0xCDEF &&
1019 v2 != 0xCDCD && i < len - 2) {
1020 _rtl92ee_config_rf_radio_b(hw,
1021 v1,
1022 v2);
1023 READ_NEXT_RF_PAIR(v1, v2, i);
1024 }
1025
1026 while (v2 != 0xDEAD && i < len - 2)
1027 READ_NEXT_RF_PAIR(v1, v2, i);
1028 }
1029 }
1030 }
1031 break;
1032 case RF90_PATH_C:
1033 case RF90_PATH_D:
1034 break;
1035 }
1036 return true;
1037}
1038
1039void rtl92ee_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
1040{
1041 struct rtl_priv *rtlpriv = rtl_priv(hw);
1042 struct rtl_phy *rtlphy = &rtlpriv->phy;
1043
1044 rtlphy->default_initialgain[0] =
1045 (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
1046 rtlphy->default_initialgain[1] =
1047 (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
1048 rtlphy->default_initialgain[2] =
1049 (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
1050 rtlphy->default_initialgain[3] =
1051 (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
1052
1053 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1054 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
1055 rtlphy->default_initialgain[0],
1056 rtlphy->default_initialgain[1],
1057 rtlphy->default_initialgain[2],
1058 rtlphy->default_initialgain[3]);
1059
1060 rtlphy->framesync = (u8)rtl_get_bbreg(hw,
1061 ROFDM0_RXDETECTOR3, MASKBYTE0);
1062 rtlphy->framesync_c34 = rtl_get_bbreg(hw,
1063 ROFDM0_RXDETECTOR2, MASKDWORD);
1064
1065 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1066 "Default framesync (0x%x) = 0x%x\n",
1067 ROFDM0_RXDETECTOR3, rtlphy->framesync);
1068}
1069
1070static void phy_init_bb_rf_register_def(struct ieee80211_hw *hw)
1071{
1072 struct rtl_priv *rtlpriv = rtl_priv(hw);
1073 struct rtl_phy *rtlphy = &rtlpriv->phy;
1074
1075 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
1076 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
1077
1078 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
1079 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
1080
1081 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
1082 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
1083
1084 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
1085 RFPGA0_XA_LSSIPARAMETER;
1086 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
1087 RFPGA0_XB_LSSIPARAMETER;
1088
1089 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
1090 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
1091
1092 rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK;
1093 rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK;
1094
1095 rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK;
1096 rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK;
1097}
1098
1099void rtl92ee_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
1100{
1101 struct rtl_priv *rtlpriv = rtl_priv(hw);
1102 struct rtl_phy *rtlphy = &rtlpriv->phy;
1103 u8 txpwr_level;
1104 long txpwr_dbm;
1105
1106 txpwr_level = rtlphy->cur_cck_txpwridx;
1107 txpwr_dbm = _rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B,
1108 txpwr_level);
1109 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
1110 if (_rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) >
1111 txpwr_dbm)
1112 txpwr_dbm = _rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
1113 txpwr_level);
1114 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
1115 if (_rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
1116 txpwr_level) > txpwr_dbm)
1117 txpwr_dbm = _rtl92ee_phy_txpwr_idx_to_dbm(hw,
1118 WIRELESS_MODE_N_24G,
1119 txpwr_level);
1120 *powerlevel = txpwr_dbm;
1121}
1122
1123static u8 _rtl92ee_phy_get_ratesection_intxpower_byrate(enum radio_path path,
1124 u8 rate)
1125{
1126 u8 rate_section = 0;
1127
1128 switch (rate) {
1129 case DESC92C_RATE1M:
1130 rate_section = 2;
1131 break;
1132 case DESC92C_RATE2M:
1133 case DESC92C_RATE5_5M:
1134 if (path == RF90_PATH_A)
1135 rate_section = 3;
1136 else if (path == RF90_PATH_B)
1137 rate_section = 2;
1138 break;
1139 case DESC92C_RATE11M:
1140 rate_section = 3;
1141 break;
1142 case DESC92C_RATE6M:
1143 case DESC92C_RATE9M:
1144 case DESC92C_RATE12M:
1145 case DESC92C_RATE18M:
1146 rate_section = 0;
1147 break;
1148 case DESC92C_RATE24M:
1149 case DESC92C_RATE36M:
1150 case DESC92C_RATE48M:
1151 case DESC92C_RATE54M:
1152 rate_section = 1;
1153 break;
1154 case DESC92C_RATEMCS0:
1155 case DESC92C_RATEMCS1:
1156 case DESC92C_RATEMCS2:
1157 case DESC92C_RATEMCS3:
1158 rate_section = 4;
1159 break;
1160 case DESC92C_RATEMCS4:
1161 case DESC92C_RATEMCS5:
1162 case DESC92C_RATEMCS6:
1163 case DESC92C_RATEMCS7:
1164 rate_section = 5;
1165 break;
1166 case DESC92C_RATEMCS8:
1167 case DESC92C_RATEMCS9:
1168 case DESC92C_RATEMCS10:
1169 case DESC92C_RATEMCS11:
1170 rate_section = 6;
1171 break;
1172 case DESC92C_RATEMCS12:
1173 case DESC92C_RATEMCS13:
1174 case DESC92C_RATEMCS14:
1175 case DESC92C_RATEMCS15:
1176 rate_section = 7;
1177 break;
1178 default:
1179 RT_ASSERT(true, "Rate_Section is Illegal\n");
1180 break;
1181 }
1182 return rate_section;
1183}
1184
1185static u8 _rtl92ee_get_txpower_by_rate(struct ieee80211_hw *hw,
1186 enum band_type band,
1187 enum radio_path rf, u8 rate)
1188{
1189 struct rtl_priv *rtlpriv = rtl_priv(hw);
1190 struct rtl_phy *rtlphy = &rtlpriv->phy;
1191 u8 shift = 0, sec, tx_num;
Arnd Bergmann08aba422016-06-15 23:30:43 +02001192 s8 diff = 0;
Larry Fingerb1a3bfc2014-09-26 16:40:23 -05001193
1194 sec = _rtl92ee_phy_get_ratesection_intxpower_byrate(rf, rate);
1195 tx_num = RF_TX_NUM_NONIMPLEMENT;
1196
1197 if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
1198 if ((rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15))
1199 tx_num = RF_2TX;
1200 else
1201 tx_num = RF_1TX;
1202 }
1203
1204 switch (rate) {
1205 case DESC92C_RATE1M:
1206 case DESC92C_RATE6M:
1207 case DESC92C_RATE24M:
1208 case DESC92C_RATEMCS0:
1209 case DESC92C_RATEMCS4:
1210 case DESC92C_RATEMCS8:
1211 case DESC92C_RATEMCS12:
1212 shift = 0;
1213 break;
1214 case DESC92C_RATE2M:
1215 case DESC92C_RATE9M:
1216 case DESC92C_RATE36M:
1217 case DESC92C_RATEMCS1:
1218 case DESC92C_RATEMCS5:
1219 case DESC92C_RATEMCS9:
1220 case DESC92C_RATEMCS13:
1221 shift = 8;
1222 break;
1223 case DESC92C_RATE5_5M:
1224 case DESC92C_RATE12M:
1225 case DESC92C_RATE48M:
1226 case DESC92C_RATEMCS2:
1227 case DESC92C_RATEMCS6:
1228 case DESC92C_RATEMCS10:
1229 case DESC92C_RATEMCS14:
1230 shift = 16;
1231 break;
1232 case DESC92C_RATE11M:
1233 case DESC92C_RATE18M:
1234 case DESC92C_RATE54M:
1235 case DESC92C_RATEMCS3:
1236 case DESC92C_RATEMCS7:
1237 case DESC92C_RATEMCS11:
1238 case DESC92C_RATEMCS15:
1239 shift = 24;
1240 break;
1241 default:
1242 RT_ASSERT(true, "Rate_Section is Illegal\n");
1243 break;
1244 }
1245
1246 diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rf][tx_num][sec] >>
1247 shift) & 0xff;
1248
1249 return diff;
1250}
1251
1252static u8 _rtl92ee_get_txpower_index(struct ieee80211_hw *hw,
1253 enum radio_path rfpath, u8 rate,
1254 u8 bw, u8 channel)
1255{
1256 struct rtl_priv *rtlpriv = rtl_priv(hw);
1257 struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
1258 u8 index = (channel - 1);
1259 u8 tx_power = 0;
1260 u8 diff = 0;
1261
1262 if (channel < 1 || channel > 14) {
1263 index = 0;
1264 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_DMESG,
1265 "Illegal channel!!\n");
1266 }
1267
Arnd Bergmann08aba422016-06-15 23:30:43 +02001268 if (IS_CCK_RATE((s8)rate))
Larry Fingerb1a3bfc2014-09-26 16:40:23 -05001269 tx_power = rtlefuse->txpwrlevel_cck[rfpath][index];
1270 else if (DESC92C_RATE6M <= rate)
1271 tx_power = rtlefuse->txpwrlevel_ht40_1s[rfpath][index];
1272
1273 /* OFDM-1T*/
1274 if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M &&
Arnd Bergmann08aba422016-06-15 23:30:43 +02001275 !IS_CCK_RATE((s8)rate))
Larry Fingerb1a3bfc2014-09-26 16:40:23 -05001276 tx_power += rtlefuse->txpwr_legacyhtdiff[rfpath][TX_1S];
1277
1278 /* BW20-1S, BW20-2S */
1279 if (bw == HT_CHANNEL_WIDTH_20) {
1280 if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1281 tx_power += rtlefuse->txpwr_ht20diff[rfpath][TX_1S];
1282 if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1283 tx_power += rtlefuse->txpwr_ht20diff[rfpath][TX_2S];
1284 } else if (bw == HT_CHANNEL_WIDTH_20_40) {/* BW40-1S, BW40-2S */
1285 if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1286 tx_power += rtlefuse->txpwr_ht40diff[rfpath][TX_1S];
1287 if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1288 tx_power += rtlefuse->txpwr_ht40diff[rfpath][TX_2S];
1289 }
1290
1291 if (rtlefuse->eeprom_regulatory != 2)
1292 diff = _rtl92ee_get_txpower_by_rate(hw, BAND_ON_2_4G,
1293 rfpath, rate);
1294
1295 tx_power += diff;
1296
1297 if (tx_power > MAX_POWER_INDEX)
1298 tx_power = MAX_POWER_INDEX;
1299
1300 return tx_power;
1301}
1302
1303static void _rtl92ee_set_txpower_index(struct ieee80211_hw *hw, u8 pwr_idx,
1304 enum radio_path rfpath, u8 rate)
1305{
1306 struct rtl_priv *rtlpriv = rtl_priv(hw);
1307
1308 if (rfpath == RF90_PATH_A) {
1309 switch (rate) {
1310 case DESC92C_RATE1M:
1311 rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1,
1312 pwr_idx);
1313 break;
1314 case DESC92C_RATE2M:
1315 rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE1,
1316 pwr_idx);
1317 break;
1318 case DESC92C_RATE5_5M:
1319 rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE2,
1320 pwr_idx);
1321 break;
1322 case DESC92C_RATE11M:
1323 rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE3,
1324 pwr_idx);
1325 break;
1326 case DESC92C_RATE6M:
1327 rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE0,
1328 pwr_idx);
1329 break;
1330 case DESC92C_RATE9M:
1331 rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE1,
1332 pwr_idx);
1333 break;
1334 case DESC92C_RATE12M:
1335 rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE2,
1336 pwr_idx);
1337 break;
1338 case DESC92C_RATE18M:
1339 rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE3,
1340 pwr_idx);
1341 break;
1342 case DESC92C_RATE24M:
1343 rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE0,
1344 pwr_idx);
1345 break;
1346 case DESC92C_RATE36M:
1347 rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE1,
1348 pwr_idx);
1349 break;
1350 case DESC92C_RATE48M:
1351 rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE2,
1352 pwr_idx);
1353 break;
1354 case DESC92C_RATE54M:
1355 rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE3,
1356 pwr_idx);
1357 break;
1358 case DESC92C_RATEMCS0:
1359 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE0,
1360 pwr_idx);
1361 break;
1362 case DESC92C_RATEMCS1:
1363 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE1,
1364 pwr_idx);
1365 break;
1366 case DESC92C_RATEMCS2:
1367 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE2,
1368 pwr_idx);
1369 break;
1370 case DESC92C_RATEMCS3:
1371 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE3,
1372 pwr_idx);
1373 break;
1374 case DESC92C_RATEMCS4:
1375 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE0,
1376 pwr_idx);
1377 break;
1378 case DESC92C_RATEMCS5:
1379 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE1,
1380 pwr_idx);
1381 break;
1382 case DESC92C_RATEMCS6:
1383 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE2,
1384 pwr_idx);
1385 break;
1386 case DESC92C_RATEMCS7:
1387 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE3,
1388 pwr_idx);
1389 break;
1390 case DESC92C_RATEMCS8:
1391 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE0,
1392 pwr_idx);
1393 break;
1394 case DESC92C_RATEMCS9:
1395 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE1,
1396 pwr_idx);
1397 break;
1398 case DESC92C_RATEMCS10:
1399 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE2,
1400 pwr_idx);
1401 break;
1402 case DESC92C_RATEMCS11:
1403 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE3,
1404 pwr_idx);
1405 break;
1406 case DESC92C_RATEMCS12:
1407 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE0,
1408 pwr_idx);
1409 break;
1410 case DESC92C_RATEMCS13:
1411 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE1,
1412 pwr_idx);
1413 break;
1414 case DESC92C_RATEMCS14:
1415 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE2,
1416 pwr_idx);
1417 break;
1418 case DESC92C_RATEMCS15:
1419 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE3,
1420 pwr_idx);
1421 break;
1422 default:
1423 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1424 "Invalid Rate!!\n");
1425 break;
1426 }
1427 } else if (rfpath == RF90_PATH_B) {
1428 switch (rate) {
1429 case DESC92C_RATE1M:
1430 rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, MASKBYTE1,
1431 pwr_idx);
1432 break;
1433 case DESC92C_RATE2M:
1434 rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, MASKBYTE2,
1435 pwr_idx);
1436 break;
1437 case DESC92C_RATE5_5M:
1438 rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, MASKBYTE3,
1439 pwr_idx);
1440 break;
1441 case DESC92C_RATE11M:
1442 rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0,
1443 pwr_idx);
1444 break;
1445 case DESC92C_RATE6M:
1446 rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE0,
1447 pwr_idx);
1448 break;
1449 case DESC92C_RATE9M:
1450 rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE1,
1451 pwr_idx);
1452 break;
1453 case DESC92C_RATE12M:
1454 rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE2,
1455 pwr_idx);
1456 break;
1457 case DESC92C_RATE18M:
1458 rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE3,
1459 pwr_idx);
1460 break;
1461 case DESC92C_RATE24M:
1462 rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE0,
1463 pwr_idx);
1464 break;
1465 case DESC92C_RATE36M:
1466 rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE1,
1467 pwr_idx);
1468 break;
1469 case DESC92C_RATE48M:
1470 rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE2,
1471 pwr_idx);
1472 break;
1473 case DESC92C_RATE54M:
1474 rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE3,
1475 pwr_idx);
1476 break;
1477 case DESC92C_RATEMCS0:
1478 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE0,
1479 pwr_idx);
1480 break;
1481 case DESC92C_RATEMCS1:
1482 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE1,
1483 pwr_idx);
1484 break;
1485 case DESC92C_RATEMCS2:
1486 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE2,
1487 pwr_idx);
1488 break;
1489 case DESC92C_RATEMCS3:
1490 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE3,
1491 pwr_idx);
1492 break;
1493 case DESC92C_RATEMCS4:
1494 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE0,
1495 pwr_idx);
1496 break;
1497 case DESC92C_RATEMCS5:
1498 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE1,
1499 pwr_idx);
1500 break;
1501 case DESC92C_RATEMCS6:
1502 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE2,
1503 pwr_idx);
1504 break;
1505 case DESC92C_RATEMCS7:
1506 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE3,
1507 pwr_idx);
1508 break;
1509 case DESC92C_RATEMCS8:
1510 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE0,
1511 pwr_idx);
1512 break;
1513 case DESC92C_RATEMCS9:
1514 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE1,
1515 pwr_idx);
1516 break;
1517 case DESC92C_RATEMCS10:
1518 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE2,
1519 pwr_idx);
1520 break;
1521 case DESC92C_RATEMCS11:
1522 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE3,
1523 pwr_idx);
1524 break;
1525 case DESC92C_RATEMCS12:
1526 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE0,
1527 pwr_idx);
1528 break;
1529 case DESC92C_RATEMCS13:
1530 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE1,
1531 pwr_idx);
1532 break;
1533 case DESC92C_RATEMCS14:
1534 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE2,
1535 pwr_idx);
1536 break;
1537 case DESC92C_RATEMCS15:
1538 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE3,
1539 pwr_idx);
1540 break;
1541 default:
1542 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1543 "Invalid Rate!!\n");
1544 break;
1545 }
1546 } else {
1547 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n");
1548 }
1549}
1550
1551static void phy_set_txpower_index_by_rate_array(struct ieee80211_hw *hw,
1552 enum radio_path rfpath, u8 bw,
1553 u8 channel, u8 *rates, u8 size)
1554{
1555 u8 i;
1556 u8 power_index;
1557
1558 for (i = 0; i < size; i++) {
1559 power_index = _rtl92ee_get_txpower_index(hw, rfpath, rates[i],
1560 bw, channel);
1561 _rtl92ee_set_txpower_index(hw, power_index, rfpath, rates[i]);
1562 }
1563}
1564
1565static void phy_set_txpower_index_by_rate_section(struct ieee80211_hw *hw,
1566 enum radio_path rfpath,
1567 u8 channel,
1568 enum rate_section section)
1569{
1570 struct rtl_priv *rtlpriv = rtl_priv(hw);
1571 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1572 struct rtl_phy *rtlphy = &rtlpriv->phy;
1573
1574 if (section == CCK) {
1575 u8 cck_rates[] = {DESC92C_RATE1M, DESC92C_RATE2M,
1576 DESC92C_RATE5_5M, DESC92C_RATE11M};
1577 if (rtlhal->current_bandtype == BAND_ON_2_4G)
1578 phy_set_txpower_index_by_rate_array(hw, rfpath,
1579 rtlphy->current_chan_bw,
1580 channel, cck_rates, 4);
1581 } else if (section == OFDM) {
1582 u8 ofdm_rates[] = {DESC92C_RATE6M, DESC92C_RATE9M,
1583 DESC92C_RATE12M, DESC92C_RATE18M,
1584 DESC92C_RATE24M, DESC92C_RATE36M,
1585 DESC92C_RATE48M, DESC92C_RATE54M};
1586 phy_set_txpower_index_by_rate_array(hw, rfpath,
1587 rtlphy->current_chan_bw,
1588 channel, ofdm_rates, 8);
1589 } else if (section == HT_MCS0_MCS7) {
1590 u8 ht_rates1t[] = {DESC92C_RATEMCS0, DESC92C_RATEMCS1,
1591 DESC92C_RATEMCS2, DESC92C_RATEMCS3,
1592 DESC92C_RATEMCS4, DESC92C_RATEMCS5,
1593 DESC92C_RATEMCS6, DESC92C_RATEMCS7};
1594 phy_set_txpower_index_by_rate_array(hw, rfpath,
1595 rtlphy->current_chan_bw,
1596 channel, ht_rates1t, 8);
1597 } else if (section == HT_MCS8_MCS15) {
1598 u8 ht_rates2t[] = {DESC92C_RATEMCS8, DESC92C_RATEMCS9,
1599 DESC92C_RATEMCS10, DESC92C_RATEMCS11,
1600 DESC92C_RATEMCS12, DESC92C_RATEMCS13,
1601 DESC92C_RATEMCS14, DESC92C_RATEMCS15};
1602 phy_set_txpower_index_by_rate_array(hw, rfpath,
1603 rtlphy->current_chan_bw,
1604 channel, ht_rates2t, 8);
1605 } else
1606 RT_TRACE(rtlpriv, FPHY, PHY_TXPWR,
1607 "Invalid RateSection %d\n", section);
1608}
1609
1610void rtl92ee_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1611{
1612 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1613 struct rtl_phy *rtlphy = &rtl_priv(hw)->phy;
1614 enum radio_path rfpath;
1615
1616 if (!rtlefuse->txpwr_fromeprom)
1617 return;
1618 for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
1619 rfpath++) {
1620 phy_set_txpower_index_by_rate_section(hw, rfpath,
1621 channel, CCK);
1622 phy_set_txpower_index_by_rate_section(hw, rfpath,
1623 channel, OFDM);
1624 phy_set_txpower_index_by_rate_section(hw, rfpath,
1625 channel,
1626 HT_MCS0_MCS7);
1627
1628 if (rtlphy->num_total_rfpath >= 2)
1629 phy_set_txpower_index_by_rate_section(hw,
1630 rfpath, channel,
1631 HT_MCS8_MCS15);
1632 }
1633}
1634
1635static long _rtl92ee_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
1636 enum wireless_mode wirelessmode,
1637 u8 txpwridx)
1638{
1639 long offset;
1640 long pwrout_dbm;
1641
1642 switch (wirelessmode) {
1643 case WIRELESS_MODE_B:
1644 offset = -7;
1645 break;
1646 case WIRELESS_MODE_G:
1647 case WIRELESS_MODE_N_24G:
1648 offset = -8;
1649 break;
1650 default:
1651 offset = -8;
1652 break;
1653 }
1654 pwrout_dbm = txpwridx / 2 + offset;
1655 return pwrout_dbm;
1656}
1657
1658void rtl92ee_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1659{
1660 struct rtl_priv *rtlpriv = rtl_priv(hw);
1661 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1662 enum io_type iotype;
1663
1664 if (!is_hal_stop(rtlhal)) {
1665 switch (operation) {
1666 case SCAN_OPT_BACKUP_BAND0:
1667 iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
1668 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1669 (u8 *)&iotype);
1670
1671 break;
1672 case SCAN_OPT_RESTORE:
1673 iotype = IO_CMD_RESUME_DM_BY_SCAN;
1674 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1675 (u8 *)&iotype);
1676 break;
1677 default:
1678 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1679 "Unknown Scan Backup operation.\n");
1680 break;
1681 }
1682 }
1683}
1684
1685void rtl92ee_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
1686{
1687 struct rtl_priv *rtlpriv = rtl_priv(hw);
1688 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1689 struct rtl_phy *rtlphy = &rtlpriv->phy;
1690 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1691 u8 reg_bw_opmode;
1692 u8 reg_prsr_rsc;
1693
1694 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1695 "Switch to %s bandwidth\n",
1696 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1697 "20MHz" : "40MHz");
1698
1699 if (is_hal_stop(rtlhal)) {
1700 rtlphy->set_bwmode_inprogress = false;
1701 return;
1702 }
1703
1704 reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1705 reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1706
1707 switch (rtlphy->current_chan_bw) {
1708 case HT_CHANNEL_WIDTH_20:
1709 reg_bw_opmode |= BW_OPMODE_20MHZ;
1710 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1711 break;
1712 case HT_CHANNEL_WIDTH_20_40:
1713 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1714 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1715 reg_prsr_rsc = (reg_prsr_rsc & 0x90) |
1716 (mac->cur_40_prime_sc << 5);
1717 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1718 break;
1719 default:
1720 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1721 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1722 break;
1723 }
1724
1725 switch (rtlphy->current_chan_bw) {
1726 case HT_CHANNEL_WIDTH_20:
1727 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1728 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1729 rtl_set_bbreg(hw, ROFDM0_TXPSEUDONOISEWGT,
1730 (BIT(31) | BIT(30)), 0);
1731 break;
1732 case HT_CHANNEL_WIDTH_20_40:
1733 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1734 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1735 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1736 (mac->cur_40_prime_sc >> 1));
1737 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00,
1738 mac->cur_40_prime_sc);
1739
1740 rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1741 (mac->cur_40_prime_sc ==
1742 HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1743 break;
1744 default:
1745 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1746 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1747 break;
1748 }
1749 rtl92ee_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1750 rtlphy->set_bwmode_inprogress = false;
1751 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
1752}
1753
1754void rtl92ee_phy_set_bw_mode(struct ieee80211_hw *hw,
1755 enum nl80211_channel_type ch_type)
1756{
1757 struct rtl_priv *rtlpriv = rtl_priv(hw);
1758 struct rtl_phy *rtlphy = &rtlpriv->phy;
1759 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1760 u8 tmp_bw = rtlphy->current_chan_bw;
1761
1762 if (rtlphy->set_bwmode_inprogress)
1763 return;
1764 rtlphy->set_bwmode_inprogress = true;
1765 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1766 rtl92ee_phy_set_bw_mode_callback(hw);
1767 } else {
1768 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1769 "false driver sleep or unload\n");
1770 rtlphy->set_bwmode_inprogress = false;
1771 rtlphy->current_chan_bw = tmp_bw;
1772 }
1773}
1774
1775void rtl92ee_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1776{
1777 struct rtl_priv *rtlpriv = rtl_priv(hw);
1778 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1779 struct rtl_phy *rtlphy = &rtlpriv->phy;
1780 u32 delay;
1781
1782 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1783 "switch to channel%d\n", rtlphy->current_channel);
1784 if (is_hal_stop(rtlhal))
1785 return;
1786 do {
1787 if (!rtlphy->sw_chnl_inprogress)
1788 break;
1789 if (!_rtl92ee_phy_sw_chnl_step_by_step
1790 (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage,
1791 &rtlphy->sw_chnl_step, &delay)) {
1792 if (delay > 0)
1793 mdelay(delay);
1794 else
1795 continue;
1796 } else {
1797 rtlphy->sw_chnl_inprogress = false;
1798 }
1799 break;
1800 } while (true);
1801 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
1802}
1803
1804u8 rtl92ee_phy_sw_chnl(struct ieee80211_hw *hw)
1805{
1806 struct rtl_priv *rtlpriv = rtl_priv(hw);
1807 struct rtl_phy *rtlphy = &rtlpriv->phy;
1808 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1809
1810 if (rtlphy->sw_chnl_inprogress)
1811 return 0;
1812 if (rtlphy->set_bwmode_inprogress)
1813 return 0;
1814 RT_ASSERT((rtlphy->current_channel <= 14),
1815 "WIRELESS_MODE_G but channel>14");
1816 rtlphy->sw_chnl_inprogress = true;
1817 rtlphy->sw_chnl_stage = 0;
1818 rtlphy->sw_chnl_step = 0;
1819 if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1820 rtl92ee_phy_sw_chnl_callback(hw);
1821 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
Masanari Iida8a190232016-06-29 12:37:19 +09001822 "sw_chnl_inprogress false schedule workitem current channel %d\n",
Larry Fingerb1a3bfc2014-09-26 16:40:23 -05001823 rtlphy->current_channel);
1824 rtlphy->sw_chnl_inprogress = false;
1825 } else {
1826 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1827 "sw_chnl_inprogress false driver sleep or unload\n");
1828 rtlphy->sw_chnl_inprogress = false;
1829 }
1830 return 1;
1831}
1832
1833static bool _rtl92ee_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
1834 u8 channel, u8 *stage, u8 *step,
1835 u32 *delay)
1836{
1837 struct rtl_priv *rtlpriv = rtl_priv(hw);
1838 struct rtl_phy *rtlphy = &rtlpriv->phy;
1839 struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
1840 u32 precommoncmdcnt;
1841 struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
1842 u32 postcommoncmdcnt;
1843 struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
1844 u32 rfdependcmdcnt;
1845 struct swchnlcmd *currentcmd = NULL;
1846 u8 rfpath;
1847 u8 num_total_rfpath = rtlphy->num_total_rfpath;
1848
1849 precommoncmdcnt = 0;
1850 _rtl92ee_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1851 MAX_PRECMD_CNT,
1852 CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
1853 _rtl92ee_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1854 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
1855
1856 postcommoncmdcnt = 0;
1857
1858 _rtl92ee_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1859 MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
1860
1861 rfdependcmdcnt = 0;
1862
1863 RT_ASSERT((channel >= 1 && channel <= 14),
1864 "illegal channel for Zebra: %d\n", channel);
1865
1866 _rtl92ee_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1867 MAX_RFDEPENDCMD_CNT,
1868 CMDID_RF_WRITEREG,
1869 RF_CHNLBW, channel, 10);
1870
1871 _rtl92ee_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1872 MAX_RFDEPENDCMD_CNT, CMDID_END,
1873 0, 0, 0);
1874
1875 do {
1876 switch (*stage) {
1877 case 0:
1878 currentcmd = &precommoncmd[*step];
1879 break;
1880 case 1:
1881 currentcmd = &rfdependcmd[*step];
1882 break;
1883 case 2:
1884 currentcmd = &postcommoncmd[*step];
1885 break;
1886 default:
1887 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1888 "Invalid 'stage' = %d, Check it!\n" , *stage);
1889 return true;
1890 }
1891
1892 if (currentcmd->cmdid == CMDID_END) {
1893 if ((*stage) == 2)
1894 return true;
1895 (*stage)++;
1896 (*step) = 0;
1897 continue;
1898 }
1899
1900 switch (currentcmd->cmdid) {
1901 case CMDID_SET_TXPOWEROWER_LEVEL:
1902 rtl92ee_phy_set_txpower_level(hw, channel);
1903 break;
1904 case CMDID_WRITEPORT_ULONG:
1905 rtl_write_dword(rtlpriv, currentcmd->para1,
1906 currentcmd->para2);
1907 break;
1908 case CMDID_WRITEPORT_USHORT:
1909 rtl_write_word(rtlpriv, currentcmd->para1,
1910 (u16)currentcmd->para2);
1911 break;
1912 case CMDID_WRITEPORT_UCHAR:
1913 rtl_write_byte(rtlpriv, currentcmd->para1,
1914 (u8)currentcmd->para2);
1915 break;
1916 case CMDID_RF_WRITEREG:
1917 for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
1918 rtlphy->rfreg_chnlval[rfpath] =
1919 ((rtlphy->rfreg_chnlval[rfpath] &
1920 0xfffff00) | currentcmd->para2);
1921
1922 rtl_set_rfreg(hw, (enum radio_path)rfpath,
1923 currentcmd->para1,
1924 0x3ff,
1925 rtlphy->rfreg_chnlval[rfpath]);
1926 }
1927 break;
1928 default:
1929 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -07001930 "switch case %#x not processed\n",
1931 currentcmd->cmdid);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -05001932 break;
1933 }
1934
1935 break;
1936 } while (true);
1937
1938 (*delay) = currentcmd->msdelay;
1939 (*step)++;
1940 return false;
1941}
1942
1943static bool _rtl92ee_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
1944 u32 cmdtableidx, u32 cmdtablesz,
1945 enum swchnlcmd_id cmdid,
1946 u32 para1, u32 para2, u32 msdelay)
1947{
1948 struct swchnlcmd *pcmd;
1949
1950 if (cmdtable == NULL) {
1951 RT_ASSERT(false, "cmdtable cannot be NULL.\n");
1952 return false;
1953 }
1954
1955 if (cmdtableidx >= cmdtablesz)
1956 return false;
1957
1958 pcmd = cmdtable + cmdtableidx;
1959 pcmd->cmdid = cmdid;
1960 pcmd->para1 = para1;
1961 pcmd->para2 = para2;
1962 pcmd->msdelay = msdelay;
1963 return true;
1964}
1965
1966static u8 _rtl92ee_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
1967{
1968 u32 reg_eac, reg_e94, reg_e9c;
1969 u8 result = 0x00;
1970 /* path-A IQK setting */
1971 /* PA/PAD controlled by 0x0 */
1972 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1973 rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x180);
1974 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1975
1976 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1977 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1978 rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1979 rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1980
1981 rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82140303);
1982 rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x68160000);
1983
1984 /*LO calibration setting*/
1985 rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1986
1987 /*One shot, path A LOK & IQK*/
1988 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1989 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1990
1991 mdelay(IQK_DELAY_TIME);
1992
1993 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1994 reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1995 reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1996
1997 if (!(reg_eac & BIT(28)) &&
1998 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1999 (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
2000 result |= 0x01;
2001 else
2002 return result;
2003
2004 return result;
2005}
2006
2007static u8 _rtl92ee_phy_path_b_iqk(struct ieee80211_hw *hw)
2008{
2009 u32 reg_eac, reg_eb4, reg_ebc;
2010 u8 result = 0x00;
2011
2012 /* PA/PAD controlled by 0x0 */
2013 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2014 rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x180);
2015 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2016
2017 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000);
2018 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
2019
2020 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2021 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2022 rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x18008c1c);
2023 rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2024
2025 rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x821403e2);
2026 rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x68160000);
2027
2028 /* LO calibration setting */
2029 rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
2030
2031 /*One shot, path B LOK & IQK*/
2032 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000);
2033 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
2034
2035 mdelay(IQK_DELAY_TIME);
2036
2037 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
2038 reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
2039 reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
2040
2041 if (!(reg_eac & BIT(31)) &&
2042 (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
2043 (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
2044 result |= 0x01;
2045 else
2046 return result;
2047
2048 return result;
2049}
2050
2051static u8 _rtl92ee_phy_path_a_rx_iqk(struct ieee80211_hw *hw, bool config_pathb)
2052{
2053 u32 reg_eac, reg_e94, reg_e9c, reg_ea4 , u32temp;
2054 u8 result = 0x00;
2055
2056 /*Get TXIMR Setting*/
2057 /*Modify RX IQK mode table*/
2058 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2059
2060 rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
2061 rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
2062 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
2063 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf117b);
2064
2065 /*PA/PAD control by 0x56, and set = 0x0*/
2066 rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x980);
2067 rtl_set_rfreg(hw, RF90_PATH_A, 0x56, RFREG_OFFSET_MASK, 0x51000);
2068
2069 /*enter IQK mode*/
2070 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2071
2072 /*IQK Setting*/
2073 rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
2074 rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2075
2076 /*path a IQK setting*/
2077 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
2078 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2079 rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2080 rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2081
2082 rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160c1f);
2083 rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x68160c1f);
2084
2085 /*LO calibration Setting*/
2086 rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
2087
2088 /*one shot,path A LOK & iqk*/
2089 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000);
2090 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
2091
2092 mdelay(IQK_DELAY_TIME);
2093
2094 /* Check failed */
2095 reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
2096 reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
2097 reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
2098
2099 if (!(reg_eac & BIT(28)) &&
2100 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
2101 (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) {
2102 result |= 0x01;
2103 } else {
2104 /* PA/PAD controlled by 0x0 */
2105 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2106 rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x180);
2107 return result;
2108 }
2109
2110 u32temp = 0x80007C00 | (reg_e94 & 0x3FF0000) |
2111 ((reg_e9c & 0x3FF0000) >> 16);
2112 rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32temp);
2113 /*RX IQK*/
2114 /*Modify RX IQK mode table*/
2115 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2116
2117 rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
2118
2119 rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
2120 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
2121 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ffa);
2122
2123 /*PA/PAD control by 0x56, and set = 0x0*/
2124 rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x980);
2125 rtl_set_rfreg(hw, RF90_PATH_A, 0x56, RFREG_OFFSET_MASK, 0x51000);
2126
2127 /*enter IQK mode*/
2128 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2129
2130 /*IQK Setting*/
2131 rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2132
2133 /*path a IQK setting*/
2134 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2135 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
2136 rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2137 rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2138
2139 rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160c1f);
2140 rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160c1f);
2141
2142 /*LO calibration Setting*/
2143 rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a891);
2144 /*one shot,path A LOK & iqk*/
2145 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000);
2146 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
2147
2148 mdelay(IQK_DELAY_TIME);
2149 /*Check failed*/
2150 reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
2151 reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
2152
2153 /*PA/PAD controlled by 0x0*/
2154 /*leave IQK mode*/
2155 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2156 rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x180);
2157 /*if Tx is OK, check whether Rx is OK*/
2158 if (!(reg_eac & BIT(27)) &&
2159 (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
2160 (((reg_eac & 0x03FF0000) >> 16) != 0x36))
2161 result |= 0x02;
2162
2163 return result;
2164}
2165
2166static u8 _rtl92ee_phy_path_b_rx_iqk(struct ieee80211_hw *hw, bool config_pathb)
2167{
2168 struct rtl_priv *rtlpriv = rtl_priv(hw);
2169 u32 reg_eac, reg_eb4, reg_ebc, reg_ecc, reg_ec4, u32temp;
2170 u8 result = 0x00;
2171
2172 /*Get TXIMR Setting*/
2173 /*Modify RX IQK mode table*/
2174 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2175
2176 rtl_set_rfreg(hw, RF90_PATH_B, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
2177 rtl_set_rfreg(hw, RF90_PATH_B, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
2178 rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
2179 rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf117b);
2180
2181 /*PA/PAD all off*/
2182 rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x980);
2183 rtl_set_rfreg(hw, RF90_PATH_B, 0x56, RFREG_OFFSET_MASK, 0x51000);
2184
2185 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2186
2187 /*IQK Setting*/
2188 rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
2189 rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2190
2191 /*path a IQK setting*/
2192 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2193 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2194 rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x18008c1c);
2195 rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2196
2197 rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82160c1f);
2198 rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x68160c1f);
2199
2200 /*LO calibration Setting*/
2201 rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
2202
2203 /*one shot,path A LOK & iqk*/
2204 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000);
2205 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
2206
2207 mdelay(IQK_DELAY_TIME);
2208
2209 /* Check failed */
2210 reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
2211 reg_eb4 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_B, MASKDWORD);
2212 reg_ebc = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_B, MASKDWORD);
2213
2214 if (!(reg_eac & BIT(31)) &&
2215 (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
2216 (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) {
2217 result |= 0x01;
2218 } else {
2219 /* PA/PAD controlled by 0x0 */
2220 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2221 rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x180);
2222 return result;
2223 }
2224
2225 u32temp = 0x80007C00 | (reg_eb4 & 0x3FF0000) |
2226 ((reg_ebc & 0x3FF0000) >> 16);
2227 rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32temp);
2228 /*RX IQK*/
2229 /*Modify RX IQK mode table*/
2230 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2231 rtl_set_rfreg(hw, RF90_PATH_B, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
2232
2233 rtl_set_rfreg(hw, RF90_PATH_B, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
2234 rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
2235 rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ffa);
2236
2237 /*PA/PAD all off*/
2238 rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x980);
2239 rtl_set_rfreg(hw, RF90_PATH_B, 0x56, RFREG_OFFSET_MASK, 0x51000);
2240
2241 /*enter IQK mode*/
2242 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2243
2244 /*IQK Setting*/
2245 rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2246
2247 /*path b IQK setting*/
2248 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2249 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2250 rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2251 rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x18008c1c);
2252
2253 rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82160c1f);
2254 rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28160c1f);
2255
2256 /*LO calibration Setting*/
2257 rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a891);
2258 /*one shot,path A LOK & iqk*/
2259 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000);
2260 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
2261
2262 mdelay(IQK_DELAY_TIME);
2263 /*Check failed*/
2264 reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
2265 reg_ec4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_B_2, MASKDWORD);
2266 reg_ecc = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_B_2, MASKDWORD);
2267 /*PA/PAD controlled by 0x0*/
2268 /*leave IQK mode*/
2269 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2270 rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x180);
2271 /*if Tx is OK, check whether Rx is OK*/
2272 if (!(reg_eac & BIT(30)) &&
2273 (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
2274 (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
2275 result |= 0x02;
2276 else
2277 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "Path B Rx IQK fail!!\n");
2278
2279 return result;
2280}
2281
2282static void _rtl92ee_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw,
2283 bool b_iqk_ok, long result[][8],
2284 u8 final_candidate,
2285 bool btxonly)
2286{
2287 u32 oldval_0, x, tx0_a, reg;
2288 long y, tx0_c;
2289
2290 if (final_candidate == 0xFF) {
2291 return;
2292 } else if (b_iqk_ok) {
2293 oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
2294 MASKDWORD) >> 22) & 0x3FF;
2295 x = result[final_candidate][0];
2296 if ((x & 0x00000200) != 0)
2297 x = x | 0xFFFFFC00;
2298 tx0_a = (x * oldval_0) >> 8;
2299 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a);
2300 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31),
2301 ((x * oldval_0 >> 7) & 0x1));
2302 y = result[final_candidate][1];
2303 if ((y & 0x00000200) != 0)
2304 y = y | 0xFFFFFC00;
2305 tx0_c = (y * oldval_0) >> 8;
2306 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000,
2307 ((tx0_c & 0x3C0) >> 6));
2308 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000,
2309 (tx0_c & 0x3F));
2310 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29),
2311 ((y * oldval_0 >> 7) & 0x1));
2312
2313 if (btxonly)
2314 return;
2315
2316 reg = result[final_candidate][2];
2317 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
2318
2319 reg = result[final_candidate][3] & 0x3F;
2320 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
2321
2322 reg = (result[final_candidate][3] >> 6) & 0xF;
2323 rtl_set_bbreg(hw, ROFDM0_RXIQEXTANTA, 0xF0000000, reg);
2324 }
2325}
2326
2327static void _rtl92ee_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,
2328 bool b_iqk_ok, long result[][8],
2329 u8 final_candidate,
2330 bool btxonly)
2331{
2332 u32 oldval_1, x, tx1_a, reg;
2333 long y, tx1_c;
2334
2335 if (final_candidate == 0xFF) {
2336 return;
2337 } else if (b_iqk_ok) {
2338 oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
2339 MASKDWORD) >> 22) & 0x3FF;
2340 x = result[final_candidate][4];
2341 if ((x & 0x00000200) != 0)
2342 x = x | 0xFFFFFC00;
2343 tx1_a = (x * oldval_1) >> 8;
2344 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx1_a);
2345 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27),
2346 ((x * oldval_1 >> 7) & 0x1));
2347 y = result[final_candidate][5];
2348 if ((y & 0x00000200) != 0)
2349 y = y | 0xFFFFFC00;
2350 tx1_c = (y * oldval_1) >> 8;
2351 rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000,
2352 ((tx1_c & 0x3C0) >> 6));
2353 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000,
2354 (tx1_c & 0x3F));
2355 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25),
2356 ((y * oldval_1 >> 7) & 0x1));
2357
2358 if (btxonly)
2359 return;
2360
2361 reg = result[final_candidate][6];
2362 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
2363
2364 reg = result[final_candidate][7] & 0x3F;
2365 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
2366
2367 reg = (result[final_candidate][7] >> 6) & 0xF;
2368 rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0xF0000000, reg);
2369 }
2370}
2371
2372static void _rtl92ee_phy_save_adda_registers(struct ieee80211_hw *hw,
2373 u32 *addareg, u32 *addabackup,
2374 u32 registernum)
2375{
2376 u32 i;
2377
2378 for (i = 0; i < registernum; i++)
2379 addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD);
2380}
2381
2382static void _rtl92ee_phy_save_mac_registers(struct ieee80211_hw *hw,
2383 u32 *macreg, u32 *macbackup)
2384{
2385 struct rtl_priv *rtlpriv = rtl_priv(hw);
2386 u32 i;
2387
2388 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
2389 macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
2390
2391 macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
2392}
2393
2394static void _rtl92ee_phy_reload_adda_registers(struct ieee80211_hw *hw,
2395 u32 *addareg, u32 *addabackup,
2396 u32 regiesternum)
2397{
2398 u32 i;
2399
2400 for (i = 0; i < regiesternum; i++)
2401 rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]);
2402}
2403
2404static void _rtl92ee_phy_reload_mac_registers(struct ieee80211_hw *hw,
2405 u32 *macreg, u32 *macbackup)
2406{
2407 struct rtl_priv *rtlpriv = rtl_priv(hw);
2408 u32 i;
2409
2410 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
2411 rtl_write_byte(rtlpriv, macreg[i], (u8)macbackup[i]);
2412 rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
2413}
2414
2415static void _rtl92ee_phy_path_adda_on(struct ieee80211_hw *hw, u32 *addareg,
2416 bool is_patha_on, bool is2t)
2417{
Larry Fingerb1a3bfc2014-09-26 16:40:23 -05002418 u32 i;
2419
Heinrich Schuchardta81605b2016-05-18 02:43:58 +02002420 for (i = 0; i < IQK_ADDA_REG_NUM; i++)
2421 rtl_set_bbreg(hw, addareg[i], MASKDWORD, 0x0fc01616);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -05002422}
2423
2424static void _rtl92ee_phy_mac_setting_calibration(struct ieee80211_hw *hw,
2425 u32 *macreg, u32 *macbackup)
2426{
2427 rtl_set_bbreg(hw, 0x520, 0x00ff0000, 0xff);
2428}
2429
2430static void _rtl92ee_phy_path_a_standby(struct ieee80211_hw *hw)
2431{
2432 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
2433 rtl_set_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK, 0x10000);
2434 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
2435}
2436
2437static bool _rtl92ee_phy_simularity_compare(struct ieee80211_hw *hw,
2438 long result[][8], u8 c1, u8 c2)
2439{
2440 u32 i, j, diff, simularity_bitmap, bound;
2441
2442 u8 final_candidate[2] = { 0xFF, 0xFF };
2443 bool bresult = true/*, is2t = true*/;
2444 s32 tmp1, tmp2;
2445
2446 bound = 8;
2447
2448 simularity_bitmap = 0;
2449
2450 for (i = 0; i < bound; i++) {
2451 if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
2452 if ((result[c1][i] & 0x00000200) != 0)
2453 tmp1 = result[c1][i] | 0xFFFFFC00;
2454 else
2455 tmp1 = result[c1][i];
2456
2457 if ((result[c2][i] & 0x00000200) != 0)
2458 tmp2 = result[c2][i] | 0xFFFFFC00;
2459 else
2460 tmp2 = result[c2][i];
2461 } else {
2462 tmp1 = result[c1][i];
2463 tmp2 = result[c2][i];
2464 }
2465
2466 diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
2467
2468 if (diff > MAX_TOLERANCE) {
2469 if ((i == 2 || i == 6) && !simularity_bitmap) {
2470 if (result[c1][i] + result[c1][i + 1] == 0)
2471 final_candidate[(i / 4)] = c2;
2472 else if (result[c2][i] + result[c2][i + 1] == 0)
2473 final_candidate[(i / 4)] = c1;
2474 else
2475 simularity_bitmap |= (1 << i);
2476 } else {
2477 simularity_bitmap |= (1 << i);
2478 }
2479 }
2480 }
2481
2482 if (simularity_bitmap == 0) {
2483 for (i = 0; i < (bound / 4); i++) {
2484 if (final_candidate[i] != 0xFF) {
2485 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
2486 result[3][j] =
2487 result[final_candidate[i]][j];
2488 bresult = false;
2489 }
2490 }
2491 return bresult;
2492 }
2493 if (!(simularity_bitmap & 0x03)) {/*path A TX OK*/
2494 for (i = 0; i < 2; i++)
2495 result[3][i] = result[c1][i];
2496 }
2497 if (!(simularity_bitmap & 0x0c)) {/*path A RX OK*/
2498 for (i = 2; i < 4; i++)
2499 result[3][i] = result[c1][i];
2500 }
2501 if (!(simularity_bitmap & 0x30)) {/*path B TX OK*/
2502 for (i = 4; i < 6; i++)
2503 result[3][i] = result[c1][i];
2504 }
2505 if (!(simularity_bitmap & 0xc0)) {/*path B RX OK*/
2506 for (i = 6; i < 8; i++)
2507 result[3][i] = result[c1][i];
2508 }
2509 return false;
2510}
2511
2512static void _rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw,
2513 long result[][8], u8 t, bool is2t)
2514{
2515 struct rtl_priv *rtlpriv = rtl_priv(hw);
2516 struct rtl_phy *rtlphy = &rtlpriv->phy;
2517 u32 i;
2518 u8 patha_ok, pathb_ok;
2519 u8 tmp_0xc50 = (u8)rtl_get_bbreg(hw, 0xc50, MASKBYTE0);
2520 u8 tmp_0xc58 = (u8)rtl_get_bbreg(hw, 0xc58, MASKBYTE0);
2521 u32 adda_reg[IQK_ADDA_REG_NUM] = {
2522 0x85c, 0xe6c, 0xe70, 0xe74,
2523 0xe78, 0xe7c, 0xe80, 0xe84,
2524 0xe88, 0xe8c, 0xed0, 0xed4,
2525 0xed8, 0xedc, 0xee0, 0xeec
2526 };
2527 u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
2528 0x522, 0x550, 0x551, 0x040
2529 };
2530 u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
2531 ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR,
2532 RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c,
2533 0x870, 0x860,
2534 0x864, 0x800
2535 };
2536 const u32 retrycount = 2;
2537
2538 if (t == 0) {
2539 _rtl92ee_phy_save_adda_registers(hw, adda_reg,
2540 rtlphy->adda_backup,
2541 IQK_ADDA_REG_NUM);
2542 _rtl92ee_phy_save_mac_registers(hw, iqk_mac_reg,
2543 rtlphy->iqk_mac_backup);
2544 _rtl92ee_phy_save_adda_registers(hw, iqk_bb_reg,
2545 rtlphy->iqk_bb_backup,
2546 IQK_BB_REG_NUM);
2547 }
2548
2549 _rtl92ee_phy_path_adda_on(hw, adda_reg, true, is2t);
2550
2551 /*BB setting*/
2552 rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00);
2553 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKDWORD, 0x03a05600);
2554 rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, MASKDWORD, 0x000800e4);
2555 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, MASKDWORD, 0x22208200);
2556
2557 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(10), 0x01);
2558 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(26), 0x01);
2559 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(10), 0x01);
2560 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BIT(10), 0x01);
2561
2562 _rtl92ee_phy_mac_setting_calibration(hw, iqk_mac_reg,
2563 rtlphy->iqk_mac_backup);
2564 /* Page B init*/
2565 /* IQ calibration setting*/
2566 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2567 rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
2568 rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2569
2570 for (i = 0 ; i < retrycount ; i++) {
2571 patha_ok = _rtl92ee_phy_path_a_iqk(hw, is2t);
2572
2573 if (patha_ok == 0x01) {
2574 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2575 "Path A Tx IQK Success!!\n");
2576 result[t][0] = (rtl_get_bbreg(hw,
2577 RTX_POWER_BEFORE_IQK_A,
2578 MASKDWORD) & 0x3FF0000)
2579 >> 16;
2580 result[t][1] = (rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A,
2581 MASKDWORD) & 0x3FF0000)
2582 >> 16;
2583 break;
2584 }
2585 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2586 "Path A Tx IQK Fail!!, ret = 0x%x\n",
2587 patha_ok);
2588 }
2589
2590 for (i = 0 ; i < retrycount ; i++) {
2591 patha_ok = _rtl92ee_phy_path_a_rx_iqk(hw, is2t);
2592
2593 if (patha_ok == 0x03) {
2594 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2595 "Path A Rx IQK Success!!\n");
2596 result[t][2] = (rtl_get_bbreg(hw,
2597 RRX_POWER_BEFORE_IQK_A_2,
2598 MASKDWORD) & 0x3FF0000)
2599 >> 16;
2600 result[t][3] = (rtl_get_bbreg(hw,
2601 RRX_POWER_AFTER_IQK_A_2,
2602 MASKDWORD) & 0x3FF0000)
2603 >> 16;
2604 break;
2605 }
2606 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2607 "Path A Rx IQK Fail!!, ret = 0x%x\n",
2608 patha_ok);
2609 }
2610
2611 if (0x00 == patha_ok)
2612 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2613 "Path A IQK failed!!, ret = 0\n");
2614 if (is2t) {
2615 _rtl92ee_phy_path_a_standby(hw);
2616 /* Turn Path B ADDA on */
2617 _rtl92ee_phy_path_adda_on(hw, adda_reg, false, is2t);
2618
2619 /* IQ calibration setting */
2620 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2621 rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
2622 rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2623
2624 for (i = 0 ; i < retrycount ; i++) {
2625 pathb_ok = _rtl92ee_phy_path_b_iqk(hw);
2626 if (pathb_ok == 0x01) {
2627 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2628 "Path B Tx IQK Success!!\n");
2629 result[t][4] = (rtl_get_bbreg(hw,
2630 RTX_POWER_BEFORE_IQK_B,
2631 MASKDWORD) & 0x3FF0000)
2632 >> 16;
2633 result[t][5] = (rtl_get_bbreg(hw,
2634 RTX_POWER_AFTER_IQK_B,
2635 MASKDWORD) & 0x3FF0000)
2636 >> 16;
2637 break;
2638 }
2639 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2640 "Path B Tx IQK Fail!!, ret = 0x%x\n",
2641 pathb_ok);
2642 }
2643
2644 for (i = 0 ; i < retrycount ; i++) {
2645 pathb_ok = _rtl92ee_phy_path_b_rx_iqk(hw, is2t);
2646 if (pathb_ok == 0x03) {
2647 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2648 "Path B Rx IQK Success!!\n");
2649 result[t][6] = (rtl_get_bbreg(hw,
2650 RRX_POWER_BEFORE_IQK_B_2,
2651 MASKDWORD) & 0x3FF0000)
2652 >> 16;
2653 result[t][7] = (rtl_get_bbreg(hw,
2654 RRX_POWER_AFTER_IQK_B_2,
2655 MASKDWORD) & 0x3FF0000)
2656 >> 16;
2657 break;
2658 }
2659 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2660 "Path B Rx IQK Fail!!, ret = 0x%x\n",
2661 pathb_ok);
2662 }
2663
2664 if (0x00 == pathb_ok)
2665 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2666 "Path B IQK failed!!, ret = 0\n");
2667 }
2668 /* Back to BB mode, load original value */
2669 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2670 "IQK:Back to BB mode, load original value!\n");
2671 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0);
2672
2673 if (t != 0) {
2674 /* Reload ADDA power saving parameters */
2675 _rtl92ee_phy_reload_adda_registers(hw, adda_reg,
2676 rtlphy->adda_backup,
2677 IQK_ADDA_REG_NUM);
2678
2679 /* Reload MAC parameters */
2680 _rtl92ee_phy_reload_mac_registers(hw, iqk_mac_reg,
2681 rtlphy->iqk_mac_backup);
2682
2683 _rtl92ee_phy_reload_adda_registers(hw, iqk_bb_reg,
2684 rtlphy->iqk_bb_backup,
2685 IQK_BB_REG_NUM);
2686
2687 /* Restore RX initial gain */
2688 rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
2689 rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_0xc50);
2690 if (is2t) {
2691 rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
2692 rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_0xc58);
2693 }
2694
2695 /* load 0xe30 IQC default value */
2696 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x01008c00);
2697 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x01008c00);
2698 }
2699}
2700
2701static void _rtl92ee_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
2702{
2703 u8 tmpreg;
2704 u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
2705 struct rtl_priv *rtlpriv = rtl_priv(hw);
2706
2707 tmpreg = rtl_read_byte(rtlpriv, 0xd03);
2708
2709 if ((tmpreg & 0x70) != 0)
2710 rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
2711 else
2712 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2713
2714 if ((tmpreg & 0x70) != 0) {
2715 rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
2716
2717 if (is2t)
2718 rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
2719 MASK12BITS);
2720
2721 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
2722 (rf_a_mode & 0x8FFFF) | 0x10000);
2723
2724 if (is2t)
2725 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
2726 (rf_b_mode & 0x8FFFF) | 0x10000);
2727 }
2728 lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
2729
2730 rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
2731
2732 mdelay(100);
2733
2734 if ((tmpreg & 0x70) != 0) {
2735 rtl_write_byte(rtlpriv, 0xd03, tmpreg);
2736 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
2737
2738 if (is2t)
2739 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
2740 rf_b_mode);
2741 } else {
2742 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2743 }
2744}
2745
2746static void _rtl92ee_phy_set_rfpath_switch(struct ieee80211_hw *hw,
2747 bool bmain, bool is2t)
2748{
2749 struct rtl_priv *rtlpriv = rtl_priv(hw);
2750 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2751 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2752
2753 RT_TRACE(rtlpriv, COMP_INIT , DBG_LOUD , "\n");
2754
2755 if (is_hal_stop(rtlhal)) {
2756 u8 u1btmp;
2757
2758 u1btmp = rtl_read_byte(rtlpriv, REG_LEDCFG0);
2759 rtl_write_byte(rtlpriv, REG_LEDCFG0, u1btmp | BIT(7));
2760 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
2761 }
2762 if (is2t) {
2763 if (bmain)
2764 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
2765 BIT(5) | BIT(6), 0x1);
2766 else
2767 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
2768 BIT(5) | BIT(6), 0x2);
2769 } else {
2770 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(8) | BIT(9), 0);
2771 rtl_set_bbreg(hw, 0x914, MASKLWORD, 0x0201);
2772
2773 /* We use the RF definition of MAIN and AUX,
2774 * left antenna and right antenna repectively.
2775 * Default output at AUX.
2776 */
2777 if (bmain) {
2778 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
2779 BIT(14) | BIT(13) | BIT(12), 0);
2780 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
2781 BIT(5) | BIT(4) | BIT(3), 0);
2782 if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
2783 rtl_set_bbreg(hw, RCONFIG_RAM64x16, BIT(31), 0);
2784 } else {
2785 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
2786 BIT(14) | BIT(13) | BIT(12), 1);
2787 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
2788 BIT(5) | BIT(4) | BIT(3), 1);
2789 if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
2790 rtl_set_bbreg(hw, RCONFIG_RAM64x16, BIT(31), 1);
2791 }
2792 }
2793}
2794
2795#undef IQK_ADDA_REG_NUM
2796#undef IQK_DELAY_TIME
2797
2798static u8 rtl92ee_get_rightchnlplace_for_iqk(u8 chnl)
2799{
2800 u8 channel_all[59] = {
2801 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
2802 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
2803 60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
2804 114, 116, 118, 120, 122, 124, 126, 128, 130,
2805 132, 134, 136, 138, 140, 149, 151, 153, 155,
2806 157, 159, 161, 163, 165
2807 };
2808 u8 place = chnl;
2809
2810 if (chnl > 14) {
2811 for (place = 14; place < sizeof(channel_all); place++) {
2812 if (channel_all[place] == chnl)
2813 return place - 13;
2814 }
2815 }
2816
2817 return 0;
2818}
2819
2820void rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
2821{
2822 struct rtl_priv *rtlpriv = rtl_priv(hw);
2823 struct rtl_phy *rtlphy = &rtlpriv->phy;
2824 long result[4][8];
2825 u8 i, final_candidate;
2826 bool b_patha_ok, b_pathb_ok;
2827 long reg_e94, reg_e9c, reg_ea4, reg_eac;
2828 long reg_eb4, reg_ebc, reg_ec4, reg_ecc;
2829 bool is12simular, is13simular, is23simular;
2830 u8 idx;
2831 u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
2832 ROFDM0_XARXIQIMBALANCE,
2833 ROFDM0_XBRXIQIMBALANCE,
2834 ROFDM0_ECCATHRESHOLD,
2835 ROFDM0_AGCRSSITABLE,
2836 ROFDM0_XATXIQIMBALANCE,
2837 ROFDM0_XBTXIQIMBALANCE,
2838 ROFDM0_XCTXAFE,
2839 ROFDM0_XDTXAFE,
2840 ROFDM0_RXIQEXTANTA
2841 };
2842
2843 if (b_recovery) {
2844 _rtl92ee_phy_reload_adda_registers(hw, iqk_bb_reg,
2845 rtlphy->iqk_bb_backup, 9);
2846 return;
2847 }
2848
2849 for (i = 0; i < 8; i++) {
2850 result[0][i] = 0;
2851 result[1][i] = 0;
2852 result[2][i] = 0;
2853
2854 if ((i == 0) || (i == 2) || (i == 4) || (i == 6))
2855 result[3][i] = 0x100;
2856 else
2857 result[3][i] = 0;
2858 }
2859 final_candidate = 0xff;
2860 b_patha_ok = false;
2861 b_pathb_ok = false;
2862 is12simular = false;
2863 is23simular = false;
2864 is13simular = false;
2865 for (i = 0; i < 3; i++) {
2866 _rtl92ee_phy_iq_calibrate(hw, result, i, true);
2867 if (i == 1) {
2868 is12simular = _rtl92ee_phy_simularity_compare(hw,
2869 result,
2870 0, 1);
2871 if (is12simular) {
2872 final_candidate = 0;
2873 break;
2874 }
2875 }
2876
2877 if (i == 2) {
2878 is13simular = _rtl92ee_phy_simularity_compare(hw,
2879 result,
2880 0, 2);
2881 if (is13simular) {
2882 final_candidate = 0;
2883 break;
2884 }
2885 is23simular = _rtl92ee_phy_simularity_compare(hw,
2886 result,
2887 1, 2);
2888 if (is23simular)
2889 final_candidate = 1;
2890 else
2891 final_candidate = 3;
2892 }
2893 }
2894
2895 for (i = 0; i < 4; i++) {
2896 reg_e94 = result[i][0];
2897 reg_e9c = result[i][1];
2898 reg_ea4 = result[i][2];
2899 reg_eac = result[i][3];
2900 reg_eb4 = result[i][4];
2901 reg_ebc = result[i][5];
2902 reg_ec4 = result[i][6];
2903 reg_ecc = result[i][7];
2904 }
2905
2906 if (final_candidate != 0xff) {
2907 reg_e94 = result[final_candidate][0];
2908 rtlphy->reg_e94 = reg_e94;
2909 reg_e9c = result[final_candidate][1];
2910 rtlphy->reg_e9c = reg_e9c;
2911 reg_ea4 = result[final_candidate][2];
2912 reg_eac = result[final_candidate][3];
2913 reg_eb4 = result[final_candidate][4];
2914 rtlphy->reg_eb4 = reg_eb4;
2915 reg_ebc = result[final_candidate][5];
2916 rtlphy->reg_ebc = reg_ebc;
2917 reg_ec4 = result[final_candidate][6];
2918 reg_ecc = result[final_candidate][7];
2919 b_patha_ok = true;
2920 b_pathb_ok = true;
2921 } else {
2922 rtlphy->reg_e94 = 0x100;
2923 rtlphy->reg_eb4 = 0x100;
2924 rtlphy->reg_e9c = 0x0;
2925 rtlphy->reg_ebc = 0x0;
2926 }
2927
2928 if (reg_e94 != 0)
2929 _rtl92ee_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result,
2930 final_candidate,
2931 (reg_ea4 == 0));
2932
2933 _rtl92ee_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, result,
2934 final_candidate,
2935 (reg_ec4 == 0));
2936
2937 idx = rtl92ee_get_rightchnlplace_for_iqk(rtlphy->current_channel);
2938
2939 /* To Fix BSOD when final_candidate is 0xff */
2940 if (final_candidate < 4) {
2941 for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
2942 rtlphy->iqk_matrix[idx].value[0][i] =
2943 result[final_candidate][i];
2944
2945 rtlphy->iqk_matrix[idx].iqk_done = true;
2946 }
2947 _rtl92ee_phy_save_adda_registers(hw, iqk_bb_reg,
2948 rtlphy->iqk_bb_backup, 9);
2949}
2950
2951void rtl92ee_phy_lc_calibrate(struct ieee80211_hw *hw)
2952{
2953 struct rtl_priv *rtlpriv = rtl_priv(hw);
2954 struct rtl_phy *rtlphy = &rtlpriv->phy;
2955 struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
2956 u32 timeout = 2000, timecount = 0;
2957
2958 while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
2959 udelay(50);
2960 timecount += 50;
2961 }
2962
2963 rtlphy->lck_inprogress = true;
2964 RTPRINT(rtlpriv, FINIT, INIT_IQK,
2965 "LCK:Start!!! currentband %x delay %d ms\n",
2966 rtlhal->current_bandtype, timecount);
2967
2968 _rtl92ee_phy_lc_calibrate(hw, false);
2969
2970 rtlphy->lck_inprogress = false;
2971}
2972
Arnd Bergmann08aba422016-06-15 23:30:43 +02002973void rtl92ee_phy_ap_calibrate(struct ieee80211_hw *hw, s8 delta)
Larry Fingerb1a3bfc2014-09-26 16:40:23 -05002974{
2975}
2976
2977void rtl92ee_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
2978{
2979 _rtl92ee_phy_set_rfpath_switch(hw, bmain, false);
2980}
2981
2982bool rtl92ee_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
2983{
2984 struct rtl_priv *rtlpriv = rtl_priv(hw);
2985 struct rtl_phy *rtlphy = &rtlpriv->phy;
2986 bool postprocessing = false;
2987
2988 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2989 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
2990 iotype, rtlphy->set_io_inprogress);
2991 do {
2992 switch (iotype) {
2993 case IO_CMD_RESUME_DM_BY_SCAN:
2994 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2995 "[IO CMD] Resume DM after scan.\n");
2996 postprocessing = true;
2997 break;
2998 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2999 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
3000 "[IO CMD] Pause DM before scan.\n");
3001 postprocessing = true;
3002 break;
3003 default:
3004 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -07003005 "switch case %#x not processed\n", iotype);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -05003006 break;
3007 }
3008 } while (false);
3009 if (postprocessing && !rtlphy->set_io_inprogress) {
3010 rtlphy->set_io_inprogress = true;
3011 rtlphy->current_io_type = iotype;
3012 } else {
3013 return false;
3014 }
3015 rtl92ee_phy_set_io(hw);
3016 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
3017 return true;
3018}
3019
3020static void rtl92ee_phy_set_io(struct ieee80211_hw *hw)
3021{
3022 struct rtl_priv *rtlpriv = rtl_priv(hw);
3023 struct rtl_phy *rtlphy = &rtlpriv->phy;
3024 struct dig_t *dm_dig = &rtlpriv->dm_digtable;
3025
3026 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
3027 "--->Cmd(%#x), set_io_inprogress(%d)\n",
3028 rtlphy->current_io_type, rtlphy->set_io_inprogress);
3029 switch (rtlphy->current_io_type) {
3030 case IO_CMD_RESUME_DM_BY_SCAN:
3031 rtl92ee_dm_write_dig(hw, rtlphy->initgain_backup.xaagccore1);
3032 rtl92ee_dm_write_cck_cca_thres(hw, rtlphy->initgain_backup.cca);
3033 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE , "no set txpower\n");
3034 rtl92ee_phy_set_txpower_level(hw, rtlphy->current_channel);
3035 break;
3036 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
3037 /* 8192eebt */
3038 rtlphy->initgain_backup.xaagccore1 = dm_dig->cur_igvalue;
3039 rtl92ee_dm_write_dig(hw, 0x17);
3040 rtlphy->initgain_backup.cca = dm_dig->cur_cck_cca_thres;
3041 rtl92ee_dm_write_cck_cca_thres(hw, 0x40);
3042 break;
3043 default:
3044 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -07003045 "switch case %#x not processed\n",
3046 rtlphy->current_io_type);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -05003047 break;
3048 }
3049 rtlphy->set_io_inprogress = false;
3050 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
3051 "(%#x)\n", rtlphy->current_io_type);
3052}
3053
3054static void rtl92ee_phy_set_rf_on(struct ieee80211_hw *hw)
3055{
3056 struct rtl_priv *rtlpriv = rtl_priv(hw);
3057
3058 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
3059 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
3060 /*rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);*/
3061 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
3062 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
3063 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
3064}
3065
3066static void _rtl92ee_phy_set_rf_sleep(struct ieee80211_hw *hw)
3067{
3068 struct rtl_priv *rtlpriv = rtl_priv(hw);
3069
3070 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
3071 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
3072
3073 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
3074 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
3075}
3076
3077static bool _rtl92ee_phy_set_rf_power_state(struct ieee80211_hw *hw,
3078 enum rf_pwrstate rfpwr_state)
3079{
3080 struct rtl_priv *rtlpriv = rtl_priv(hw);
3081 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
3082 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
3083 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
3084 bool bresult = true;
3085 u8 i, queue_id;
3086 struct rtl8192_tx_ring *ring = NULL;
3087
3088 switch (rfpwr_state) {
3089 case ERFON:
3090 if ((ppsc->rfpwr_state == ERFOFF) &&
3091 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
3092 bool rtstatus;
3093 u32 initializecount = 0;
3094
3095 do {
3096 initializecount++;
3097 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
3098 "IPS Set eRf nic enable\n");
3099 rtstatus = rtl_ps_enable_nic(hw);
3100 } while (!rtstatus && (initializecount < 10));
3101 RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
3102 } else {
3103 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
3104 "Set ERFON sleeping:%d ms\n",
3105 jiffies_to_msecs(jiffies -
3106 ppsc->last_sleep_jiffies));
3107 ppsc->last_awake_jiffies = jiffies;
3108 rtl92ee_phy_set_rf_on(hw);
3109 }
3110 if (mac->link_state == MAC80211_LINKED)
3111 rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
3112 else
3113 rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
3114 break;
3115 case ERFOFF:
3116 for (queue_id = 0, i = 0;
3117 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
3118 ring = &pcipriv->dev.tx_ring[queue_id];
3119 if (queue_id == BEACON_QUEUE ||
3120 skb_queue_len(&ring->queue) == 0) {
3121 queue_id++;
3122 continue;
3123 } else {
3124 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3125 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
3126 (i + 1), queue_id,
3127 skb_queue_len(&ring->queue));
3128
3129 udelay(10);
3130 i++;
3131 }
3132 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
3133 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3134 "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
3135 MAX_DOZE_WAITING_TIMES_9x,
3136 queue_id,
3137 skb_queue_len(&ring->queue));
3138 break;
3139 }
3140 }
3141
3142 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
3143 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
3144 "IPS Set eRf nic disable\n");
3145 rtl_ps_disable_nic(hw);
3146 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
3147 } else {
3148 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
3149 rtlpriv->cfg->ops->led_control(hw,
3150 LED_CTL_NO_LINK);
3151 } else {
3152 rtlpriv->cfg->ops->led_control(hw,
3153 LED_CTL_POWER_OFF);
3154 }
3155 }
3156 break;
3157 case ERFSLEEP:
3158 if (ppsc->rfpwr_state == ERFOFF)
3159 break;
3160 for (queue_id = 0, i = 0;
3161 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
3162 ring = &pcipriv->dev.tx_ring[queue_id];
3163 if (skb_queue_len(&ring->queue) == 0) {
3164 queue_id++;
3165 continue;
3166 } else {
3167 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3168 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
3169 (i + 1), queue_id,
3170 skb_queue_len(&ring->queue));
3171 udelay(10);
3172 i++;
3173 }
3174 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
3175 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3176 "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
3177 MAX_DOZE_WAITING_TIMES_9x,
3178 queue_id,
3179 skb_queue_len(&ring->queue));
3180 break;
3181 }
3182 }
3183 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
3184 "Set ERFSLEEP awaked:%d ms\n",
3185 jiffies_to_msecs(jiffies -
3186 ppsc->last_awake_jiffies));
3187 ppsc->last_sleep_jiffies = jiffies;
3188 _rtl92ee_phy_set_rf_sleep(hw);
3189 break;
3190 default:
3191 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -07003192 "switch case %#x not processed\n", rfpwr_state);
Larry Fingerb1a3bfc2014-09-26 16:40:23 -05003193 bresult = false;
3194 break;
3195 }
3196 if (bresult)
3197 ppsc->rfpwr_state = rfpwr_state;
3198 return bresult;
3199}
3200
3201bool rtl92ee_phy_set_rf_power_state(struct ieee80211_hw *hw,
3202 enum rf_pwrstate rfpwr_state)
3203{
3204 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
3205
3206 bool bresult = false;
3207
3208 if (rfpwr_state == ppsc->rfpwr_state)
3209 return bresult;
3210 bresult = _rtl92ee_phy_set_rf_power_state(hw, rfpwr_state);
3211 return bresult;
3212}