blob: 442031256bceeda3df1bc56a45fbdcb9edd6aff3 [file] [log] [blame]
Chaoming Li7274a8c2011-06-10 15:10:25 -05001/******************************************************************************
2 *
Larry Finger6a57b082012-01-07 20:46:46 -06003 * Copyright(c) 2009-2012 Realtek Corporation.
Chaoming Li7274a8c2011-06-10 15:10:25 -05004 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
30#include "../wifi.h"
31#include "../pci.h"
32#include "../ps.h"
33#include "reg.h"
34#include "def.h"
35#include "phy.h"
36#include "rf.h"
37#include "dm.h"
38#include "table.h"
39#include "sw.h"
40#include "hw.h"
41
42#define MAX_RF_IMR_INDEX 12
43#define MAX_RF_IMR_INDEX_NORMAL 13
44#define RF_REG_NUM_FOR_C_CUT_5G 6
45#define RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA 7
46#define RF_REG_NUM_FOR_C_CUT_2G 5
47#define RF_CHNL_NUM_5G 19
48#define RF_CHNL_NUM_5G_40M 17
49#define TARGET_CHNL_NUM_5G 221
50#define TARGET_CHNL_NUM_2G 14
51#define CV_CURVE_CNT 64
52
53static u32 rf_reg_for_5g_swchnl_normal[MAX_RF_IMR_INDEX_NORMAL] = {
54 0, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x0
55};
56
57static u8 rf_reg_for_c_cut_5g[RF_REG_NUM_FOR_C_CUT_5G] = {
58 RF_SYN_G1, RF_SYN_G2, RF_SYN_G3, RF_SYN_G4, RF_SYN_G5, RF_SYN_G6
59};
60
61static u8 rf_reg_for_c_cut_2g[RF_REG_NUM_FOR_C_CUT_2G] = {
62 RF_SYN_G1, RF_SYN_G2, RF_SYN_G3, RF_SYN_G7, RF_SYN_G8
63};
64
65static u8 rf_for_c_cut_5g_internal_pa[RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA] = {
66 0x0B, 0x48, 0x49, 0x4B, 0x03, 0x04, 0x0E
67};
68
69static u32 rf_reg_mask_for_c_cut_2g[RF_REG_NUM_FOR_C_CUT_2G] = {
70 BIT(19) | BIT(18) | BIT(17) | BIT(14) | BIT(1),
71 BIT(10) | BIT(9),
72 BIT(18) | BIT(17) | BIT(16) | BIT(1),
73 BIT(2) | BIT(1),
74 BIT(15) | BIT(14) | BIT(13) | BIT(12) | BIT(11)
75};
76
77static u8 rf_chnl_5g[RF_CHNL_NUM_5G] = {
78 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108,
79 112, 116, 120, 124, 128, 132, 136, 140
80};
81
82static u8 rf_chnl_5g_40m[RF_CHNL_NUM_5G_40M] = {
83 38, 42, 46, 50, 54, 58, 62, 102, 106, 110, 114,
84 118, 122, 126, 130, 134, 138
85};
86static u32 rf_reg_pram_c_5g[5][RF_REG_NUM_FOR_C_CUT_5G] = {
87 {0xE43BE, 0xFC638, 0x77C0A, 0xDE471, 0xd7110, 0x8EB04},
88 {0xE43BE, 0xFC078, 0xF7C1A, 0xE0C71, 0xD7550, 0xAEB04},
89 {0xE43BF, 0xFF038, 0xF7C0A, 0xDE471, 0xE5550, 0xAEB04},
90 {0xE43BF, 0xFF079, 0xF7C1A, 0xDE471, 0xE5550, 0xAEB04},
91 {0xE43BF, 0xFF038, 0xF7C1A, 0xDE471, 0xd7550, 0xAEB04}
92};
93
94static u32 rf_reg_param_for_c_cut_2g[3][RF_REG_NUM_FOR_C_CUT_2G] = {
95 {0x643BC, 0xFC038, 0x77C1A, 0x41289, 0x01840},
96 {0x643BC, 0xFC038, 0x07C1A, 0x41289, 0x01840},
97 {0x243BC, 0xFC438, 0x07C1A, 0x4128B, 0x0FC41}
98};
99
100static u32 rf_syn_g4_for_c_cut_2g = 0xD1C31 & 0x7FF;
101
102static u32 rf_pram_c_5g_int_pa[3][RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA] = {
103 {0x01a00, 0x40443, 0x00eb5, 0x89bec, 0x94a12, 0x94a12, 0x94a12},
104 {0x01800, 0xc0443, 0x00730, 0x896ee, 0x94a52, 0x94a52, 0x94a52},
105 {0x01800, 0xc0443, 0x00730, 0x896ee, 0x94a12, 0x94a12, 0x94a12}
106};
107
108/* [mode][patha+b][reg] */
109static u32 rf_imr_param_normal[1][3][MAX_RF_IMR_INDEX_NORMAL] = {
110 {
111 /* channel 1-14. */
112 {
113 0x70000, 0x00ff0, 0x4400f, 0x00ff0, 0x0, 0x0, 0x0,
114 0x0, 0x0, 0x64888, 0xe266c, 0x00090, 0x22fff
115 },
116 /* path 36-64 */
117 {
118 0x70000, 0x22880, 0x4470f, 0x55880, 0x00070, 0x88000,
119 0x0, 0x88080, 0x70000, 0x64a82, 0xe466c, 0x00090,
120 0x32c9a
121 },
122 /* 100 -165 */
123 {
124 0x70000, 0x44880, 0x4477f, 0x77880, 0x00070, 0x88000,
125 0x0, 0x880b0, 0x0, 0x64b82, 0xe466c, 0x00090, 0x32c9a
126 }
127 }
128};
129
130static u32 curveindex_5g[TARGET_CHNL_NUM_5G] = {0};
131
132static u32 curveindex_2g[TARGET_CHNL_NUM_2G] = {0};
133
134static u32 targetchnl_5g[TARGET_CHNL_NUM_5G] = {
135 25141, 25116, 25091, 25066, 25041,
136 25016, 24991, 24966, 24941, 24917,
137 24892, 24867, 24843, 24818, 24794,
138 24770, 24765, 24721, 24697, 24672,
139 24648, 24624, 24600, 24576, 24552,
140 24528, 24504, 24480, 24457, 24433,
141 24409, 24385, 24362, 24338, 24315,
142 24291, 24268, 24245, 24221, 24198,
143 24175, 24151, 24128, 24105, 24082,
144 24059, 24036, 24013, 23990, 23967,
145 23945, 23922, 23899, 23876, 23854,
146 23831, 23809, 23786, 23764, 23741,
147 23719, 23697, 23674, 23652, 23630,
148 23608, 23586, 23564, 23541, 23519,
149 23498, 23476, 23454, 23432, 23410,
150 23388, 23367, 23345, 23323, 23302,
151 23280, 23259, 23237, 23216, 23194,
152 23173, 23152, 23130, 23109, 23088,
153 23067, 23046, 23025, 23003, 22982,
154 22962, 22941, 22920, 22899, 22878,
155 22857, 22837, 22816, 22795, 22775,
156 22754, 22733, 22713, 22692, 22672,
157 22652, 22631, 22611, 22591, 22570,
158 22550, 22530, 22510, 22490, 22469,
159 22449, 22429, 22409, 22390, 22370,
160 22350, 22336, 22310, 22290, 22271,
161 22251, 22231, 22212, 22192, 22173,
162 22153, 22134, 22114, 22095, 22075,
163 22056, 22037, 22017, 21998, 21979,
164 21960, 21941, 21921, 21902, 21883,
165 21864, 21845, 21826, 21807, 21789,
166 21770, 21751, 21732, 21713, 21695,
167 21676, 21657, 21639, 21620, 21602,
168 21583, 21565, 21546, 21528, 21509,
169 21491, 21473, 21454, 21436, 21418,
170 21400, 21381, 21363, 21345, 21327,
171 21309, 21291, 21273, 21255, 21237,
172 21219, 21201, 21183, 21166, 21148,
173 21130, 21112, 21095, 21077, 21059,
174 21042, 21024, 21007, 20989, 20972,
175 25679, 25653, 25627, 25601, 25575,
176 25549, 25523, 25497, 25471, 25446,
177 25420, 25394, 25369, 25343, 25318,
178 25292, 25267, 25242, 25216, 25191,
179 25166
180};
181
182/* channel 1~14 */
183static u32 targetchnl_2g[TARGET_CHNL_NUM_2G] = {
184 26084, 26030, 25976, 25923, 25869, 25816, 25764,
185 25711, 25658, 25606, 25554, 25502, 25451, 25328
186};
187
188static u32 _rtl92d_phy_calculate_bit_shift(u32 bitmask)
189{
190 u32 i;
191
192 for (i = 0; i <= 31; i++) {
193 if (((bitmask >> i) & 0x1) == 1)
194 break;
195 }
196
197 return i;
198}
199
200u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
201{
202 struct rtl_priv *rtlpriv = rtl_priv(hw);
203 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
204 u32 returnvalue, originalvalue, bitshift;
205 u8 dbi_direct;
206
Joe Perchesf30d7502012-01-04 19:40:41 -0800207 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n",
208 regaddr, bitmask);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500209 if (rtlhal->during_mac1init_radioa || rtlhal->during_mac0init_radiob) {
210 /* mac1 use phy0 read radio_b. */
211 /* mac0 use phy1 read radio_b. */
212 if (rtlhal->during_mac1init_radioa)
213 dbi_direct = BIT(3);
214 else if (rtlhal->during_mac0init_radiob)
215 dbi_direct = BIT(3) | BIT(2);
216 originalvalue = rtl92de_read_dword_dbi(hw, (u16)regaddr,
217 dbi_direct);
218 } else {
219 originalvalue = rtl_read_dword(rtlpriv, regaddr);
220 }
221 bitshift = _rtl92d_phy_calculate_bit_shift(bitmask);
222 returnvalue = (originalvalue & bitmask) >> bitshift;
Joe Perchesf30d7502012-01-04 19:40:41 -0800223 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
224 "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
225 bitmask, regaddr, originalvalue);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500226 return returnvalue;
227}
228
229void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw,
230 u32 regaddr, u32 bitmask, u32 data)
231{
232 struct rtl_priv *rtlpriv = rtl_priv(hw);
233 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
234 u8 dbi_direct = 0;
235 u32 originalvalue, bitshift;
236
Joe Perchesf30d7502012-01-04 19:40:41 -0800237 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
238 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
239 regaddr, bitmask, data);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500240 if (rtlhal->during_mac1init_radioa)
241 dbi_direct = BIT(3);
242 else if (rtlhal->during_mac0init_radiob)
243 /* mac0 use phy1 write radio_b. */
244 dbi_direct = BIT(3) | BIT(2);
245 if (bitmask != BMASKDWORD) {
246 if (rtlhal->during_mac1init_radioa ||
247 rtlhal->during_mac0init_radiob)
248 originalvalue = rtl92de_read_dword_dbi(hw,
249 (u16) regaddr,
250 dbi_direct);
251 else
252 originalvalue = rtl_read_dword(rtlpriv, regaddr);
253 bitshift = _rtl92d_phy_calculate_bit_shift(bitmask);
254 data = ((originalvalue & (~bitmask)) | (data << bitshift));
255 }
256 if (rtlhal->during_mac1init_radioa || rtlhal->during_mac0init_radiob)
257 rtl92de_write_dword_dbi(hw, (u16) regaddr, data, dbi_direct);
258 else
259 rtl_write_dword(rtlpriv, regaddr, data);
Joe Perchesf30d7502012-01-04 19:40:41 -0800260 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
261 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
262 regaddr, bitmask, data);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500263}
264
265static u32 _rtl92d_phy_rf_serial_read(struct ieee80211_hw *hw,
266 enum radio_path rfpath, u32 offset)
267{
268
269 struct rtl_priv *rtlpriv = rtl_priv(hw);
270 struct rtl_phy *rtlphy = &(rtlpriv->phy);
271 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
272 u32 newoffset;
273 u32 tmplong, tmplong2;
274 u8 rfpi_enable = 0;
275 u32 retvalue;
276
277 newoffset = offset;
278 tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, BMASKDWORD);
279 if (rfpath == RF90_PATH_A)
280 tmplong2 = tmplong;
281 else
282 tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, BMASKDWORD);
283 tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
284 (newoffset << 23) | BLSSIREADEDGE;
285 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, BMASKDWORD,
286 tmplong & (~BLSSIREADEDGE));
287 udelay(10);
288 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, BMASKDWORD, tmplong2);
289 udelay(50);
290 udelay(50);
291 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, BMASKDWORD,
292 tmplong | BLSSIREADEDGE);
293 udelay(10);
294 if (rfpath == RF90_PATH_A)
295 rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
296 BIT(8));
297 else if (rfpath == RF90_PATH_B)
298 rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
299 BIT(8));
300 if (rfpi_enable)
301 retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi,
302 BLSSIREADBACKDATA);
303 else
304 retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
305 BLSSIREADBACKDATA);
Joe Perchesf30d7502012-01-04 19:40:41 -0800306 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x] = 0x%x\n",
307 rfpath, pphyreg->rflssi_readback, retvalue);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500308 return retvalue;
309}
310
311static void _rtl92d_phy_rf_serial_write(struct ieee80211_hw *hw,
312 enum radio_path rfpath,
313 u32 offset, u32 data)
314{
315 u32 data_and_addr;
316 u32 newoffset;
317 struct rtl_priv *rtlpriv = rtl_priv(hw);
318 struct rtl_phy *rtlphy = &(rtlpriv->phy);
319 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
320
321 newoffset = offset;
322 /* T65 RF */
323 data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
324 rtl_set_bbreg(hw, pphyreg->rf3wire_offset, BMASKDWORD, data_and_addr);
Joe Perchesf30d7502012-01-04 19:40:41 -0800325 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n",
326 rfpath, pphyreg->rf3wire_offset, data_and_addr);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500327}
328
329u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw,
330 enum radio_path rfpath, u32 regaddr, u32 bitmask)
331{
332 struct rtl_priv *rtlpriv = rtl_priv(hw);
333 u32 original_value, readback_value, bitshift;
334 unsigned long flags;
335
Joe Perchesf30d7502012-01-04 19:40:41 -0800336 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
337 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
338 regaddr, rfpath, bitmask);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500339 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
340 original_value = _rtl92d_phy_rf_serial_read(hw, rfpath, regaddr);
341 bitshift = _rtl92d_phy_calculate_bit_shift(bitmask);
342 readback_value = (original_value & bitmask) >> bitshift;
343 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
Joe Perchesf30d7502012-01-04 19:40:41 -0800344 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
345 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
346 regaddr, rfpath, bitmask, original_value);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500347 return readback_value;
348}
349
350void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
351 u32 regaddr, u32 bitmask, u32 data)
352{
353 struct rtl_priv *rtlpriv = rtl_priv(hw);
354 struct rtl_phy *rtlphy = &(rtlpriv->phy);
355 u32 original_value, bitshift;
356 unsigned long flags;
357
358 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800359 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
360 regaddr, bitmask, data, rfpath);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500361 if (bitmask == 0)
362 return;
363 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
364 if (rtlphy->rf_mode != RF_OP_BY_FW) {
365 if (bitmask != BRFREGOFFSETMASK) {
366 original_value = _rtl92d_phy_rf_serial_read(hw,
367 rfpath, regaddr);
368 bitshift = _rtl92d_phy_calculate_bit_shift(bitmask);
369 data = ((original_value & (~bitmask)) |
370 (data << bitshift));
371 }
372 _rtl92d_phy_rf_serial_write(hw, rfpath, regaddr, data);
373 }
374 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
Joe Perchesf30d7502012-01-04 19:40:41 -0800375 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
376 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
377 regaddr, bitmask, data, rfpath);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500378}
379
380bool rtl92d_phy_mac_config(struct ieee80211_hw *hw)
381{
382 struct rtl_priv *rtlpriv = rtl_priv(hw);
383 u32 i;
384 u32 arraylength;
385 u32 *ptrarray;
386
Joe Perchesf30d7502012-01-04 19:40:41 -0800387 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500388 arraylength = MAC_2T_ARRAYLENGTH;
389 ptrarray = rtl8192de_mac_2tarray;
Joe Perchesf30d7502012-01-04 19:40:41 -0800390 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:Rtl819XMAC_Array\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500391 for (i = 0; i < arraylength; i = i + 2)
392 rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
393 if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) {
394 /* improve 2-stream TX EVM */
395 /* rtl_write_byte(rtlpriv, 0x14,0x71); */
396 /* AMPDU aggregation number 9 */
397 /* rtl_write_word(rtlpriv, REG_MAX_AGGR_NUM, MAX_AGGR_NUM); */
398 rtl_write_byte(rtlpriv, REG_MAX_AGGR_NUM, 0x0B);
399 } else {
400 /* 92D need to test to decide the num. */
401 rtl_write_byte(rtlpriv, REG_MAX_AGGR_NUM, 0x07);
402 }
403 return true;
404}
405
406static void _rtl92d_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
407{
408 struct rtl_priv *rtlpriv = rtl_priv(hw);
409 struct rtl_phy *rtlphy = &(rtlpriv->phy);
410
411 /* RF Interface Sowrtware Control */
412 /* 16 LSBs if read 32-bit from 0x870 */
413 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
414 /* 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) */
415 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
416 /* 16 LSBs if read 32-bit from 0x874 */
417 rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
418 /* 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876) */
419
420 rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
421 /* RF Interface Readback Value */
422 /* 16 LSBs if read 32-bit from 0x8E0 */
423 rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
424 /* 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2) */
425 rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
426 /* 16 LSBs if read 32-bit from 0x8E4 */
427 rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
428 /* 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6) */
429 rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
430
431 /* RF Interface Output (and Enable) */
432 /* 16 LSBs if read 32-bit from 0x860 */
433 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
434 /* 16 LSBs if read 32-bit from 0x864 */
435 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
436
437 /* RF Interface (Output and) Enable */
438 /* 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */
439 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
440 /* 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) */
441 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
442
443 /* Addr of LSSI. Wirte RF register by driver */
444 /* LSSI Parameter */
445 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
446 RFPGA0_XA_LSSIPARAMETER;
447 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
448 RFPGA0_XB_LSSIPARAMETER;
449
450 /* RF parameter */
451 /* BB Band Select */
452 rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER;
453 rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER;
454 rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER;
455 rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER;
456
457 /* Tx AGC Gain Stage (same for all path. Should we remove this?) */
458 /* Tx gain stage */
459 rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
460 /* Tx gain stage */
461 rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
462 /* Tx gain stage */
463 rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
464 /* Tx gain stage */
465 rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
466
467 /* Tranceiver A~D HSSI Parameter-1 */
468 /* wire control parameter1 */
469 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
470 /* wire control parameter1 */
471 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
472
473 /* Tranceiver A~D HSSI Parameter-2 */
474 /* wire control parameter2 */
475 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
476 /* wire control parameter2 */
477 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
478
479 /* RF switch Control */
480 /* TR/Ant switch control */
481 rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control =
482 RFPGA0_XAB_SWITCHCONTROL;
483 rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control =
484 RFPGA0_XAB_SWITCHCONTROL;
485 rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control =
486 RFPGA0_XCD_SWITCHCONTROL;
487 rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control =
488 RFPGA0_XCD_SWITCHCONTROL;
489
490 /* AGC control 1 */
491 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
492 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
493 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
494 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
495
496 /* AGC control 2 */
497 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
498 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
499 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
500 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
501
502 /* RX AFE control 1 */
503 rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance =
504 ROFDM0_XARXIQIMBALANCE;
505 rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance =
506 ROFDM0_XBRXIQIMBALANCE;
507 rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance =
508 ROFDM0_XCRXIQIMBALANCE;
509 rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance =
510 ROFDM0_XDRXIQIMBALANCE;
511
512 /*RX AFE control 1 */
513 rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
514 rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
515 rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
516 rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
517
518 /* Tx AFE control 1 */
519 rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance =
520 ROFDM0_XATxIQIMBALANCE;
521 rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance =
522 ROFDM0_XBTxIQIMBALANCE;
523 rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance =
524 ROFDM0_XCTxIQIMBALANCE;
525 rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance =
526 ROFDM0_XDTxIQIMBALANCE;
527
528 /* Tx AFE control 2 */
529 rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATxAFE;
530 rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTxAFE;
531 rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTxAFE;
532 rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTxAFE;
533
534 /* Tranceiver LSSI Readback SI mode */
535 rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback =
536 RFPGA0_XA_LSSIREADBACK;
537 rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback =
538 RFPGA0_XB_LSSIREADBACK;
539 rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback =
540 RFPGA0_XC_LSSIREADBACK;
541 rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback =
542 RFPGA0_XD_LSSIREADBACK;
543
544 /* Tranceiver LSSI Readback PI mode */
545 rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi =
546 TRANSCEIVERA_HSPI_READBACK;
547 rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi =
548 TRANSCEIVERB_HSPI_READBACK;
549}
550
551static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
552 u8 configtype)
553{
554 int i;
555 u32 *phy_regarray_table;
556 u32 *agctab_array_table = NULL;
557 u32 *agctab_5garray_table;
558 u16 phy_reg_arraylen, agctab_arraylen = 0, agctab_5garraylen;
559 struct rtl_priv *rtlpriv = rtl_priv(hw);
560 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
561
562 /* Normal chip,Mac0 use AGC_TAB.txt for 2G and 5G band. */
563 if (rtlhal->interfaceindex == 0) {
564 agctab_arraylen = AGCTAB_ARRAYLENGTH;
565 agctab_array_table = rtl8192de_agctab_array;
566 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -0800567 " ===> phy:MAC0, Rtl819XAGCTAB_Array\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500568 } else {
569 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
570 agctab_arraylen = AGCTAB_2G_ARRAYLENGTH;
571 agctab_array_table = rtl8192de_agctab_2garray;
572 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -0800573 " ===> phy:MAC1, Rtl819XAGCTAB_2GArray\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500574 } else {
575 agctab_5garraylen = AGCTAB_5G_ARRAYLENGTH;
576 agctab_5garray_table = rtl8192de_agctab_5garray;
577 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -0800578 " ===> phy:MAC1, Rtl819XAGCTAB_5GArray\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500579
580 }
581 }
582 phy_reg_arraylen = PHY_REG_2T_ARRAYLENGTH;
583 phy_regarray_table = rtl8192de_phy_reg_2tarray;
584 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -0800585 " ===> phy:Rtl819XPHY_REG_Array_PG\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500586 if (configtype == BASEBAND_CONFIG_PHY_REG) {
587 for (i = 0; i < phy_reg_arraylen; i = i + 2) {
588 if (phy_regarray_table[i] == 0xfe)
589 mdelay(50);
590 else if (phy_regarray_table[i] == 0xfd)
591 mdelay(5);
592 else if (phy_regarray_table[i] == 0xfc)
593 mdelay(1);
594 else if (phy_regarray_table[i] == 0xfb)
595 udelay(50);
596 else if (phy_regarray_table[i] == 0xfa)
597 udelay(5);
598 else if (phy_regarray_table[i] == 0xf9)
599 udelay(1);
600 rtl_set_bbreg(hw, phy_regarray_table[i], BMASKDWORD,
601 phy_regarray_table[i + 1]);
602 udelay(1);
603 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800604 "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
605 phy_regarray_table[i],
606 phy_regarray_table[i + 1]);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500607 }
608 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
609 if (rtlhal->interfaceindex == 0) {
610 for (i = 0; i < agctab_arraylen; i = i + 2) {
611 rtl_set_bbreg(hw, agctab_array_table[i],
612 BMASKDWORD,
613 agctab_array_table[i + 1]);
614 /* Add 1us delay between BB/RF register
615 * setting. */
616 udelay(1);
617 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800618 "The Rtl819XAGCTAB_Array_Table[0] is %ul Rtl819XPHY_REGArray[1] is %ul\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -0500619 agctab_array_table[i],
Joe Perchesf30d7502012-01-04 19:40:41 -0800620 agctab_array_table[i + 1]);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500621 }
622 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -0800623 "Normal Chip, MAC0, load Rtl819XAGCTAB_Array\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500624 } else {
625 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
626 for (i = 0; i < agctab_arraylen; i = i + 2) {
627 rtl_set_bbreg(hw, agctab_array_table[i],
628 BMASKDWORD,
629 agctab_array_table[i + 1]);
630 /* Add 1us delay between BB/RF register
631 * setting. */
632 udelay(1);
633 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800634 "The Rtl819XAGCTAB_Array_Table[0] is %ul Rtl819XPHY_REGArray[1] is %ul\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -0500635 agctab_array_table[i],
Joe Perchesf30d7502012-01-04 19:40:41 -0800636 agctab_array_table[i + 1]);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500637 }
638 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -0800639 "Load Rtl819XAGCTAB_2GArray\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500640 } else {
641 for (i = 0; i < agctab_5garraylen; i = i + 2) {
642 rtl_set_bbreg(hw,
643 agctab_5garray_table[i],
644 BMASKDWORD,
645 agctab_5garray_table[i + 1]);
646 /* Add 1us delay between BB/RF registeri
647 * setting. */
648 udelay(1);
649 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800650 "The Rtl819XAGCTAB_5GArray_Table[0] is %ul Rtl819XPHY_REGArray[1] is %ul\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -0500651 agctab_5garray_table[i],
Joe Perchesf30d7502012-01-04 19:40:41 -0800652 agctab_5garray_table[i + 1]);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500653 }
654 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -0800655 "Load Rtl819XAGCTAB_5GArray\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500656 }
657 }
658 }
659 return true;
660}
661
662static void _rtl92d_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw,
663 u32 regaddr, u32 bitmask,
664 u32 data)
665{
666 struct rtl_priv *rtlpriv = rtl_priv(hw);
667 struct rtl_phy *rtlphy = &(rtlpriv->phy);
Larry Finger02b6ab02012-02-08 20:56:52 -0600668 int index;
Chaoming Li7274a8c2011-06-10 15:10:25 -0500669
Larry Finger02b6ab02012-02-08 20:56:52 -0600670 if (regaddr == RTXAGC_A_RATE18_06)
671 index = 0;
672 else if (regaddr == RTXAGC_A_RATE54_24)
673 index = 1;
674 else if (regaddr == RTXAGC_A_CCK1_MCS32)
675 index = 6;
676 else if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00)
677 index = 7;
678 else if (regaddr == RTXAGC_A_MCS03_MCS00)
679 index = 2;
680 else if (regaddr == RTXAGC_A_MCS07_MCS04)
681 index = 3;
682 else if (regaddr == RTXAGC_A_MCS11_MCS08)
683 index = 4;
684 else if (regaddr == RTXAGC_A_MCS15_MCS12)
685 index = 5;
686 else if (regaddr == RTXAGC_B_RATE18_06)
687 index = 8;
688 else if (regaddr == RTXAGC_B_RATE54_24)
689 index = 9;
690 else if (regaddr == RTXAGC_B_CCK1_55_MCS32)
691 index = 14;
692 else if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff)
693 index = 15;
694 else if (regaddr == RTXAGC_B_MCS03_MCS00)
695 index = 10;
696 else if (regaddr == RTXAGC_B_MCS07_MCS04)
697 index = 11;
698 else if (regaddr == RTXAGC_B_MCS11_MCS08)
699 index = 12;
700 else if (regaddr == RTXAGC_B_MCS15_MCS12)
701 index = 13;
702 else
703 return;
704
705 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][index] = data;
706 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
707 "MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%ulx\n",
708 rtlphy->pwrgroup_cnt, index,
709 rtlphy->mcs_txpwrlevel_origoffset
710 [rtlphy->pwrgroup_cnt][index]);
711 if (index == 13)
Chaoming Li7274a8c2011-06-10 15:10:25 -0500712 rtlphy->pwrgroup_cnt++;
Chaoming Li7274a8c2011-06-10 15:10:25 -0500713}
714
715static bool _rtl92d_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
716 u8 configtype)
717{
718 struct rtl_priv *rtlpriv = rtl_priv(hw);
719 int i;
720 u32 *phy_regarray_table_pg;
721 u16 phy_regarray_pg_len;
722
723 phy_regarray_pg_len = PHY_REG_ARRAY_PG_LENGTH;
724 phy_regarray_table_pg = rtl8192de_phy_reg_array_pg;
725 if (configtype == BASEBAND_CONFIG_PHY_REG) {
726 for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
727 if (phy_regarray_table_pg[i] == 0xfe)
728 mdelay(50);
729 else if (phy_regarray_table_pg[i] == 0xfd)
730 mdelay(5);
731 else if (phy_regarray_table_pg[i] == 0xfc)
732 mdelay(1);
733 else if (phy_regarray_table_pg[i] == 0xfb)
734 udelay(50);
735 else if (phy_regarray_table_pg[i] == 0xfa)
736 udelay(5);
737 else if (phy_regarray_table_pg[i] == 0xf9)
738 udelay(1);
739 _rtl92d_store_pwrindex_diffrate_offset(hw,
740 phy_regarray_table_pg[i],
741 phy_regarray_table_pg[i + 1],
742 phy_regarray_table_pg[i + 2]);
743 }
744 } else {
745 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800746 "configtype != BaseBand_Config_PHY_REG\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500747 }
748 return true;
749}
750
751static bool _rtl92d_phy_bb_config(struct ieee80211_hw *hw)
752{
753 struct rtl_priv *rtlpriv = rtl_priv(hw);
754 struct rtl_phy *rtlphy = &(rtlpriv->phy);
755 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
756 bool rtstatus = true;
757
Joe Perchesf30d7502012-01-04 19:40:41 -0800758 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500759 rtstatus = _rtl92d_phy_config_bb_with_headerfile(hw,
760 BASEBAND_CONFIG_PHY_REG);
Joe Perches23677ce2012-02-09 11:17:23 +0000761 if (!rtstatus) {
Joe Perchesf30d7502012-01-04 19:40:41 -0800762 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500763 return false;
764 }
765
766 /* if (rtlphy->rf_type == RF_1T2R) {
767 * _rtl92c_phy_bb_config_1t(hw);
Joe Perchesf30d7502012-01-04 19:40:41 -0800768 * RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500769 *} */
770
771 if (rtlefuse->autoload_failflag == false) {
772 rtlphy->pwrgroup_cnt = 0;
773 rtstatus = _rtl92d_phy_config_bb_with_pgheaderfile(hw,
774 BASEBAND_CONFIG_PHY_REG);
775 }
Joe Perches23677ce2012-02-09 11:17:23 +0000776 if (!rtstatus) {
Joe Perchesf30d7502012-01-04 19:40:41 -0800777 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500778 return false;
779 }
780 rtstatus = _rtl92d_phy_config_bb_with_headerfile(hw,
781 BASEBAND_CONFIG_AGC_TAB);
Joe Perches23677ce2012-02-09 11:17:23 +0000782 if (!rtstatus) {
Joe Perchesf30d7502012-01-04 19:40:41 -0800783 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500784 return false;
785 }
786 rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
787 RFPGA0_XA_HSSIPARAMETER2, 0x200));
788
789 return true;
790}
791
792bool rtl92d_phy_bb_config(struct ieee80211_hw *hw)
793{
794 struct rtl_priv *rtlpriv = rtl_priv(hw);
795 u16 regval;
796 u32 regvaldw;
797 u8 value;
798
799 _rtl92d_phy_init_bb_rf_register_definition(hw);
800 regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
801 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
802 regval | BIT(13) | BIT(0) | BIT(1));
803 rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83);
804 rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb);
805 /* 0x1f bit7 bit6 represent for mac0/mac1 driver ready */
806 value = rtl_read_byte(rtlpriv, REG_RF_CTRL);
807 rtl_write_byte(rtlpriv, REG_RF_CTRL, value | RF_EN | RF_RSTB |
808 RF_SDMRSTB);
809 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_PPLL | FEN_PCIEA |
810 FEN_DIO_PCIE | FEN_BB_GLB_RSTn | FEN_BBRSTB);
811 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
812 if (!(IS_92D_SINGLEPHY(rtlpriv->rtlhal.version))) {
813 regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0);
814 rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23));
815 }
816
817 return _rtl92d_phy_bb_config(hw);
818}
819
820bool rtl92d_phy_rf_config(struct ieee80211_hw *hw)
821{
822 return rtl92d_phy_rf6052_config(hw);
823}
824
825bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
826 enum rf_content content,
827 enum radio_path rfpath)
828{
Larry Fingereb8b27a2011-07-01 08:50:48 -0500829 int i;
Chaoming Li7274a8c2011-06-10 15:10:25 -0500830 u32 *radioa_array_table;
831 u32 *radiob_array_table;
832 u16 radioa_arraylen, radiob_arraylen;
833 struct rtl_priv *rtlpriv = rtl_priv(hw);
834
835 radioa_arraylen = RADIOA_2T_ARRAYLENGTH;
836 radioa_array_table = rtl8192de_radioa_2tarray;
837 radiob_arraylen = RADIOB_2T_ARRAYLENGTH;
838 radiob_array_table = rtl8192de_radiob_2tarray;
839 if (rtlpriv->efuse.internal_pa_5g[0]) {
840 radioa_arraylen = RADIOA_2T_INT_PA_ARRAYLENGTH;
841 radioa_array_table = rtl8192de_radioa_2t_int_paarray;
842 }
843 if (rtlpriv->efuse.internal_pa_5g[1]) {
844 radiob_arraylen = RADIOB_2T_INT_PA_ARRAYLENGTH;
845 radiob_array_table = rtl8192de_radiob_2t_int_paarray;
846 }
847 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -0800848 "PHY_ConfigRFWithHeaderFile() Radio_A:Rtl819XRadioA_1TArray\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500849 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -0800850 "PHY_ConfigRFWithHeaderFile() Radio_B:Rtl819XRadioB_1TArray\n");
851 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500852
853 /* this only happens when DMDP, mac0 start on 2.4G,
854 * mac1 start on 5G, mac 0 has to set phy0&phy1
855 * pathA or mac1 has to set phy0&phy1 pathA */
856 if ((content == radiob_txt) && (rfpath == RF90_PATH_A)) {
857 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -0800858 " ===> althougth Path A, we load radiob.txt\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500859 radioa_arraylen = radiob_arraylen;
860 radioa_array_table = radiob_array_table;
861 }
862 switch (rfpath) {
863 case RF90_PATH_A:
864 for (i = 0; i < radioa_arraylen; i = i + 2) {
865 if (radioa_array_table[i] == 0xfe) {
866 mdelay(50);
867 } else if (radioa_array_table[i] == 0xfd) {
868 /* delay_ms(5); */
Larry Fingereb8b27a2011-07-01 08:50:48 -0500869 mdelay(5);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500870 } else if (radioa_array_table[i] == 0xfc) {
871 /* delay_ms(1); */
Larry Fingereb8b27a2011-07-01 08:50:48 -0500872 mdelay(1);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500873 } else if (radioa_array_table[i] == 0xfb) {
874 udelay(50);
875 } else if (radioa_array_table[i] == 0xfa) {
876 udelay(5);
877 } else if (radioa_array_table[i] == 0xf9) {
878 udelay(1);
879 } else {
880 rtl_set_rfreg(hw, rfpath, radioa_array_table[i],
881 BRFREGOFFSETMASK,
882 radioa_array_table[i + 1]);
883 /* Add 1us delay between BB/RF register set. */
884 udelay(1);
885 }
886 }
887 break;
888 case RF90_PATH_B:
889 for (i = 0; i < radiob_arraylen; i = i + 2) {
890 if (radiob_array_table[i] == 0xfe) {
891 /* Delay specific ms. Only RF configuration
892 * requires delay. */
893 mdelay(50);
894 } else if (radiob_array_table[i] == 0xfd) {
895 /* delay_ms(5); */
Larry Fingereb8b27a2011-07-01 08:50:48 -0500896 mdelay(5);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500897 } else if (radiob_array_table[i] == 0xfc) {
898 /* delay_ms(1); */
Larry Fingereb8b27a2011-07-01 08:50:48 -0500899 mdelay(1);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500900 } else if (radiob_array_table[i] == 0xfb) {
901 udelay(50);
902 } else if (radiob_array_table[i] == 0xfa) {
903 udelay(5);
904 } else if (radiob_array_table[i] == 0xf9) {
905 udelay(1);
906 } else {
907 rtl_set_rfreg(hw, rfpath, radiob_array_table[i],
908 BRFREGOFFSETMASK,
909 radiob_array_table[i + 1]);
910 /* Add 1us delay between BB/RF register set. */
911 udelay(1);
912 }
913 }
914 break;
915 case RF90_PATH_C:
916 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -0800917 "switch case not processed\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500918 break;
919 case RF90_PATH_D:
920 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -0800921 "switch case not processed\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500922 break;
923 }
924 return true;
925}
926
927void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
928{
929 struct rtl_priv *rtlpriv = rtl_priv(hw);
930 struct rtl_phy *rtlphy = &(rtlpriv->phy);
931
932 rtlphy->default_initialgain[0] =
933 (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, BMASKBYTE0);
934 rtlphy->default_initialgain[1] =
935 (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, BMASKBYTE0);
936 rtlphy->default_initialgain[2] =
937 (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, BMASKBYTE0);
938 rtlphy->default_initialgain[3] =
939 (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, BMASKBYTE0);
940 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800941 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
942 rtlphy->default_initialgain[0],
943 rtlphy->default_initialgain[1],
944 rtlphy->default_initialgain[2],
945 rtlphy->default_initialgain[3]);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500946 rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3,
947 BMASKBYTE0);
948 rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
949 BMASKDWORD);
950 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800951 "Default framesync (0x%x) = 0x%x\n",
952 ROFDM0_RXDETECTOR3, rtlphy->framesync);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500953}
954
955static void _rtl92d_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
956 u8 *cckpowerlevel, u8 *ofdmpowerlevel)
957{
958 struct rtl_priv *rtlpriv = rtl_priv(hw);
959 struct rtl_phy *rtlphy = &(rtlpriv->phy);
960 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
961 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
962 u8 index = (channel - 1);
963
964 /* 1. CCK */
965 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
966 /* RF-A */
967 cckpowerlevel[RF90_PATH_A] =
968 rtlefuse->txpwrlevel_cck[RF90_PATH_A][index];
969 /* RF-B */
970 cckpowerlevel[RF90_PATH_B] =
971 rtlefuse->txpwrlevel_cck[RF90_PATH_B][index];
972 } else {
973 cckpowerlevel[RF90_PATH_A] = 0;
974 cckpowerlevel[RF90_PATH_B] = 0;
975 }
976 /* 2. OFDM for 1S or 2S */
977 if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_1T1R) {
978 /* Read HT 40 OFDM TX power */
979 ofdmpowerlevel[RF90_PATH_A] =
980 rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index];
981 ofdmpowerlevel[RF90_PATH_B] =
982 rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index];
983 } else if (rtlphy->rf_type == RF_2T2R) {
984 /* Read HT 40 OFDM TX power */
985 ofdmpowerlevel[RF90_PATH_A] =
986 rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index];
987 ofdmpowerlevel[RF90_PATH_B] =
988 rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index];
989 }
990}
991
992static void _rtl92d_ccxpower_index_check(struct ieee80211_hw *hw,
993 u8 channel, u8 *cckpowerlevel, u8 *ofdmpowerlevel)
994{
995 struct rtl_priv *rtlpriv = rtl_priv(hw);
996 struct rtl_phy *rtlphy = &(rtlpriv->phy);
997
998 rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
999 rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
1000}
1001
1002static u8 _rtl92c_phy_get_rightchnlplace(u8 chnl)
1003{
1004 u8 channel_5g[59] = {
1005 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
1006 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
1007 60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
1008 114, 116, 118, 120, 122, 124, 126, 128,
1009 130, 132, 134, 136, 138, 140, 149, 151,
1010 153, 155, 157, 159, 161, 163, 165
1011 };
1012 u8 place = chnl;
1013
1014 if (chnl > 14) {
1015 for (place = 14; place < sizeof(channel_5g); place++) {
1016 if (channel_5g[place] == chnl) {
1017 place++;
1018 break;
1019 }
1020 }
1021 }
1022 return place;
1023}
1024
1025void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1026{
1027 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1028 struct rtl_priv *rtlpriv = rtl_priv(hw);
1029 u8 cckpowerlevel[2], ofdmpowerlevel[2];
1030
Joe Perches23677ce2012-02-09 11:17:23 +00001031 if (!rtlefuse->txpwr_fromeprom)
Chaoming Li7274a8c2011-06-10 15:10:25 -05001032 return;
1033 channel = _rtl92c_phy_get_rightchnlplace(channel);
1034 _rtl92d_get_txpower_index(hw, channel, &cckpowerlevel[0],
1035 &ofdmpowerlevel[0]);
1036 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
1037 _rtl92d_ccxpower_index_check(hw, channel, &cckpowerlevel[0],
1038 &ofdmpowerlevel[0]);
1039 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
1040 rtl92d_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]);
1041 rtl92d_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel);
1042}
1043
1044void rtl92d_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1045{
1046 struct rtl_priv *rtlpriv = rtl_priv(hw);
1047 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1048 enum io_type iotype;
1049
1050 if (!is_hal_stop(rtlhal)) {
1051 switch (operation) {
1052 case SCAN_OPT_BACKUP:
1053 rtlhal->current_bandtypebackup =
1054 rtlhal->current_bandtype;
1055 iotype = IO_CMD_PAUSE_DM_BY_SCAN;
1056 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1057 (u8 *)&iotype);
1058 break;
1059 case SCAN_OPT_RESTORE:
1060 iotype = IO_CMD_RESUME_DM_BY_SCAN;
1061 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1062 (u8 *)&iotype);
1063 break;
1064 default:
1065 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -08001066 "Unknown Scan Backup operation\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001067 break;
1068 }
1069 }
1070}
1071
1072void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw,
1073 enum nl80211_channel_type ch_type)
1074{
1075 struct rtl_priv *rtlpriv = rtl_priv(hw);
1076 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1077 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1078 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1079 unsigned long flag = 0;
1080 u8 reg_prsr_rsc;
1081 u8 reg_bw_opmode;
1082
1083 if (rtlphy->set_bwmode_inprogress)
1084 return;
1085 if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
1086 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
Joe Perchesf30d7502012-01-04 19:40:41 -08001087 "FALSE driver sleep or unload\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001088 return;
1089 }
1090 rtlphy->set_bwmode_inprogress = true;
Joe Perchesf30d7502012-01-04 19:40:41 -08001091 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n",
1092 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1093 "20MHz" : "40MHz");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001094 reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1095 reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1096 switch (rtlphy->current_chan_bw) {
1097 case HT_CHANNEL_WIDTH_20:
1098 reg_bw_opmode |= BW_OPMODE_20MHZ;
1099 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1100 break;
1101 case HT_CHANNEL_WIDTH_20_40:
1102 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1103 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1104
1105 reg_prsr_rsc = (reg_prsr_rsc & 0x90) |
1106 (mac->cur_40_prime_sc << 5);
1107 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1108 break;
1109 default:
1110 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -08001111 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001112 break;
1113 }
1114 switch (rtlphy->current_chan_bw) {
1115 case HT_CHANNEL_WIDTH_20:
1116 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1117 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1118 /* SET BIT10 BIT11 for receive cck */
1119 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10) |
1120 BIT(11), 3);
1121 break;
1122 case HT_CHANNEL_WIDTH_20_40:
1123 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1124 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1125 /* Set Control channel to upper or lower.
1126 * These settings are required only for 40MHz */
1127 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
1128 rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
1129 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCKSIDEBAND,
1130 (mac->cur_40_prime_sc >> 1));
1131 rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
1132 }
1133 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
1134 /* SET BIT10 BIT11 for receive cck */
1135 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10) |
1136 BIT(11), 0);
1137 rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1138 (mac->cur_40_prime_sc ==
1139 HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1140 break;
1141 default:
1142 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -08001143 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001144 break;
1145
1146 }
1147 rtl92d_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1148 rtlphy->set_bwmode_inprogress = false;
Joe Perchesf30d7502012-01-04 19:40:41 -08001149 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001150}
1151
1152static void _rtl92d_phy_stop_trx_before_changeband(struct ieee80211_hw *hw)
1153{
1154 rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0);
1155 rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0);
1156 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0x00);
1157 rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x0);
1158}
1159
1160static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band)
1161{
1162 struct rtl_priv *rtlpriv = rtl_priv(hw);
1163 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
Larry Fingereb8b27a2011-07-01 08:50:48 -05001164 u8 value8;
Chaoming Li7274a8c2011-06-10 15:10:25 -05001165
Joe Perchesf30d7502012-01-04 19:40:41 -08001166 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "==>\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001167 rtlhal->bandset = band;
1168 rtlhal->current_bandtype = band;
1169 if (IS_92D_SINGLEPHY(rtlhal->version))
1170 rtlhal->bandset = BAND_ON_BOTH;
1171 /* stop RX/Tx */
1172 _rtl92d_phy_stop_trx_before_changeband(hw);
1173 /* reconfig BB/RF according to wireless mode */
1174 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
1175 /* BB & RF Config */
Joe Perchesf30d7502012-01-04 19:40:41 -08001176 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "====>2.4G\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001177 if (rtlhal->interfaceindex == 1)
1178 _rtl92d_phy_config_bb_with_headerfile(hw,
1179 BASEBAND_CONFIG_AGC_TAB);
1180 } else {
1181 /* 5G band */
Joe Perchesf30d7502012-01-04 19:40:41 -08001182 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "====>5G\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001183 if (rtlhal->interfaceindex == 1)
1184 _rtl92d_phy_config_bb_with_headerfile(hw,
1185 BASEBAND_CONFIG_AGC_TAB);
1186 }
1187 rtl92d_update_bbrf_configuration(hw);
1188 if (rtlhal->current_bandtype == BAND_ON_2_4G)
1189 rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
1190 rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
1191
1192 /* 20M BW. */
1193 /* rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); */
1194 rtlhal->reloadtxpowerindex = true;
1195 /* notice fw know band status 0x81[1]/0x53[1] = 0: 5G, 1: 2G */
1196 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
1197 value8 = rtl_read_byte(rtlpriv, (rtlhal->interfaceindex ==
1198 0 ? REG_MAC0 : REG_MAC1));
1199 value8 |= BIT(1);
1200 rtl_write_byte(rtlpriv, (rtlhal->interfaceindex ==
1201 0 ? REG_MAC0 : REG_MAC1), value8);
1202 } else {
1203 value8 = rtl_read_byte(rtlpriv, (rtlhal->interfaceindex ==
1204 0 ? REG_MAC0 : REG_MAC1));
1205 value8 &= (~BIT(1));
1206 rtl_write_byte(rtlpriv, (rtlhal->interfaceindex ==
1207 0 ? REG_MAC0 : REG_MAC1), value8);
1208 }
Larry Fingereb8b27a2011-07-01 08:50:48 -05001209 mdelay(1);
Joe Perchesf30d7502012-01-04 19:40:41 -08001210 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<==Switch Band OK\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001211}
1212
1213static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw,
1214 u8 channel, u8 rfpath)
1215{
1216 struct rtl_priv *rtlpriv = rtl_priv(hw);
1217 u32 imr_num = MAX_RF_IMR_INDEX;
1218 u32 rfmask = BRFREGOFFSETMASK;
1219 u8 group, i;
1220 unsigned long flag = 0;
1221
Joe Perchesf30d7502012-01-04 19:40:41 -08001222 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>path %d\n", rfpath);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001223 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {
Joe Perchesf30d7502012-01-04 19:40:41 -08001224 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001225 rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(25) | BIT(24), 0);
1226 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf);
1227 /* fc area 0xd2c */
1228 if (channel > 99)
1229 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(13) |
1230 BIT(14), 2);
1231 else
1232 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(13) |
1233 BIT(14), 1);
1234 /* leave 0 for channel1-14. */
1235 group = channel <= 64 ? 1 : 2;
1236 imr_num = MAX_RF_IMR_INDEX_NORMAL;
1237 for (i = 0; i < imr_num; i++)
1238 rtl_set_rfreg(hw, (enum radio_path)rfpath,
1239 rf_reg_for_5g_swchnl_normal[i], rfmask,
1240 rf_imr_param_normal[0][group][i]);
1241 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0);
1242 rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 1);
1243 } else {
1244 /* G band. */
1245 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08001246 "Load RF IMR parameters for G band. IMR already setting %d\n",
1247 rtlpriv->rtlhal.load_imrandiqk_setting_for2g);
1248 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001249 if (!rtlpriv->rtlhal.load_imrandiqk_setting_for2g) {
1250 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08001251 "Load RF IMR parameters for G band. %d\n",
1252 rfpath);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001253 rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
1254 rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(25) | BIT(24), 0);
1255 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4,
1256 0x00f00000, 0xf);
1257 imr_num = MAX_RF_IMR_INDEX_NORMAL;
1258 for (i = 0; i < imr_num; i++) {
1259 rtl_set_rfreg(hw, (enum radio_path)rfpath,
1260 rf_reg_for_5g_swchnl_normal[i],
1261 BRFREGOFFSETMASK,
1262 rf_imr_param_normal[0][0][i]);
1263 }
1264 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4,
1265 0x00f00000, 0);
1266 rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN | BCCKEN, 3);
1267 rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
1268 }
1269 }
Joe Perchesf30d7502012-01-04 19:40:41 -08001270 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001271}
1272
1273static void _rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw,
1274 u8 rfpath, u32 *pu4_regval)
1275{
1276 struct rtl_priv *rtlpriv = rtl_priv(hw);
1277 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1278 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
1279
Joe Perchesf30d7502012-01-04 19:40:41 -08001280 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "====>\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001281 /*----Store original RFENV control type----*/
1282 switch (rfpath) {
1283 case RF90_PATH_A:
1284 case RF90_PATH_C:
1285 *pu4_regval = rtl_get_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV);
1286 break;
1287 case RF90_PATH_B:
1288 case RF90_PATH_D:
1289 *pu4_regval =
1290 rtl_get_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16);
1291 break;
1292 }
1293 /*----Set RF_ENV enable----*/
1294 rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
1295 udelay(1);
1296 /*----Set RF_ENV output high----*/
1297 rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
1298 udelay(1);
1299 /* Set bit number of Address and Data for RF register */
1300 /* Set 1 to 4 bits for 8255 */
1301 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREADDRESSLENGTH, 0x0);
1302 udelay(1);
1303 /*Set 0 to 12 bits for 8255 */
1304 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
1305 udelay(1);
Joe Perchesf30d7502012-01-04 19:40:41 -08001306 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<====\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001307}
1308
1309static void _rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath,
1310 u32 *pu4_regval)
1311{
1312 struct rtl_priv *rtlpriv = rtl_priv(hw);
1313 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1314 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
1315
Joe Perchesf30d7502012-01-04 19:40:41 -08001316 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "=====>\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001317 /*----Restore RFENV control type----*/ ;
1318 switch (rfpath) {
1319 case RF90_PATH_A:
1320 case RF90_PATH_C:
1321 rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV, *pu4_regval);
1322 break;
1323 case RF90_PATH_B:
1324 case RF90_PATH_D:
1325 rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16,
1326 *pu4_regval);
1327 break;
1328 }
Joe Perchesf30d7502012-01-04 19:40:41 -08001329 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<=====\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001330}
1331
1332static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
1333{
1334 struct rtl_priv *rtlpriv = rtl_priv(hw);
1335 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1336 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
1337 u8 path = rtlhal->current_bandtype ==
1338 BAND_ON_5G ? RF90_PATH_A : RF90_PATH_B;
1339 u8 index = 0, i = 0, rfpath = RF90_PATH_A;
1340 bool need_pwr_down = false, internal_pa = false;
1341 u32 u4regvalue, mask = 0x1C000, value = 0, u4tmp, u4tmp2;
1342
Joe Perchesf30d7502012-01-04 19:40:41 -08001343 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001344 /* config path A for 5G */
1345 if (rtlhal->current_bandtype == BAND_ON_5G) {
Joe Perchesf30d7502012-01-04 19:40:41 -08001346 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001347 u4tmp = curveindex_5g[channel - 1];
Joe Perches4c488692012-01-04 19:40:42 -08001348 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1349 "ver 1 set RF-A, 5G, 0x28 = 0x%x !!\n", u4tmp);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001350 for (i = 0; i < RF_CHNL_NUM_5G; i++) {
1351 if (channel == rf_chnl_5g[i] && channel <= 140)
1352 index = 0;
1353 }
1354 for (i = 0; i < RF_CHNL_NUM_5G_40M; i++) {
1355 if (channel == rf_chnl_5g_40m[i] && channel <= 140)
1356 index = 1;
1357 }
1358 if (channel == 149 || channel == 155 || channel == 161)
1359 index = 2;
1360 else if (channel == 151 || channel == 153 || channel == 163
1361 || channel == 165)
1362 index = 3;
1363 else if (channel == 157 || channel == 159)
1364 index = 4;
1365
1366 if (rtlhal->macphymode == DUALMAC_DUALPHY
1367 && rtlhal->interfaceindex == 1) {
1368 need_pwr_down = rtl92d_phy_enable_anotherphy(hw, false);
1369 rtlhal->during_mac1init_radioa = true;
1370 /* asume no this case */
1371 if (need_pwr_down)
1372 _rtl92d_phy_enable_rf_env(hw, path,
1373 &u4regvalue);
1374 }
1375 for (i = 0; i < RF_REG_NUM_FOR_C_CUT_5G; i++) {
1376 if (i == 0 && (rtlhal->macphymode == DUALMAC_DUALPHY)) {
1377 rtl_set_rfreg(hw, (enum radio_path)path,
1378 rf_reg_for_c_cut_5g[i],
1379 BRFREGOFFSETMASK, 0xE439D);
1380 } else if (rf_reg_for_c_cut_5g[i] == RF_SYN_G4) {
1381 u4tmp2 = (rf_reg_pram_c_5g[index][i] &
1382 0x7FF) | (u4tmp << 11);
1383 if (channel == 36)
1384 u4tmp2 &= ~(BIT(7) | BIT(6));
1385 rtl_set_rfreg(hw, (enum radio_path)path,
1386 rf_reg_for_c_cut_5g[i],
1387 BRFREGOFFSETMASK, u4tmp2);
1388 } else {
1389 rtl_set_rfreg(hw, (enum radio_path)path,
1390 rf_reg_for_c_cut_5g[i],
1391 BRFREGOFFSETMASK,
1392 rf_reg_pram_c_5g[index][i]);
1393 }
1394 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -08001395 "offset 0x%x value 0x%x path %d index %d readback 0x%x\n",
1396 rf_reg_for_c_cut_5g[i],
1397 rf_reg_pram_c_5g[index][i],
1398 path, index,
1399 rtl_get_rfreg(hw, (enum radio_path)path,
1400 rf_reg_for_c_cut_5g[i],
1401 BRFREGOFFSETMASK));
Chaoming Li7274a8c2011-06-10 15:10:25 -05001402 }
1403 if (need_pwr_down)
1404 _rtl92d_phy_restore_rf_env(hw, path, &u4regvalue);
1405 if (rtlhal->during_mac1init_radioa)
1406 rtl92d_phy_powerdown_anotherphy(hw, false);
1407 if (channel < 149)
1408 value = 0x07;
1409 else if (channel >= 149)
1410 value = 0x02;
1411 if (channel >= 36 && channel <= 64)
1412 index = 0;
1413 else if (channel >= 100 && channel <= 140)
1414 index = 1;
1415 else
1416 index = 2;
1417 for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
1418 rfpath++) {
1419 if (rtlhal->macphymode == DUALMAC_DUALPHY &&
1420 rtlhal->interfaceindex == 1) /* MAC 1 5G */
1421 internal_pa = rtlpriv->efuse.internal_pa_5g[1];
1422 else
1423 internal_pa =
1424 rtlpriv->efuse.internal_pa_5g[rfpath];
1425 if (internal_pa) {
1426 for (i = 0;
1427 i < RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA;
1428 i++) {
1429 rtl_set_rfreg(hw, rfpath,
1430 rf_for_c_cut_5g_internal_pa[i],
1431 BRFREGOFFSETMASK,
1432 rf_pram_c_5g_int_pa[index][i]);
1433 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08001434 "offset 0x%x value 0x%x path %d index %d\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -05001435 rf_for_c_cut_5g_internal_pa[i],
1436 rf_pram_c_5g_int_pa[index][i],
Joe Perchesf30d7502012-01-04 19:40:41 -08001437 rfpath, index);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001438 }
1439 } else {
1440 rtl_set_rfreg(hw, (enum radio_path)rfpath, 0x0B,
1441 mask, value);
1442 }
1443 }
1444 } else if (rtlhal->current_bandtype == BAND_ON_2_4G) {
Joe Perchesf30d7502012-01-04 19:40:41 -08001445 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001446 u4tmp = curveindex_2g[channel - 1];
Joe Perches4c488692012-01-04 19:40:42 -08001447 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1448 "ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", u4tmp);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001449 if (channel == 1 || channel == 2 || channel == 4 || channel == 9
1450 || channel == 10 || channel == 11 || channel == 12)
1451 index = 0;
1452 else if (channel == 3 || channel == 13 || channel == 14)
1453 index = 1;
1454 else if (channel >= 5 && channel <= 8)
1455 index = 2;
1456 if (rtlhal->macphymode == DUALMAC_DUALPHY) {
1457 path = RF90_PATH_A;
1458 if (rtlhal->interfaceindex == 0) {
1459 need_pwr_down =
1460 rtl92d_phy_enable_anotherphy(hw, true);
1461 rtlhal->during_mac0init_radiob = true;
1462
1463 if (need_pwr_down)
1464 _rtl92d_phy_enable_rf_env(hw, path,
1465 &u4regvalue);
1466 }
1467 }
1468 for (i = 0; i < RF_REG_NUM_FOR_C_CUT_2G; i++) {
1469 if (rf_reg_for_c_cut_2g[i] == RF_SYN_G7)
1470 rtl_set_rfreg(hw, (enum radio_path)path,
1471 rf_reg_for_c_cut_2g[i],
1472 BRFREGOFFSETMASK,
1473 (rf_reg_param_for_c_cut_2g[index][i] |
1474 BIT(17)));
1475 else
1476 rtl_set_rfreg(hw, (enum radio_path)path,
1477 rf_reg_for_c_cut_2g[i],
1478 BRFREGOFFSETMASK,
1479 rf_reg_param_for_c_cut_2g
1480 [index][i]);
1481 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -08001482 "offset 0x%x value 0x%x mak 0x%x path %d index %d readback 0x%x\n",
1483 rf_reg_for_c_cut_2g[i],
1484 rf_reg_param_for_c_cut_2g[index][i],
1485 rf_reg_mask_for_c_cut_2g[i], path, index,
1486 rtl_get_rfreg(hw, (enum radio_path)path,
1487 rf_reg_for_c_cut_2g[i],
1488 BRFREGOFFSETMASK));
Chaoming Li7274a8c2011-06-10 15:10:25 -05001489 }
1490 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001491 "cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n",
1492 rf_syn_g4_for_c_cut_2g | (u4tmp << 11));
Chaoming Li7274a8c2011-06-10 15:10:25 -05001493
1494 rtl_set_rfreg(hw, (enum radio_path)path, RF_SYN_G4,
1495 BRFREGOFFSETMASK,
1496 rf_syn_g4_for_c_cut_2g | (u4tmp << 11));
1497 if (need_pwr_down)
1498 _rtl92d_phy_restore_rf_env(hw, path, &u4regvalue);
1499 if (rtlhal->during_mac0init_radiob)
1500 rtl92d_phy_powerdown_anotherphy(hw, true);
1501 }
Joe Perchesf30d7502012-01-04 19:40:41 -08001502 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001503}
1504
1505u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl)
1506{
1507 u8 channel_all[59] = {
1508 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
1509 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
1510 60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
1511 114, 116, 118, 120, 122, 124, 126, 128, 130,
1512 132, 134, 136, 138, 140, 149, 151, 153, 155,
1513 157, 159, 161, 163, 165
1514 };
1515 u8 place = chnl;
1516
1517 if (chnl > 14) {
1518 for (place = 14; place < sizeof(channel_all); place++) {
1519 if (channel_all[place] == chnl)
1520 return place - 13;
1521 }
1522 }
1523
1524 return 0;
1525}
1526
1527#define MAX_TOLERANCE 5
1528#define IQK_DELAY_TIME 1 /* ms */
1529#define MAX_TOLERANCE_92D 3
1530
1531/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1532static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb)
1533{
1534 struct rtl_priv *rtlpriv = rtl_priv(hw);
1535 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1536 u32 regeac, rege94, rege9c, regea4;
1537 u8 result = 0;
1538
Joe Perches4c488692012-01-04 19:40:42 -08001539 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001540 /* path-A IQK setting */
Joe Perches4c488692012-01-04 19:40:42 -08001541 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001542 if (rtlhal->interfaceindex == 0) {
1543 rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x10008c1f);
1544 rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x10008c1f);
1545 } else {
1546 rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x10008c22);
1547 rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x10008c22);
1548 }
1549 rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82140102);
1550 rtl_set_bbreg(hw, 0xe3c, BMASKDWORD, 0x28160206);
1551 /* path-B IQK setting */
1552 if (configpathb) {
1553 rtl_set_bbreg(hw, 0xe50, BMASKDWORD, 0x10008c22);
1554 rtl_set_bbreg(hw, 0xe54, BMASKDWORD, 0x10008c22);
1555 rtl_set_bbreg(hw, 0xe58, BMASKDWORD, 0x82140102);
1556 rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x28160206);
1557 }
1558 /* LO calibration setting */
Joe Perches4c488692012-01-04 19:40:42 -08001559 RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001560 rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911);
1561 /* One shot, path A LOK & IQK */
Joe Perches4c488692012-01-04 19:40:42 -08001562 RTPRINT(rtlpriv, FINIT, INIT_IQK, "One shot, path A LOK & IQK!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001563 rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000);
1564 rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000);
1565 /* delay x ms */
1566 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001567 "Delay %d ms for One shot, path A LOK & IQK\n",
1568 IQK_DELAY_TIME);
Andrew Mortonfaeef8a2011-06-30 16:28:50 -05001569 mdelay(IQK_DELAY_TIME);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001570 /* Check failed */
1571 regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001572 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001573 rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001574 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe94 = 0x%x\n", rege94);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001575 rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001576 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe9c = 0x%x\n", rege9c);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001577 regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001578 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xea4 = 0x%x\n", regea4);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001579 if (!(regeac & BIT(28)) && (((rege94 & 0x03FF0000) >> 16) != 0x142) &&
1580 (((rege9c & 0x03FF0000) >> 16) != 0x42))
1581 result |= 0x01;
1582 else /* if Tx not OK, ignore Rx */
1583 return result;
1584 /* if Tx is OK, check whether Rx is OK */
1585 if (!(regeac & BIT(27)) && (((regea4 & 0x03FF0000) >> 16) != 0x132) &&
1586 (((regeac & 0x03FF0000) >> 16) != 0x36))
1587 result |= 0x02;
1588 else
Joe Perches4c488692012-01-04 19:40:42 -08001589 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A Rx IQK fail!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001590 return result;
1591}
1592
1593/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1594static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw,
1595 bool configpathb)
1596{
1597 struct rtl_priv *rtlpriv = rtl_priv(hw);
1598 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1599 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1600 u32 regeac, rege94, rege9c, regea4;
1601 u8 result = 0;
1602 u8 i;
1603 u8 retrycount = 2;
1604 u32 TxOKBit = BIT(28), RxOKBit = BIT(27);
1605
1606 if (rtlhal->interfaceindex == 1) { /* PHY1 */
1607 TxOKBit = BIT(31);
1608 RxOKBit = BIT(30);
1609 }
Joe Perches4c488692012-01-04 19:40:42 -08001610 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001611 /* path-A IQK setting */
Joe Perches4c488692012-01-04 19:40:42 -08001612 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001613 rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f);
1614 rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f);
1615 rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82140307);
1616 rtl_set_bbreg(hw, 0xe3c, BMASKDWORD, 0x68160960);
1617 /* path-B IQK setting */
1618 if (configpathb) {
1619 rtl_set_bbreg(hw, 0xe50, BMASKDWORD, 0x18008c2f);
1620 rtl_set_bbreg(hw, 0xe54, BMASKDWORD, 0x18008c2f);
1621 rtl_set_bbreg(hw, 0xe58, BMASKDWORD, 0x82110000);
1622 rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68110000);
1623 }
1624 /* LO calibration setting */
Joe Perches4c488692012-01-04 19:40:42 -08001625 RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001626 rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911);
1627 /* path-A PA on */
1628 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, 0x07000f60);
1629 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BMASKDWORD, 0x66e60e30);
1630 for (i = 0; i < retrycount; i++) {
1631 /* One shot, path A LOK & IQK */
1632 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001633 "One shot, path A LOK & IQK!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001634 rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000);
1635 rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000);
1636 /* delay x ms */
1637 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001638 "Delay %d ms for One shot, path A LOK & IQK.\n",
1639 IQK_DELAY_TIME);
Andrew Mortonfaeef8a2011-06-30 16:28:50 -05001640 mdelay(IQK_DELAY_TIME * 10);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001641 /* Check failed */
1642 regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001643 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001644 rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001645 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe94 = 0x%x\n", rege94);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001646 rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001647 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe9c = 0x%x\n", rege9c);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001648 regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001649 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xea4 = 0x%x\n", regea4);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001650 if (!(regeac & TxOKBit) &&
1651 (((rege94 & 0x03FF0000) >> 16) != 0x142)) {
1652 result |= 0x01;
1653 } else { /* if Tx not OK, ignore Rx */
1654 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001655 "Path A Tx IQK fail!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001656 continue;
1657 }
1658
1659 /* if Tx is OK, check whether Rx is OK */
1660 if (!(regeac & RxOKBit) &&
1661 (((regea4 & 0x03FF0000) >> 16) != 0x132)) {
1662 result |= 0x02;
1663 break;
1664 } else {
1665 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001666 "Path A Rx IQK fail!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001667 }
1668 }
1669 /* path A PA off */
1670 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD,
1671 rtlphy->iqk_bb_backup[0]);
1672 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BMASKDWORD,
1673 rtlphy->iqk_bb_backup[1]);
1674 return result;
1675}
1676
1677/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1678static u8 _rtl92d_phy_pathb_iqk(struct ieee80211_hw *hw)
1679{
1680 struct rtl_priv *rtlpriv = rtl_priv(hw);
1681 u32 regeac, regeb4, regebc, regec4, regecc;
1682 u8 result = 0;
1683
Joe Perches4c488692012-01-04 19:40:42 -08001684 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQK!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001685 /* One shot, path B LOK & IQK */
Joe Perches4c488692012-01-04 19:40:42 -08001686 RTPRINT(rtlpriv, FINIT, INIT_IQK, "One shot, path A LOK & IQK!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001687 rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000002);
1688 rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000000);
1689 /* delay x ms */
1690 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001691 "Delay %d ms for One shot, path B LOK & IQK\n", IQK_DELAY_TIME);
Andrew Mortonfaeef8a2011-06-30 16:28:50 -05001692 mdelay(IQK_DELAY_TIME);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001693 /* Check failed */
1694 regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001695 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001696 regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001697 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeb4 = 0x%x\n", regeb4);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001698 regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001699 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xebc = 0x%x\n", regebc);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001700 regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001701 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xec4 = 0x%x\n", regec4);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001702 regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001703 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xecc = 0x%x\n", regecc);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001704 if (!(regeac & BIT(31)) && (((regeb4 & 0x03FF0000) >> 16) != 0x142) &&
1705 (((regebc & 0x03FF0000) >> 16) != 0x42))
1706 result |= 0x01;
1707 else
1708 return result;
1709 if (!(regeac & BIT(30)) && (((regec4 & 0x03FF0000) >> 16) != 0x132) &&
1710 (((regecc & 0x03FF0000) >> 16) != 0x36))
1711 result |= 0x02;
1712 else
Joe Perches4c488692012-01-04 19:40:42 -08001713 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B Rx IQK fail!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001714 return result;
1715}
1716
1717/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1718static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw)
1719{
1720 struct rtl_priv *rtlpriv = rtl_priv(hw);
1721 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1722 u32 regeac, regeb4, regebc, regec4, regecc;
1723 u8 result = 0;
1724 u8 i;
1725 u8 retrycount = 2;
1726
Joe Perches4c488692012-01-04 19:40:42 -08001727 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQK!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001728 /* path-A IQK setting */
Joe Perches4c488692012-01-04 19:40:42 -08001729 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001730 rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f);
1731 rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f);
1732 rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82110000);
1733 rtl_set_bbreg(hw, 0xe3c, BMASKDWORD, 0x68110000);
1734
1735 /* path-B IQK setting */
1736 rtl_set_bbreg(hw, 0xe50, BMASKDWORD, 0x18008c2f);
1737 rtl_set_bbreg(hw, 0xe54, BMASKDWORD, 0x18008c2f);
1738 rtl_set_bbreg(hw, 0xe58, BMASKDWORD, 0x82140307);
1739 rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68160960);
1740
1741 /* LO calibration setting */
Joe Perches4c488692012-01-04 19:40:42 -08001742 RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001743 rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911);
1744
1745 /* path-B PA on */
1746 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, 0x0f600700);
1747 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BMASKDWORD, 0x061f0d30);
1748
1749 for (i = 0; i < retrycount; i++) {
1750 /* One shot, path B LOK & IQK */
1751 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001752 "One shot, path A LOK & IQK!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001753 rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xfa000000);
1754 rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000);
1755
1756 /* delay x ms */
1757 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001758 "Delay %d ms for One shot, path B LOK & IQK.\n", 10);
Andrew Mortonfaeef8a2011-06-30 16:28:50 -05001759 mdelay(IQK_DELAY_TIME * 10);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001760
1761 /* Check failed */
1762 regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001763 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001764 regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001765 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeb4 = 0x%x\n", regeb4);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001766 regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001767 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xebc = 0x%x\n", regebc);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001768 regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001769 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xec4 = 0x%x\n", regec4);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001770 regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001771 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xecc = 0x%x\n", regecc);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001772 if (!(regeac & BIT(31)) &&
1773 (((regeb4 & 0x03FF0000) >> 16) != 0x142))
1774 result |= 0x01;
1775 else
1776 continue;
1777 if (!(regeac & BIT(30)) &&
1778 (((regec4 & 0x03FF0000) >> 16) != 0x132)) {
1779 result |= 0x02;
1780 break;
1781 } else {
1782 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001783 "Path B Rx IQK fail!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001784 }
1785 }
1786
1787 /* path B PA off */
1788 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD,
1789 rtlphy->iqk_bb_backup[0]);
1790 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BMASKDWORD,
1791 rtlphy->iqk_bb_backup[2]);
1792 return result;
1793}
1794
1795static void _rtl92d_phy_save_adda_registers(struct ieee80211_hw *hw,
1796 u32 *adda_reg, u32 *adda_backup,
1797 u32 regnum)
1798{
1799 struct rtl_priv *rtlpriv = rtl_priv(hw);
1800 u32 i;
1801
Joe Perches4c488692012-01-04 19:40:42 -08001802 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Save ADDA parameters.\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001803 for (i = 0; i < regnum; i++)
1804 adda_backup[i] = rtl_get_bbreg(hw, adda_reg[i], BMASKDWORD);
1805}
1806
1807static void _rtl92d_phy_save_mac_registers(struct ieee80211_hw *hw,
1808 u32 *macreg, u32 *macbackup)
1809{
1810 struct rtl_priv *rtlpriv = rtl_priv(hw);
1811 u32 i;
1812
Joe Perches4c488692012-01-04 19:40:42 -08001813 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Save MAC parameters.\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001814 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1815 macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
1816 macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
1817}
1818
1819static void _rtl92d_phy_reload_adda_registers(struct ieee80211_hw *hw,
1820 u32 *adda_reg, u32 *adda_backup,
1821 u32 regnum)
1822{
1823 struct rtl_priv *rtlpriv = rtl_priv(hw);
1824 u32 i;
1825
1826 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001827 "Reload ADDA power saving parameters !\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001828 for (i = 0; i < regnum; i++)
1829 rtl_set_bbreg(hw, adda_reg[i], BMASKDWORD, adda_backup[i]);
1830}
1831
1832static void _rtl92d_phy_reload_mac_registers(struct ieee80211_hw *hw,
1833 u32 *macreg, u32 *macbackup)
1834{
1835 struct rtl_priv *rtlpriv = rtl_priv(hw);
1836 u32 i;
1837
Joe Perches4c488692012-01-04 19:40:42 -08001838 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Reload MAC parameters !\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001839 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1840 rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]);
1841 rtl_write_byte(rtlpriv, macreg[i], macbackup[i]);
1842}
1843
1844static void _rtl92d_phy_path_adda_on(struct ieee80211_hw *hw,
1845 u32 *adda_reg, bool patha_on, bool is2t)
1846{
1847 struct rtl_priv *rtlpriv = rtl_priv(hw);
1848 u32 pathon;
1849 u32 i;
1850
Joe Perches4c488692012-01-04 19:40:42 -08001851 RTPRINT(rtlpriv, FINIT, INIT_IQK, "ADDA ON.\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001852 pathon = patha_on ? 0x04db25a4 : 0x0b1b25a4;
1853 if (patha_on)
1854 pathon = rtlpriv->rtlhal.interfaceindex == 0 ?
1855 0x04db25a4 : 0x0b1b25a4;
1856 for (i = 0; i < IQK_ADDA_REG_NUM; i++)
1857 rtl_set_bbreg(hw, adda_reg[i], BMASKDWORD, pathon);
1858}
1859
1860static void _rtl92d_phy_mac_setting_calibration(struct ieee80211_hw *hw,
1861 u32 *macreg, u32 *macbackup)
1862{
1863 struct rtl_priv *rtlpriv = rtl_priv(hw);
1864 u32 i;
1865
Joe Perches4c488692012-01-04 19:40:42 -08001866 RTPRINT(rtlpriv, FINIT, INIT_IQK, "MAC settings for Calibration.\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001867 rtl_write_byte(rtlpriv, macreg[0], 0x3F);
1868
1869 for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
1870 rtl_write_byte(rtlpriv, macreg[i], (u8)(macbackup[i] &
1871 (~BIT(3))));
1872 rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5))));
1873}
1874
1875static void _rtl92d_phy_patha_standby(struct ieee80211_hw *hw)
1876{
1877 struct rtl_priv *rtlpriv = rtl_priv(hw);
Joe Perches4c488692012-01-04 19:40:42 -08001878 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A standby mode!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001879
1880 rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x0);
1881 rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, BMASKDWORD, 0x00010000);
1882 rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000);
1883}
1884
1885static void _rtl92d_phy_pimode_switch(struct ieee80211_hw *hw, bool pi_mode)
1886{
1887 struct rtl_priv *rtlpriv = rtl_priv(hw);
1888 u32 mode;
1889
1890 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001891 "BB Switch to %s mode!\n", pi_mode ? "PI" : "SI");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001892 mode = pi_mode ? 0x01000100 : 0x01000000;
1893 rtl_set_bbreg(hw, 0x820, BMASKDWORD, mode);
1894 rtl_set_bbreg(hw, 0x828, BMASKDWORD, mode);
1895}
1896
1897static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
1898 u8 t, bool is2t)
1899{
1900 struct rtl_priv *rtlpriv = rtl_priv(hw);
1901 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1902 u32 i;
1903 u8 patha_ok, pathb_ok;
1904 static u32 adda_reg[IQK_ADDA_REG_NUM] = {
1905 RFPGA0_XCD_SWITCHCONTROL, 0xe6c, 0xe70, 0xe74,
1906 0xe78, 0xe7c, 0xe80, 0xe84,
1907 0xe88, 0xe8c, 0xed0, 0xed4,
1908 0xed8, 0xedc, 0xee0, 0xeec
1909 };
1910 static u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1911 0x522, 0x550, 0x551, 0x040
1912 };
1913 static u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
1914 RFPGA0_XAB_RFINTERFACESW, RFPGA0_XA_RFINTERFACEOE,
1915 RFPGA0_XB_RFINTERFACEOE, ROFDM0_TRMUXPAR,
1916 RFPGA0_XCD_RFINTERFACESW, ROFDM0_TRXPATHENABLE,
1917 RFPGA0_RFMOD, RFPGA0_ANALOGPARAMETER4,
1918 ROFDM0_XAAGCCORE1, ROFDM0_XBAGCCORE1
1919 };
1920 const u32 retrycount = 2;
1921 u32 bbvalue;
1922
Joe Perches4c488692012-01-04 19:40:42 -08001923 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK for 2.4G :Start!!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001924 if (t == 0) {
1925 bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001926 RTPRINT(rtlpriv, FINIT, INIT_IQK, "==>0x%08x\n", bbvalue);
1927 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n",
1928 is2t ? "2T2R" : "1T1R");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001929
1930 /* Save ADDA parameters, turn Path A ADDA on */
1931 _rtl92d_phy_save_adda_registers(hw, adda_reg,
1932 rtlphy->adda_backup, IQK_ADDA_REG_NUM);
1933 _rtl92d_phy_save_mac_registers(hw, iqk_mac_reg,
1934 rtlphy->iqk_mac_backup);
1935 _rtl92d_phy_save_adda_registers(hw, iqk_bb_reg,
1936 rtlphy->iqk_bb_backup, IQK_BB_REG_NUM);
1937 }
1938 _rtl92d_phy_path_adda_on(hw, adda_reg, true, is2t);
1939 if (t == 0)
1940 rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
1941 RFPGA0_XA_HSSIPARAMETER1, BIT(8));
1942
1943 /* Switch BB to PI mode to do IQ Calibration. */
1944 if (!rtlphy->rfpi_enable)
1945 _rtl92d_phy_pimode_switch(hw, true);
1946
1947 rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00);
1948 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKDWORD, 0x03a05600);
1949 rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, BMASKDWORD, 0x000800e4);
1950 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, BMASKDWORD, 0x22204000);
1951 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xf00000, 0x0f);
1952 if (is2t) {
1953 rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, BMASKDWORD,
1954 0x00010000);
1955 rtl_set_bbreg(hw, RFPGA0_XB_LSSIPARAMETER, BMASKDWORD,
1956 0x00010000);
1957 }
1958 /* MAC settings */
1959 _rtl92d_phy_mac_setting_calibration(hw, iqk_mac_reg,
1960 rtlphy->iqk_mac_backup);
1961 /* Page B init */
1962 rtl_set_bbreg(hw, 0xb68, BMASKDWORD, 0x0f600000);
1963 if (is2t)
1964 rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000);
1965 /* IQ calibration setting */
Joe Perches4c488692012-01-04 19:40:42 -08001966 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK setting!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001967 rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000);
1968 rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x01007c00);
1969 rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800);
1970 for (i = 0; i < retrycount; i++) {
1971 patha_ok = _rtl92d_phy_patha_iqk(hw, is2t);
1972 if (patha_ok == 0x03) {
1973 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001974 "Path A IQK Success!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001975 result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) &
1976 0x3FF0000) >> 16;
1977 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) &
1978 0x3FF0000) >> 16;
1979 result[t][2] = (rtl_get_bbreg(hw, 0xea4, BMASKDWORD) &
1980 0x3FF0000) >> 16;
1981 result[t][3] = (rtl_get_bbreg(hw, 0xeac, BMASKDWORD) &
1982 0x3FF0000) >> 16;
1983 break;
1984 } else if (i == (retrycount - 1) && patha_ok == 0x01) {
1985 /* Tx IQK OK */
1986 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001987 "Path A IQK Only Tx Success!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001988
1989 result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) &
1990 0x3FF0000) >> 16;
1991 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) &
1992 0x3FF0000) >> 16;
1993 }
1994 }
1995 if (0x00 == patha_ok)
Joe Perches4c488692012-01-04 19:40:42 -08001996 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK failed!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001997 if (is2t) {
1998 _rtl92d_phy_patha_standby(hw);
1999 /* Turn Path B ADDA on */
2000 _rtl92d_phy_path_adda_on(hw, adda_reg, false, is2t);
2001 for (i = 0; i < retrycount; i++) {
2002 pathb_ok = _rtl92d_phy_pathb_iqk(hw);
2003 if (pathb_ok == 0x03) {
2004 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002005 "Path B IQK Success!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002006 result[t][4] = (rtl_get_bbreg(hw, 0xeb4,
2007 BMASKDWORD) & 0x3FF0000) >> 16;
2008 result[t][5] = (rtl_get_bbreg(hw, 0xebc,
2009 BMASKDWORD) & 0x3FF0000) >> 16;
2010 result[t][6] = (rtl_get_bbreg(hw, 0xec4,
2011 BMASKDWORD) & 0x3FF0000) >> 16;
2012 result[t][7] = (rtl_get_bbreg(hw, 0xecc,
2013 BMASKDWORD) & 0x3FF0000) >> 16;
2014 break;
2015 } else if (i == (retrycount - 1) && pathb_ok == 0x01) {
2016 /* Tx IQK OK */
2017 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002018 "Path B Only Tx IQK Success!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002019 result[t][4] = (rtl_get_bbreg(hw, 0xeb4,
2020 BMASKDWORD) & 0x3FF0000) >> 16;
2021 result[t][5] = (rtl_get_bbreg(hw, 0xebc,
2022 BMASKDWORD) & 0x3FF0000) >> 16;
2023 }
2024 }
2025 if (0x00 == pathb_ok)
2026 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002027 "Path B IQK failed!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002028 }
2029
2030 /* Back to BB mode, load original value */
2031 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002032 "IQK:Back to BB mode, load original value!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002033
2034 rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0);
2035 if (t != 0) {
2036 /* Switch back BB to SI mode after finish IQ Calibration. */
2037 if (!rtlphy->rfpi_enable)
2038 _rtl92d_phy_pimode_switch(hw, false);
2039 /* Reload ADDA power saving parameters */
2040 _rtl92d_phy_reload_adda_registers(hw, adda_reg,
2041 rtlphy->adda_backup, IQK_ADDA_REG_NUM);
2042 /* Reload MAC parameters */
2043 _rtl92d_phy_reload_mac_registers(hw, iqk_mac_reg,
2044 rtlphy->iqk_mac_backup);
2045 if (is2t)
2046 _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg,
2047 rtlphy->iqk_bb_backup,
2048 IQK_BB_REG_NUM);
2049 else
2050 _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg,
2051 rtlphy->iqk_bb_backup,
2052 IQK_BB_REG_NUM - 1);
2053 /* load 0xe30 IQC default value */
2054 rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x01008c00);
2055 rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x01008c00);
2056 }
Joe Perches4c488692012-01-04 19:40:42 -08002057 RTPRINT(rtlpriv, FINIT, INIT_IQK, "<==\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002058}
2059
2060static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
2061 long result[][8], u8 t)
2062{
2063 struct rtl_priv *rtlpriv = rtl_priv(hw);
2064 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2065 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
2066 u8 patha_ok, pathb_ok;
2067 static u32 adda_reg[IQK_ADDA_REG_NUM] = {
2068 RFPGA0_XCD_SWITCHCONTROL, 0xe6c, 0xe70, 0xe74,
2069 0xe78, 0xe7c, 0xe80, 0xe84,
2070 0xe88, 0xe8c, 0xed0, 0xed4,
2071 0xed8, 0xedc, 0xee0, 0xeec
2072 };
2073 static u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
2074 0x522, 0x550, 0x551, 0x040
2075 };
2076 static u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
2077 RFPGA0_XAB_RFINTERFACESW, RFPGA0_XA_RFINTERFACEOE,
2078 RFPGA0_XB_RFINTERFACEOE, ROFDM0_TRMUXPAR,
2079 RFPGA0_XCD_RFINTERFACESW, ROFDM0_TRXPATHENABLE,
2080 RFPGA0_RFMOD, RFPGA0_ANALOGPARAMETER4,
2081 ROFDM0_XAAGCCORE1, ROFDM0_XBAGCCORE1
2082 };
2083 u32 bbvalue;
2084 bool is2t = IS_92D_SINGLEPHY(rtlhal->version);
2085
2086 /* Note: IQ calibration must be performed after loading
2087 * PHY_REG.txt , and radio_a, radio_b.txt */
2088
Joe Perches4c488692012-01-04 19:40:42 -08002089 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK for 5G NORMAL:Start!!!\n");
Andrew Mortonfaeef8a2011-06-30 16:28:50 -05002090 mdelay(IQK_DELAY_TIME * 20);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002091 if (t == 0) {
2092 bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08002093 RTPRINT(rtlpriv, FINIT, INIT_IQK, "==>0x%08x\n", bbvalue);
2094 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n",
2095 is2t ? "2T2R" : "1T1R");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002096 /* Save ADDA parameters, turn Path A ADDA on */
2097 _rtl92d_phy_save_adda_registers(hw, adda_reg,
2098 rtlphy->adda_backup,
2099 IQK_ADDA_REG_NUM);
2100 _rtl92d_phy_save_mac_registers(hw, iqk_mac_reg,
2101 rtlphy->iqk_mac_backup);
2102 if (is2t)
2103 _rtl92d_phy_save_adda_registers(hw, iqk_bb_reg,
2104 rtlphy->iqk_bb_backup,
2105 IQK_BB_REG_NUM);
2106 else
2107 _rtl92d_phy_save_adda_registers(hw, iqk_bb_reg,
2108 rtlphy->iqk_bb_backup,
2109 IQK_BB_REG_NUM - 1);
2110 }
2111 _rtl92d_phy_path_adda_on(hw, adda_reg, true, is2t);
2112 /* MAC settings */
2113 _rtl92d_phy_mac_setting_calibration(hw, iqk_mac_reg,
2114 rtlphy->iqk_mac_backup);
2115 if (t == 0)
2116 rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
2117 RFPGA0_XA_HSSIPARAMETER1, BIT(8));
2118 /* Switch BB to PI mode to do IQ Calibration. */
2119 if (!rtlphy->rfpi_enable)
2120 _rtl92d_phy_pimode_switch(hw, true);
2121 rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00);
2122 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKDWORD, 0x03a05600);
2123 rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, BMASKDWORD, 0x000800e4);
2124 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, BMASKDWORD, 0x22208000);
2125 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xf00000, 0x0f);
2126
2127 /* Page B init */
2128 rtl_set_bbreg(hw, 0xb68, BMASKDWORD, 0x0f600000);
2129 if (is2t)
2130 rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000);
2131 /* IQ calibration setting */
Joe Perches4c488692012-01-04 19:40:42 -08002132 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK setting!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002133 rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000);
2134 rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x10007c00);
2135 rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800);
2136 patha_ok = _rtl92d_phy_patha_iqk_5g_normal(hw, is2t);
2137 if (patha_ok == 0x03) {
Joe Perches4c488692012-01-04 19:40:42 -08002138 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK Success!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002139 result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) &
2140 0x3FF0000) >> 16;
2141 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) &
2142 0x3FF0000) >> 16;
2143 result[t][2] = (rtl_get_bbreg(hw, 0xea4, BMASKDWORD) &
2144 0x3FF0000) >> 16;
2145 result[t][3] = (rtl_get_bbreg(hw, 0xeac, BMASKDWORD) &
2146 0x3FF0000) >> 16;
2147 } else if (patha_ok == 0x01) { /* Tx IQK OK */
2148 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002149 "Path A IQK Only Tx Success!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002150
2151 result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) &
2152 0x3FF0000) >> 16;
2153 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) &
2154 0x3FF0000) >> 16;
2155 } else {
Joe Perches4c488692012-01-04 19:40:42 -08002156 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK Fail!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002157 }
2158 if (is2t) {
2159 /* _rtl92d_phy_patha_standby(hw); */
2160 /* Turn Path B ADDA on */
2161 _rtl92d_phy_path_adda_on(hw, adda_reg, false, is2t);
2162 pathb_ok = _rtl92d_phy_pathb_iqk_5g_normal(hw);
2163 if (pathb_ok == 0x03) {
2164 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002165 "Path B IQK Success!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002166 result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) &
2167 0x3FF0000) >> 16;
2168 result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) &
2169 0x3FF0000) >> 16;
2170 result[t][6] = (rtl_get_bbreg(hw, 0xec4, BMASKDWORD) &
2171 0x3FF0000) >> 16;
2172 result[t][7] = (rtl_get_bbreg(hw, 0xecc, BMASKDWORD) &
2173 0x3FF0000) >> 16;
2174 } else if (pathb_ok == 0x01) { /* Tx IQK OK */
2175 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002176 "Path B Only Tx IQK Success!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002177 result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) &
2178 0x3FF0000) >> 16;
2179 result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) &
2180 0x3FF0000) >> 16;
2181 } else {
2182 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002183 "Path B IQK failed!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002184 }
2185 }
2186
2187 /* Back to BB mode, load original value */
2188 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002189 "IQK:Back to BB mode, load original value!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002190 rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0);
2191 if (t != 0) {
2192 if (is2t)
2193 _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg,
2194 rtlphy->iqk_bb_backup,
2195 IQK_BB_REG_NUM);
2196 else
2197 _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg,
2198 rtlphy->iqk_bb_backup,
2199 IQK_BB_REG_NUM - 1);
2200 /* Reload MAC parameters */
2201 _rtl92d_phy_reload_mac_registers(hw, iqk_mac_reg,
2202 rtlphy->iqk_mac_backup);
2203 /* Switch back BB to SI mode after finish IQ Calibration. */
2204 if (!rtlphy->rfpi_enable)
2205 _rtl92d_phy_pimode_switch(hw, false);
2206 /* Reload ADDA power saving parameters */
2207 _rtl92d_phy_reload_adda_registers(hw, adda_reg,
2208 rtlphy->adda_backup,
2209 IQK_ADDA_REG_NUM);
2210 }
Joe Perches4c488692012-01-04 19:40:42 -08002211 RTPRINT(rtlpriv, FINIT, INIT_IQK, "<==\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002212}
2213
2214static bool _rtl92d_phy_simularity_compare(struct ieee80211_hw *hw,
2215 long result[][8], u8 c1, u8 c2)
2216{
2217 struct rtl_priv *rtlpriv = rtl_priv(hw);
2218 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
2219 u32 i, j, diff, sim_bitmap, bound;
2220 u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */
2221 bool bresult = true;
2222 bool is2t = IS_92D_SINGLEPHY(rtlhal->version);
2223
2224 if (is2t)
2225 bound = 8;
2226 else
2227 bound = 4;
2228 sim_bitmap = 0;
2229 for (i = 0; i < bound; i++) {
2230 diff = (result[c1][i] > result[c2][i]) ? (result[c1][i] -
2231 result[c2][i]) : (result[c2][i] - result[c1][i]);
2232 if (diff > MAX_TOLERANCE_92D) {
2233 if ((i == 2 || i == 6) && !sim_bitmap) {
2234 if (result[c1][i] + result[c1][i + 1] == 0)
2235 final_candidate[(i / 4)] = c2;
2236 else if (result[c2][i] + result[c2][i + 1] == 0)
2237 final_candidate[(i / 4)] = c1;
2238 else
2239 sim_bitmap = sim_bitmap | (1 << i);
2240 } else {
2241 sim_bitmap = sim_bitmap | (1 << i);
2242 }
2243 }
2244 }
2245 if (sim_bitmap == 0) {
2246 for (i = 0; i < (bound / 4); i++) {
2247 if (final_candidate[i] != 0xFF) {
2248 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
2249 result[3][j] =
2250 result[final_candidate[i]][j];
2251 bresult = false;
2252 }
2253 }
2254 return bresult;
2255 }
2256 if (!(sim_bitmap & 0x0F)) { /* path A OK */
2257 for (i = 0; i < 4; i++)
2258 result[3][i] = result[c1][i];
2259 } else if (!(sim_bitmap & 0x03)) { /* path A, Tx OK */
2260 for (i = 0; i < 2; i++)
2261 result[3][i] = result[c1][i];
2262 }
2263 if (!(sim_bitmap & 0xF0) && is2t) { /* path B OK */
2264 for (i = 4; i < 8; i++)
2265 result[3][i] = result[c1][i];
2266 } else if (!(sim_bitmap & 0x30)) { /* path B, Tx OK */
2267 for (i = 4; i < 6; i++)
2268 result[3][i] = result[c1][i];
2269 }
2270 return false;
2271}
2272
2273static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw,
2274 bool iqk_ok, long result[][8],
2275 u8 final_candidate, bool txonly)
2276{
2277 struct rtl_priv *rtlpriv = rtl_priv(hw);
2278 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
2279 u32 oldval_0, val_x, tx0_a, reg;
2280 long val_y, tx0_c;
2281 bool is2t = IS_92D_SINGLEPHY(rtlhal->version) ||
2282 rtlhal->macphymode == DUALMAC_DUALPHY;
2283
2284 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002285 "Path A IQ Calibration %s !\n", iqk_ok ? "Success" : "Failed");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002286 if (final_candidate == 0xFF) {
2287 return;
2288 } else if (iqk_ok) {
2289 oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE,
2290 BMASKDWORD) >> 22) & 0x3FF; /* OFDM0_D */
2291 val_x = result[final_candidate][0];
2292 if ((val_x & 0x00000200) != 0)
2293 val_x = val_x | 0xFFFFFC00;
2294 tx0_a = (val_x * oldval_0) >> 8;
Joe Perches4c488692012-01-04 19:40:42 -08002295 RTPRINT(rtlpriv, FINIT, INIT_IQK,
2296 "X = 0x%x, tx0_a = 0x%x, oldval_0 0x%x\n",
2297 val_x, tx0_a, oldval_0);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002298 rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 0x3FF, tx0_a);
2299 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24),
2300 ((val_x * oldval_0 >> 7) & 0x1));
2301 val_y = result[final_candidate][1];
2302 if ((val_y & 0x00000200) != 0)
2303 val_y = val_y | 0xFFFFFC00;
2304 /* path B IQK result + 3 */
2305 if (rtlhal->interfaceindex == 1 &&
2306 rtlhal->current_bandtype == BAND_ON_5G)
2307 val_y += 3;
2308 tx0_c = (val_y * oldval_0) >> 8;
Joe Perches4c488692012-01-04 19:40:42 -08002309 RTPRINT(rtlpriv, FINIT, INIT_IQK,
2310 "Y = 0x%lx, tx0_c = 0x%lx\n",
2311 val_y, tx0_c);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002312 rtl_set_bbreg(hw, ROFDM0_XCTxAFE, 0xF0000000,
2313 ((tx0_c & 0x3C0) >> 6));
2314 rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 0x003F0000,
2315 (tx0_c & 0x3F));
2316 if (is2t)
2317 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(26),
2318 ((val_y * oldval_0 >> 7) & 0x1));
Joe Perches4c488692012-01-04 19:40:42 -08002319 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xC80 = 0x%x\n",
2320 rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE,
2321 BMASKDWORD));
Chaoming Li7274a8c2011-06-10 15:10:25 -05002322 if (txonly) {
Joe Perches4c488692012-01-04 19:40:42 -08002323 RTPRINT(rtlpriv, FINIT, INIT_IQK, "only Tx OK\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002324 return;
2325 }
2326 reg = result[final_candidate][2];
2327 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
2328 reg = result[final_candidate][3] & 0x3F;
2329 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
2330 reg = (result[final_candidate][3] >> 6) & 0xF;
2331 rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg);
2332 }
2333}
2334
2335static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw,
2336 bool iqk_ok, long result[][8], u8 final_candidate, bool txonly)
2337{
2338 struct rtl_priv *rtlpriv = rtl_priv(hw);
2339 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
2340 u32 oldval_1, val_x, tx1_a, reg;
2341 long val_y, tx1_c;
2342
Joe Perches4c488692012-01-04 19:40:42 -08002343 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQ Calibration %s !\n",
2344 iqk_ok ? "Success" : "Failed");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002345 if (final_candidate == 0xFF) {
2346 return;
2347 } else if (iqk_ok) {
2348 oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTxIQIMBALANCE,
2349 BMASKDWORD) >> 22) & 0x3FF;
2350 val_x = result[final_candidate][4];
2351 if ((val_x & 0x00000200) != 0)
2352 val_x = val_x | 0xFFFFFC00;
2353 tx1_a = (val_x * oldval_1) >> 8;
Joe Perches4c488692012-01-04 19:40:42 -08002354 RTPRINT(rtlpriv, FINIT, INIT_IQK, "X = 0x%x, tx1_a = 0x%x\n",
2355 val_x, tx1_a);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002356 rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, 0x3FF, tx1_a);
2357 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28),
2358 ((val_x * oldval_1 >> 7) & 0x1));
2359 val_y = result[final_candidate][5];
2360 if ((val_y & 0x00000200) != 0)
2361 val_y = val_y | 0xFFFFFC00;
2362 if (rtlhal->current_bandtype == BAND_ON_5G)
2363 val_y += 3;
2364 tx1_c = (val_y * oldval_1) >> 8;
Joe Perches4c488692012-01-04 19:40:42 -08002365 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Y = 0x%lx, tx1_c = 0x%lx\n",
2366 val_y, tx1_c);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002367 rtl_set_bbreg(hw, ROFDM0_XDTxAFE, 0xF0000000,
2368 ((tx1_c & 0x3C0) >> 6));
2369 rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, 0x003F0000,
2370 (tx1_c & 0x3F));
2371 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(30),
2372 ((val_y * oldval_1 >> 7) & 0x1));
2373 if (txonly)
2374 return;
2375 reg = result[final_candidate][6];
2376 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
2377 reg = result[final_candidate][7] & 0x3F;
2378 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
2379 reg = (result[final_candidate][7] >> 6) & 0xF;
2380 rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg);
2381 }
2382}
2383
2384void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw)
2385{
2386 struct rtl_priv *rtlpriv = rtl_priv(hw);
2387 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2388 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
2389 long result[4][8];
2390 u8 i, final_candidate, indexforchannel;
2391 bool patha_ok, pathb_ok;
2392 long rege94, rege9c, regea4, regeac, regeb4;
2393 long regebc, regec4, regecc, regtmp = 0;
2394 bool is12simular, is13simular, is23simular;
2395 unsigned long flag = 0;
2396
2397 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002398 "IQK:Start!!!channel %d\n", rtlphy->current_channel);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002399 for (i = 0; i < 8; i++) {
2400 result[0][i] = 0;
2401 result[1][i] = 0;
2402 result[2][i] = 0;
2403 result[3][i] = 0;
2404 }
2405 final_candidate = 0xff;
2406 patha_ok = false;
2407 pathb_ok = false;
2408 is12simular = false;
2409 is23simular = false;
2410 is13simular = false;
2411 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002412 "IQK !!!currentband %d\n", rtlhal->current_bandtype);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002413 rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
2414 for (i = 0; i < 3; i++) {
2415 if (rtlhal->current_bandtype == BAND_ON_5G) {
2416 _rtl92d_phy_iq_calibrate_5g_normal(hw, result, i);
2417 } else if (rtlhal->current_bandtype == BAND_ON_2_4G) {
2418 if (IS_92D_SINGLEPHY(rtlhal->version))
2419 _rtl92d_phy_iq_calibrate(hw, result, i, true);
2420 else
2421 _rtl92d_phy_iq_calibrate(hw, result, i, false);
2422 }
2423 if (i == 1) {
2424 is12simular = _rtl92d_phy_simularity_compare(hw, result,
2425 0, 1);
2426 if (is12simular) {
2427 final_candidate = 0;
2428 break;
2429 }
2430 }
2431 if (i == 2) {
2432 is13simular = _rtl92d_phy_simularity_compare(hw, result,
2433 0, 2);
2434 if (is13simular) {
2435 final_candidate = 0;
2436 break;
2437 }
2438 is23simular = _rtl92d_phy_simularity_compare(hw, result,
2439 1, 2);
2440 if (is23simular) {
2441 final_candidate = 1;
2442 } else {
2443 for (i = 0; i < 8; i++)
2444 regtmp += result[3][i];
2445
2446 if (regtmp != 0)
2447 final_candidate = 3;
2448 else
2449 final_candidate = 0xFF;
2450 }
2451 }
2452 }
2453 rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
2454 for (i = 0; i < 4; i++) {
2455 rege94 = result[i][0];
2456 rege9c = result[i][1];
2457 regea4 = result[i][2];
2458 regeac = result[i][3];
2459 regeb4 = result[i][4];
2460 regebc = result[i][5];
2461 regec4 = result[i][6];
2462 regecc = result[i][7];
2463 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002464 "IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -05002465 rege94, rege9c, regea4, regeac, regeb4, regebc, regec4,
Joe Perches4c488692012-01-04 19:40:42 -08002466 regecc);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002467 }
2468 if (final_candidate != 0xff) {
2469 rtlphy->reg_e94 = rege94 = result[final_candidate][0];
2470 rtlphy->reg_e9c = rege9c = result[final_candidate][1];
2471 regea4 = result[final_candidate][2];
2472 regeac = result[final_candidate][3];
2473 rtlphy->reg_eb4 = regeb4 = result[final_candidate][4];
2474 rtlphy->reg_ebc = regebc = result[final_candidate][5];
2475 regec4 = result[final_candidate][6];
2476 regecc = result[final_candidate][7];
2477 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002478 "IQK: final_candidate is %x\n", final_candidate);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002479 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002480 "IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -05002481 rege94, rege9c, regea4, regeac, regeb4, regebc, regec4,
Joe Perches4c488692012-01-04 19:40:42 -08002482 regecc);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002483 patha_ok = pathb_ok = true;
2484 } else {
2485 rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; /* X default value */
2486 rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; /* Y default value */
2487 }
2488 if ((rege94 != 0) /*&&(regea4 != 0) */)
2489 _rtl92d_phy_patha_fill_iqk_matrix(hw, patha_ok, result,
2490 final_candidate, (regea4 == 0));
2491 if (IS_92D_SINGLEPHY(rtlhal->version)) {
2492 if ((regeb4 != 0) /*&&(regec4 != 0) */)
2493 _rtl92d_phy_pathb_fill_iqk_matrix(hw, pathb_ok, result,
2494 final_candidate, (regec4 == 0));
2495 }
2496 if (final_candidate != 0xFF) {
2497 indexforchannel = rtl92d_get_rightchnlplace_for_iqk(
2498 rtlphy->current_channel);
2499
2500 for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
2501 rtlphy->iqk_matrix_regsetting[indexforchannel].
2502 value[0][i] = result[final_candidate][i];
2503 rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done =
2504 true;
2505
2506 RT_TRACE(rtlpriv, COMP_SCAN | COMP_MLME, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08002507 "IQK OK indexforchannel %d\n", indexforchannel);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002508 }
2509}
2510
2511void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel)
2512{
2513 struct rtl_priv *rtlpriv = rtl_priv(hw);
2514 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2515 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
2516 u8 indexforchannel;
2517
Joe Perchesf30d7502012-01-04 19:40:41 -08002518 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "channel %d\n", channel);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002519 /*------Do IQK for normal chip and test chip 5G band------- */
2520 indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel);
Joe Perchesf30d7502012-01-04 19:40:41 -08002521 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "indexforchannel %d done %d\n",
2522 indexforchannel,
2523 rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002524 if (0 && !rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done &&
2525 rtlphy->need_iqk) {
2526 /* Re Do IQK. */
2527 RT_TRACE(rtlpriv, COMP_SCAN | COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08002528 "Do IQK Matrix reg for channel:%d....\n", channel);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002529 rtl92d_phy_iq_calibrate(hw);
2530 } else {
2531 /* Just load the value. */
2532 /* 2G band just load once. */
2533 if (((!rtlhal->load_imrandiqk_setting_for2g) &&
2534 indexforchannel == 0) || indexforchannel > 0) {
2535 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08002536 "Just Read IQK Matrix reg for channel:%d....\n",
2537 channel);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002538 if ((rtlphy->iqk_matrix_regsetting[indexforchannel].
2539 value[0] != NULL)
2540 /*&&(regea4 != 0) */)
2541 _rtl92d_phy_patha_fill_iqk_matrix(hw, true,
2542 rtlphy->iqk_matrix_regsetting[
2543 indexforchannel].value, 0,
2544 (rtlphy->iqk_matrix_regsetting[
2545 indexforchannel].value[0][2] == 0));
2546 if (IS_92D_SINGLEPHY(rtlhal->version)) {
2547 if ((rtlphy->iqk_matrix_regsetting[
2548 indexforchannel].value[0][4] != 0)
2549 /*&&(regec4 != 0) */)
2550 _rtl92d_phy_pathb_fill_iqk_matrix(hw,
2551 true,
2552 rtlphy->iqk_matrix_regsetting[
2553 indexforchannel].value, 0,
2554 (rtlphy->iqk_matrix_regsetting[
2555 indexforchannel].value[0][6]
2556 == 0));
2557 }
2558 }
2559 }
2560 rtlphy->need_iqk = false;
Joe Perchesf30d7502012-01-04 19:40:41 -08002561 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002562}
2563
2564static u32 _rtl92d_phy_get_abs(u32 val1, u32 val2)
2565{
2566 u32 ret;
2567
2568 if (val1 >= val2)
2569 ret = val1 - val2;
2570 else
2571 ret = val2 - val1;
2572 return ret;
2573}
2574
2575static bool _rtl92d_is_legal_5g_channel(struct ieee80211_hw *hw, u8 channel)
2576{
2577
2578 int i;
2579 u8 channel_5g[45] = {
2580 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
2581 60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
2582 114, 116, 118, 120, 122, 124, 126, 128, 130, 132,
2583 134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
2584 161, 163, 165
2585 };
2586
2587 for (i = 0; i < sizeof(channel_5g); i++)
2588 if (channel == channel_5g[i])
2589 return true;
2590 return false;
2591}
2592
2593static void _rtl92d_phy_calc_curvindex(struct ieee80211_hw *hw,
2594 u32 *targetchnl, u32 * curvecount_val,
2595 bool is5g, u32 *curveindex)
2596{
2597 struct rtl_priv *rtlpriv = rtl_priv(hw);
2598 u32 smallest_abs_val = 0xffffffff, u4tmp;
2599 u8 i, j;
2600 u8 chnl_num = is5g ? TARGET_CHNL_NUM_5G : TARGET_CHNL_NUM_2G;
2601
2602 for (i = 0; i < chnl_num; i++) {
2603 if (is5g && !_rtl92d_is_legal_5g_channel(hw, i + 1))
2604 continue;
2605 curveindex[i] = 0;
2606 for (j = 0; j < (CV_CURVE_CNT * 2); j++) {
2607 u4tmp = _rtl92d_phy_get_abs(targetchnl[i],
2608 curvecount_val[j]);
2609
2610 if (u4tmp < smallest_abs_val) {
2611 curveindex[i] = j;
2612 smallest_abs_val = u4tmp;
2613 }
2614 }
2615 smallest_abs_val = 0xffffffff;
Joe Perches4c488692012-01-04 19:40:42 -08002616 RTPRINT(rtlpriv, FINIT, INIT_IQK, "curveindex[%d] = %x\n",
2617 i, curveindex[i]);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002618 }
2619}
2620
2621static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw,
2622 u8 channel)
2623{
2624 struct rtl_priv *rtlpriv = rtl_priv(hw);
2625 u8 erfpath = rtlpriv->rtlhal.current_bandtype ==
2626 BAND_ON_5G ? RF90_PATH_A :
2627 IS_92D_SINGLEPHY(rtlpriv->rtlhal.version) ?
2628 RF90_PATH_B : RF90_PATH_A;
2629 u32 u4tmp = 0, u4regvalue = 0;
2630 bool bneed_powerdown_radio = false;
2631
Joe Perchesf30d7502012-01-04 19:40:41 -08002632 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "path %d\n", erfpath);
Joe Perches4c488692012-01-04 19:40:42 -08002633 RTPRINT(rtlpriv, FINIT, INIT_IQK, "band type = %d\n",
2634 rtlpriv->rtlhal.current_bandtype);
2635 RTPRINT(rtlpriv, FINIT, INIT_IQK, "channel = %d\n", channel);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002636 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {/* Path-A for 5G */
2637 u4tmp = curveindex_5g[channel-1];
2638 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002639 "ver 1 set RF-A, 5G, 0x28 = 0x%ulx !!\n", u4tmp);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002640 if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY &&
2641 rtlpriv->rtlhal.interfaceindex == 1) {
2642 bneed_powerdown_radio =
2643 rtl92d_phy_enable_anotherphy(hw, false);
2644 rtlpriv->rtlhal.during_mac1init_radioa = true;
2645 /* asume no this case */
2646 if (bneed_powerdown_radio)
2647 _rtl92d_phy_enable_rf_env(hw, erfpath,
2648 &u4regvalue);
2649 }
2650 rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp);
2651 if (bneed_powerdown_radio)
2652 _rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue);
2653 if (rtlpriv->rtlhal.during_mac1init_radioa)
2654 rtl92d_phy_powerdown_anotherphy(hw, false);
2655 } else if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) {
2656 u4tmp = curveindex_2g[channel-1];
2657 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002658 "ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", u4tmp);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002659 if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY &&
2660 rtlpriv->rtlhal.interfaceindex == 0) {
2661 bneed_powerdown_radio =
2662 rtl92d_phy_enable_anotherphy(hw, true);
2663 rtlpriv->rtlhal.during_mac0init_radiob = true;
2664 if (bneed_powerdown_radio)
2665 _rtl92d_phy_enable_rf_env(hw, erfpath,
2666 &u4regvalue);
2667 }
2668 rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp);
2669 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002670 "ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n",
2671 rtl_get_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800));
Chaoming Li7274a8c2011-06-10 15:10:25 -05002672 if (bneed_powerdown_radio)
2673 _rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue);
2674 if (rtlpriv->rtlhal.during_mac0init_radiob)
2675 rtl92d_phy_powerdown_anotherphy(hw, true);
2676 }
Joe Perchesf30d7502012-01-04 19:40:41 -08002677 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002678}
2679
2680static void _rtl92d_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t)
2681{
2682 struct rtl_priv *rtlpriv = rtl_priv(hw);
2683 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
2684 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
2685 u8 tmpreg, index, rf_mode[2];
2686 u8 path = is2t ? 2 : 1;
2687 u8 i;
2688 u32 u4tmp, offset;
2689 u32 curvecount_val[CV_CURVE_CNT * 2] = {0};
2690 u16 timeout = 800, timecount = 0;
2691
2692 /* Check continuous TX and Packet TX */
2693 tmpreg = rtl_read_byte(rtlpriv, 0xd03);
2694 /* if Deal with contisuous TX case, disable all continuous TX */
2695 /* if Deal with Packet TX case, block all queues */
2696 if ((tmpreg & 0x70) != 0)
2697 rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
2698 else
2699 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2700 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xF00000, 0x0F);
2701 for (index = 0; index < path; index++) {
2702 /* 1. Read original RF mode */
2703 offset = index == 0 ? ROFDM0_XAAGCCORE1 : ROFDM0_XBAGCCORE1;
2704 rf_mode[index] = rtl_read_byte(rtlpriv, offset);
2705 /* 2. Set RF mode = standby mode */
2706 rtl_set_rfreg(hw, (enum radio_path)index, RF_AC,
2707 BRFREGOFFSETMASK, 0x010000);
2708 if (rtlpci->init_ready) {
2709 /* switch CV-curve control by LC-calibration */
2710 rtl_set_rfreg(hw, (enum radio_path)index, RF_SYN_G7,
2711 BIT(17), 0x0);
2712 /* 4. Set LC calibration begin */
2713 rtl_set_rfreg(hw, (enum radio_path)index, RF_CHNLBW,
2714 0x08000, 0x01);
2715 }
2716 u4tmp = rtl_get_rfreg(hw, (enum radio_path)index, RF_SYN_G6,
2717 BRFREGOFFSETMASK);
2718 while ((!(u4tmp & BIT(11))) && timecount <= timeout) {
2719 mdelay(50);
2720 timecount += 50;
2721 u4tmp = rtl_get_rfreg(hw, (enum radio_path)index,
2722 RF_SYN_G6, BRFREGOFFSETMASK);
2723 }
2724 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002725 "PHY_LCK finish delay for %d ms=2\n", timecount);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002726 u4tmp = rtl_get_rfreg(hw, index, RF_SYN_G4, BRFREGOFFSETMASK);
2727 if (index == 0 && rtlhal->interfaceindex == 0) {
2728 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002729 "path-A / 5G LCK\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002730 } else {
2731 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002732 "path-B / 2.4G LCK\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002733 }
2734 memset(&curvecount_val[0], 0, CV_CURVE_CNT * 2);
2735 /* Set LC calibration off */
2736 rtl_set_rfreg(hw, (enum radio_path)index, RF_CHNLBW,
2737 0x08000, 0x0);
Joe Perches4c488692012-01-04 19:40:42 -08002738 RTPRINT(rtlpriv, FINIT, INIT_IQK, "set RF 0x18[15] = 0\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002739 /* save Curve-counting number */
2740 for (i = 0; i < CV_CURVE_CNT; i++) {
2741 u32 readval = 0, readval2 = 0;
2742 rtl_set_rfreg(hw, (enum radio_path)index, 0x3F,
2743 0x7f, i);
2744
2745 rtl_set_rfreg(hw, (enum radio_path)index, 0x4D,
2746 BRFREGOFFSETMASK, 0x0);
2747 readval = rtl_get_rfreg(hw, (enum radio_path)index,
2748 0x4F, BRFREGOFFSETMASK);
2749 curvecount_val[2 * i + 1] = (readval & 0xfffe0) >> 5;
2750 /* reg 0x4f [4:0] */
2751 /* reg 0x50 [19:10] */
2752 readval2 = rtl_get_rfreg(hw, (enum radio_path)index,
2753 0x50, 0xffc00);
2754 curvecount_val[2 * i] = (((readval & 0x1F) << 10) |
2755 readval2);
2756 }
2757 if (index == 0 && rtlhal->interfaceindex == 0)
2758 _rtl92d_phy_calc_curvindex(hw, targetchnl_5g,
2759 curvecount_val,
2760 true, curveindex_5g);
2761 else
2762 _rtl92d_phy_calc_curvindex(hw, targetchnl_2g,
2763 curvecount_val,
2764 false, curveindex_2g);
2765 /* switch CV-curve control mode */
2766 rtl_set_rfreg(hw, (enum radio_path)index, RF_SYN_G7,
2767 BIT(17), 0x1);
2768 }
2769
2770 /* Restore original situation */
2771 for (index = 0; index < path; index++) {
2772 offset = index == 0 ? ROFDM0_XAAGCCORE1 : ROFDM0_XBAGCCORE1;
2773 rtl_write_byte(rtlpriv, offset, 0x50);
2774 rtl_write_byte(rtlpriv, offset, rf_mode[index]);
2775 }
2776 if ((tmpreg & 0x70) != 0)
2777 rtl_write_byte(rtlpriv, 0xd03, tmpreg);
2778 else /*Deal with Packet TX case */
2779 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2780 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xF00000, 0x00);
2781 _rtl92d_phy_reload_lck_setting(hw, rtlpriv->phy.current_channel);
2782}
2783
2784static void _rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
2785{
2786 struct rtl_priv *rtlpriv = rtl_priv(hw);
2787
Joe Perches4c488692012-01-04 19:40:42 -08002788 RTPRINT(rtlpriv, FINIT, INIT_IQK, "cosa PHY_LCK ver=2\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002789 _rtl92d_phy_lc_calibrate_sw(hw, is2t);
2790}
2791
2792void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw)
2793{
2794 struct rtl_priv *rtlpriv = rtl_priv(hw);
2795 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2796 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
2797 u32 timeout = 2000, timecount = 0;
2798
2799 while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
2800 udelay(50);
2801 timecount += 50;
2802 }
2803
2804 rtlphy->lck_inprogress = true;
2805 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002806 "LCK:Start!!! currentband %x delay %d ms\n",
2807 rtlhal->current_bandtype, timecount);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002808 if (IS_92D_SINGLEPHY(rtlhal->version)) {
2809 _rtl92d_phy_lc_calibrate(hw, true);
2810 } else {
2811 /* For 1T1R */
2812 _rtl92d_phy_lc_calibrate(hw, false);
2813 }
2814 rtlphy->lck_inprogress = false;
Joe Perches4c488692012-01-04 19:40:42 -08002815 RTPRINT(rtlpriv, FINIT, INIT_IQK, "LCK:Finish!!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002816}
2817
2818void rtl92d_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
2819{
2820 return;
2821}
2822
2823static bool _rtl92d_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
2824 u32 cmdtableidx, u32 cmdtablesz, enum swchnlcmd_id cmdid,
2825 u32 para1, u32 para2, u32 msdelay)
2826{
2827 struct swchnlcmd *pcmd;
2828
2829 if (cmdtable == NULL) {
Joe Perches9d833ed2012-01-04 19:40:43 -08002830 RT_ASSERT(false, "cmdtable cannot be NULL\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002831 return false;
2832 }
2833 if (cmdtableidx >= cmdtablesz)
2834 return false;
2835
2836 pcmd = cmdtable + cmdtableidx;
2837 pcmd->cmdid = cmdid;
2838 pcmd->para1 = para1;
2839 pcmd->para2 = para2;
2840 pcmd->msdelay = msdelay;
2841 return true;
2842}
2843
2844void rtl92d_phy_reset_iqk_result(struct ieee80211_hw *hw)
2845{
2846 struct rtl_priv *rtlpriv = rtl_priv(hw);
2847 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2848 u8 i;
2849
2850 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08002851 "settings regs %d default regs %d\n",
2852 (int)(sizeof(rtlphy->iqk_matrix_regsetting) /
2853 sizeof(struct iqk_matrix_regs)),
2854 IQK_MATRIX_REG_NUM);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002855 /* 0xe94, 0xe9c, 0xea4, 0xeac, 0xeb4, 0xebc, 0xec4, 0xecc */
2856 for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
2857 rtlphy->iqk_matrix_regsetting[i].value[0][0] = 0x100;
2858 rtlphy->iqk_matrix_regsetting[i].value[0][2] = 0x100;
2859 rtlphy->iqk_matrix_regsetting[i].value[0][4] = 0x100;
2860 rtlphy->iqk_matrix_regsetting[i].value[0][6] = 0x100;
2861 rtlphy->iqk_matrix_regsetting[i].value[0][1] = 0x0;
2862 rtlphy->iqk_matrix_regsetting[i].value[0][3] = 0x0;
2863 rtlphy->iqk_matrix_regsetting[i].value[0][5] = 0x0;
2864 rtlphy->iqk_matrix_regsetting[i].value[0][7] = 0x0;
2865 rtlphy->iqk_matrix_regsetting[i].iqk_done = false;
2866 }
2867}
2868
2869static bool _rtl92d_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
2870 u8 channel, u8 *stage, u8 *step,
2871 u32 *delay)
2872{
2873 struct rtl_priv *rtlpriv = rtl_priv(hw);
2874 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2875 struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
2876 u32 precommoncmdcnt;
2877 struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
2878 u32 postcommoncmdcnt;
2879 struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
2880 u32 rfdependcmdcnt;
2881 struct swchnlcmd *currentcmd = NULL;
2882 u8 rfpath;
2883 u8 num_total_rfpath = rtlphy->num_total_rfpath;
2884
2885 precommoncmdcnt = 0;
2886 _rtl92d_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
2887 MAX_PRECMD_CNT,
2888 CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
2889 _rtl92d_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
2890 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
2891 postcommoncmdcnt = 0;
2892 _rtl92d_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
2893 MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
2894 rfdependcmdcnt = 0;
2895 _rtl92d_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
2896 MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
2897 RF_CHNLBW, channel, 0);
2898 _rtl92d_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
2899 MAX_RFDEPENDCMD_CNT, CMDID_END,
2900 0, 0, 0);
2901
2902 do {
2903 switch (*stage) {
2904 case 0:
2905 currentcmd = &precommoncmd[*step];
2906 break;
2907 case 1:
2908 currentcmd = &rfdependcmd[*step];
2909 break;
2910 case 2:
2911 currentcmd = &postcommoncmd[*step];
2912 break;
2913 }
2914 if (currentcmd->cmdid == CMDID_END) {
2915 if ((*stage) == 2) {
2916 return true;
2917 } else {
2918 (*stage)++;
2919 (*step) = 0;
2920 continue;
2921 }
2922 }
2923 switch (currentcmd->cmdid) {
2924 case CMDID_SET_TXPOWEROWER_LEVEL:
2925 rtl92d_phy_set_txpower_level(hw, channel);
2926 break;
2927 case CMDID_WRITEPORT_ULONG:
2928 rtl_write_dword(rtlpriv, currentcmd->para1,
2929 currentcmd->para2);
2930 break;
2931 case CMDID_WRITEPORT_USHORT:
2932 rtl_write_word(rtlpriv, currentcmd->para1,
2933 (u16)currentcmd->para2);
2934 break;
2935 case CMDID_WRITEPORT_UCHAR:
2936 rtl_write_byte(rtlpriv, currentcmd->para1,
2937 (u8)currentcmd->para2);
2938 break;
2939 case CMDID_RF_WRITEREG:
2940 for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
2941 rtlphy->rfreg_chnlval[rfpath] =
2942 ((rtlphy->rfreg_chnlval[rfpath] &
2943 0xffffff00) | currentcmd->para2);
2944 if (rtlpriv->rtlhal.current_bandtype ==
2945 BAND_ON_5G) {
2946 if (currentcmd->para2 > 99)
2947 rtlphy->rfreg_chnlval[rfpath] =
2948 rtlphy->rfreg_chnlval
2949 [rfpath] | (BIT(18));
2950 else
2951 rtlphy->rfreg_chnlval[rfpath] =
2952 rtlphy->rfreg_chnlval
2953 [rfpath] & (~BIT(18));
2954 rtlphy->rfreg_chnlval[rfpath] |=
2955 (BIT(16) | BIT(8));
2956 } else {
2957 rtlphy->rfreg_chnlval[rfpath] &=
2958 ~(BIT(8) | BIT(16) | BIT(18));
2959 }
2960 rtl_set_rfreg(hw, (enum radio_path)rfpath,
2961 currentcmd->para1,
2962 BRFREGOFFSETMASK,
2963 rtlphy->rfreg_chnlval[rfpath]);
2964 _rtl92d_phy_reload_imr_setting(hw, channel,
2965 rfpath);
2966 }
2967 _rtl92d_phy_switch_rf_setting(hw, channel);
2968 /* do IQK when all parameters are ready */
2969 rtl92d_phy_reload_iqk_setting(hw, channel);
2970 break;
2971 default:
2972 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -08002973 "switch case not processed\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002974 break;
2975 }
2976 break;
2977 } while (true);
2978 (*delay) = currentcmd->msdelay;
2979 (*step)++;
2980 return false;
2981}
2982
2983u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw)
2984{
2985 struct rtl_priv *rtlpriv = rtl_priv(hw);
2986 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2987 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2988 u32 delay;
2989 u32 timeout = 1000, timecount = 0;
2990 u8 channel = rtlphy->current_channel;
2991 u32 ret_value;
2992
2993 if (rtlphy->sw_chnl_inprogress)
2994 return 0;
2995 if (rtlphy->set_bwmode_inprogress)
2996 return 0;
2997
2998 if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
2999 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08003000 "sw_chnl_inprogress false driver sleep or unload\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003001 return 0;
3002 }
3003 while (rtlphy->lck_inprogress && timecount < timeout) {
3004 mdelay(50);
3005 timecount += 50;
3006 }
3007 if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY &&
3008 rtlhal->bandset == BAND_ON_BOTH) {
3009 ret_value = rtl_get_bbreg(hw, RFPGA0_XAB_RFPARAMETER,
3010 BMASKDWORD);
3011 if (rtlphy->current_channel > 14 && !(ret_value & BIT(0)))
3012 rtl92d_phy_switch_wirelessband(hw, BAND_ON_5G);
3013 else if (rtlphy->current_channel <= 14 && (ret_value & BIT(0)))
3014 rtl92d_phy_switch_wirelessband(hw, BAND_ON_2_4G);
3015 }
3016 switch (rtlhal->current_bandtype) {
3017 case BAND_ON_5G:
3018 /* Get first channel error when change between
3019 * 5G and 2.4G band. */
3020 if (channel <= 14)
3021 return 0;
Joe Perches9d833ed2012-01-04 19:40:43 -08003022 RT_ASSERT((channel > 14), "5G but channel<=14\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003023 break;
3024 case BAND_ON_2_4G:
3025 /* Get first channel error when change between
3026 * 5G and 2.4G band. */
3027 if (channel > 14)
3028 return 0;
Joe Perches9d833ed2012-01-04 19:40:43 -08003029 RT_ASSERT((channel <= 14), "2G but channel>14\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003030 break;
3031 default:
Joe Perches9d833ed2012-01-04 19:40:43 -08003032 RT_ASSERT(false, "Invalid WirelessMode(%#x)!!\n",
3033 rtlpriv->mac80211.mode);
Chaoming Li7274a8c2011-06-10 15:10:25 -05003034 break;
3035 }
3036 rtlphy->sw_chnl_inprogress = true;
3037 if (channel == 0)
3038 channel = 1;
3039 rtlphy->sw_chnl_stage = 0;
3040 rtlphy->sw_chnl_step = 0;
3041 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -08003042 "switch to channel%d\n", rtlphy->current_channel);
Chaoming Li7274a8c2011-06-10 15:10:25 -05003043
3044 do {
3045 if (!rtlphy->sw_chnl_inprogress)
3046 break;
3047 if (!_rtl92d_phy_sw_chnl_step_by_step(hw,
3048 rtlphy->current_channel,
3049 &rtlphy->sw_chnl_stage, &rtlphy->sw_chnl_step, &delay)) {
3050 if (delay > 0)
3051 mdelay(delay);
3052 else
3053 continue;
3054 } else {
3055 rtlphy->sw_chnl_inprogress = false;
3056 }
3057 break;
3058 } while (true);
Joe Perchesf30d7502012-01-04 19:40:41 -08003059 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003060 rtlphy->sw_chnl_inprogress = false;
3061 return 1;
3062}
3063
3064static void rtl92d_phy_set_io(struct ieee80211_hw *hw)
3065{
3066 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Fingerc21916e2012-04-19 16:32:43 -05003067 struct dig_t *de_digtable = &rtlpriv->dm_digtable;
Chaoming Li7274a8c2011-06-10 15:10:25 -05003068 struct rtl_phy *rtlphy = &(rtlpriv->phy);
3069
3070 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -08003071 "--->Cmd(%#x), set_io_inprogress(%d)\n",
3072 rtlphy->current_io_type, rtlphy->set_io_inprogress);
Chaoming Li7274a8c2011-06-10 15:10:25 -05003073 switch (rtlphy->current_io_type) {
3074 case IO_CMD_RESUME_DM_BY_SCAN:
Larry Fingerc21916e2012-04-19 16:32:43 -05003075 de_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;
Chaoming Li7274a8c2011-06-10 15:10:25 -05003076 rtl92d_dm_write_dig(hw);
3077 rtl92d_phy_set_txpower_level(hw, rtlphy->current_channel);
3078 break;
3079 case IO_CMD_PAUSE_DM_BY_SCAN:
Larry Fingerc21916e2012-04-19 16:32:43 -05003080 rtlphy->initgain_backup.xaagccore1 = de_digtable->cur_igvalue;
3081 de_digtable->cur_igvalue = 0x37;
Chaoming Li7274a8c2011-06-10 15:10:25 -05003082 rtl92d_dm_write_dig(hw);
3083 break;
3084 default:
3085 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -08003086 "switch case not processed\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003087 break;
3088 }
3089 rtlphy->set_io_inprogress = false;
Joe Perchesf30d7502012-01-04 19:40:41 -08003090 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<---(%#x)\n",
3091 rtlphy->current_io_type);
Chaoming Li7274a8c2011-06-10 15:10:25 -05003092}
3093
3094bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
3095{
3096 struct rtl_priv *rtlpriv = rtl_priv(hw);
3097 struct rtl_phy *rtlphy = &(rtlpriv->phy);
3098 bool postprocessing = false;
3099
3100 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -08003101 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
3102 iotype, rtlphy->set_io_inprogress);
Chaoming Li7274a8c2011-06-10 15:10:25 -05003103 do {
3104 switch (iotype) {
3105 case IO_CMD_RESUME_DM_BY_SCAN:
3106 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -08003107 "[IO CMD] Resume DM after scan\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003108 postprocessing = true;
3109 break;
3110 case IO_CMD_PAUSE_DM_BY_SCAN:
3111 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -08003112 "[IO CMD] Pause DM before scan\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003113 postprocessing = true;
3114 break;
3115 default:
3116 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -08003117 "switch case not processed\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003118 break;
3119 }
3120 } while (false);
3121 if (postprocessing && !rtlphy->set_io_inprogress) {
3122 rtlphy->set_io_inprogress = true;
3123 rtlphy->current_io_type = iotype;
3124 } else {
3125 return false;
3126 }
3127 rtl92d_phy_set_io(hw);
Joe Perchesf30d7502012-01-04 19:40:41 -08003128 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype);
Chaoming Li7274a8c2011-06-10 15:10:25 -05003129 return true;
3130}
3131
3132static void _rtl92d_phy_set_rfon(struct ieee80211_hw *hw)
3133{
3134 struct rtl_priv *rtlpriv = rtl_priv(hw);
3135
3136 /* a. SYS_CLKR 0x08[11] = 1 restore MAC clock */
3137 /* b. SPS_CTRL 0x11[7:0] = 0x2b */
3138 if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY)
3139 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
3140 /* c. For PCIE: SYS_FUNC_EN 0x02[7:0] = 0xE3 enable BB TRX function */
3141 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
3142 /* RF_ON_EXCEP(d~g): */
3143 /* d. APSD_CTRL 0x600[7:0] = 0x00 */
3144 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
3145 /* e. SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB TRX function again */
3146 /* f. SYS_FUNC_EN 0x02[7:0] = 0xE3 enable BB TRX function*/
3147 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
3148 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
3149 /* g. txpause 0x522[7:0] = 0x00 enable mac tx queue */
3150 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
3151}
3152
3153static void _rtl92d_phy_set_rfsleep(struct ieee80211_hw *hw)
3154{
3155 struct rtl_priv *rtlpriv = rtl_priv(hw);
3156 u32 u4btmp;
3157 u8 delay = 5;
3158
3159 /* a. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue */
3160 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
3161 /* b. RF path 0 offset 0x00 = 0x00 disable RF */
3162 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, BRFREGOFFSETMASK, 0x00);
3163 /* c. APSD_CTRL 0x600[7:0] = 0x40 */
3164 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
3165 /* d. APSD_CTRL 0x600[7:0] = 0x00
3166 * APSD_CTRL 0x600[7:0] = 0x00
3167 * RF path 0 offset 0x00 = 0x00
3168 * APSD_CTRL 0x600[7:0] = 0x40
3169 * */
3170 u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, BRFREGOFFSETMASK);
3171 while (u4btmp != 0 && delay > 0) {
3172 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
3173 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, BRFREGOFFSETMASK, 0x00);
3174 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
3175 u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, BRFREGOFFSETMASK);
3176 delay--;
3177 }
3178 if (delay == 0) {
3179 /* Jump out the LPS turn off sequence to RF_ON_EXCEP */
3180 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
3181
3182 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
3183 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
3184 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
3185 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08003186 "Fail !!! Switch RF timeout\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003187 return;
3188 }
3189 /* e. For PCIE: SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB TRX function */
3190 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
3191 /* f. SPS_CTRL 0x11[7:0] = 0x22 */
3192 if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY)
3193 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
3194 /* g. SYS_CLKR 0x08[11] = 0 gated MAC clock */
3195}
3196
3197bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw,
3198 enum rf_pwrstate rfpwr_state)
3199{
3200
3201 bool bresult = true;
3202 struct rtl_priv *rtlpriv = rtl_priv(hw);
3203 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
3204 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
3205 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
3206 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
3207 u8 i, queue_id;
3208 struct rtl8192_tx_ring *ring = NULL;
3209
3210 if (rfpwr_state == ppsc->rfpwr_state)
3211 return false;
3212 switch (rfpwr_state) {
3213 case ERFON:
3214 if ((ppsc->rfpwr_state == ERFOFF) &&
3215 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
3216 bool rtstatus;
3217 u32 InitializeCount = 0;
3218 do {
3219 InitializeCount++;
3220 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
Joe Perchesf30d7502012-01-04 19:40:41 -08003221 "IPS Set eRf nic enable\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003222 rtstatus = rtl_ps_enable_nic(hw);
Joe Perches23677ce2012-02-09 11:17:23 +00003223 } while (!rtstatus && (InitializeCount < 10));
Chaoming Li7274a8c2011-06-10 15:10:25 -05003224
3225 RT_CLEAR_PS_LEVEL(ppsc,
3226 RT_RF_OFF_LEVL_HALT_NIC);
3227 } else {
3228 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
Joe Perchesf30d7502012-01-04 19:40:41 -08003229 "awake, sleeped:%d ms state_inap:%x\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -05003230 jiffies_to_msecs(jiffies -
Joe Perchesf30d7502012-01-04 19:40:41 -08003231 ppsc->last_sleep_jiffies),
3232 rtlpriv->psc.state_inap);
Chaoming Li7274a8c2011-06-10 15:10:25 -05003233 ppsc->last_awake_jiffies = jiffies;
3234 _rtl92d_phy_set_rfon(hw);
3235 }
3236
3237 if (mac->link_state == MAC80211_LINKED)
3238 rtlpriv->cfg->ops->led_control(hw,
3239 LED_CTL_LINK);
3240 else
3241 rtlpriv->cfg->ops->led_control(hw,
3242 LED_CTL_NO_LINK);
3243 break;
3244 case ERFOFF:
3245 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
3246 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
Joe Perchesf30d7502012-01-04 19:40:41 -08003247 "IPS Set eRf nic disable\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003248 rtl_ps_disable_nic(hw);
3249 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
3250 } else {
3251 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
3252 rtlpriv->cfg->ops->led_control(hw,
3253 LED_CTL_NO_LINK);
3254 else
3255 rtlpriv->cfg->ops->led_control(hw,
3256 LED_CTL_POWER_OFF);
3257 }
3258 break;
3259 case ERFSLEEP:
3260 if (ppsc->rfpwr_state == ERFOFF)
Philipp Dreimann91ddff82011-12-07 13:43:31 -06003261 return false;
Chaoming Li7274a8c2011-06-10 15:10:25 -05003262
3263 for (queue_id = 0, i = 0;
3264 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
3265 ring = &pcipriv->dev.tx_ring[queue_id];
3266 if (skb_queue_len(&ring->queue) == 0 ||
3267 queue_id == BEACON_QUEUE) {
3268 queue_id++;
3269 continue;
3270 } else if (rtlpci->pdev->current_state != PCI_D0) {
3271 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08003272 "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 but lower power state!\n",
3273 i + 1, queue_id);
Chaoming Li7274a8c2011-06-10 15:10:25 -05003274 break;
3275 } else {
3276 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
Joe Perchesf30d7502012-01-04 19:40:41 -08003277 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
3278 i + 1, queue_id,
3279 skb_queue_len(&ring->queue));
Chaoming Li7274a8c2011-06-10 15:10:25 -05003280 udelay(10);
3281 i++;
3282 }
3283
3284 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
3285 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
Joe Perchesf30d7502012-01-04 19:40:41 -08003286 "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n",
3287 MAX_DOZE_WAITING_TIMES_9x, queue_id,
3288 skb_queue_len(&ring->queue));
Chaoming Li7274a8c2011-06-10 15:10:25 -05003289 break;
3290 }
3291 }
3292 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
Joe Perchesf30d7502012-01-04 19:40:41 -08003293 "Set rfsleep awaked:%d ms\n",
3294 jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies));
3295 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
3296 "sleep awaked:%d ms state_inap:%x\n",
3297 jiffies_to_msecs(jiffies -
3298 ppsc->last_awake_jiffies),
3299 rtlpriv->psc.state_inap);
Chaoming Li7274a8c2011-06-10 15:10:25 -05003300 ppsc->last_sleep_jiffies = jiffies;
3301 _rtl92d_phy_set_rfsleep(hw);
3302 break;
3303 default:
3304 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -08003305 "switch case not processed\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003306 bresult = false;
3307 break;
3308 }
3309 if (bresult)
3310 ppsc->rfpwr_state = rfpwr_state;
3311 return bresult;
3312}
3313
3314void rtl92d_phy_config_macphymode(struct ieee80211_hw *hw)
3315{
3316 struct rtl_priv *rtlpriv = rtl_priv(hw);
3317 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3318 u8 offset = REG_MAC_PHY_CTRL_NORMAL;
3319
3320 switch (rtlhal->macphymode) {
3321 case DUALMAC_DUALPHY:
3322 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08003323 "MacPhyMode: DUALMAC_DUALPHY\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003324 rtl_write_byte(rtlpriv, offset, 0xF3);
3325 break;
3326 case SINGLEMAC_SINGLEPHY:
3327 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08003328 "MacPhyMode: SINGLEMAC_SINGLEPHY\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003329 rtl_write_byte(rtlpriv, offset, 0xF4);
3330 break;
3331 case DUALMAC_SINGLEPHY:
3332 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08003333 "MacPhyMode: DUALMAC_SINGLEPHY\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003334 rtl_write_byte(rtlpriv, offset, 0xF1);
3335 break;
3336 }
3337}
3338
3339void rtl92d_phy_config_macphymode_info(struct ieee80211_hw *hw)
3340{
3341 struct rtl_priv *rtlpriv = rtl_priv(hw);
3342 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3343 struct rtl_phy *rtlphy = &(rtlpriv->phy);
3344
3345 switch (rtlhal->macphymode) {
3346 case DUALMAC_SINGLEPHY:
3347 rtlphy->rf_type = RF_2T2R;
Forest Bondf1b00f42012-07-13 12:26:06 -04003348 rtlhal->version |= RF_TYPE_2T2R;
Chaoming Li7274a8c2011-06-10 15:10:25 -05003349 rtlhal->bandset = BAND_ON_BOTH;
3350 rtlhal->current_bandtype = BAND_ON_2_4G;
3351 break;
3352
3353 case SINGLEMAC_SINGLEPHY:
3354 rtlphy->rf_type = RF_2T2R;
Forest Bondf1b00f42012-07-13 12:26:06 -04003355 rtlhal->version |= RF_TYPE_2T2R;
Chaoming Li7274a8c2011-06-10 15:10:25 -05003356 rtlhal->bandset = BAND_ON_BOTH;
3357 rtlhal->current_bandtype = BAND_ON_2_4G;
3358 break;
3359
3360 case DUALMAC_DUALPHY:
3361 rtlphy->rf_type = RF_1T1R;
Forest Bondf1b00f42012-07-13 12:26:06 -04003362 rtlhal->version &= RF_TYPE_1T1R;
Chaoming Li7274a8c2011-06-10 15:10:25 -05003363 /* Now we let MAC0 run on 5G band. */
3364 if (rtlhal->interfaceindex == 0) {
3365 rtlhal->bandset = BAND_ON_5G;
3366 rtlhal->current_bandtype = BAND_ON_5G;
3367 } else {
3368 rtlhal->bandset = BAND_ON_2_4G;
3369 rtlhal->current_bandtype = BAND_ON_2_4G;
3370 }
3371 break;
3372 default:
3373 break;
3374 }
3375}
3376
3377u8 rtl92d_get_chnlgroup_fromarray(u8 chnl)
3378{
3379 u8 group;
3380 u8 channel_info[59] = {
3381 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
3382 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56,
3383 58, 60, 62, 64, 100, 102, 104, 106, 108,
3384 110, 112, 114, 116, 118, 120, 122, 124,
3385 126, 128, 130, 132, 134, 136, 138, 140,
3386 149, 151, 153, 155, 157, 159, 161, 163,
3387 165
3388 };
3389
3390 if (channel_info[chnl] <= 3)
3391 group = 0;
3392 else if (channel_info[chnl] <= 9)
3393 group = 1;
3394 else if (channel_info[chnl] <= 14)
3395 group = 2;
3396 else if (channel_info[chnl] <= 44)
3397 group = 3;
3398 else if (channel_info[chnl] <= 54)
3399 group = 4;
3400 else if (channel_info[chnl] <= 64)
3401 group = 5;
3402 else if (channel_info[chnl] <= 112)
3403 group = 6;
3404 else if (channel_info[chnl] <= 126)
3405 group = 7;
3406 else if (channel_info[chnl] <= 140)
3407 group = 8;
3408 else if (channel_info[chnl] <= 153)
3409 group = 9;
3410 else if (channel_info[chnl] <= 159)
3411 group = 10;
3412 else
3413 group = 11;
3414 return group;
3415}
3416
3417void rtl92d_phy_set_poweron(struct ieee80211_hw *hw)
3418{
3419 struct rtl_priv *rtlpriv = rtl_priv(hw);
3420 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3421 unsigned long flags;
3422 u8 value8;
3423 u16 i;
3424 u32 mac_reg = (rtlhal->interfaceindex == 0 ? REG_MAC0 : REG_MAC1);
3425
3426 /* notice fw know band status 0x81[1]/0x53[1] = 0: 5G, 1: 2G */
3427 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
3428 value8 = rtl_read_byte(rtlpriv, mac_reg);
3429 value8 |= BIT(1);
3430 rtl_write_byte(rtlpriv, mac_reg, value8);
3431 } else {
3432 value8 = rtl_read_byte(rtlpriv, mac_reg);
3433 value8 &= (~BIT(1));
3434 rtl_write_byte(rtlpriv, mac_reg, value8);
3435 }
3436
3437 if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY) {
3438 value8 = rtl_read_byte(rtlpriv, REG_MAC0);
3439 rtl_write_byte(rtlpriv, REG_MAC0, value8 | MAC0_ON);
3440 } else {
3441 spin_lock_irqsave(&globalmutex_power, flags);
3442 if (rtlhal->interfaceindex == 0) {
3443 value8 = rtl_read_byte(rtlpriv, REG_MAC0);
3444 rtl_write_byte(rtlpriv, REG_MAC0, value8 | MAC0_ON);
3445 } else {
3446 value8 = rtl_read_byte(rtlpriv, REG_MAC1);
3447 rtl_write_byte(rtlpriv, REG_MAC1, value8 | MAC1_ON);
3448 }
3449 value8 = rtl_read_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS);
3450 spin_unlock_irqrestore(&globalmutex_power, flags);
3451 for (i = 0; i < 200; i++) {
3452 if ((value8 & BIT(7)) == 0) {
3453 break;
3454 } else {
3455 udelay(500);
3456 spin_lock_irqsave(&globalmutex_power, flags);
3457 value8 = rtl_read_byte(rtlpriv,
3458 REG_POWER_OFF_IN_PROCESS);
3459 spin_unlock_irqrestore(&globalmutex_power,
3460 flags);
3461 }
3462 }
3463 if (i == 200)
Joe Perches9d833ed2012-01-04 19:40:43 -08003464 RT_ASSERT(false, "Another mac power off over time\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003465 }
3466}
3467
3468void rtl92d_phy_config_maccoexist_rfpage(struct ieee80211_hw *hw)
3469{
3470 struct rtl_priv *rtlpriv = rtl_priv(hw);
3471
3472 switch (rtlpriv->rtlhal.macphymode) {
3473 case DUALMAC_DUALPHY:
3474 rtl_write_byte(rtlpriv, REG_DMC, 0x0);
3475 rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x08);
3476 rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x13ff);
3477 break;
3478 case DUALMAC_SINGLEPHY:
3479 rtl_write_byte(rtlpriv, REG_DMC, 0xf8);
3480 rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x08);
3481 rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x13ff);
3482 break;
3483 case SINGLEMAC_SINGLEPHY:
3484 rtl_write_byte(rtlpriv, REG_DMC, 0x0);
3485 rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x10);
3486 rtl_write_word(rtlpriv, (REG_TRXFF_BNDY + 2), 0x27FF);
3487 break;
3488 default:
3489 break;
3490 }
3491}
3492
3493void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw)
3494{
3495 struct rtl_priv *rtlpriv = rtl_priv(hw);
3496 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3497 struct rtl_phy *rtlphy = &(rtlpriv->phy);
3498 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
3499 u8 rfpath, i;
3500
Joe Perchesf30d7502012-01-04 19:40:41 -08003501 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "==>\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003502 /* r_select_5G for path_A/B 0 for 2.4G, 1 for 5G */
3503 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
3504 /* r_select_5G for path_A/B,0x878 */
3505 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(0), 0x0);
3506 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), 0x0);
3507 if (rtlhal->macphymode != DUALMAC_DUALPHY) {
3508 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(16), 0x0);
3509 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(31), 0x0);
3510 }
3511 /* rssi_table_select:index 0 for 2.4G.1~3 for 5G,0xc78 */
3512 rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, BIT(6) | BIT(7), 0x0);
3513 /* fc_area 0xd2c */
3514 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(14) | BIT(13), 0x0);
3515 /* 5G LAN ON */
3516 rtl_set_bbreg(hw, 0xB30, 0x00F00000, 0xa);
3517 /* TX BB gain shift*1,Just for testchip,0xc80,0xc88 */
3518 rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, BMASKDWORD,
3519 0x40000100);
3520 rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, BMASKDWORD,
3521 0x40000100);
3522 if (rtlhal->macphymode == DUALMAC_DUALPHY) {
3523 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW,
3524 BIT(10) | BIT(6) | BIT(5),
3525 ((rtlefuse->eeprom_c9 & BIT(3)) >> 3) |
3526 (rtlefuse->eeprom_c9 & BIT(1)) |
3527 ((rtlefuse->eeprom_cc & BIT(1)) << 4));
3528 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
3529 BIT(10) | BIT(6) | BIT(5),
3530 ((rtlefuse->eeprom_c9 & BIT(2)) >> 2) |
3531 ((rtlefuse->eeprom_c9 & BIT(0)) << 1) |
3532 ((rtlefuse->eeprom_cc & BIT(0)) << 5));
3533 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), 0);
3534 } else {
3535 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW,
3536 BIT(26) | BIT(22) | BIT(21) | BIT(10) |
3537 BIT(6) | BIT(5),
3538 ((rtlefuse->eeprom_c9 & BIT(3)) >> 3) |
3539 (rtlefuse->eeprom_c9 & BIT(1)) |
3540 ((rtlefuse->eeprom_cc & BIT(1)) << 4) |
3541 ((rtlefuse->eeprom_c9 & BIT(7)) << 9) |
3542 ((rtlefuse->eeprom_c9 & BIT(5)) << 12) |
3543 ((rtlefuse->eeprom_cc & BIT(3)) << 18));
3544 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
3545 BIT(10) | BIT(6) | BIT(5),
3546 ((rtlefuse->eeprom_c9 & BIT(2)) >> 2) |
3547 ((rtlefuse->eeprom_c9 & BIT(0)) << 1) |
3548 ((rtlefuse->eeprom_cc & BIT(0)) << 5));
3549 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
3550 BIT(10) | BIT(6) | BIT(5),
3551 ((rtlefuse->eeprom_c9 & BIT(6)) >> 6) |
3552 ((rtlefuse->eeprom_c9 & BIT(4)) >> 3) |
3553 ((rtlefuse->eeprom_cc & BIT(2)) << 3));
3554 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER,
3555 BIT(31) | BIT(15), 0);
3556 }
3557 /* 1.5V_LDO */
3558 } else {
3559 /* r_select_5G for path_A/B */
3560 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(0), 0x1);
3561 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), 0x1);
3562 if (rtlhal->macphymode != DUALMAC_DUALPHY) {
3563 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(16), 0x1);
3564 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(31), 0x1);
3565 }
3566 /* rssi_table_select:index 0 for 2.4G.1~3 for 5G */
3567 rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, BIT(6) | BIT(7), 0x1);
3568 /* fc_area */
3569 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(14) | BIT(13), 0x1);
3570 /* 5G LAN ON */
3571 rtl_set_bbreg(hw, 0xB30, 0x00F00000, 0x0);
3572 /* TX BB gain shift,Just for testchip,0xc80,0xc88 */
3573 if (rtlefuse->internal_pa_5g[0])
3574 rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, BMASKDWORD,
3575 0x2d4000b5);
3576 else
3577 rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, BMASKDWORD,
3578 0x20000080);
3579 if (rtlefuse->internal_pa_5g[1])
3580 rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, BMASKDWORD,
3581 0x2d4000b5);
3582 else
3583 rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, BMASKDWORD,
3584 0x20000080);
3585 if (rtlhal->macphymode == DUALMAC_DUALPHY) {
3586 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW,
3587 BIT(10) | BIT(6) | BIT(5),
3588 (rtlefuse->eeprom_cc & BIT(5)));
3589 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(10),
3590 ((rtlefuse->eeprom_cc & BIT(4)) >> 4));
3591 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15),
3592 (rtlefuse->eeprom_cc & BIT(4)) >> 4);
3593 } else {
3594 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW,
3595 BIT(26) | BIT(22) | BIT(21) | BIT(10) |
3596 BIT(6) | BIT(5),
3597 (rtlefuse->eeprom_cc & BIT(5)) |
3598 ((rtlefuse->eeprom_cc & BIT(7)) << 14));
3599 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(10),
3600 ((rtlefuse->eeprom_cc & BIT(4)) >> 4));
3601 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BIT(10),
3602 ((rtlefuse->eeprom_cc & BIT(6)) >> 6));
3603 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER,
3604 BIT(31) | BIT(15),
3605 ((rtlefuse->eeprom_cc & BIT(4)) >> 4) |
3606 ((rtlefuse->eeprom_cc & BIT(6)) << 10));
3607 }
3608 }
3609 /* update IQK related settings */
3610 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, BMASKDWORD, 0x40000100);
3611 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, BMASKDWORD, 0x40000100);
3612 rtl_set_bbreg(hw, ROFDM0_XCTxAFE, 0xF0000000, 0x00);
3613 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(30) | BIT(28) |
3614 BIT(26) | BIT(24), 0x00);
3615 rtl_set_bbreg(hw, ROFDM0_XDTxAFE, 0xF0000000, 0x00);
3616 rtl_set_bbreg(hw, 0xca0, 0xF0000000, 0x00);
3617 rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, 0x00);
3618
3619 /* Update RF */
3620 for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
3621 rfpath++) {
3622 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
3623 /* MOD_AG for RF paht_A 0x18 BIT8,BIT16 */
3624 rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(8) | BIT(16) |
3625 BIT(18), 0);
3626 /* RF0x0b[16:14] =3b'111 */
3627 rtl_set_rfreg(hw, (enum radio_path)rfpath, 0x0B,
3628 0x1c000, 0x07);
3629 } else {
3630 /* MOD_AG for RF paht_A 0x18 BIT8,BIT16 */
3631 rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(8) |
3632 BIT(16) | BIT(18),
3633 (BIT(16) | BIT(8)) >> 8);
3634 }
3635 }
3636 /* Update for all band. */
3637 /* DMDP */
3638 if (rtlphy->rf_type == RF_1T1R) {
3639 /* Use antenna 0,0xc04,0xd04 */
3640 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0x11);
3641 rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x1);
3642
3643 /* enable ad/da clock1 for dual-phy reg0x888 */
3644 if (rtlhal->interfaceindex == 0) {
3645 rtl_set_bbreg(hw, RFPGA0_ADDALLOCKEN, BIT(12) |
3646 BIT(13), 0x3);
3647 } else {
3648 rtl92d_phy_enable_anotherphy(hw, false);
3649 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08003650 "MAC1 use DBI to update 0x888\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003651 /* 0x888 */
3652 rtl92de_write_dword_dbi(hw, RFPGA0_ADDALLOCKEN,
3653 rtl92de_read_dword_dbi(hw,
3654 RFPGA0_ADDALLOCKEN,
3655 BIT(3)) | BIT(12) | BIT(13),
3656 BIT(3));
3657 rtl92d_phy_powerdown_anotherphy(hw, false);
3658 }
3659 } else {
3660 /* Single PHY */
3661 /* Use antenna 0 & 1,0xc04,0xd04 */
3662 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0x33);
3663 rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x3);
3664 /* disable ad/da clock1,0x888 */
3665 rtl_set_bbreg(hw, RFPGA0_ADDALLOCKEN, BIT(12) | BIT(13), 0);
3666 }
3667 for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
3668 rfpath++) {
3669 rtlphy->rfreg_chnlval[rfpath] = rtl_get_rfreg(hw, rfpath,
3670 RF_CHNLBW, BRFREGOFFSETMASK);
3671 rtlphy->reg_rf3c[rfpath] = rtl_get_rfreg(hw, rfpath, 0x3C,
3672 BRFREGOFFSETMASK);
3673 }
3674 for (i = 0; i < 2; i++)
Joe Perchesf30d7502012-01-04 19:40:41 -08003675 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "RF 0x18 = 0x%x\n",
3676 rtlphy->rfreg_chnlval[i]);
3677 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<==\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003678
3679}
3680
3681bool rtl92d_phy_check_poweroff(struct ieee80211_hw *hw)
3682{
3683 struct rtl_priv *rtlpriv = rtl_priv(hw);
3684 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3685 u8 u1btmp;
3686 unsigned long flags;
3687
3688 if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY) {
3689 u1btmp = rtl_read_byte(rtlpriv, REG_MAC0);
3690 rtl_write_byte(rtlpriv, REG_MAC0, u1btmp & (~MAC0_ON));
3691 return true;
3692 }
3693 spin_lock_irqsave(&globalmutex_power, flags);
3694 if (rtlhal->interfaceindex == 0) {
3695 u1btmp = rtl_read_byte(rtlpriv, REG_MAC0);
3696 rtl_write_byte(rtlpriv, REG_MAC0, u1btmp & (~MAC0_ON));
3697 u1btmp = rtl_read_byte(rtlpriv, REG_MAC1);
3698 u1btmp &= MAC1_ON;
3699 } else {
3700 u1btmp = rtl_read_byte(rtlpriv, REG_MAC1);
3701 rtl_write_byte(rtlpriv, REG_MAC1, u1btmp & (~MAC1_ON));
3702 u1btmp = rtl_read_byte(rtlpriv, REG_MAC0);
3703 u1btmp &= MAC0_ON;
3704 }
3705 if (u1btmp) {
3706 spin_unlock_irqrestore(&globalmutex_power, flags);
3707 return false;
3708 }
3709 u1btmp = rtl_read_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS);
3710 u1btmp |= BIT(7);
3711 rtl_write_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS, u1btmp);
3712 spin_unlock_irqrestore(&globalmutex_power, flags);
3713 return true;
3714}