blob: 93eecbd89402ba2ed7362d814ea42a6a21c23384 [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);
668
669 if (regaddr == RTXAGC_A_RATE18_06) {
670 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] =
671 data;
672 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800673 "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%ulx\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -0500674 rtlphy->pwrgroup_cnt,
675 rtlphy->mcs_txpwrlevel_origoffset
Joe Perchesf30d7502012-01-04 19:40:41 -0800676 [rtlphy->pwrgroup_cnt][0]);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500677 }
678 if (regaddr == RTXAGC_A_RATE54_24) {
679 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] =
680 data;
681 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800682 "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%ulx\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -0500683 rtlphy->pwrgroup_cnt,
684 rtlphy->mcs_txpwrlevel_origoffset
Joe Perchesf30d7502012-01-04 19:40:41 -0800685 [rtlphy->pwrgroup_cnt][1]);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500686 }
687 if (regaddr == RTXAGC_A_CCK1_MCS32) {
688 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] =
689 data;
690 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800691 "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%ulx\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -0500692 rtlphy->pwrgroup_cnt,
693 rtlphy->mcs_txpwrlevel_origoffset
Joe Perchesf30d7502012-01-04 19:40:41 -0800694 [rtlphy->pwrgroup_cnt][6]);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500695 }
696 if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) {
697 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] =
698 data;
699 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800700 "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%ulx\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -0500701 rtlphy->pwrgroup_cnt,
702 rtlphy->mcs_txpwrlevel_origoffset
Joe Perchesf30d7502012-01-04 19:40:41 -0800703 [rtlphy->pwrgroup_cnt][7]);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500704 }
705 if (regaddr == RTXAGC_A_MCS03_MCS00) {
706 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] =
707 data;
708 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800709 "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%ulx\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -0500710 rtlphy->pwrgroup_cnt,
711 rtlphy->mcs_txpwrlevel_origoffset
Joe Perchesf30d7502012-01-04 19:40:41 -0800712 [rtlphy->pwrgroup_cnt][2]);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500713 }
714 if (regaddr == RTXAGC_A_MCS07_MCS04) {
715 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] =
716 data;
717 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800718 "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%ulx\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -0500719 rtlphy->pwrgroup_cnt,
720 rtlphy->mcs_txpwrlevel_origoffset
Joe Perchesf30d7502012-01-04 19:40:41 -0800721 [rtlphy->pwrgroup_cnt][3]);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500722 }
723 if (regaddr == RTXAGC_A_MCS11_MCS08) {
724 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] =
725 data;
726 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800727 "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%ulx\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -0500728 rtlphy->pwrgroup_cnt,
729 rtlphy->mcs_txpwrlevel_origoffset
Joe Perchesf30d7502012-01-04 19:40:41 -0800730 [rtlphy->pwrgroup_cnt][4]);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500731 }
732 if (regaddr == RTXAGC_A_MCS15_MCS12) {
733 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] =
734 data;
735 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800736 "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%ulx\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -0500737 rtlphy->pwrgroup_cnt,
738 rtlphy->mcs_txpwrlevel_origoffset
Joe Perchesf30d7502012-01-04 19:40:41 -0800739 [rtlphy->pwrgroup_cnt][5]);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500740 }
741 if (regaddr == RTXAGC_B_RATE18_06) {
742 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] =
743 data;
744 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800745 "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%ulx\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -0500746 rtlphy->pwrgroup_cnt,
747 rtlphy->mcs_txpwrlevel_origoffset
Joe Perchesf30d7502012-01-04 19:40:41 -0800748 [rtlphy->pwrgroup_cnt][8]);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500749 }
750 if (regaddr == RTXAGC_B_RATE54_24) {
751 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] =
752 data;
753 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800754 "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%ulx\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -0500755 rtlphy->pwrgroup_cnt,
756 rtlphy->mcs_txpwrlevel_origoffset
Joe Perchesf30d7502012-01-04 19:40:41 -0800757 [rtlphy->pwrgroup_cnt][9]);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500758 }
759 if (regaddr == RTXAGC_B_CCK1_55_MCS32) {
760 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] =
761 data;
762 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800763 "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%ulx\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -0500764 rtlphy->pwrgroup_cnt,
765 rtlphy->mcs_txpwrlevel_origoffset
Joe Perchesf30d7502012-01-04 19:40:41 -0800766 [rtlphy->pwrgroup_cnt][14]);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500767 }
768 if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {
769 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] =
770 data;
771 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800772 "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%ulx\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -0500773 rtlphy->pwrgroup_cnt,
774 rtlphy->mcs_txpwrlevel_origoffset
Joe Perchesf30d7502012-01-04 19:40:41 -0800775 [rtlphy->pwrgroup_cnt][15]);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500776 }
777 if (regaddr == RTXAGC_B_MCS03_MCS00) {
778 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] =
779 data;
780 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800781 "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%ulx\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -0500782 rtlphy->pwrgroup_cnt,
783 rtlphy->mcs_txpwrlevel_origoffset
Joe Perchesf30d7502012-01-04 19:40:41 -0800784 [rtlphy->pwrgroup_cnt][10]);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500785 }
786 if (regaddr == RTXAGC_B_MCS07_MCS04) {
787 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] =
788 data;
789 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800790 "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%ulx\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -0500791 rtlphy->pwrgroup_cnt,
792 rtlphy->mcs_txpwrlevel_origoffset
Joe Perchesf30d7502012-01-04 19:40:41 -0800793 [rtlphy->pwrgroup_cnt][11]);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500794 }
795 if (regaddr == RTXAGC_B_MCS11_MCS08) {
796 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] =
797 data;
798 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800799 "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%ulx\n",
800 rtlphy->pwrgroup_cnt,
801 rtlphy->mcs_txpwrlevel_origoffset
802 [rtlphy->pwrgroup_cnt][12]);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500803 }
804 if (regaddr == RTXAGC_B_MCS15_MCS12) {
805 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] =
806 data;
807 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800808 "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%ulx\n",
809 rtlphy->pwrgroup_cnt,
810 rtlphy->mcs_txpwrlevel_origoffset
811 [rtlphy->pwrgroup_cnt][13]);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500812 rtlphy->pwrgroup_cnt++;
813 }
814}
815
816static bool _rtl92d_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
817 u8 configtype)
818{
819 struct rtl_priv *rtlpriv = rtl_priv(hw);
820 int i;
821 u32 *phy_regarray_table_pg;
822 u16 phy_regarray_pg_len;
823
824 phy_regarray_pg_len = PHY_REG_ARRAY_PG_LENGTH;
825 phy_regarray_table_pg = rtl8192de_phy_reg_array_pg;
826 if (configtype == BASEBAND_CONFIG_PHY_REG) {
827 for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
828 if (phy_regarray_table_pg[i] == 0xfe)
829 mdelay(50);
830 else if (phy_regarray_table_pg[i] == 0xfd)
831 mdelay(5);
832 else if (phy_regarray_table_pg[i] == 0xfc)
833 mdelay(1);
834 else if (phy_regarray_table_pg[i] == 0xfb)
835 udelay(50);
836 else if (phy_regarray_table_pg[i] == 0xfa)
837 udelay(5);
838 else if (phy_regarray_table_pg[i] == 0xf9)
839 udelay(1);
840 _rtl92d_store_pwrindex_diffrate_offset(hw,
841 phy_regarray_table_pg[i],
842 phy_regarray_table_pg[i + 1],
843 phy_regarray_table_pg[i + 2]);
844 }
845 } else {
846 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -0800847 "configtype != BaseBand_Config_PHY_REG\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500848 }
849 return true;
850}
851
852static bool _rtl92d_phy_bb_config(struct ieee80211_hw *hw)
853{
854 struct rtl_priv *rtlpriv = rtl_priv(hw);
855 struct rtl_phy *rtlphy = &(rtlpriv->phy);
856 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
857 bool rtstatus = true;
858
Joe Perchesf30d7502012-01-04 19:40:41 -0800859 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500860 rtstatus = _rtl92d_phy_config_bb_with_headerfile(hw,
861 BASEBAND_CONFIG_PHY_REG);
Joe Perches23677ce2012-02-09 11:17:23 +0000862 if (!rtstatus) {
Joe Perchesf30d7502012-01-04 19:40:41 -0800863 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500864 return false;
865 }
866
867 /* if (rtlphy->rf_type == RF_1T2R) {
868 * _rtl92c_phy_bb_config_1t(hw);
Joe Perchesf30d7502012-01-04 19:40:41 -0800869 * RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500870 *} */
871
872 if (rtlefuse->autoload_failflag == false) {
873 rtlphy->pwrgroup_cnt = 0;
874 rtstatus = _rtl92d_phy_config_bb_with_pgheaderfile(hw,
875 BASEBAND_CONFIG_PHY_REG);
876 }
Joe Perches23677ce2012-02-09 11:17:23 +0000877 if (!rtstatus) {
Joe Perchesf30d7502012-01-04 19:40:41 -0800878 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500879 return false;
880 }
881 rtstatus = _rtl92d_phy_config_bb_with_headerfile(hw,
882 BASEBAND_CONFIG_AGC_TAB);
Joe Perches23677ce2012-02-09 11:17:23 +0000883 if (!rtstatus) {
Joe Perchesf30d7502012-01-04 19:40:41 -0800884 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500885 return false;
886 }
887 rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
888 RFPGA0_XA_HSSIPARAMETER2, 0x200));
889
890 return true;
891}
892
893bool rtl92d_phy_bb_config(struct ieee80211_hw *hw)
894{
895 struct rtl_priv *rtlpriv = rtl_priv(hw);
896 u16 regval;
897 u32 regvaldw;
898 u8 value;
899
900 _rtl92d_phy_init_bb_rf_register_definition(hw);
901 regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
902 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
903 regval | BIT(13) | BIT(0) | BIT(1));
904 rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83);
905 rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb);
906 /* 0x1f bit7 bit6 represent for mac0/mac1 driver ready */
907 value = rtl_read_byte(rtlpriv, REG_RF_CTRL);
908 rtl_write_byte(rtlpriv, REG_RF_CTRL, value | RF_EN | RF_RSTB |
909 RF_SDMRSTB);
910 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_PPLL | FEN_PCIEA |
911 FEN_DIO_PCIE | FEN_BB_GLB_RSTn | FEN_BBRSTB);
912 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
913 if (!(IS_92D_SINGLEPHY(rtlpriv->rtlhal.version))) {
914 regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0);
915 rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23));
916 }
917
918 return _rtl92d_phy_bb_config(hw);
919}
920
921bool rtl92d_phy_rf_config(struct ieee80211_hw *hw)
922{
923 return rtl92d_phy_rf6052_config(hw);
924}
925
926bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
927 enum rf_content content,
928 enum radio_path rfpath)
929{
Larry Fingereb8b27a2011-07-01 08:50:48 -0500930 int i;
Chaoming Li7274a8c2011-06-10 15:10:25 -0500931 u32 *radioa_array_table;
932 u32 *radiob_array_table;
933 u16 radioa_arraylen, radiob_arraylen;
934 struct rtl_priv *rtlpriv = rtl_priv(hw);
935
936 radioa_arraylen = RADIOA_2T_ARRAYLENGTH;
937 radioa_array_table = rtl8192de_radioa_2tarray;
938 radiob_arraylen = RADIOB_2T_ARRAYLENGTH;
939 radiob_array_table = rtl8192de_radiob_2tarray;
940 if (rtlpriv->efuse.internal_pa_5g[0]) {
941 radioa_arraylen = RADIOA_2T_INT_PA_ARRAYLENGTH;
942 radioa_array_table = rtl8192de_radioa_2t_int_paarray;
943 }
944 if (rtlpriv->efuse.internal_pa_5g[1]) {
945 radiob_arraylen = RADIOB_2T_INT_PA_ARRAYLENGTH;
946 radiob_array_table = rtl8192de_radiob_2t_int_paarray;
947 }
948 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -0800949 "PHY_ConfigRFWithHeaderFile() Radio_A:Rtl819XRadioA_1TArray\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500950 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -0800951 "PHY_ConfigRFWithHeaderFile() Radio_B:Rtl819XRadioB_1TArray\n");
952 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500953
954 /* this only happens when DMDP, mac0 start on 2.4G,
955 * mac1 start on 5G, mac 0 has to set phy0&phy1
956 * pathA or mac1 has to set phy0&phy1 pathA */
957 if ((content == radiob_txt) && (rfpath == RF90_PATH_A)) {
958 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -0800959 " ===> althougth Path A, we load radiob.txt\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -0500960 radioa_arraylen = radiob_arraylen;
961 radioa_array_table = radiob_array_table;
962 }
963 switch (rfpath) {
964 case RF90_PATH_A:
965 for (i = 0; i < radioa_arraylen; i = i + 2) {
966 if (radioa_array_table[i] == 0xfe) {
967 mdelay(50);
968 } else if (radioa_array_table[i] == 0xfd) {
969 /* delay_ms(5); */
Larry Fingereb8b27a2011-07-01 08:50:48 -0500970 mdelay(5);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500971 } else if (radioa_array_table[i] == 0xfc) {
972 /* delay_ms(1); */
Larry Fingereb8b27a2011-07-01 08:50:48 -0500973 mdelay(1);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500974 } else if (radioa_array_table[i] == 0xfb) {
975 udelay(50);
976 } else if (radioa_array_table[i] == 0xfa) {
977 udelay(5);
978 } else if (radioa_array_table[i] == 0xf9) {
979 udelay(1);
980 } else {
981 rtl_set_rfreg(hw, rfpath, radioa_array_table[i],
982 BRFREGOFFSETMASK,
983 radioa_array_table[i + 1]);
984 /* Add 1us delay between BB/RF register set. */
985 udelay(1);
986 }
987 }
988 break;
989 case RF90_PATH_B:
990 for (i = 0; i < radiob_arraylen; i = i + 2) {
991 if (radiob_array_table[i] == 0xfe) {
992 /* Delay specific ms. Only RF configuration
993 * requires delay. */
994 mdelay(50);
995 } else if (radiob_array_table[i] == 0xfd) {
996 /* delay_ms(5); */
Larry Fingereb8b27a2011-07-01 08:50:48 -0500997 mdelay(5);
Chaoming Li7274a8c2011-06-10 15:10:25 -0500998 } else if (radiob_array_table[i] == 0xfc) {
999 /* delay_ms(1); */
Larry Fingereb8b27a2011-07-01 08:50:48 -05001000 mdelay(1);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001001 } else if (radiob_array_table[i] == 0xfb) {
1002 udelay(50);
1003 } else if (radiob_array_table[i] == 0xfa) {
1004 udelay(5);
1005 } else if (radiob_array_table[i] == 0xf9) {
1006 udelay(1);
1007 } else {
1008 rtl_set_rfreg(hw, rfpath, radiob_array_table[i],
1009 BRFREGOFFSETMASK,
1010 radiob_array_table[i + 1]);
1011 /* Add 1us delay between BB/RF register set. */
1012 udelay(1);
1013 }
1014 }
1015 break;
1016 case RF90_PATH_C:
1017 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -08001018 "switch case not processed\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001019 break;
1020 case RF90_PATH_D:
1021 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -08001022 "switch case not processed\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001023 break;
1024 }
1025 return true;
1026}
1027
1028void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
1029{
1030 struct rtl_priv *rtlpriv = rtl_priv(hw);
1031 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1032
1033 rtlphy->default_initialgain[0] =
1034 (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, BMASKBYTE0);
1035 rtlphy->default_initialgain[1] =
1036 (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, BMASKBYTE0);
1037 rtlphy->default_initialgain[2] =
1038 (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, BMASKBYTE0);
1039 rtlphy->default_initialgain[3] =
1040 (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, BMASKBYTE0);
1041 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -08001042 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
1043 rtlphy->default_initialgain[0],
1044 rtlphy->default_initialgain[1],
1045 rtlphy->default_initialgain[2],
1046 rtlphy->default_initialgain[3]);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001047 rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3,
1048 BMASKBYTE0);
1049 rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
1050 BMASKDWORD);
1051 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -08001052 "Default framesync (0x%x) = 0x%x\n",
1053 ROFDM0_RXDETECTOR3, rtlphy->framesync);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001054}
1055
1056static void _rtl92d_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
1057 u8 *cckpowerlevel, u8 *ofdmpowerlevel)
1058{
1059 struct rtl_priv *rtlpriv = rtl_priv(hw);
1060 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1061 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
1062 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1063 u8 index = (channel - 1);
1064
1065 /* 1. CCK */
1066 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
1067 /* RF-A */
1068 cckpowerlevel[RF90_PATH_A] =
1069 rtlefuse->txpwrlevel_cck[RF90_PATH_A][index];
1070 /* RF-B */
1071 cckpowerlevel[RF90_PATH_B] =
1072 rtlefuse->txpwrlevel_cck[RF90_PATH_B][index];
1073 } else {
1074 cckpowerlevel[RF90_PATH_A] = 0;
1075 cckpowerlevel[RF90_PATH_B] = 0;
1076 }
1077 /* 2. OFDM for 1S or 2S */
1078 if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_1T1R) {
1079 /* Read HT 40 OFDM TX power */
1080 ofdmpowerlevel[RF90_PATH_A] =
1081 rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index];
1082 ofdmpowerlevel[RF90_PATH_B] =
1083 rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index];
1084 } else if (rtlphy->rf_type == RF_2T2R) {
1085 /* Read HT 40 OFDM TX power */
1086 ofdmpowerlevel[RF90_PATH_A] =
1087 rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index];
1088 ofdmpowerlevel[RF90_PATH_B] =
1089 rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index];
1090 }
1091}
1092
1093static void _rtl92d_ccxpower_index_check(struct ieee80211_hw *hw,
1094 u8 channel, u8 *cckpowerlevel, u8 *ofdmpowerlevel)
1095{
1096 struct rtl_priv *rtlpriv = rtl_priv(hw);
1097 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1098
1099 rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
1100 rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
1101}
1102
1103static u8 _rtl92c_phy_get_rightchnlplace(u8 chnl)
1104{
1105 u8 channel_5g[59] = {
1106 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
1107 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
1108 60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
1109 114, 116, 118, 120, 122, 124, 126, 128,
1110 130, 132, 134, 136, 138, 140, 149, 151,
1111 153, 155, 157, 159, 161, 163, 165
1112 };
1113 u8 place = chnl;
1114
1115 if (chnl > 14) {
1116 for (place = 14; place < sizeof(channel_5g); place++) {
1117 if (channel_5g[place] == chnl) {
1118 place++;
1119 break;
1120 }
1121 }
1122 }
1123 return place;
1124}
1125
1126void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1127{
1128 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1129 struct rtl_priv *rtlpriv = rtl_priv(hw);
1130 u8 cckpowerlevel[2], ofdmpowerlevel[2];
1131
Joe Perches23677ce2012-02-09 11:17:23 +00001132 if (!rtlefuse->txpwr_fromeprom)
Chaoming Li7274a8c2011-06-10 15:10:25 -05001133 return;
1134 channel = _rtl92c_phy_get_rightchnlplace(channel);
1135 _rtl92d_get_txpower_index(hw, channel, &cckpowerlevel[0],
1136 &ofdmpowerlevel[0]);
1137 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
1138 _rtl92d_ccxpower_index_check(hw, channel, &cckpowerlevel[0],
1139 &ofdmpowerlevel[0]);
1140 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
1141 rtl92d_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]);
1142 rtl92d_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel);
1143}
1144
1145void rtl92d_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1146{
1147 struct rtl_priv *rtlpriv = rtl_priv(hw);
1148 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1149 enum io_type iotype;
1150
1151 if (!is_hal_stop(rtlhal)) {
1152 switch (operation) {
1153 case SCAN_OPT_BACKUP:
1154 rtlhal->current_bandtypebackup =
1155 rtlhal->current_bandtype;
1156 iotype = IO_CMD_PAUSE_DM_BY_SCAN;
1157 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1158 (u8 *)&iotype);
1159 break;
1160 case SCAN_OPT_RESTORE:
1161 iotype = IO_CMD_RESUME_DM_BY_SCAN;
1162 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1163 (u8 *)&iotype);
1164 break;
1165 default:
1166 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -08001167 "Unknown Scan Backup operation\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001168 break;
1169 }
1170 }
1171}
1172
1173void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw,
1174 enum nl80211_channel_type ch_type)
1175{
1176 struct rtl_priv *rtlpriv = rtl_priv(hw);
1177 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1178 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1179 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1180 unsigned long flag = 0;
1181 u8 reg_prsr_rsc;
1182 u8 reg_bw_opmode;
1183
1184 if (rtlphy->set_bwmode_inprogress)
1185 return;
1186 if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
1187 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
Joe Perchesf30d7502012-01-04 19:40:41 -08001188 "FALSE driver sleep or unload\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001189 return;
1190 }
1191 rtlphy->set_bwmode_inprogress = true;
Joe Perchesf30d7502012-01-04 19:40:41 -08001192 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n",
1193 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1194 "20MHz" : "40MHz");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001195 reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1196 reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1197 switch (rtlphy->current_chan_bw) {
1198 case HT_CHANNEL_WIDTH_20:
1199 reg_bw_opmode |= BW_OPMODE_20MHZ;
1200 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1201 break;
1202 case HT_CHANNEL_WIDTH_20_40:
1203 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1204 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1205
1206 reg_prsr_rsc = (reg_prsr_rsc & 0x90) |
1207 (mac->cur_40_prime_sc << 5);
1208 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1209 break;
1210 default:
1211 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -08001212 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001213 break;
1214 }
1215 switch (rtlphy->current_chan_bw) {
1216 case HT_CHANNEL_WIDTH_20:
1217 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1218 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1219 /* SET BIT10 BIT11 for receive cck */
1220 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10) |
1221 BIT(11), 3);
1222 break;
1223 case HT_CHANNEL_WIDTH_20_40:
1224 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1225 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1226 /* Set Control channel to upper or lower.
1227 * These settings are required only for 40MHz */
1228 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
1229 rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
1230 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCKSIDEBAND,
1231 (mac->cur_40_prime_sc >> 1));
1232 rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
1233 }
1234 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
1235 /* SET BIT10 BIT11 for receive cck */
1236 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10) |
1237 BIT(11), 0);
1238 rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1239 (mac->cur_40_prime_sc ==
1240 HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1241 break;
1242 default:
1243 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -08001244 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001245 break;
1246
1247 }
1248 rtl92d_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1249 rtlphy->set_bwmode_inprogress = false;
Joe Perchesf30d7502012-01-04 19:40:41 -08001250 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001251}
1252
1253static void _rtl92d_phy_stop_trx_before_changeband(struct ieee80211_hw *hw)
1254{
1255 rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0);
1256 rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0);
1257 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0x00);
1258 rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x0);
1259}
1260
1261static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band)
1262{
1263 struct rtl_priv *rtlpriv = rtl_priv(hw);
1264 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
Larry Fingereb8b27a2011-07-01 08:50:48 -05001265 u8 value8;
Chaoming Li7274a8c2011-06-10 15:10:25 -05001266
Joe Perchesf30d7502012-01-04 19:40:41 -08001267 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "==>\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001268 rtlhal->bandset = band;
1269 rtlhal->current_bandtype = band;
1270 if (IS_92D_SINGLEPHY(rtlhal->version))
1271 rtlhal->bandset = BAND_ON_BOTH;
1272 /* stop RX/Tx */
1273 _rtl92d_phy_stop_trx_before_changeband(hw);
1274 /* reconfig BB/RF according to wireless mode */
1275 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
1276 /* BB & RF Config */
Joe Perchesf30d7502012-01-04 19:40:41 -08001277 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "====>2.4G\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001278 if (rtlhal->interfaceindex == 1)
1279 _rtl92d_phy_config_bb_with_headerfile(hw,
1280 BASEBAND_CONFIG_AGC_TAB);
1281 } else {
1282 /* 5G band */
Joe Perchesf30d7502012-01-04 19:40:41 -08001283 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "====>5G\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001284 if (rtlhal->interfaceindex == 1)
1285 _rtl92d_phy_config_bb_with_headerfile(hw,
1286 BASEBAND_CONFIG_AGC_TAB);
1287 }
1288 rtl92d_update_bbrf_configuration(hw);
1289 if (rtlhal->current_bandtype == BAND_ON_2_4G)
1290 rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
1291 rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
1292
1293 /* 20M BW. */
1294 /* rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); */
1295 rtlhal->reloadtxpowerindex = true;
1296 /* notice fw know band status 0x81[1]/0x53[1] = 0: 5G, 1: 2G */
1297 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
1298 value8 = rtl_read_byte(rtlpriv, (rtlhal->interfaceindex ==
1299 0 ? REG_MAC0 : REG_MAC1));
1300 value8 |= BIT(1);
1301 rtl_write_byte(rtlpriv, (rtlhal->interfaceindex ==
1302 0 ? REG_MAC0 : REG_MAC1), value8);
1303 } else {
1304 value8 = rtl_read_byte(rtlpriv, (rtlhal->interfaceindex ==
1305 0 ? REG_MAC0 : REG_MAC1));
1306 value8 &= (~BIT(1));
1307 rtl_write_byte(rtlpriv, (rtlhal->interfaceindex ==
1308 0 ? REG_MAC0 : REG_MAC1), value8);
1309 }
Larry Fingereb8b27a2011-07-01 08:50:48 -05001310 mdelay(1);
Joe Perchesf30d7502012-01-04 19:40:41 -08001311 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<==Switch Band OK\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001312}
1313
1314static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw,
1315 u8 channel, u8 rfpath)
1316{
1317 struct rtl_priv *rtlpriv = rtl_priv(hw);
1318 u32 imr_num = MAX_RF_IMR_INDEX;
1319 u32 rfmask = BRFREGOFFSETMASK;
1320 u8 group, i;
1321 unsigned long flag = 0;
1322
Joe Perchesf30d7502012-01-04 19:40:41 -08001323 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>path %d\n", rfpath);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001324 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {
Joe Perchesf30d7502012-01-04 19:40:41 -08001325 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001326 rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(25) | BIT(24), 0);
1327 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf);
1328 /* fc area 0xd2c */
1329 if (channel > 99)
1330 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(13) |
1331 BIT(14), 2);
1332 else
1333 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(13) |
1334 BIT(14), 1);
1335 /* leave 0 for channel1-14. */
1336 group = channel <= 64 ? 1 : 2;
1337 imr_num = MAX_RF_IMR_INDEX_NORMAL;
1338 for (i = 0; i < imr_num; i++)
1339 rtl_set_rfreg(hw, (enum radio_path)rfpath,
1340 rf_reg_for_5g_swchnl_normal[i], rfmask,
1341 rf_imr_param_normal[0][group][i]);
1342 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0);
1343 rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 1);
1344 } else {
1345 /* G band. */
1346 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08001347 "Load RF IMR parameters for G band. IMR already setting %d\n",
1348 rtlpriv->rtlhal.load_imrandiqk_setting_for2g);
1349 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001350 if (!rtlpriv->rtlhal.load_imrandiqk_setting_for2g) {
1351 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08001352 "Load RF IMR parameters for G band. %d\n",
1353 rfpath);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001354 rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
1355 rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(25) | BIT(24), 0);
1356 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4,
1357 0x00f00000, 0xf);
1358 imr_num = MAX_RF_IMR_INDEX_NORMAL;
1359 for (i = 0; i < imr_num; i++) {
1360 rtl_set_rfreg(hw, (enum radio_path)rfpath,
1361 rf_reg_for_5g_swchnl_normal[i],
1362 BRFREGOFFSETMASK,
1363 rf_imr_param_normal[0][0][i]);
1364 }
1365 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4,
1366 0x00f00000, 0);
1367 rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN | BCCKEN, 3);
1368 rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
1369 }
1370 }
Joe Perchesf30d7502012-01-04 19:40:41 -08001371 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001372}
1373
1374static void _rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw,
1375 u8 rfpath, u32 *pu4_regval)
1376{
1377 struct rtl_priv *rtlpriv = rtl_priv(hw);
1378 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1379 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
1380
Joe Perchesf30d7502012-01-04 19:40:41 -08001381 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "====>\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001382 /*----Store original RFENV control type----*/
1383 switch (rfpath) {
1384 case RF90_PATH_A:
1385 case RF90_PATH_C:
1386 *pu4_regval = rtl_get_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV);
1387 break;
1388 case RF90_PATH_B:
1389 case RF90_PATH_D:
1390 *pu4_regval =
1391 rtl_get_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16);
1392 break;
1393 }
1394 /*----Set RF_ENV enable----*/
1395 rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
1396 udelay(1);
1397 /*----Set RF_ENV output high----*/
1398 rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
1399 udelay(1);
1400 /* Set bit number of Address and Data for RF register */
1401 /* Set 1 to 4 bits for 8255 */
1402 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREADDRESSLENGTH, 0x0);
1403 udelay(1);
1404 /*Set 0 to 12 bits for 8255 */
1405 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
1406 udelay(1);
Joe Perchesf30d7502012-01-04 19:40:41 -08001407 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<====\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001408}
1409
1410static void _rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath,
1411 u32 *pu4_regval)
1412{
1413 struct rtl_priv *rtlpriv = rtl_priv(hw);
1414 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1415 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
1416
Joe Perchesf30d7502012-01-04 19:40:41 -08001417 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "=====>\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001418 /*----Restore RFENV control type----*/ ;
1419 switch (rfpath) {
1420 case RF90_PATH_A:
1421 case RF90_PATH_C:
1422 rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV, *pu4_regval);
1423 break;
1424 case RF90_PATH_B:
1425 case RF90_PATH_D:
1426 rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16,
1427 *pu4_regval);
1428 break;
1429 }
Joe Perchesf30d7502012-01-04 19:40:41 -08001430 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<=====\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001431}
1432
1433static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel)
1434{
1435 struct rtl_priv *rtlpriv = rtl_priv(hw);
1436 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1437 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
1438 u8 path = rtlhal->current_bandtype ==
1439 BAND_ON_5G ? RF90_PATH_A : RF90_PATH_B;
1440 u8 index = 0, i = 0, rfpath = RF90_PATH_A;
1441 bool need_pwr_down = false, internal_pa = false;
1442 u32 u4regvalue, mask = 0x1C000, value = 0, u4tmp, u4tmp2;
1443
Joe Perchesf30d7502012-01-04 19:40:41 -08001444 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001445 /* config path A for 5G */
1446 if (rtlhal->current_bandtype == BAND_ON_5G) {
Joe Perchesf30d7502012-01-04 19:40:41 -08001447 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001448 u4tmp = curveindex_5g[channel - 1];
Joe Perches4c488692012-01-04 19:40:42 -08001449 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1450 "ver 1 set RF-A, 5G, 0x28 = 0x%x !!\n", u4tmp);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001451 for (i = 0; i < RF_CHNL_NUM_5G; i++) {
1452 if (channel == rf_chnl_5g[i] && channel <= 140)
1453 index = 0;
1454 }
1455 for (i = 0; i < RF_CHNL_NUM_5G_40M; i++) {
1456 if (channel == rf_chnl_5g_40m[i] && channel <= 140)
1457 index = 1;
1458 }
1459 if (channel == 149 || channel == 155 || channel == 161)
1460 index = 2;
1461 else if (channel == 151 || channel == 153 || channel == 163
1462 || channel == 165)
1463 index = 3;
1464 else if (channel == 157 || channel == 159)
1465 index = 4;
1466
1467 if (rtlhal->macphymode == DUALMAC_DUALPHY
1468 && rtlhal->interfaceindex == 1) {
1469 need_pwr_down = rtl92d_phy_enable_anotherphy(hw, false);
1470 rtlhal->during_mac1init_radioa = true;
1471 /* asume no this case */
1472 if (need_pwr_down)
1473 _rtl92d_phy_enable_rf_env(hw, path,
1474 &u4regvalue);
1475 }
1476 for (i = 0; i < RF_REG_NUM_FOR_C_CUT_5G; i++) {
1477 if (i == 0 && (rtlhal->macphymode == DUALMAC_DUALPHY)) {
1478 rtl_set_rfreg(hw, (enum radio_path)path,
1479 rf_reg_for_c_cut_5g[i],
1480 BRFREGOFFSETMASK, 0xE439D);
1481 } else if (rf_reg_for_c_cut_5g[i] == RF_SYN_G4) {
1482 u4tmp2 = (rf_reg_pram_c_5g[index][i] &
1483 0x7FF) | (u4tmp << 11);
1484 if (channel == 36)
1485 u4tmp2 &= ~(BIT(7) | BIT(6));
1486 rtl_set_rfreg(hw, (enum radio_path)path,
1487 rf_reg_for_c_cut_5g[i],
1488 BRFREGOFFSETMASK, u4tmp2);
1489 } else {
1490 rtl_set_rfreg(hw, (enum radio_path)path,
1491 rf_reg_for_c_cut_5g[i],
1492 BRFREGOFFSETMASK,
1493 rf_reg_pram_c_5g[index][i]);
1494 }
1495 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -08001496 "offset 0x%x value 0x%x path %d index %d readback 0x%x\n",
1497 rf_reg_for_c_cut_5g[i],
1498 rf_reg_pram_c_5g[index][i],
1499 path, index,
1500 rtl_get_rfreg(hw, (enum radio_path)path,
1501 rf_reg_for_c_cut_5g[i],
1502 BRFREGOFFSETMASK));
Chaoming Li7274a8c2011-06-10 15:10:25 -05001503 }
1504 if (need_pwr_down)
1505 _rtl92d_phy_restore_rf_env(hw, path, &u4regvalue);
1506 if (rtlhal->during_mac1init_radioa)
1507 rtl92d_phy_powerdown_anotherphy(hw, false);
1508 if (channel < 149)
1509 value = 0x07;
1510 else if (channel >= 149)
1511 value = 0x02;
1512 if (channel >= 36 && channel <= 64)
1513 index = 0;
1514 else if (channel >= 100 && channel <= 140)
1515 index = 1;
1516 else
1517 index = 2;
1518 for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
1519 rfpath++) {
1520 if (rtlhal->macphymode == DUALMAC_DUALPHY &&
1521 rtlhal->interfaceindex == 1) /* MAC 1 5G */
1522 internal_pa = rtlpriv->efuse.internal_pa_5g[1];
1523 else
1524 internal_pa =
1525 rtlpriv->efuse.internal_pa_5g[rfpath];
1526 if (internal_pa) {
1527 for (i = 0;
1528 i < RF_REG_NUM_FOR_C_CUT_5G_INTERNALPA;
1529 i++) {
1530 rtl_set_rfreg(hw, rfpath,
1531 rf_for_c_cut_5g_internal_pa[i],
1532 BRFREGOFFSETMASK,
1533 rf_pram_c_5g_int_pa[index][i]);
1534 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08001535 "offset 0x%x value 0x%x path %d index %d\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -05001536 rf_for_c_cut_5g_internal_pa[i],
1537 rf_pram_c_5g_int_pa[index][i],
Joe Perchesf30d7502012-01-04 19:40:41 -08001538 rfpath, index);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001539 }
1540 } else {
1541 rtl_set_rfreg(hw, (enum radio_path)rfpath, 0x0B,
1542 mask, value);
1543 }
1544 }
1545 } else if (rtlhal->current_bandtype == BAND_ON_2_4G) {
Joe Perchesf30d7502012-01-04 19:40:41 -08001546 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001547 u4tmp = curveindex_2g[channel - 1];
Joe Perches4c488692012-01-04 19:40:42 -08001548 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1549 "ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", u4tmp);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001550 if (channel == 1 || channel == 2 || channel == 4 || channel == 9
1551 || channel == 10 || channel == 11 || channel == 12)
1552 index = 0;
1553 else if (channel == 3 || channel == 13 || channel == 14)
1554 index = 1;
1555 else if (channel >= 5 && channel <= 8)
1556 index = 2;
1557 if (rtlhal->macphymode == DUALMAC_DUALPHY) {
1558 path = RF90_PATH_A;
1559 if (rtlhal->interfaceindex == 0) {
1560 need_pwr_down =
1561 rtl92d_phy_enable_anotherphy(hw, true);
1562 rtlhal->during_mac0init_radiob = true;
1563
1564 if (need_pwr_down)
1565 _rtl92d_phy_enable_rf_env(hw, path,
1566 &u4regvalue);
1567 }
1568 }
1569 for (i = 0; i < RF_REG_NUM_FOR_C_CUT_2G; i++) {
1570 if (rf_reg_for_c_cut_2g[i] == RF_SYN_G7)
1571 rtl_set_rfreg(hw, (enum radio_path)path,
1572 rf_reg_for_c_cut_2g[i],
1573 BRFREGOFFSETMASK,
1574 (rf_reg_param_for_c_cut_2g[index][i] |
1575 BIT(17)));
1576 else
1577 rtl_set_rfreg(hw, (enum radio_path)path,
1578 rf_reg_for_c_cut_2g[i],
1579 BRFREGOFFSETMASK,
1580 rf_reg_param_for_c_cut_2g
1581 [index][i]);
1582 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -08001583 "offset 0x%x value 0x%x mak 0x%x path %d index %d readback 0x%x\n",
1584 rf_reg_for_c_cut_2g[i],
1585 rf_reg_param_for_c_cut_2g[index][i],
1586 rf_reg_mask_for_c_cut_2g[i], path, index,
1587 rtl_get_rfreg(hw, (enum radio_path)path,
1588 rf_reg_for_c_cut_2g[i],
1589 BRFREGOFFSETMASK));
Chaoming Li7274a8c2011-06-10 15:10:25 -05001590 }
1591 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001592 "cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n",
1593 rf_syn_g4_for_c_cut_2g | (u4tmp << 11));
Chaoming Li7274a8c2011-06-10 15:10:25 -05001594
1595 rtl_set_rfreg(hw, (enum radio_path)path, RF_SYN_G4,
1596 BRFREGOFFSETMASK,
1597 rf_syn_g4_for_c_cut_2g | (u4tmp << 11));
1598 if (need_pwr_down)
1599 _rtl92d_phy_restore_rf_env(hw, path, &u4regvalue);
1600 if (rtlhal->during_mac0init_radiob)
1601 rtl92d_phy_powerdown_anotherphy(hw, true);
1602 }
Joe Perchesf30d7502012-01-04 19:40:41 -08001603 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001604}
1605
1606u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl)
1607{
1608 u8 channel_all[59] = {
1609 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
1610 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
1611 60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
1612 114, 116, 118, 120, 122, 124, 126, 128, 130,
1613 132, 134, 136, 138, 140, 149, 151, 153, 155,
1614 157, 159, 161, 163, 165
1615 };
1616 u8 place = chnl;
1617
1618 if (chnl > 14) {
1619 for (place = 14; place < sizeof(channel_all); place++) {
1620 if (channel_all[place] == chnl)
1621 return place - 13;
1622 }
1623 }
1624
1625 return 0;
1626}
1627
1628#define MAX_TOLERANCE 5
1629#define IQK_DELAY_TIME 1 /* ms */
1630#define MAX_TOLERANCE_92D 3
1631
1632/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1633static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb)
1634{
1635 struct rtl_priv *rtlpriv = rtl_priv(hw);
1636 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1637 u32 regeac, rege94, rege9c, regea4;
1638 u8 result = 0;
1639
Joe Perches4c488692012-01-04 19:40:42 -08001640 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001641 /* path-A IQK setting */
Joe Perches4c488692012-01-04 19:40:42 -08001642 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001643 if (rtlhal->interfaceindex == 0) {
1644 rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x10008c1f);
1645 rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x10008c1f);
1646 } else {
1647 rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x10008c22);
1648 rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x10008c22);
1649 }
1650 rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82140102);
1651 rtl_set_bbreg(hw, 0xe3c, BMASKDWORD, 0x28160206);
1652 /* path-B IQK setting */
1653 if (configpathb) {
1654 rtl_set_bbreg(hw, 0xe50, BMASKDWORD, 0x10008c22);
1655 rtl_set_bbreg(hw, 0xe54, BMASKDWORD, 0x10008c22);
1656 rtl_set_bbreg(hw, 0xe58, BMASKDWORD, 0x82140102);
1657 rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x28160206);
1658 }
1659 /* LO calibration setting */
Joe Perches4c488692012-01-04 19:40:42 -08001660 RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001661 rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911);
1662 /* One shot, path A LOK & IQK */
Joe Perches4c488692012-01-04 19:40:42 -08001663 RTPRINT(rtlpriv, FINIT, INIT_IQK, "One shot, path A LOK & IQK!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001664 rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000);
1665 rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000);
1666 /* delay x ms */
1667 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001668 "Delay %d ms for One shot, path A LOK & IQK\n",
1669 IQK_DELAY_TIME);
Andrew Mortonfaeef8a2011-06-30 16:28:50 -05001670 mdelay(IQK_DELAY_TIME);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001671 /* Check failed */
1672 regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001673 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001674 rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001675 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe94 = 0x%x\n", rege94);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001676 rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001677 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe9c = 0x%x\n", rege9c);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001678 regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001679 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xea4 = 0x%x\n", regea4);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001680 if (!(regeac & BIT(28)) && (((rege94 & 0x03FF0000) >> 16) != 0x142) &&
1681 (((rege9c & 0x03FF0000) >> 16) != 0x42))
1682 result |= 0x01;
1683 else /* if Tx not OK, ignore Rx */
1684 return result;
1685 /* if Tx is OK, check whether Rx is OK */
1686 if (!(regeac & BIT(27)) && (((regea4 & 0x03FF0000) >> 16) != 0x132) &&
1687 (((regeac & 0x03FF0000) >> 16) != 0x36))
1688 result |= 0x02;
1689 else
Joe Perches4c488692012-01-04 19:40:42 -08001690 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A Rx IQK fail!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001691 return result;
1692}
1693
1694/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1695static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw,
1696 bool configpathb)
1697{
1698 struct rtl_priv *rtlpriv = rtl_priv(hw);
1699 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1700 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1701 u32 regeac, rege94, rege9c, regea4;
1702 u8 result = 0;
1703 u8 i;
1704 u8 retrycount = 2;
1705 u32 TxOKBit = BIT(28), RxOKBit = BIT(27);
1706
1707 if (rtlhal->interfaceindex == 1) { /* PHY1 */
1708 TxOKBit = BIT(31);
1709 RxOKBit = BIT(30);
1710 }
Joe Perches4c488692012-01-04 19:40:42 -08001711 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001712 /* path-A IQK setting */
Joe Perches4c488692012-01-04 19:40:42 -08001713 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001714 rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f);
1715 rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f);
1716 rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82140307);
1717 rtl_set_bbreg(hw, 0xe3c, BMASKDWORD, 0x68160960);
1718 /* path-B IQK setting */
1719 if (configpathb) {
1720 rtl_set_bbreg(hw, 0xe50, BMASKDWORD, 0x18008c2f);
1721 rtl_set_bbreg(hw, 0xe54, BMASKDWORD, 0x18008c2f);
1722 rtl_set_bbreg(hw, 0xe58, BMASKDWORD, 0x82110000);
1723 rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68110000);
1724 }
1725 /* LO calibration setting */
Joe Perches4c488692012-01-04 19:40:42 -08001726 RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001727 rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911);
1728 /* path-A PA on */
1729 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, 0x07000f60);
1730 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BMASKDWORD, 0x66e60e30);
1731 for (i = 0; i < retrycount; i++) {
1732 /* One shot, path A LOK & IQK */
1733 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001734 "One shot, path A LOK & IQK!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001735 rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000);
1736 rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000);
1737 /* delay x ms */
1738 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001739 "Delay %d ms for One shot, path A LOK & IQK.\n",
1740 IQK_DELAY_TIME);
Andrew Mortonfaeef8a2011-06-30 16:28:50 -05001741 mdelay(IQK_DELAY_TIME * 10);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001742 /* Check failed */
1743 regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001744 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001745 rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001746 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe94 = 0x%x\n", rege94);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001747 rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001748 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe9c = 0x%x\n", rege9c);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001749 regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001750 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xea4 = 0x%x\n", regea4);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001751 if (!(regeac & TxOKBit) &&
1752 (((rege94 & 0x03FF0000) >> 16) != 0x142)) {
1753 result |= 0x01;
1754 } else { /* if Tx not OK, ignore Rx */
1755 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001756 "Path A Tx IQK fail!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001757 continue;
1758 }
1759
1760 /* if Tx is OK, check whether Rx is OK */
1761 if (!(regeac & RxOKBit) &&
1762 (((regea4 & 0x03FF0000) >> 16) != 0x132)) {
1763 result |= 0x02;
1764 break;
1765 } else {
1766 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001767 "Path A Rx IQK fail!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001768 }
1769 }
1770 /* path A PA off */
1771 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD,
1772 rtlphy->iqk_bb_backup[0]);
1773 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BMASKDWORD,
1774 rtlphy->iqk_bb_backup[1]);
1775 return result;
1776}
1777
1778/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1779static u8 _rtl92d_phy_pathb_iqk(struct ieee80211_hw *hw)
1780{
1781 struct rtl_priv *rtlpriv = rtl_priv(hw);
1782 u32 regeac, regeb4, regebc, regec4, regecc;
1783 u8 result = 0;
1784
Joe Perches4c488692012-01-04 19:40:42 -08001785 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQK!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001786 /* One shot, path B LOK & IQK */
Joe Perches4c488692012-01-04 19:40:42 -08001787 RTPRINT(rtlpriv, FINIT, INIT_IQK, "One shot, path A LOK & IQK!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001788 rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000002);
1789 rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000000);
1790 /* delay x ms */
1791 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001792 "Delay %d ms for One shot, path B LOK & IQK\n", IQK_DELAY_TIME);
Andrew Mortonfaeef8a2011-06-30 16:28:50 -05001793 mdelay(IQK_DELAY_TIME);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001794 /* Check failed */
1795 regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001796 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001797 regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001798 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeb4 = 0x%x\n", regeb4);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001799 regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001800 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xebc = 0x%x\n", regebc);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001801 regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001802 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xec4 = 0x%x\n", regec4);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001803 regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001804 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xecc = 0x%x\n", regecc);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001805 if (!(regeac & BIT(31)) && (((regeb4 & 0x03FF0000) >> 16) != 0x142) &&
1806 (((regebc & 0x03FF0000) >> 16) != 0x42))
1807 result |= 0x01;
1808 else
1809 return result;
1810 if (!(regeac & BIT(30)) && (((regec4 & 0x03FF0000) >> 16) != 0x132) &&
1811 (((regecc & 0x03FF0000) >> 16) != 0x36))
1812 result |= 0x02;
1813 else
Joe Perches4c488692012-01-04 19:40:42 -08001814 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B Rx IQK fail!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001815 return result;
1816}
1817
1818/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1819static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw)
1820{
1821 struct rtl_priv *rtlpriv = rtl_priv(hw);
1822 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1823 u32 regeac, regeb4, regebc, regec4, regecc;
1824 u8 result = 0;
1825 u8 i;
1826 u8 retrycount = 2;
1827
Joe Perches4c488692012-01-04 19:40:42 -08001828 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQK!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001829 /* path-A IQK setting */
Joe Perches4c488692012-01-04 19:40:42 -08001830 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001831 rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f);
1832 rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f);
1833 rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82110000);
1834 rtl_set_bbreg(hw, 0xe3c, BMASKDWORD, 0x68110000);
1835
1836 /* path-B IQK setting */
1837 rtl_set_bbreg(hw, 0xe50, BMASKDWORD, 0x18008c2f);
1838 rtl_set_bbreg(hw, 0xe54, BMASKDWORD, 0x18008c2f);
1839 rtl_set_bbreg(hw, 0xe58, BMASKDWORD, 0x82140307);
1840 rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68160960);
1841
1842 /* LO calibration setting */
Joe Perches4c488692012-01-04 19:40:42 -08001843 RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001844 rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911);
1845
1846 /* path-B PA on */
1847 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, 0x0f600700);
1848 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BMASKDWORD, 0x061f0d30);
1849
1850 for (i = 0; i < retrycount; i++) {
1851 /* One shot, path B LOK & IQK */
1852 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001853 "One shot, path A LOK & IQK!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001854 rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xfa000000);
1855 rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000);
1856
1857 /* delay x ms */
1858 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001859 "Delay %d ms for One shot, path B LOK & IQK.\n", 10);
Andrew Mortonfaeef8a2011-06-30 16:28:50 -05001860 mdelay(IQK_DELAY_TIME * 10);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001861
1862 /* Check failed */
1863 regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001864 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001865 regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001866 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeb4 = 0x%x\n", regeb4);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001867 regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001868 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xebc = 0x%x\n", regebc);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001869 regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001870 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xec4 = 0x%x\n", regec4);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001871 regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08001872 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xecc = 0x%x\n", regecc);
Chaoming Li7274a8c2011-06-10 15:10:25 -05001873 if (!(regeac & BIT(31)) &&
1874 (((regeb4 & 0x03FF0000) >> 16) != 0x142))
1875 result |= 0x01;
1876 else
1877 continue;
1878 if (!(regeac & BIT(30)) &&
1879 (((regec4 & 0x03FF0000) >> 16) != 0x132)) {
1880 result |= 0x02;
1881 break;
1882 } else {
1883 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001884 "Path B Rx IQK fail!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001885 }
1886 }
1887
1888 /* path B PA off */
1889 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD,
1890 rtlphy->iqk_bb_backup[0]);
1891 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BMASKDWORD,
1892 rtlphy->iqk_bb_backup[2]);
1893 return result;
1894}
1895
1896static void _rtl92d_phy_save_adda_registers(struct ieee80211_hw *hw,
1897 u32 *adda_reg, u32 *adda_backup,
1898 u32 regnum)
1899{
1900 struct rtl_priv *rtlpriv = rtl_priv(hw);
1901 u32 i;
1902
Joe Perches4c488692012-01-04 19:40:42 -08001903 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Save ADDA parameters.\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001904 for (i = 0; i < regnum; i++)
1905 adda_backup[i] = rtl_get_bbreg(hw, adda_reg[i], BMASKDWORD);
1906}
1907
1908static void _rtl92d_phy_save_mac_registers(struct ieee80211_hw *hw,
1909 u32 *macreg, u32 *macbackup)
1910{
1911 struct rtl_priv *rtlpriv = rtl_priv(hw);
1912 u32 i;
1913
Joe Perches4c488692012-01-04 19:40:42 -08001914 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Save MAC parameters.\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001915 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1916 macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
1917 macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
1918}
1919
1920static void _rtl92d_phy_reload_adda_registers(struct ieee80211_hw *hw,
1921 u32 *adda_reg, u32 *adda_backup,
1922 u32 regnum)
1923{
1924 struct rtl_priv *rtlpriv = rtl_priv(hw);
1925 u32 i;
1926
1927 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001928 "Reload ADDA power saving parameters !\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001929 for (i = 0; i < regnum; i++)
1930 rtl_set_bbreg(hw, adda_reg[i], BMASKDWORD, adda_backup[i]);
1931}
1932
1933static void _rtl92d_phy_reload_mac_registers(struct ieee80211_hw *hw,
1934 u32 *macreg, u32 *macbackup)
1935{
1936 struct rtl_priv *rtlpriv = rtl_priv(hw);
1937 u32 i;
1938
Joe Perches4c488692012-01-04 19:40:42 -08001939 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Reload MAC parameters !\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001940 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1941 rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]);
1942 rtl_write_byte(rtlpriv, macreg[i], macbackup[i]);
1943}
1944
1945static void _rtl92d_phy_path_adda_on(struct ieee80211_hw *hw,
1946 u32 *adda_reg, bool patha_on, bool is2t)
1947{
1948 struct rtl_priv *rtlpriv = rtl_priv(hw);
1949 u32 pathon;
1950 u32 i;
1951
Joe Perches4c488692012-01-04 19:40:42 -08001952 RTPRINT(rtlpriv, FINIT, INIT_IQK, "ADDA ON.\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001953 pathon = patha_on ? 0x04db25a4 : 0x0b1b25a4;
1954 if (patha_on)
1955 pathon = rtlpriv->rtlhal.interfaceindex == 0 ?
1956 0x04db25a4 : 0x0b1b25a4;
1957 for (i = 0; i < IQK_ADDA_REG_NUM; i++)
1958 rtl_set_bbreg(hw, adda_reg[i], BMASKDWORD, pathon);
1959}
1960
1961static void _rtl92d_phy_mac_setting_calibration(struct ieee80211_hw *hw,
1962 u32 *macreg, u32 *macbackup)
1963{
1964 struct rtl_priv *rtlpriv = rtl_priv(hw);
1965 u32 i;
1966
Joe Perches4c488692012-01-04 19:40:42 -08001967 RTPRINT(rtlpriv, FINIT, INIT_IQK, "MAC settings for Calibration.\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001968 rtl_write_byte(rtlpriv, macreg[0], 0x3F);
1969
1970 for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
1971 rtl_write_byte(rtlpriv, macreg[i], (u8)(macbackup[i] &
1972 (~BIT(3))));
1973 rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5))));
1974}
1975
1976static void _rtl92d_phy_patha_standby(struct ieee80211_hw *hw)
1977{
1978 struct rtl_priv *rtlpriv = rtl_priv(hw);
Joe Perches4c488692012-01-04 19:40:42 -08001979 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A standby mode!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001980
1981 rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x0);
1982 rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, BMASKDWORD, 0x00010000);
1983 rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000);
1984}
1985
1986static void _rtl92d_phy_pimode_switch(struct ieee80211_hw *hw, bool pi_mode)
1987{
1988 struct rtl_priv *rtlpriv = rtl_priv(hw);
1989 u32 mode;
1990
1991 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08001992 "BB Switch to %s mode!\n", pi_mode ? "PI" : "SI");
Chaoming Li7274a8c2011-06-10 15:10:25 -05001993 mode = pi_mode ? 0x01000100 : 0x01000000;
1994 rtl_set_bbreg(hw, 0x820, BMASKDWORD, mode);
1995 rtl_set_bbreg(hw, 0x828, BMASKDWORD, mode);
1996}
1997
1998static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8],
1999 u8 t, bool is2t)
2000{
2001 struct rtl_priv *rtlpriv = rtl_priv(hw);
2002 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2003 u32 i;
2004 u8 patha_ok, pathb_ok;
2005 static u32 adda_reg[IQK_ADDA_REG_NUM] = {
2006 RFPGA0_XCD_SWITCHCONTROL, 0xe6c, 0xe70, 0xe74,
2007 0xe78, 0xe7c, 0xe80, 0xe84,
2008 0xe88, 0xe8c, 0xed0, 0xed4,
2009 0xed8, 0xedc, 0xee0, 0xeec
2010 };
2011 static u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
2012 0x522, 0x550, 0x551, 0x040
2013 };
2014 static u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
2015 RFPGA0_XAB_RFINTERFACESW, RFPGA0_XA_RFINTERFACEOE,
2016 RFPGA0_XB_RFINTERFACEOE, ROFDM0_TRMUXPAR,
2017 RFPGA0_XCD_RFINTERFACESW, ROFDM0_TRXPATHENABLE,
2018 RFPGA0_RFMOD, RFPGA0_ANALOGPARAMETER4,
2019 ROFDM0_XAAGCCORE1, ROFDM0_XBAGCCORE1
2020 };
2021 const u32 retrycount = 2;
2022 u32 bbvalue;
2023
Joe Perches4c488692012-01-04 19:40:42 -08002024 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK for 2.4G :Start!!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002025 if (t == 0) {
2026 bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08002027 RTPRINT(rtlpriv, FINIT, INIT_IQK, "==>0x%08x\n", bbvalue);
2028 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n",
2029 is2t ? "2T2R" : "1T1R");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002030
2031 /* Save ADDA parameters, turn Path A ADDA on */
2032 _rtl92d_phy_save_adda_registers(hw, adda_reg,
2033 rtlphy->adda_backup, IQK_ADDA_REG_NUM);
2034 _rtl92d_phy_save_mac_registers(hw, iqk_mac_reg,
2035 rtlphy->iqk_mac_backup);
2036 _rtl92d_phy_save_adda_registers(hw, iqk_bb_reg,
2037 rtlphy->iqk_bb_backup, IQK_BB_REG_NUM);
2038 }
2039 _rtl92d_phy_path_adda_on(hw, adda_reg, true, is2t);
2040 if (t == 0)
2041 rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
2042 RFPGA0_XA_HSSIPARAMETER1, BIT(8));
2043
2044 /* Switch BB to PI mode to do IQ Calibration. */
2045 if (!rtlphy->rfpi_enable)
2046 _rtl92d_phy_pimode_switch(hw, true);
2047
2048 rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00);
2049 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKDWORD, 0x03a05600);
2050 rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, BMASKDWORD, 0x000800e4);
2051 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, BMASKDWORD, 0x22204000);
2052 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xf00000, 0x0f);
2053 if (is2t) {
2054 rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, BMASKDWORD,
2055 0x00010000);
2056 rtl_set_bbreg(hw, RFPGA0_XB_LSSIPARAMETER, BMASKDWORD,
2057 0x00010000);
2058 }
2059 /* MAC settings */
2060 _rtl92d_phy_mac_setting_calibration(hw, iqk_mac_reg,
2061 rtlphy->iqk_mac_backup);
2062 /* Page B init */
2063 rtl_set_bbreg(hw, 0xb68, BMASKDWORD, 0x0f600000);
2064 if (is2t)
2065 rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000);
2066 /* IQ calibration setting */
Joe Perches4c488692012-01-04 19:40:42 -08002067 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK setting!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002068 rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000);
2069 rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x01007c00);
2070 rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800);
2071 for (i = 0; i < retrycount; i++) {
2072 patha_ok = _rtl92d_phy_patha_iqk(hw, is2t);
2073 if (patha_ok == 0x03) {
2074 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002075 "Path A IQK Success!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002076 result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) &
2077 0x3FF0000) >> 16;
2078 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) &
2079 0x3FF0000) >> 16;
2080 result[t][2] = (rtl_get_bbreg(hw, 0xea4, BMASKDWORD) &
2081 0x3FF0000) >> 16;
2082 result[t][3] = (rtl_get_bbreg(hw, 0xeac, BMASKDWORD) &
2083 0x3FF0000) >> 16;
2084 break;
2085 } else if (i == (retrycount - 1) && patha_ok == 0x01) {
2086 /* Tx IQK OK */
2087 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002088 "Path A IQK Only Tx Success!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002089
2090 result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) &
2091 0x3FF0000) >> 16;
2092 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) &
2093 0x3FF0000) >> 16;
2094 }
2095 }
2096 if (0x00 == patha_ok)
Joe Perches4c488692012-01-04 19:40:42 -08002097 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK failed!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002098 if (is2t) {
2099 _rtl92d_phy_patha_standby(hw);
2100 /* Turn Path B ADDA on */
2101 _rtl92d_phy_path_adda_on(hw, adda_reg, false, is2t);
2102 for (i = 0; i < retrycount; i++) {
2103 pathb_ok = _rtl92d_phy_pathb_iqk(hw);
2104 if (pathb_ok == 0x03) {
2105 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002106 "Path B IQK Success!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002107 result[t][4] = (rtl_get_bbreg(hw, 0xeb4,
2108 BMASKDWORD) & 0x3FF0000) >> 16;
2109 result[t][5] = (rtl_get_bbreg(hw, 0xebc,
2110 BMASKDWORD) & 0x3FF0000) >> 16;
2111 result[t][6] = (rtl_get_bbreg(hw, 0xec4,
2112 BMASKDWORD) & 0x3FF0000) >> 16;
2113 result[t][7] = (rtl_get_bbreg(hw, 0xecc,
2114 BMASKDWORD) & 0x3FF0000) >> 16;
2115 break;
2116 } else if (i == (retrycount - 1) && pathb_ok == 0x01) {
2117 /* Tx IQK OK */
2118 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002119 "Path B Only Tx IQK Success!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002120 result[t][4] = (rtl_get_bbreg(hw, 0xeb4,
2121 BMASKDWORD) & 0x3FF0000) >> 16;
2122 result[t][5] = (rtl_get_bbreg(hw, 0xebc,
2123 BMASKDWORD) & 0x3FF0000) >> 16;
2124 }
2125 }
2126 if (0x00 == pathb_ok)
2127 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002128 "Path B IQK failed!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002129 }
2130
2131 /* Back to BB mode, load original value */
2132 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002133 "IQK:Back to BB mode, load original value!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002134
2135 rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0);
2136 if (t != 0) {
2137 /* Switch back BB to SI mode after finish IQ Calibration. */
2138 if (!rtlphy->rfpi_enable)
2139 _rtl92d_phy_pimode_switch(hw, false);
2140 /* Reload ADDA power saving parameters */
2141 _rtl92d_phy_reload_adda_registers(hw, adda_reg,
2142 rtlphy->adda_backup, IQK_ADDA_REG_NUM);
2143 /* Reload MAC parameters */
2144 _rtl92d_phy_reload_mac_registers(hw, iqk_mac_reg,
2145 rtlphy->iqk_mac_backup);
2146 if (is2t)
2147 _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg,
2148 rtlphy->iqk_bb_backup,
2149 IQK_BB_REG_NUM);
2150 else
2151 _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg,
2152 rtlphy->iqk_bb_backup,
2153 IQK_BB_REG_NUM - 1);
2154 /* load 0xe30 IQC default value */
2155 rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x01008c00);
2156 rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x01008c00);
2157 }
Joe Perches4c488692012-01-04 19:40:42 -08002158 RTPRINT(rtlpriv, FINIT, INIT_IQK, "<==\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002159}
2160
2161static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw,
2162 long result[][8], u8 t)
2163{
2164 struct rtl_priv *rtlpriv = rtl_priv(hw);
2165 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2166 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
2167 u8 patha_ok, pathb_ok;
2168 static u32 adda_reg[IQK_ADDA_REG_NUM] = {
2169 RFPGA0_XCD_SWITCHCONTROL, 0xe6c, 0xe70, 0xe74,
2170 0xe78, 0xe7c, 0xe80, 0xe84,
2171 0xe88, 0xe8c, 0xed0, 0xed4,
2172 0xed8, 0xedc, 0xee0, 0xeec
2173 };
2174 static u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
2175 0x522, 0x550, 0x551, 0x040
2176 };
2177 static u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
2178 RFPGA0_XAB_RFINTERFACESW, RFPGA0_XA_RFINTERFACEOE,
2179 RFPGA0_XB_RFINTERFACEOE, ROFDM0_TRMUXPAR,
2180 RFPGA0_XCD_RFINTERFACESW, ROFDM0_TRXPATHENABLE,
2181 RFPGA0_RFMOD, RFPGA0_ANALOGPARAMETER4,
2182 ROFDM0_XAAGCCORE1, ROFDM0_XBAGCCORE1
2183 };
2184 u32 bbvalue;
2185 bool is2t = IS_92D_SINGLEPHY(rtlhal->version);
2186
2187 /* Note: IQ calibration must be performed after loading
2188 * PHY_REG.txt , and radio_a, radio_b.txt */
2189
Joe Perches4c488692012-01-04 19:40:42 -08002190 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK for 5G NORMAL:Start!!!\n");
Andrew Mortonfaeef8a2011-06-30 16:28:50 -05002191 mdelay(IQK_DELAY_TIME * 20);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002192 if (t == 0) {
2193 bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD);
Joe Perches4c488692012-01-04 19:40:42 -08002194 RTPRINT(rtlpriv, FINIT, INIT_IQK, "==>0x%08x\n", bbvalue);
2195 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n",
2196 is2t ? "2T2R" : "1T1R");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002197 /* Save ADDA parameters, turn Path A ADDA on */
2198 _rtl92d_phy_save_adda_registers(hw, adda_reg,
2199 rtlphy->adda_backup,
2200 IQK_ADDA_REG_NUM);
2201 _rtl92d_phy_save_mac_registers(hw, iqk_mac_reg,
2202 rtlphy->iqk_mac_backup);
2203 if (is2t)
2204 _rtl92d_phy_save_adda_registers(hw, iqk_bb_reg,
2205 rtlphy->iqk_bb_backup,
2206 IQK_BB_REG_NUM);
2207 else
2208 _rtl92d_phy_save_adda_registers(hw, iqk_bb_reg,
2209 rtlphy->iqk_bb_backup,
2210 IQK_BB_REG_NUM - 1);
2211 }
2212 _rtl92d_phy_path_adda_on(hw, adda_reg, true, is2t);
2213 /* MAC settings */
2214 _rtl92d_phy_mac_setting_calibration(hw, iqk_mac_reg,
2215 rtlphy->iqk_mac_backup);
2216 if (t == 0)
2217 rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
2218 RFPGA0_XA_HSSIPARAMETER1, BIT(8));
2219 /* Switch BB to PI mode to do IQ Calibration. */
2220 if (!rtlphy->rfpi_enable)
2221 _rtl92d_phy_pimode_switch(hw, true);
2222 rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00);
2223 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKDWORD, 0x03a05600);
2224 rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, BMASKDWORD, 0x000800e4);
2225 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, BMASKDWORD, 0x22208000);
2226 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xf00000, 0x0f);
2227
2228 /* Page B init */
2229 rtl_set_bbreg(hw, 0xb68, BMASKDWORD, 0x0f600000);
2230 if (is2t)
2231 rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000);
2232 /* IQ calibration setting */
Joe Perches4c488692012-01-04 19:40:42 -08002233 RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK setting!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002234 rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000);
2235 rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x10007c00);
2236 rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800);
2237 patha_ok = _rtl92d_phy_patha_iqk_5g_normal(hw, is2t);
2238 if (patha_ok == 0x03) {
Joe Perches4c488692012-01-04 19:40:42 -08002239 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK Success!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002240 result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) &
2241 0x3FF0000) >> 16;
2242 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) &
2243 0x3FF0000) >> 16;
2244 result[t][2] = (rtl_get_bbreg(hw, 0xea4, BMASKDWORD) &
2245 0x3FF0000) >> 16;
2246 result[t][3] = (rtl_get_bbreg(hw, 0xeac, BMASKDWORD) &
2247 0x3FF0000) >> 16;
2248 } else if (patha_ok == 0x01) { /* Tx IQK OK */
2249 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002250 "Path A IQK Only Tx Success!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002251
2252 result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) &
2253 0x3FF0000) >> 16;
2254 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) &
2255 0x3FF0000) >> 16;
2256 } else {
Joe Perches4c488692012-01-04 19:40:42 -08002257 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK Fail!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002258 }
2259 if (is2t) {
2260 /* _rtl92d_phy_patha_standby(hw); */
2261 /* Turn Path B ADDA on */
2262 _rtl92d_phy_path_adda_on(hw, adda_reg, false, is2t);
2263 pathb_ok = _rtl92d_phy_pathb_iqk_5g_normal(hw);
2264 if (pathb_ok == 0x03) {
2265 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002266 "Path B IQK Success!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002267 result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) &
2268 0x3FF0000) >> 16;
2269 result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) &
2270 0x3FF0000) >> 16;
2271 result[t][6] = (rtl_get_bbreg(hw, 0xec4, BMASKDWORD) &
2272 0x3FF0000) >> 16;
2273 result[t][7] = (rtl_get_bbreg(hw, 0xecc, BMASKDWORD) &
2274 0x3FF0000) >> 16;
2275 } else if (pathb_ok == 0x01) { /* Tx IQK OK */
2276 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002277 "Path B Only Tx IQK Success!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002278 result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) &
2279 0x3FF0000) >> 16;
2280 result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) &
2281 0x3FF0000) >> 16;
2282 } else {
2283 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002284 "Path B IQK failed!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002285 }
2286 }
2287
2288 /* Back to BB mode, load original value */
2289 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002290 "IQK:Back to BB mode, load original value!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002291 rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0);
2292 if (t != 0) {
2293 if (is2t)
2294 _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg,
2295 rtlphy->iqk_bb_backup,
2296 IQK_BB_REG_NUM);
2297 else
2298 _rtl92d_phy_reload_adda_registers(hw, iqk_bb_reg,
2299 rtlphy->iqk_bb_backup,
2300 IQK_BB_REG_NUM - 1);
2301 /* Reload MAC parameters */
2302 _rtl92d_phy_reload_mac_registers(hw, iqk_mac_reg,
2303 rtlphy->iqk_mac_backup);
2304 /* Switch back BB to SI mode after finish IQ Calibration. */
2305 if (!rtlphy->rfpi_enable)
2306 _rtl92d_phy_pimode_switch(hw, false);
2307 /* Reload ADDA power saving parameters */
2308 _rtl92d_phy_reload_adda_registers(hw, adda_reg,
2309 rtlphy->adda_backup,
2310 IQK_ADDA_REG_NUM);
2311 }
Joe Perches4c488692012-01-04 19:40:42 -08002312 RTPRINT(rtlpriv, FINIT, INIT_IQK, "<==\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002313}
2314
2315static bool _rtl92d_phy_simularity_compare(struct ieee80211_hw *hw,
2316 long result[][8], u8 c1, u8 c2)
2317{
2318 struct rtl_priv *rtlpriv = rtl_priv(hw);
2319 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
2320 u32 i, j, diff, sim_bitmap, bound;
2321 u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */
2322 bool bresult = true;
2323 bool is2t = IS_92D_SINGLEPHY(rtlhal->version);
2324
2325 if (is2t)
2326 bound = 8;
2327 else
2328 bound = 4;
2329 sim_bitmap = 0;
2330 for (i = 0; i < bound; i++) {
2331 diff = (result[c1][i] > result[c2][i]) ? (result[c1][i] -
2332 result[c2][i]) : (result[c2][i] - result[c1][i]);
2333 if (diff > MAX_TOLERANCE_92D) {
2334 if ((i == 2 || i == 6) && !sim_bitmap) {
2335 if (result[c1][i] + result[c1][i + 1] == 0)
2336 final_candidate[(i / 4)] = c2;
2337 else if (result[c2][i] + result[c2][i + 1] == 0)
2338 final_candidate[(i / 4)] = c1;
2339 else
2340 sim_bitmap = sim_bitmap | (1 << i);
2341 } else {
2342 sim_bitmap = sim_bitmap | (1 << i);
2343 }
2344 }
2345 }
2346 if (sim_bitmap == 0) {
2347 for (i = 0; i < (bound / 4); i++) {
2348 if (final_candidate[i] != 0xFF) {
2349 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
2350 result[3][j] =
2351 result[final_candidate[i]][j];
2352 bresult = false;
2353 }
2354 }
2355 return bresult;
2356 }
2357 if (!(sim_bitmap & 0x0F)) { /* path A OK */
2358 for (i = 0; i < 4; i++)
2359 result[3][i] = result[c1][i];
2360 } else if (!(sim_bitmap & 0x03)) { /* path A, Tx OK */
2361 for (i = 0; i < 2; i++)
2362 result[3][i] = result[c1][i];
2363 }
2364 if (!(sim_bitmap & 0xF0) && is2t) { /* path B OK */
2365 for (i = 4; i < 8; i++)
2366 result[3][i] = result[c1][i];
2367 } else if (!(sim_bitmap & 0x30)) { /* path B, Tx OK */
2368 for (i = 4; i < 6; i++)
2369 result[3][i] = result[c1][i];
2370 }
2371 return false;
2372}
2373
2374static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw,
2375 bool iqk_ok, long result[][8],
2376 u8 final_candidate, bool txonly)
2377{
2378 struct rtl_priv *rtlpriv = rtl_priv(hw);
2379 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
2380 u32 oldval_0, val_x, tx0_a, reg;
2381 long val_y, tx0_c;
2382 bool is2t = IS_92D_SINGLEPHY(rtlhal->version) ||
2383 rtlhal->macphymode == DUALMAC_DUALPHY;
2384
2385 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002386 "Path A IQ Calibration %s !\n", iqk_ok ? "Success" : "Failed");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002387 if (final_candidate == 0xFF) {
2388 return;
2389 } else if (iqk_ok) {
2390 oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE,
2391 BMASKDWORD) >> 22) & 0x3FF; /* OFDM0_D */
2392 val_x = result[final_candidate][0];
2393 if ((val_x & 0x00000200) != 0)
2394 val_x = val_x | 0xFFFFFC00;
2395 tx0_a = (val_x * oldval_0) >> 8;
Joe Perches4c488692012-01-04 19:40:42 -08002396 RTPRINT(rtlpriv, FINIT, INIT_IQK,
2397 "X = 0x%x, tx0_a = 0x%x, oldval_0 0x%x\n",
2398 val_x, tx0_a, oldval_0);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002399 rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 0x3FF, tx0_a);
2400 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24),
2401 ((val_x * oldval_0 >> 7) & 0x1));
2402 val_y = result[final_candidate][1];
2403 if ((val_y & 0x00000200) != 0)
2404 val_y = val_y | 0xFFFFFC00;
2405 /* path B IQK result + 3 */
2406 if (rtlhal->interfaceindex == 1 &&
2407 rtlhal->current_bandtype == BAND_ON_5G)
2408 val_y += 3;
2409 tx0_c = (val_y * oldval_0) >> 8;
Joe Perches4c488692012-01-04 19:40:42 -08002410 RTPRINT(rtlpriv, FINIT, INIT_IQK,
2411 "Y = 0x%lx, tx0_c = 0x%lx\n",
2412 val_y, tx0_c);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002413 rtl_set_bbreg(hw, ROFDM0_XCTxAFE, 0xF0000000,
2414 ((tx0_c & 0x3C0) >> 6));
2415 rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 0x003F0000,
2416 (tx0_c & 0x3F));
2417 if (is2t)
2418 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(26),
2419 ((val_y * oldval_0 >> 7) & 0x1));
Joe Perches4c488692012-01-04 19:40:42 -08002420 RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xC80 = 0x%x\n",
2421 rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE,
2422 BMASKDWORD));
Chaoming Li7274a8c2011-06-10 15:10:25 -05002423 if (txonly) {
Joe Perches4c488692012-01-04 19:40:42 -08002424 RTPRINT(rtlpriv, FINIT, INIT_IQK, "only Tx OK\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002425 return;
2426 }
2427 reg = result[final_candidate][2];
2428 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
2429 reg = result[final_candidate][3] & 0x3F;
2430 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
2431 reg = (result[final_candidate][3] >> 6) & 0xF;
2432 rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg);
2433 }
2434}
2435
2436static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw,
2437 bool iqk_ok, long result[][8], u8 final_candidate, bool txonly)
2438{
2439 struct rtl_priv *rtlpriv = rtl_priv(hw);
2440 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
2441 u32 oldval_1, val_x, tx1_a, reg;
2442 long val_y, tx1_c;
2443
Joe Perches4c488692012-01-04 19:40:42 -08002444 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQ Calibration %s !\n",
2445 iqk_ok ? "Success" : "Failed");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002446 if (final_candidate == 0xFF) {
2447 return;
2448 } else if (iqk_ok) {
2449 oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTxIQIMBALANCE,
2450 BMASKDWORD) >> 22) & 0x3FF;
2451 val_x = result[final_candidate][4];
2452 if ((val_x & 0x00000200) != 0)
2453 val_x = val_x | 0xFFFFFC00;
2454 tx1_a = (val_x * oldval_1) >> 8;
Joe Perches4c488692012-01-04 19:40:42 -08002455 RTPRINT(rtlpriv, FINIT, INIT_IQK, "X = 0x%x, tx1_a = 0x%x\n",
2456 val_x, tx1_a);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002457 rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, 0x3FF, tx1_a);
2458 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28),
2459 ((val_x * oldval_1 >> 7) & 0x1));
2460 val_y = result[final_candidate][5];
2461 if ((val_y & 0x00000200) != 0)
2462 val_y = val_y | 0xFFFFFC00;
2463 if (rtlhal->current_bandtype == BAND_ON_5G)
2464 val_y += 3;
2465 tx1_c = (val_y * oldval_1) >> 8;
Joe Perches4c488692012-01-04 19:40:42 -08002466 RTPRINT(rtlpriv, FINIT, INIT_IQK, "Y = 0x%lx, tx1_c = 0x%lx\n",
2467 val_y, tx1_c);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002468 rtl_set_bbreg(hw, ROFDM0_XDTxAFE, 0xF0000000,
2469 ((tx1_c & 0x3C0) >> 6));
2470 rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, 0x003F0000,
2471 (tx1_c & 0x3F));
2472 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(30),
2473 ((val_y * oldval_1 >> 7) & 0x1));
2474 if (txonly)
2475 return;
2476 reg = result[final_candidate][6];
2477 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
2478 reg = result[final_candidate][7] & 0x3F;
2479 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
2480 reg = (result[final_candidate][7] >> 6) & 0xF;
2481 rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg);
2482 }
2483}
2484
2485void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw)
2486{
2487 struct rtl_priv *rtlpriv = rtl_priv(hw);
2488 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2489 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
2490 long result[4][8];
2491 u8 i, final_candidate, indexforchannel;
2492 bool patha_ok, pathb_ok;
2493 long rege94, rege9c, regea4, regeac, regeb4;
2494 long regebc, regec4, regecc, regtmp = 0;
2495 bool is12simular, is13simular, is23simular;
2496 unsigned long flag = 0;
2497
2498 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002499 "IQK:Start!!!channel %d\n", rtlphy->current_channel);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002500 for (i = 0; i < 8; i++) {
2501 result[0][i] = 0;
2502 result[1][i] = 0;
2503 result[2][i] = 0;
2504 result[3][i] = 0;
2505 }
2506 final_candidate = 0xff;
2507 patha_ok = false;
2508 pathb_ok = false;
2509 is12simular = false;
2510 is23simular = false;
2511 is13simular = false;
2512 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002513 "IQK !!!currentband %d\n", rtlhal->current_bandtype);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002514 rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag);
2515 for (i = 0; i < 3; i++) {
2516 if (rtlhal->current_bandtype == BAND_ON_5G) {
2517 _rtl92d_phy_iq_calibrate_5g_normal(hw, result, i);
2518 } else if (rtlhal->current_bandtype == BAND_ON_2_4G) {
2519 if (IS_92D_SINGLEPHY(rtlhal->version))
2520 _rtl92d_phy_iq_calibrate(hw, result, i, true);
2521 else
2522 _rtl92d_phy_iq_calibrate(hw, result, i, false);
2523 }
2524 if (i == 1) {
2525 is12simular = _rtl92d_phy_simularity_compare(hw, result,
2526 0, 1);
2527 if (is12simular) {
2528 final_candidate = 0;
2529 break;
2530 }
2531 }
2532 if (i == 2) {
2533 is13simular = _rtl92d_phy_simularity_compare(hw, result,
2534 0, 2);
2535 if (is13simular) {
2536 final_candidate = 0;
2537 break;
2538 }
2539 is23simular = _rtl92d_phy_simularity_compare(hw, result,
2540 1, 2);
2541 if (is23simular) {
2542 final_candidate = 1;
2543 } else {
2544 for (i = 0; i < 8; i++)
2545 regtmp += result[3][i];
2546
2547 if (regtmp != 0)
2548 final_candidate = 3;
2549 else
2550 final_candidate = 0xFF;
2551 }
2552 }
2553 }
2554 rtl92d_release_cckandrw_pagea_ctl(hw, &flag);
2555 for (i = 0; i < 4; i++) {
2556 rege94 = result[i][0];
2557 rege9c = result[i][1];
2558 regea4 = result[i][2];
2559 regeac = result[i][3];
2560 regeb4 = result[i][4];
2561 regebc = result[i][5];
2562 regec4 = result[i][6];
2563 regecc = result[i][7];
2564 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002565 "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 -05002566 rege94, rege9c, regea4, regeac, regeb4, regebc, regec4,
Joe Perches4c488692012-01-04 19:40:42 -08002567 regecc);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002568 }
2569 if (final_candidate != 0xff) {
2570 rtlphy->reg_e94 = rege94 = result[final_candidate][0];
2571 rtlphy->reg_e9c = rege9c = result[final_candidate][1];
2572 regea4 = result[final_candidate][2];
2573 regeac = result[final_candidate][3];
2574 rtlphy->reg_eb4 = regeb4 = result[final_candidate][4];
2575 rtlphy->reg_ebc = regebc = result[final_candidate][5];
2576 regec4 = result[final_candidate][6];
2577 regecc = result[final_candidate][7];
2578 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002579 "IQK: final_candidate is %x\n", final_candidate);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002580 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002581 "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 -05002582 rege94, rege9c, regea4, regeac, regeb4, regebc, regec4,
Joe Perches4c488692012-01-04 19:40:42 -08002583 regecc);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002584 patha_ok = pathb_ok = true;
2585 } else {
2586 rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; /* X default value */
2587 rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; /* Y default value */
2588 }
2589 if ((rege94 != 0) /*&&(regea4 != 0) */)
2590 _rtl92d_phy_patha_fill_iqk_matrix(hw, patha_ok, result,
2591 final_candidate, (regea4 == 0));
2592 if (IS_92D_SINGLEPHY(rtlhal->version)) {
2593 if ((regeb4 != 0) /*&&(regec4 != 0) */)
2594 _rtl92d_phy_pathb_fill_iqk_matrix(hw, pathb_ok, result,
2595 final_candidate, (regec4 == 0));
2596 }
2597 if (final_candidate != 0xFF) {
2598 indexforchannel = rtl92d_get_rightchnlplace_for_iqk(
2599 rtlphy->current_channel);
2600
2601 for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
2602 rtlphy->iqk_matrix_regsetting[indexforchannel].
2603 value[0][i] = result[final_candidate][i];
2604 rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done =
2605 true;
2606
2607 RT_TRACE(rtlpriv, COMP_SCAN | COMP_MLME, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08002608 "IQK OK indexforchannel %d\n", indexforchannel);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002609 }
2610}
2611
2612void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel)
2613{
2614 struct rtl_priv *rtlpriv = rtl_priv(hw);
2615 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2616 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
2617 u8 indexforchannel;
2618
Joe Perchesf30d7502012-01-04 19:40:41 -08002619 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "channel %d\n", channel);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002620 /*------Do IQK for normal chip and test chip 5G band------- */
2621 indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel);
Joe Perchesf30d7502012-01-04 19:40:41 -08002622 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "indexforchannel %d done %d\n",
2623 indexforchannel,
2624 rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002625 if (0 && !rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done &&
2626 rtlphy->need_iqk) {
2627 /* Re Do IQK. */
2628 RT_TRACE(rtlpriv, COMP_SCAN | COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08002629 "Do IQK Matrix reg for channel:%d....\n", channel);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002630 rtl92d_phy_iq_calibrate(hw);
2631 } else {
2632 /* Just load the value. */
2633 /* 2G band just load once. */
2634 if (((!rtlhal->load_imrandiqk_setting_for2g) &&
2635 indexforchannel == 0) || indexforchannel > 0) {
2636 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08002637 "Just Read IQK Matrix reg for channel:%d....\n",
2638 channel);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002639 if ((rtlphy->iqk_matrix_regsetting[indexforchannel].
2640 value[0] != NULL)
2641 /*&&(regea4 != 0) */)
2642 _rtl92d_phy_patha_fill_iqk_matrix(hw, true,
2643 rtlphy->iqk_matrix_regsetting[
2644 indexforchannel].value, 0,
2645 (rtlphy->iqk_matrix_regsetting[
2646 indexforchannel].value[0][2] == 0));
2647 if (IS_92D_SINGLEPHY(rtlhal->version)) {
2648 if ((rtlphy->iqk_matrix_regsetting[
2649 indexforchannel].value[0][4] != 0)
2650 /*&&(regec4 != 0) */)
2651 _rtl92d_phy_pathb_fill_iqk_matrix(hw,
2652 true,
2653 rtlphy->iqk_matrix_regsetting[
2654 indexforchannel].value, 0,
2655 (rtlphy->iqk_matrix_regsetting[
2656 indexforchannel].value[0][6]
2657 == 0));
2658 }
2659 }
2660 }
2661 rtlphy->need_iqk = false;
Joe Perchesf30d7502012-01-04 19:40:41 -08002662 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002663}
2664
2665static u32 _rtl92d_phy_get_abs(u32 val1, u32 val2)
2666{
2667 u32 ret;
2668
2669 if (val1 >= val2)
2670 ret = val1 - val2;
2671 else
2672 ret = val2 - val1;
2673 return ret;
2674}
2675
2676static bool _rtl92d_is_legal_5g_channel(struct ieee80211_hw *hw, u8 channel)
2677{
2678
2679 int i;
2680 u8 channel_5g[45] = {
2681 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
2682 60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
2683 114, 116, 118, 120, 122, 124, 126, 128, 130, 132,
2684 134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
2685 161, 163, 165
2686 };
2687
2688 for (i = 0; i < sizeof(channel_5g); i++)
2689 if (channel == channel_5g[i])
2690 return true;
2691 return false;
2692}
2693
2694static void _rtl92d_phy_calc_curvindex(struct ieee80211_hw *hw,
2695 u32 *targetchnl, u32 * curvecount_val,
2696 bool is5g, u32 *curveindex)
2697{
2698 struct rtl_priv *rtlpriv = rtl_priv(hw);
2699 u32 smallest_abs_val = 0xffffffff, u4tmp;
2700 u8 i, j;
2701 u8 chnl_num = is5g ? TARGET_CHNL_NUM_5G : TARGET_CHNL_NUM_2G;
2702
2703 for (i = 0; i < chnl_num; i++) {
2704 if (is5g && !_rtl92d_is_legal_5g_channel(hw, i + 1))
2705 continue;
2706 curveindex[i] = 0;
2707 for (j = 0; j < (CV_CURVE_CNT * 2); j++) {
2708 u4tmp = _rtl92d_phy_get_abs(targetchnl[i],
2709 curvecount_val[j]);
2710
2711 if (u4tmp < smallest_abs_val) {
2712 curveindex[i] = j;
2713 smallest_abs_val = u4tmp;
2714 }
2715 }
2716 smallest_abs_val = 0xffffffff;
Joe Perches4c488692012-01-04 19:40:42 -08002717 RTPRINT(rtlpriv, FINIT, INIT_IQK, "curveindex[%d] = %x\n",
2718 i, curveindex[i]);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002719 }
2720}
2721
2722static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw,
2723 u8 channel)
2724{
2725 struct rtl_priv *rtlpriv = rtl_priv(hw);
2726 u8 erfpath = rtlpriv->rtlhal.current_bandtype ==
2727 BAND_ON_5G ? RF90_PATH_A :
2728 IS_92D_SINGLEPHY(rtlpriv->rtlhal.version) ?
2729 RF90_PATH_B : RF90_PATH_A;
2730 u32 u4tmp = 0, u4regvalue = 0;
2731 bool bneed_powerdown_radio = false;
2732
Joe Perchesf30d7502012-01-04 19:40:41 -08002733 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "path %d\n", erfpath);
Joe Perches4c488692012-01-04 19:40:42 -08002734 RTPRINT(rtlpriv, FINIT, INIT_IQK, "band type = %d\n",
2735 rtlpriv->rtlhal.current_bandtype);
2736 RTPRINT(rtlpriv, FINIT, INIT_IQK, "channel = %d\n", channel);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002737 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {/* Path-A for 5G */
2738 u4tmp = curveindex_5g[channel-1];
2739 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002740 "ver 1 set RF-A, 5G, 0x28 = 0x%ulx !!\n", u4tmp);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002741 if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY &&
2742 rtlpriv->rtlhal.interfaceindex == 1) {
2743 bneed_powerdown_radio =
2744 rtl92d_phy_enable_anotherphy(hw, false);
2745 rtlpriv->rtlhal.during_mac1init_radioa = true;
2746 /* asume no this case */
2747 if (bneed_powerdown_radio)
2748 _rtl92d_phy_enable_rf_env(hw, erfpath,
2749 &u4regvalue);
2750 }
2751 rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp);
2752 if (bneed_powerdown_radio)
2753 _rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue);
2754 if (rtlpriv->rtlhal.during_mac1init_radioa)
2755 rtl92d_phy_powerdown_anotherphy(hw, false);
2756 } else if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) {
2757 u4tmp = curveindex_2g[channel-1];
2758 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002759 "ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", u4tmp);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002760 if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY &&
2761 rtlpriv->rtlhal.interfaceindex == 0) {
2762 bneed_powerdown_radio =
2763 rtl92d_phy_enable_anotherphy(hw, true);
2764 rtlpriv->rtlhal.during_mac0init_radiob = true;
2765 if (bneed_powerdown_radio)
2766 _rtl92d_phy_enable_rf_env(hw, erfpath,
2767 &u4regvalue);
2768 }
2769 rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp);
2770 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002771 "ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n",
2772 rtl_get_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800));
Chaoming Li7274a8c2011-06-10 15:10:25 -05002773 if (bneed_powerdown_radio)
2774 _rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue);
2775 if (rtlpriv->rtlhal.during_mac0init_radiob)
2776 rtl92d_phy_powerdown_anotherphy(hw, true);
2777 }
Joe Perchesf30d7502012-01-04 19:40:41 -08002778 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002779}
2780
2781static void _rtl92d_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t)
2782{
2783 struct rtl_priv *rtlpriv = rtl_priv(hw);
2784 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
2785 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
2786 u8 tmpreg, index, rf_mode[2];
2787 u8 path = is2t ? 2 : 1;
2788 u8 i;
2789 u32 u4tmp, offset;
2790 u32 curvecount_val[CV_CURVE_CNT * 2] = {0};
2791 u16 timeout = 800, timecount = 0;
2792
2793 /* Check continuous TX and Packet TX */
2794 tmpreg = rtl_read_byte(rtlpriv, 0xd03);
2795 /* if Deal with contisuous TX case, disable all continuous TX */
2796 /* if Deal with Packet TX case, block all queues */
2797 if ((tmpreg & 0x70) != 0)
2798 rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
2799 else
2800 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2801 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xF00000, 0x0F);
2802 for (index = 0; index < path; index++) {
2803 /* 1. Read original RF mode */
2804 offset = index == 0 ? ROFDM0_XAAGCCORE1 : ROFDM0_XBAGCCORE1;
2805 rf_mode[index] = rtl_read_byte(rtlpriv, offset);
2806 /* 2. Set RF mode = standby mode */
2807 rtl_set_rfreg(hw, (enum radio_path)index, RF_AC,
2808 BRFREGOFFSETMASK, 0x010000);
2809 if (rtlpci->init_ready) {
2810 /* switch CV-curve control by LC-calibration */
2811 rtl_set_rfreg(hw, (enum radio_path)index, RF_SYN_G7,
2812 BIT(17), 0x0);
2813 /* 4. Set LC calibration begin */
2814 rtl_set_rfreg(hw, (enum radio_path)index, RF_CHNLBW,
2815 0x08000, 0x01);
2816 }
2817 u4tmp = rtl_get_rfreg(hw, (enum radio_path)index, RF_SYN_G6,
2818 BRFREGOFFSETMASK);
2819 while ((!(u4tmp & BIT(11))) && timecount <= timeout) {
2820 mdelay(50);
2821 timecount += 50;
2822 u4tmp = rtl_get_rfreg(hw, (enum radio_path)index,
2823 RF_SYN_G6, BRFREGOFFSETMASK);
2824 }
2825 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002826 "PHY_LCK finish delay for %d ms=2\n", timecount);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002827 u4tmp = rtl_get_rfreg(hw, index, RF_SYN_G4, BRFREGOFFSETMASK);
2828 if (index == 0 && rtlhal->interfaceindex == 0) {
2829 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002830 "path-A / 5G LCK\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002831 } else {
2832 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002833 "path-B / 2.4G LCK\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002834 }
2835 memset(&curvecount_val[0], 0, CV_CURVE_CNT * 2);
2836 /* Set LC calibration off */
2837 rtl_set_rfreg(hw, (enum radio_path)index, RF_CHNLBW,
2838 0x08000, 0x0);
Joe Perches4c488692012-01-04 19:40:42 -08002839 RTPRINT(rtlpriv, FINIT, INIT_IQK, "set RF 0x18[15] = 0\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002840 /* save Curve-counting number */
2841 for (i = 0; i < CV_CURVE_CNT; i++) {
2842 u32 readval = 0, readval2 = 0;
2843 rtl_set_rfreg(hw, (enum radio_path)index, 0x3F,
2844 0x7f, i);
2845
2846 rtl_set_rfreg(hw, (enum radio_path)index, 0x4D,
2847 BRFREGOFFSETMASK, 0x0);
2848 readval = rtl_get_rfreg(hw, (enum radio_path)index,
2849 0x4F, BRFREGOFFSETMASK);
2850 curvecount_val[2 * i + 1] = (readval & 0xfffe0) >> 5;
2851 /* reg 0x4f [4:0] */
2852 /* reg 0x50 [19:10] */
2853 readval2 = rtl_get_rfreg(hw, (enum radio_path)index,
2854 0x50, 0xffc00);
2855 curvecount_val[2 * i] = (((readval & 0x1F) << 10) |
2856 readval2);
2857 }
2858 if (index == 0 && rtlhal->interfaceindex == 0)
2859 _rtl92d_phy_calc_curvindex(hw, targetchnl_5g,
2860 curvecount_val,
2861 true, curveindex_5g);
2862 else
2863 _rtl92d_phy_calc_curvindex(hw, targetchnl_2g,
2864 curvecount_val,
2865 false, curveindex_2g);
2866 /* switch CV-curve control mode */
2867 rtl_set_rfreg(hw, (enum radio_path)index, RF_SYN_G7,
2868 BIT(17), 0x1);
2869 }
2870
2871 /* Restore original situation */
2872 for (index = 0; index < path; index++) {
2873 offset = index == 0 ? ROFDM0_XAAGCCORE1 : ROFDM0_XBAGCCORE1;
2874 rtl_write_byte(rtlpriv, offset, 0x50);
2875 rtl_write_byte(rtlpriv, offset, rf_mode[index]);
2876 }
2877 if ((tmpreg & 0x70) != 0)
2878 rtl_write_byte(rtlpriv, 0xd03, tmpreg);
2879 else /*Deal with Packet TX case */
2880 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2881 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0xF00000, 0x00);
2882 _rtl92d_phy_reload_lck_setting(hw, rtlpriv->phy.current_channel);
2883}
2884
2885static void _rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
2886{
2887 struct rtl_priv *rtlpriv = rtl_priv(hw);
2888
Joe Perches4c488692012-01-04 19:40:42 -08002889 RTPRINT(rtlpriv, FINIT, INIT_IQK, "cosa PHY_LCK ver=2\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002890 _rtl92d_phy_lc_calibrate_sw(hw, is2t);
2891}
2892
2893void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw)
2894{
2895 struct rtl_priv *rtlpriv = rtl_priv(hw);
2896 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2897 struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
2898 u32 timeout = 2000, timecount = 0;
2899
2900 while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
2901 udelay(50);
2902 timecount += 50;
2903 }
2904
2905 rtlphy->lck_inprogress = true;
2906 RTPRINT(rtlpriv, FINIT, INIT_IQK,
Joe Perches4c488692012-01-04 19:40:42 -08002907 "LCK:Start!!! currentband %x delay %d ms\n",
2908 rtlhal->current_bandtype, timecount);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002909 if (IS_92D_SINGLEPHY(rtlhal->version)) {
2910 _rtl92d_phy_lc_calibrate(hw, true);
2911 } else {
2912 /* For 1T1R */
2913 _rtl92d_phy_lc_calibrate(hw, false);
2914 }
2915 rtlphy->lck_inprogress = false;
Joe Perches4c488692012-01-04 19:40:42 -08002916 RTPRINT(rtlpriv, FINIT, INIT_IQK, "LCK:Finish!!!\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002917}
2918
2919void rtl92d_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
2920{
2921 return;
2922}
2923
2924static bool _rtl92d_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
2925 u32 cmdtableidx, u32 cmdtablesz, enum swchnlcmd_id cmdid,
2926 u32 para1, u32 para2, u32 msdelay)
2927{
2928 struct swchnlcmd *pcmd;
2929
2930 if (cmdtable == NULL) {
Joe Perches9d833ed2012-01-04 19:40:43 -08002931 RT_ASSERT(false, "cmdtable cannot be NULL\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05002932 return false;
2933 }
2934 if (cmdtableidx >= cmdtablesz)
2935 return false;
2936
2937 pcmd = cmdtable + cmdtableidx;
2938 pcmd->cmdid = cmdid;
2939 pcmd->para1 = para1;
2940 pcmd->para2 = para2;
2941 pcmd->msdelay = msdelay;
2942 return true;
2943}
2944
2945void rtl92d_phy_reset_iqk_result(struct ieee80211_hw *hw)
2946{
2947 struct rtl_priv *rtlpriv = rtl_priv(hw);
2948 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2949 u8 i;
2950
2951 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08002952 "settings regs %d default regs %d\n",
2953 (int)(sizeof(rtlphy->iqk_matrix_regsetting) /
2954 sizeof(struct iqk_matrix_regs)),
2955 IQK_MATRIX_REG_NUM);
Chaoming Li7274a8c2011-06-10 15:10:25 -05002956 /* 0xe94, 0xe9c, 0xea4, 0xeac, 0xeb4, 0xebc, 0xec4, 0xecc */
2957 for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
2958 rtlphy->iqk_matrix_regsetting[i].value[0][0] = 0x100;
2959 rtlphy->iqk_matrix_regsetting[i].value[0][2] = 0x100;
2960 rtlphy->iqk_matrix_regsetting[i].value[0][4] = 0x100;
2961 rtlphy->iqk_matrix_regsetting[i].value[0][6] = 0x100;
2962 rtlphy->iqk_matrix_regsetting[i].value[0][1] = 0x0;
2963 rtlphy->iqk_matrix_regsetting[i].value[0][3] = 0x0;
2964 rtlphy->iqk_matrix_regsetting[i].value[0][5] = 0x0;
2965 rtlphy->iqk_matrix_regsetting[i].value[0][7] = 0x0;
2966 rtlphy->iqk_matrix_regsetting[i].iqk_done = false;
2967 }
2968}
2969
2970static bool _rtl92d_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
2971 u8 channel, u8 *stage, u8 *step,
2972 u32 *delay)
2973{
2974 struct rtl_priv *rtlpriv = rtl_priv(hw);
2975 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2976 struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
2977 u32 precommoncmdcnt;
2978 struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
2979 u32 postcommoncmdcnt;
2980 struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
2981 u32 rfdependcmdcnt;
2982 struct swchnlcmd *currentcmd = NULL;
2983 u8 rfpath;
2984 u8 num_total_rfpath = rtlphy->num_total_rfpath;
2985
2986 precommoncmdcnt = 0;
2987 _rtl92d_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
2988 MAX_PRECMD_CNT,
2989 CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
2990 _rtl92d_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
2991 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
2992 postcommoncmdcnt = 0;
2993 _rtl92d_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
2994 MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
2995 rfdependcmdcnt = 0;
2996 _rtl92d_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
2997 MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
2998 RF_CHNLBW, channel, 0);
2999 _rtl92d_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
3000 MAX_RFDEPENDCMD_CNT, CMDID_END,
3001 0, 0, 0);
3002
3003 do {
3004 switch (*stage) {
3005 case 0:
3006 currentcmd = &precommoncmd[*step];
3007 break;
3008 case 1:
3009 currentcmd = &rfdependcmd[*step];
3010 break;
3011 case 2:
3012 currentcmd = &postcommoncmd[*step];
3013 break;
3014 }
3015 if (currentcmd->cmdid == CMDID_END) {
3016 if ((*stage) == 2) {
3017 return true;
3018 } else {
3019 (*stage)++;
3020 (*step) = 0;
3021 continue;
3022 }
3023 }
3024 switch (currentcmd->cmdid) {
3025 case CMDID_SET_TXPOWEROWER_LEVEL:
3026 rtl92d_phy_set_txpower_level(hw, channel);
3027 break;
3028 case CMDID_WRITEPORT_ULONG:
3029 rtl_write_dword(rtlpriv, currentcmd->para1,
3030 currentcmd->para2);
3031 break;
3032 case CMDID_WRITEPORT_USHORT:
3033 rtl_write_word(rtlpriv, currentcmd->para1,
3034 (u16)currentcmd->para2);
3035 break;
3036 case CMDID_WRITEPORT_UCHAR:
3037 rtl_write_byte(rtlpriv, currentcmd->para1,
3038 (u8)currentcmd->para2);
3039 break;
3040 case CMDID_RF_WRITEREG:
3041 for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
3042 rtlphy->rfreg_chnlval[rfpath] =
3043 ((rtlphy->rfreg_chnlval[rfpath] &
3044 0xffffff00) | currentcmd->para2);
3045 if (rtlpriv->rtlhal.current_bandtype ==
3046 BAND_ON_5G) {
3047 if (currentcmd->para2 > 99)
3048 rtlphy->rfreg_chnlval[rfpath] =
3049 rtlphy->rfreg_chnlval
3050 [rfpath] | (BIT(18));
3051 else
3052 rtlphy->rfreg_chnlval[rfpath] =
3053 rtlphy->rfreg_chnlval
3054 [rfpath] & (~BIT(18));
3055 rtlphy->rfreg_chnlval[rfpath] |=
3056 (BIT(16) | BIT(8));
3057 } else {
3058 rtlphy->rfreg_chnlval[rfpath] &=
3059 ~(BIT(8) | BIT(16) | BIT(18));
3060 }
3061 rtl_set_rfreg(hw, (enum radio_path)rfpath,
3062 currentcmd->para1,
3063 BRFREGOFFSETMASK,
3064 rtlphy->rfreg_chnlval[rfpath]);
3065 _rtl92d_phy_reload_imr_setting(hw, channel,
3066 rfpath);
3067 }
3068 _rtl92d_phy_switch_rf_setting(hw, channel);
3069 /* do IQK when all parameters are ready */
3070 rtl92d_phy_reload_iqk_setting(hw, channel);
3071 break;
3072 default:
3073 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -08003074 "switch case not processed\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003075 break;
3076 }
3077 break;
3078 } while (true);
3079 (*delay) = currentcmd->msdelay;
3080 (*step)++;
3081 return false;
3082}
3083
3084u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw)
3085{
3086 struct rtl_priv *rtlpriv = rtl_priv(hw);
3087 struct rtl_phy *rtlphy = &(rtlpriv->phy);
3088 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3089 u32 delay;
3090 u32 timeout = 1000, timecount = 0;
3091 u8 channel = rtlphy->current_channel;
3092 u32 ret_value;
3093
3094 if (rtlphy->sw_chnl_inprogress)
3095 return 0;
3096 if (rtlphy->set_bwmode_inprogress)
3097 return 0;
3098
3099 if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
3100 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08003101 "sw_chnl_inprogress false driver sleep or unload\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003102 return 0;
3103 }
3104 while (rtlphy->lck_inprogress && timecount < timeout) {
3105 mdelay(50);
3106 timecount += 50;
3107 }
3108 if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY &&
3109 rtlhal->bandset == BAND_ON_BOTH) {
3110 ret_value = rtl_get_bbreg(hw, RFPGA0_XAB_RFPARAMETER,
3111 BMASKDWORD);
3112 if (rtlphy->current_channel > 14 && !(ret_value & BIT(0)))
3113 rtl92d_phy_switch_wirelessband(hw, BAND_ON_5G);
3114 else if (rtlphy->current_channel <= 14 && (ret_value & BIT(0)))
3115 rtl92d_phy_switch_wirelessband(hw, BAND_ON_2_4G);
3116 }
3117 switch (rtlhal->current_bandtype) {
3118 case BAND_ON_5G:
3119 /* Get first channel error when change between
3120 * 5G and 2.4G band. */
3121 if (channel <= 14)
3122 return 0;
Joe Perches9d833ed2012-01-04 19:40:43 -08003123 RT_ASSERT((channel > 14), "5G but channel<=14\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003124 break;
3125 case BAND_ON_2_4G:
3126 /* Get first channel error when change between
3127 * 5G and 2.4G band. */
3128 if (channel > 14)
3129 return 0;
Joe Perches9d833ed2012-01-04 19:40:43 -08003130 RT_ASSERT((channel <= 14), "2G but channel>14\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003131 break;
3132 default:
Joe Perches9d833ed2012-01-04 19:40:43 -08003133 RT_ASSERT(false, "Invalid WirelessMode(%#x)!!\n",
3134 rtlpriv->mac80211.mode);
Chaoming Li7274a8c2011-06-10 15:10:25 -05003135 break;
3136 }
3137 rtlphy->sw_chnl_inprogress = true;
3138 if (channel == 0)
3139 channel = 1;
3140 rtlphy->sw_chnl_stage = 0;
3141 rtlphy->sw_chnl_step = 0;
3142 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -08003143 "switch to channel%d\n", rtlphy->current_channel);
Chaoming Li7274a8c2011-06-10 15:10:25 -05003144
3145 do {
3146 if (!rtlphy->sw_chnl_inprogress)
3147 break;
3148 if (!_rtl92d_phy_sw_chnl_step_by_step(hw,
3149 rtlphy->current_channel,
3150 &rtlphy->sw_chnl_stage, &rtlphy->sw_chnl_step, &delay)) {
3151 if (delay > 0)
3152 mdelay(delay);
3153 else
3154 continue;
3155 } else {
3156 rtlphy->sw_chnl_inprogress = false;
3157 }
3158 break;
3159 } while (true);
Joe Perchesf30d7502012-01-04 19:40:41 -08003160 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003161 rtlphy->sw_chnl_inprogress = false;
3162 return 1;
3163}
3164
3165static void rtl92d_phy_set_io(struct ieee80211_hw *hw)
3166{
3167 struct rtl_priv *rtlpriv = rtl_priv(hw);
3168 struct rtl_phy *rtlphy = &(rtlpriv->phy);
3169
3170 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -08003171 "--->Cmd(%#x), set_io_inprogress(%d)\n",
3172 rtlphy->current_io_type, rtlphy->set_io_inprogress);
Chaoming Li7274a8c2011-06-10 15:10:25 -05003173 switch (rtlphy->current_io_type) {
3174 case IO_CMD_RESUME_DM_BY_SCAN:
Larry Fingerab049fb2011-06-28 18:55:50 -05003175 de_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1;
Chaoming Li7274a8c2011-06-10 15:10:25 -05003176 rtl92d_dm_write_dig(hw);
3177 rtl92d_phy_set_txpower_level(hw, rtlphy->current_channel);
3178 break;
3179 case IO_CMD_PAUSE_DM_BY_SCAN:
Larry Fingerab049fb2011-06-28 18:55:50 -05003180 rtlphy->initgain_backup.xaagccore1 = de_digtable.cur_igvalue;
3181 de_digtable.cur_igvalue = 0x17;
Chaoming Li7274a8c2011-06-10 15:10:25 -05003182 rtl92d_dm_write_dig(hw);
3183 break;
3184 default:
3185 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -08003186 "switch case not processed\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003187 break;
3188 }
3189 rtlphy->set_io_inprogress = false;
Joe Perchesf30d7502012-01-04 19:40:41 -08003190 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<---(%#x)\n",
3191 rtlphy->current_io_type);
Chaoming Li7274a8c2011-06-10 15:10:25 -05003192}
3193
3194bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
3195{
3196 struct rtl_priv *rtlpriv = rtl_priv(hw);
3197 struct rtl_phy *rtlphy = &(rtlpriv->phy);
3198 bool postprocessing = false;
3199
3200 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -08003201 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
3202 iotype, rtlphy->set_io_inprogress);
Chaoming Li7274a8c2011-06-10 15:10:25 -05003203 do {
3204 switch (iotype) {
3205 case IO_CMD_RESUME_DM_BY_SCAN:
3206 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -08003207 "[IO CMD] Resume DM after scan\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003208 postprocessing = true;
3209 break;
3210 case IO_CMD_PAUSE_DM_BY_SCAN:
3211 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
Joe Perchesf30d7502012-01-04 19:40:41 -08003212 "[IO CMD] Pause DM before scan\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003213 postprocessing = true;
3214 break;
3215 default:
3216 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -08003217 "switch case not processed\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003218 break;
3219 }
3220 } while (false);
3221 if (postprocessing && !rtlphy->set_io_inprogress) {
3222 rtlphy->set_io_inprogress = true;
3223 rtlphy->current_io_type = iotype;
3224 } else {
3225 return false;
3226 }
3227 rtl92d_phy_set_io(hw);
Joe Perchesf30d7502012-01-04 19:40:41 -08003228 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype);
Chaoming Li7274a8c2011-06-10 15:10:25 -05003229 return true;
3230}
3231
3232static void _rtl92d_phy_set_rfon(struct ieee80211_hw *hw)
3233{
3234 struct rtl_priv *rtlpriv = rtl_priv(hw);
3235
3236 /* a. SYS_CLKR 0x08[11] = 1 restore MAC clock */
3237 /* b. SPS_CTRL 0x11[7:0] = 0x2b */
3238 if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY)
3239 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
3240 /* c. For PCIE: SYS_FUNC_EN 0x02[7:0] = 0xE3 enable BB TRX function */
3241 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
3242 /* RF_ON_EXCEP(d~g): */
3243 /* d. APSD_CTRL 0x600[7:0] = 0x00 */
3244 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
3245 /* e. SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB TRX function again */
3246 /* f. SYS_FUNC_EN 0x02[7:0] = 0xE3 enable BB TRX function*/
3247 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
3248 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
3249 /* g. txpause 0x522[7:0] = 0x00 enable mac tx queue */
3250 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
3251}
3252
3253static void _rtl92d_phy_set_rfsleep(struct ieee80211_hw *hw)
3254{
3255 struct rtl_priv *rtlpriv = rtl_priv(hw);
3256 u32 u4btmp;
3257 u8 delay = 5;
3258
3259 /* a. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue */
3260 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
3261 /* b. RF path 0 offset 0x00 = 0x00 disable RF */
3262 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, BRFREGOFFSETMASK, 0x00);
3263 /* c. APSD_CTRL 0x600[7:0] = 0x40 */
3264 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
3265 /* d. APSD_CTRL 0x600[7:0] = 0x00
3266 * APSD_CTRL 0x600[7:0] = 0x00
3267 * RF path 0 offset 0x00 = 0x00
3268 * APSD_CTRL 0x600[7:0] = 0x40
3269 * */
3270 u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, BRFREGOFFSETMASK);
3271 while (u4btmp != 0 && delay > 0) {
3272 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
3273 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, BRFREGOFFSETMASK, 0x00);
3274 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
3275 u4btmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, BRFREGOFFSETMASK);
3276 delay--;
3277 }
3278 if (delay == 0) {
3279 /* Jump out the LPS turn off sequence to RF_ON_EXCEP */
3280 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
3281
3282 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
3283 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
3284 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
3285 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08003286 "Fail !!! Switch RF timeout\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003287 return;
3288 }
3289 /* e. For PCIE: SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB TRX function */
3290 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
3291 /* f. SPS_CTRL 0x11[7:0] = 0x22 */
3292 if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY)
3293 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
3294 /* g. SYS_CLKR 0x08[11] = 0 gated MAC clock */
3295}
3296
3297bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw,
3298 enum rf_pwrstate rfpwr_state)
3299{
3300
3301 bool bresult = true;
3302 struct rtl_priv *rtlpriv = rtl_priv(hw);
3303 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
3304 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
3305 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
3306 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
3307 u8 i, queue_id;
3308 struct rtl8192_tx_ring *ring = NULL;
3309
3310 if (rfpwr_state == ppsc->rfpwr_state)
3311 return false;
3312 switch (rfpwr_state) {
3313 case ERFON:
3314 if ((ppsc->rfpwr_state == ERFOFF) &&
3315 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
3316 bool rtstatus;
3317 u32 InitializeCount = 0;
3318 do {
3319 InitializeCount++;
3320 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
Joe Perchesf30d7502012-01-04 19:40:41 -08003321 "IPS Set eRf nic enable\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003322 rtstatus = rtl_ps_enable_nic(hw);
Joe Perches23677ce2012-02-09 11:17:23 +00003323 } while (!rtstatus && (InitializeCount < 10));
Chaoming Li7274a8c2011-06-10 15:10:25 -05003324
3325 RT_CLEAR_PS_LEVEL(ppsc,
3326 RT_RF_OFF_LEVL_HALT_NIC);
3327 } else {
3328 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
Joe Perchesf30d7502012-01-04 19:40:41 -08003329 "awake, sleeped:%d ms state_inap:%x\n",
Chaoming Li7274a8c2011-06-10 15:10:25 -05003330 jiffies_to_msecs(jiffies -
Joe Perchesf30d7502012-01-04 19:40:41 -08003331 ppsc->last_sleep_jiffies),
3332 rtlpriv->psc.state_inap);
Chaoming Li7274a8c2011-06-10 15:10:25 -05003333 ppsc->last_awake_jiffies = jiffies;
3334 _rtl92d_phy_set_rfon(hw);
3335 }
3336
3337 if (mac->link_state == MAC80211_LINKED)
3338 rtlpriv->cfg->ops->led_control(hw,
3339 LED_CTL_LINK);
3340 else
3341 rtlpriv->cfg->ops->led_control(hw,
3342 LED_CTL_NO_LINK);
3343 break;
3344 case ERFOFF:
3345 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
3346 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
Joe Perchesf30d7502012-01-04 19:40:41 -08003347 "IPS Set eRf nic disable\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003348 rtl_ps_disable_nic(hw);
3349 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
3350 } else {
3351 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
3352 rtlpriv->cfg->ops->led_control(hw,
3353 LED_CTL_NO_LINK);
3354 else
3355 rtlpriv->cfg->ops->led_control(hw,
3356 LED_CTL_POWER_OFF);
3357 }
3358 break;
3359 case ERFSLEEP:
3360 if (ppsc->rfpwr_state == ERFOFF)
Philipp Dreimann91ddff82011-12-07 13:43:31 -06003361 return false;
Chaoming Li7274a8c2011-06-10 15:10:25 -05003362
3363 for (queue_id = 0, i = 0;
3364 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
3365 ring = &pcipriv->dev.tx_ring[queue_id];
3366 if (skb_queue_len(&ring->queue) == 0 ||
3367 queue_id == BEACON_QUEUE) {
3368 queue_id++;
3369 continue;
3370 } else if (rtlpci->pdev->current_state != PCI_D0) {
3371 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08003372 "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 but lower power state!\n",
3373 i + 1, queue_id);
Chaoming Li7274a8c2011-06-10 15:10:25 -05003374 break;
3375 } else {
3376 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
Joe Perchesf30d7502012-01-04 19:40:41 -08003377 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
3378 i + 1, queue_id,
3379 skb_queue_len(&ring->queue));
Chaoming Li7274a8c2011-06-10 15:10:25 -05003380 udelay(10);
3381 i++;
3382 }
3383
3384 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
3385 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
Joe Perchesf30d7502012-01-04 19:40:41 -08003386 "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n",
3387 MAX_DOZE_WAITING_TIMES_9x, queue_id,
3388 skb_queue_len(&ring->queue));
Chaoming Li7274a8c2011-06-10 15:10:25 -05003389 break;
3390 }
3391 }
3392 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
Joe Perchesf30d7502012-01-04 19:40:41 -08003393 "Set rfsleep awaked:%d ms\n",
3394 jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies));
3395 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
3396 "sleep awaked:%d ms state_inap:%x\n",
3397 jiffies_to_msecs(jiffies -
3398 ppsc->last_awake_jiffies),
3399 rtlpriv->psc.state_inap);
Chaoming Li7274a8c2011-06-10 15:10:25 -05003400 ppsc->last_sleep_jiffies = jiffies;
3401 _rtl92d_phy_set_rfsleep(hw);
3402 break;
3403 default:
3404 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Joe Perchesf30d7502012-01-04 19:40:41 -08003405 "switch case not processed\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003406 bresult = false;
3407 break;
3408 }
3409 if (bresult)
3410 ppsc->rfpwr_state = rfpwr_state;
3411 return bresult;
3412}
3413
3414void rtl92d_phy_config_macphymode(struct ieee80211_hw *hw)
3415{
3416 struct rtl_priv *rtlpriv = rtl_priv(hw);
3417 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3418 u8 offset = REG_MAC_PHY_CTRL_NORMAL;
3419
3420 switch (rtlhal->macphymode) {
3421 case DUALMAC_DUALPHY:
3422 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08003423 "MacPhyMode: DUALMAC_DUALPHY\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003424 rtl_write_byte(rtlpriv, offset, 0xF3);
3425 break;
3426 case SINGLEMAC_SINGLEPHY:
3427 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08003428 "MacPhyMode: SINGLEMAC_SINGLEPHY\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003429 rtl_write_byte(rtlpriv, offset, 0xF4);
3430 break;
3431 case DUALMAC_SINGLEPHY:
3432 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08003433 "MacPhyMode: DUALMAC_SINGLEPHY\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003434 rtl_write_byte(rtlpriv, offset, 0xF1);
3435 break;
3436 }
3437}
3438
3439void rtl92d_phy_config_macphymode_info(struct ieee80211_hw *hw)
3440{
3441 struct rtl_priv *rtlpriv = rtl_priv(hw);
3442 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3443 struct rtl_phy *rtlphy = &(rtlpriv->phy);
3444
3445 switch (rtlhal->macphymode) {
3446 case DUALMAC_SINGLEPHY:
3447 rtlphy->rf_type = RF_2T2R;
3448 rtlhal->version |= CHIP_92D_SINGLEPHY;
3449 rtlhal->bandset = BAND_ON_BOTH;
3450 rtlhal->current_bandtype = BAND_ON_2_4G;
3451 break;
3452
3453 case SINGLEMAC_SINGLEPHY:
3454 rtlphy->rf_type = RF_2T2R;
3455 rtlhal->version |= CHIP_92D_SINGLEPHY;
3456 rtlhal->bandset = BAND_ON_BOTH;
3457 rtlhal->current_bandtype = BAND_ON_2_4G;
3458 break;
3459
3460 case DUALMAC_DUALPHY:
3461 rtlphy->rf_type = RF_1T1R;
3462 rtlhal->version &= (~CHIP_92D_SINGLEPHY);
3463 /* Now we let MAC0 run on 5G band. */
3464 if (rtlhal->interfaceindex == 0) {
3465 rtlhal->bandset = BAND_ON_5G;
3466 rtlhal->current_bandtype = BAND_ON_5G;
3467 } else {
3468 rtlhal->bandset = BAND_ON_2_4G;
3469 rtlhal->current_bandtype = BAND_ON_2_4G;
3470 }
3471 break;
3472 default:
3473 break;
3474 }
3475}
3476
3477u8 rtl92d_get_chnlgroup_fromarray(u8 chnl)
3478{
3479 u8 group;
3480 u8 channel_info[59] = {
3481 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
3482 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56,
3483 58, 60, 62, 64, 100, 102, 104, 106, 108,
3484 110, 112, 114, 116, 118, 120, 122, 124,
3485 126, 128, 130, 132, 134, 136, 138, 140,
3486 149, 151, 153, 155, 157, 159, 161, 163,
3487 165
3488 };
3489
3490 if (channel_info[chnl] <= 3)
3491 group = 0;
3492 else if (channel_info[chnl] <= 9)
3493 group = 1;
3494 else if (channel_info[chnl] <= 14)
3495 group = 2;
3496 else if (channel_info[chnl] <= 44)
3497 group = 3;
3498 else if (channel_info[chnl] <= 54)
3499 group = 4;
3500 else if (channel_info[chnl] <= 64)
3501 group = 5;
3502 else if (channel_info[chnl] <= 112)
3503 group = 6;
3504 else if (channel_info[chnl] <= 126)
3505 group = 7;
3506 else if (channel_info[chnl] <= 140)
3507 group = 8;
3508 else if (channel_info[chnl] <= 153)
3509 group = 9;
3510 else if (channel_info[chnl] <= 159)
3511 group = 10;
3512 else
3513 group = 11;
3514 return group;
3515}
3516
3517void rtl92d_phy_set_poweron(struct ieee80211_hw *hw)
3518{
3519 struct rtl_priv *rtlpriv = rtl_priv(hw);
3520 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3521 unsigned long flags;
3522 u8 value8;
3523 u16 i;
3524 u32 mac_reg = (rtlhal->interfaceindex == 0 ? REG_MAC0 : REG_MAC1);
3525
3526 /* notice fw know band status 0x81[1]/0x53[1] = 0: 5G, 1: 2G */
3527 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
3528 value8 = rtl_read_byte(rtlpriv, mac_reg);
3529 value8 |= BIT(1);
3530 rtl_write_byte(rtlpriv, mac_reg, value8);
3531 } else {
3532 value8 = rtl_read_byte(rtlpriv, mac_reg);
3533 value8 &= (~BIT(1));
3534 rtl_write_byte(rtlpriv, mac_reg, value8);
3535 }
3536
3537 if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY) {
3538 value8 = rtl_read_byte(rtlpriv, REG_MAC0);
3539 rtl_write_byte(rtlpriv, REG_MAC0, value8 | MAC0_ON);
3540 } else {
3541 spin_lock_irqsave(&globalmutex_power, flags);
3542 if (rtlhal->interfaceindex == 0) {
3543 value8 = rtl_read_byte(rtlpriv, REG_MAC0);
3544 rtl_write_byte(rtlpriv, REG_MAC0, value8 | MAC0_ON);
3545 } else {
3546 value8 = rtl_read_byte(rtlpriv, REG_MAC1);
3547 rtl_write_byte(rtlpriv, REG_MAC1, value8 | MAC1_ON);
3548 }
3549 value8 = rtl_read_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS);
3550 spin_unlock_irqrestore(&globalmutex_power, flags);
3551 for (i = 0; i < 200; i++) {
3552 if ((value8 & BIT(7)) == 0) {
3553 break;
3554 } else {
3555 udelay(500);
3556 spin_lock_irqsave(&globalmutex_power, flags);
3557 value8 = rtl_read_byte(rtlpriv,
3558 REG_POWER_OFF_IN_PROCESS);
3559 spin_unlock_irqrestore(&globalmutex_power,
3560 flags);
3561 }
3562 }
3563 if (i == 200)
Joe Perches9d833ed2012-01-04 19:40:43 -08003564 RT_ASSERT(false, "Another mac power off over time\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003565 }
3566}
3567
3568void rtl92d_phy_config_maccoexist_rfpage(struct ieee80211_hw *hw)
3569{
3570 struct rtl_priv *rtlpriv = rtl_priv(hw);
3571
3572 switch (rtlpriv->rtlhal.macphymode) {
3573 case DUALMAC_DUALPHY:
3574 rtl_write_byte(rtlpriv, REG_DMC, 0x0);
3575 rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x08);
3576 rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x13ff);
3577 break;
3578 case DUALMAC_SINGLEPHY:
3579 rtl_write_byte(rtlpriv, REG_DMC, 0xf8);
3580 rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x08);
3581 rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x13ff);
3582 break;
3583 case SINGLEMAC_SINGLEPHY:
3584 rtl_write_byte(rtlpriv, REG_DMC, 0x0);
3585 rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x10);
3586 rtl_write_word(rtlpriv, (REG_TRXFF_BNDY + 2), 0x27FF);
3587 break;
3588 default:
3589 break;
3590 }
3591}
3592
3593void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw)
3594{
3595 struct rtl_priv *rtlpriv = rtl_priv(hw);
3596 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3597 struct rtl_phy *rtlphy = &(rtlpriv->phy);
3598 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
3599 u8 rfpath, i;
3600
Joe Perchesf30d7502012-01-04 19:40:41 -08003601 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "==>\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003602 /* r_select_5G for path_A/B 0 for 2.4G, 1 for 5G */
3603 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
3604 /* r_select_5G for path_A/B,0x878 */
3605 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(0), 0x0);
3606 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), 0x0);
3607 if (rtlhal->macphymode != DUALMAC_DUALPHY) {
3608 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(16), 0x0);
3609 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(31), 0x0);
3610 }
3611 /* rssi_table_select:index 0 for 2.4G.1~3 for 5G,0xc78 */
3612 rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, BIT(6) | BIT(7), 0x0);
3613 /* fc_area 0xd2c */
3614 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(14) | BIT(13), 0x0);
3615 /* 5G LAN ON */
3616 rtl_set_bbreg(hw, 0xB30, 0x00F00000, 0xa);
3617 /* TX BB gain shift*1,Just for testchip,0xc80,0xc88 */
3618 rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, BMASKDWORD,
3619 0x40000100);
3620 rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, BMASKDWORD,
3621 0x40000100);
3622 if (rtlhal->macphymode == DUALMAC_DUALPHY) {
3623 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW,
3624 BIT(10) | BIT(6) | BIT(5),
3625 ((rtlefuse->eeprom_c9 & BIT(3)) >> 3) |
3626 (rtlefuse->eeprom_c9 & BIT(1)) |
3627 ((rtlefuse->eeprom_cc & BIT(1)) << 4));
3628 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
3629 BIT(10) | BIT(6) | BIT(5),
3630 ((rtlefuse->eeprom_c9 & BIT(2)) >> 2) |
3631 ((rtlefuse->eeprom_c9 & BIT(0)) << 1) |
3632 ((rtlefuse->eeprom_cc & BIT(0)) << 5));
3633 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), 0);
3634 } else {
3635 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW,
3636 BIT(26) | BIT(22) | BIT(21) | BIT(10) |
3637 BIT(6) | BIT(5),
3638 ((rtlefuse->eeprom_c9 & BIT(3)) >> 3) |
3639 (rtlefuse->eeprom_c9 & BIT(1)) |
3640 ((rtlefuse->eeprom_cc & BIT(1)) << 4) |
3641 ((rtlefuse->eeprom_c9 & BIT(7)) << 9) |
3642 ((rtlefuse->eeprom_c9 & BIT(5)) << 12) |
3643 ((rtlefuse->eeprom_cc & BIT(3)) << 18));
3644 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
3645 BIT(10) | BIT(6) | BIT(5),
3646 ((rtlefuse->eeprom_c9 & BIT(2)) >> 2) |
3647 ((rtlefuse->eeprom_c9 & BIT(0)) << 1) |
3648 ((rtlefuse->eeprom_cc & BIT(0)) << 5));
3649 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
3650 BIT(10) | BIT(6) | BIT(5),
3651 ((rtlefuse->eeprom_c9 & BIT(6)) >> 6) |
3652 ((rtlefuse->eeprom_c9 & BIT(4)) >> 3) |
3653 ((rtlefuse->eeprom_cc & BIT(2)) << 3));
3654 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER,
3655 BIT(31) | BIT(15), 0);
3656 }
3657 /* 1.5V_LDO */
3658 } else {
3659 /* r_select_5G for path_A/B */
3660 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(0), 0x1);
3661 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15), 0x1);
3662 if (rtlhal->macphymode != DUALMAC_DUALPHY) {
3663 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(16), 0x1);
3664 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(31), 0x1);
3665 }
3666 /* rssi_table_select:index 0 for 2.4G.1~3 for 5G */
3667 rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, BIT(6) | BIT(7), 0x1);
3668 /* fc_area */
3669 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(14) | BIT(13), 0x1);
3670 /* 5G LAN ON */
3671 rtl_set_bbreg(hw, 0xB30, 0x00F00000, 0x0);
3672 /* TX BB gain shift,Just for testchip,0xc80,0xc88 */
3673 if (rtlefuse->internal_pa_5g[0])
3674 rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, BMASKDWORD,
3675 0x2d4000b5);
3676 else
3677 rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, BMASKDWORD,
3678 0x20000080);
3679 if (rtlefuse->internal_pa_5g[1])
3680 rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, BMASKDWORD,
3681 0x2d4000b5);
3682 else
3683 rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, BMASKDWORD,
3684 0x20000080);
3685 if (rtlhal->macphymode == DUALMAC_DUALPHY) {
3686 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW,
3687 BIT(10) | BIT(6) | BIT(5),
3688 (rtlefuse->eeprom_cc & BIT(5)));
3689 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(10),
3690 ((rtlefuse->eeprom_cc & BIT(4)) >> 4));
3691 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(15),
3692 (rtlefuse->eeprom_cc & BIT(4)) >> 4);
3693 } else {
3694 rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW,
3695 BIT(26) | BIT(22) | BIT(21) | BIT(10) |
3696 BIT(6) | BIT(5),
3697 (rtlefuse->eeprom_cc & BIT(5)) |
3698 ((rtlefuse->eeprom_cc & BIT(7)) << 14));
3699 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(10),
3700 ((rtlefuse->eeprom_cc & BIT(4)) >> 4));
3701 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BIT(10),
3702 ((rtlefuse->eeprom_cc & BIT(6)) >> 6));
3703 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER,
3704 BIT(31) | BIT(15),
3705 ((rtlefuse->eeprom_cc & BIT(4)) >> 4) |
3706 ((rtlefuse->eeprom_cc & BIT(6)) << 10));
3707 }
3708 }
3709 /* update IQK related settings */
3710 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, BMASKDWORD, 0x40000100);
3711 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, BMASKDWORD, 0x40000100);
3712 rtl_set_bbreg(hw, ROFDM0_XCTxAFE, 0xF0000000, 0x00);
3713 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(30) | BIT(28) |
3714 BIT(26) | BIT(24), 0x00);
3715 rtl_set_bbreg(hw, ROFDM0_XDTxAFE, 0xF0000000, 0x00);
3716 rtl_set_bbreg(hw, 0xca0, 0xF0000000, 0x00);
3717 rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, 0x00);
3718
3719 /* Update RF */
3720 for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
3721 rfpath++) {
3722 if (rtlhal->current_bandtype == BAND_ON_2_4G) {
3723 /* MOD_AG for RF paht_A 0x18 BIT8,BIT16 */
3724 rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(8) | BIT(16) |
3725 BIT(18), 0);
3726 /* RF0x0b[16:14] =3b'111 */
3727 rtl_set_rfreg(hw, (enum radio_path)rfpath, 0x0B,
3728 0x1c000, 0x07);
3729 } else {
3730 /* MOD_AG for RF paht_A 0x18 BIT8,BIT16 */
3731 rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(8) |
3732 BIT(16) | BIT(18),
3733 (BIT(16) | BIT(8)) >> 8);
3734 }
3735 }
3736 /* Update for all band. */
3737 /* DMDP */
3738 if (rtlphy->rf_type == RF_1T1R) {
3739 /* Use antenna 0,0xc04,0xd04 */
3740 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0x11);
3741 rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x1);
3742
3743 /* enable ad/da clock1 for dual-phy reg0x888 */
3744 if (rtlhal->interfaceindex == 0) {
3745 rtl_set_bbreg(hw, RFPGA0_ADDALLOCKEN, BIT(12) |
3746 BIT(13), 0x3);
3747 } else {
3748 rtl92d_phy_enable_anotherphy(hw, false);
3749 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Joe Perchesf30d7502012-01-04 19:40:41 -08003750 "MAC1 use DBI to update 0x888\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003751 /* 0x888 */
3752 rtl92de_write_dword_dbi(hw, RFPGA0_ADDALLOCKEN,
3753 rtl92de_read_dword_dbi(hw,
3754 RFPGA0_ADDALLOCKEN,
3755 BIT(3)) | BIT(12) | BIT(13),
3756 BIT(3));
3757 rtl92d_phy_powerdown_anotherphy(hw, false);
3758 }
3759 } else {
3760 /* Single PHY */
3761 /* Use antenna 0 & 1,0xc04,0xd04 */
3762 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, BMASKBYTE0, 0x33);
3763 rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0x3);
3764 /* disable ad/da clock1,0x888 */
3765 rtl_set_bbreg(hw, RFPGA0_ADDALLOCKEN, BIT(12) | BIT(13), 0);
3766 }
3767 for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
3768 rfpath++) {
3769 rtlphy->rfreg_chnlval[rfpath] = rtl_get_rfreg(hw, rfpath,
3770 RF_CHNLBW, BRFREGOFFSETMASK);
3771 rtlphy->reg_rf3c[rfpath] = rtl_get_rfreg(hw, rfpath, 0x3C,
3772 BRFREGOFFSETMASK);
3773 }
3774 for (i = 0; i < 2; i++)
Joe Perchesf30d7502012-01-04 19:40:41 -08003775 RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "RF 0x18 = 0x%x\n",
3776 rtlphy->rfreg_chnlval[i]);
3777 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<==\n");
Chaoming Li7274a8c2011-06-10 15:10:25 -05003778
3779}
3780
3781bool rtl92d_phy_check_poweroff(struct ieee80211_hw *hw)
3782{
3783 struct rtl_priv *rtlpriv = rtl_priv(hw);
3784 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3785 u8 u1btmp;
3786 unsigned long flags;
3787
3788 if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY) {
3789 u1btmp = rtl_read_byte(rtlpriv, REG_MAC0);
3790 rtl_write_byte(rtlpriv, REG_MAC0, u1btmp & (~MAC0_ON));
3791 return true;
3792 }
3793 spin_lock_irqsave(&globalmutex_power, flags);
3794 if (rtlhal->interfaceindex == 0) {
3795 u1btmp = rtl_read_byte(rtlpriv, REG_MAC0);
3796 rtl_write_byte(rtlpriv, REG_MAC0, u1btmp & (~MAC0_ON));
3797 u1btmp = rtl_read_byte(rtlpriv, REG_MAC1);
3798 u1btmp &= MAC1_ON;
3799 } else {
3800 u1btmp = rtl_read_byte(rtlpriv, REG_MAC1);
3801 rtl_write_byte(rtlpriv, REG_MAC1, u1btmp & (~MAC1_ON));
3802 u1btmp = rtl_read_byte(rtlpriv, REG_MAC0);
3803 u1btmp &= MAC0_ON;
3804 }
3805 if (u1btmp) {
3806 spin_unlock_irqrestore(&globalmutex_power, flags);
3807 return false;
3808 }
3809 u1btmp = rtl_read_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS);
3810 u1btmp |= BIT(7);
3811 rtl_write_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS, u1btmp);
3812 spin_unlock_irqrestore(&globalmutex_power, flags);
3813 return true;
3814}