blob: 1f07558debf2b05b41bad4391b8fbccae9a19c68 [file] [log] [blame]
Larry Finger4295cd22011-02-19 16:29:12 -06001/******************************************************************************
2 *
3 * Copyright(c) 2009-2010 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
20 *
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
25 *
26 * Larry Finger <Larry.Finger@lwfinger.net>
27 *
28 *****************************************************************************/
29
Paul Gortmakeree40fa02011-05-27 16:14:23 -040030#include <linux/export.h>
Larry Finger1472d3a2011-02-23 10:24:58 -060031#include "../wifi.h"
32#include "../rtl8192ce/reg.h"
33#include "../rtl8192ce/def.h"
34#include "dm_common.h"
35#include "phy_common.h"
36
Larry Finger4295cd22011-02-19 16:29:12 -060037/* Define macro to shorten lines */
38#define MCS_TXPWR mcs_txpwrlevel_origoffset
39
Larry Finger4295cd22011-02-19 16:29:12 -060040u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
41{
42 struct rtl_priv *rtlpriv = rtl_priv(hw);
43 u32 returnvalue, originalvalue, bitshift;
44
45 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), "
46 "bitmask(%#x)\n", regaddr,
47 bitmask));
48 originalvalue = rtl_read_dword(rtlpriv, regaddr);
49 bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
50 returnvalue = (originalvalue & bitmask) >> bitshift;
51
52 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x "
53 "Addr[0x%x]=0x%x\n", bitmask,
54 regaddr, originalvalue));
55
56 return returnvalue;
57
58}
Larry Finger1472d3a2011-02-23 10:24:58 -060059EXPORT_SYMBOL(rtl92c_phy_query_bb_reg);
Larry Finger4295cd22011-02-19 16:29:12 -060060
61void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
62 u32 regaddr, u32 bitmask, u32 data)
63{
64 struct rtl_priv *rtlpriv = rtl_priv(hw);
65 u32 originalvalue, bitshift;
66
67 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
68 " data(%#x)\n", regaddr, bitmask,
69 data));
70
71 if (bitmask != MASKDWORD) {
72 originalvalue = rtl_read_dword(rtlpriv, regaddr);
73 bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
74 data = ((originalvalue & (~bitmask)) | (data << bitshift));
75 }
76
77 rtl_write_dword(rtlpriv, regaddr, data);
78
79 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
80 " data(%#x)\n", regaddr, bitmask,
81 data));
Chaoming_Lic07ccff2011-04-25 12:53:45 -050082
Larry Finger4295cd22011-02-19 16:29:12 -060083}
Larry Finger1472d3a2011-02-23 10:24:58 -060084EXPORT_SYMBOL(rtl92c_phy_set_bb_reg);
Larry Finger4295cd22011-02-19 16:29:12 -060085
Chaoming_Li76c34f92011-04-25 12:54:05 -050086u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw,
Larry Fingerd3bb1422011-04-25 13:23:20 -050087 enum radio_path rfpath, u32 offset)
Larry Finger4295cd22011-02-19 16:29:12 -060088{
89 RT_ASSERT(false, ("deprecated!\n"));
90 return 0;
Chaoming_Lic07ccff2011-04-25 12:53:45 -050091
Larry Finger4295cd22011-02-19 16:29:12 -060092}
Larry Finger1472d3a2011-02-23 10:24:58 -060093EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_read);
Larry Finger4295cd22011-02-19 16:29:12 -060094
Chaoming_Li76c34f92011-04-25 12:54:05 -050095void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
Larry Fingerd3bb1422011-04-25 13:23:20 -050096 enum radio_path rfpath, u32 offset,
97 u32 data)
Larry Finger4295cd22011-02-19 16:29:12 -060098{
99 RT_ASSERT(false, ("deprecated!\n"));
100}
Larry Finger1472d3a2011-02-23 10:24:58 -0600101EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_write);
Larry Finger4295cd22011-02-19 16:29:12 -0600102
Chaoming_Li76c34f92011-04-25 12:54:05 -0500103u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw,
Larry Fingerd3bb1422011-04-25 13:23:20 -0500104 enum radio_path rfpath, u32 offset)
Larry Finger4295cd22011-02-19 16:29:12 -0600105{
106 struct rtl_priv *rtlpriv = rtl_priv(hw);
107 struct rtl_phy *rtlphy = &(rtlpriv->phy);
108 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
109 u32 newoffset;
110 u32 tmplong, tmplong2;
111 u8 rfpi_enable = 0;
112 u32 retvalue;
113
114 offset &= 0x3f;
115 newoffset = offset;
116 if (RT_CANNOT_IO(hw)) {
117 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("return all one\n"));
118 return 0xFFFFFFFF;
119 }
120 tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
121 if (rfpath == RF90_PATH_A)
122 tmplong2 = tmplong;
123 else
124 tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
125 tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
126 (newoffset << 23) | BLSSIREADEDGE;
127 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
128 tmplong & (~BLSSIREADEDGE));
129 mdelay(1);
130 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
131 mdelay(1);
132 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
133 tmplong | BLSSIREADEDGE);
134 mdelay(1);
135 if (rfpath == RF90_PATH_A)
136 rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
137 BIT(8));
138 else if (rfpath == RF90_PATH_B)
139 rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
140 BIT(8));
141 if (rfpi_enable)
142 retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi,
143 BLSSIREADBACKDATA);
144 else
145 retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
146 BLSSIREADBACKDATA);
147 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n",
148 rfpath, pphyreg->rflssi_readback,
149 retvalue));
150 return retvalue;
151}
Larry Finger1472d3a2011-02-23 10:24:58 -0600152EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read);
Larry Finger4295cd22011-02-19 16:29:12 -0600153
Chaoming_Li76c34f92011-04-25 12:54:05 -0500154void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw,
Larry Fingerd3bb1422011-04-25 13:23:20 -0500155 enum radio_path rfpath, u32 offset,
156 u32 data)
Larry Finger4295cd22011-02-19 16:29:12 -0600157{
158 u32 data_and_addr;
159 u32 newoffset;
160 struct rtl_priv *rtlpriv = rtl_priv(hw);
161 struct rtl_phy *rtlphy = &(rtlpriv->phy);
162 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
163
164 if (RT_CANNOT_IO(hw)) {
165 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("stop\n"));
166 return;
167 }
168 offset &= 0x3f;
169 newoffset = offset;
170 data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
171 rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
172 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n",
173 rfpath, pphyreg->rf3wire_offset,
174 data_and_addr));
175}
Larry Finger1472d3a2011-02-23 10:24:58 -0600176EXPORT_SYMBOL(_rtl92c_phy_rf_serial_write);
Larry Finger4295cd22011-02-19 16:29:12 -0600177
Larry Finger1472d3a2011-02-23 10:24:58 -0600178u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask)
Larry Finger4295cd22011-02-19 16:29:12 -0600179{
180 u32 i;
181
182 for (i = 0; i <= 31; i++) {
183 if (((bitmask >> i) & 0x1) == 1)
184 break;
185 }
186 return i;
187}
Larry Finger1472d3a2011-02-23 10:24:58 -0600188EXPORT_SYMBOL(_rtl92c_phy_calculate_bit_shift);
Larry Finger4295cd22011-02-19 16:29:12 -0600189
190static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw)
191{
192 rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2);
193 rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022);
194 rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45);
195 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23);
196 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1);
197 rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2);
198 rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2);
199 rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2);
200 rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2);
201 rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2);
202}
Chaoming_Lic07ccff2011-04-25 12:53:45 -0500203
Larry Finger4295cd22011-02-19 16:29:12 -0600204bool rtl92c_phy_rf_config(struct ieee80211_hw *hw)
205{
Larry Finger1472d3a2011-02-23 10:24:58 -0600206 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger4295cd22011-02-19 16:29:12 -0600207
Larry Finger1472d3a2011-02-23 10:24:58 -0600208 return rtlpriv->cfg->ops->phy_rf6052_config(hw);
209}
210EXPORT_SYMBOL(rtl92c_phy_rf_config);
211
Chaoming_Li76c34f92011-04-25 12:54:05 -0500212bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw)
Larry Finger4295cd22011-02-19 16:29:12 -0600213{
214 struct rtl_priv *rtlpriv = rtl_priv(hw);
215 struct rtl_phy *rtlphy = &(rtlpriv->phy);
216 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
217 bool rtstatus;
218
219 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n"));
Larry Finger1472d3a2011-02-23 10:24:58 -0600220 rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw,
Larry Finger4295cd22011-02-19 16:29:12 -0600221 BASEBAND_CONFIG_PHY_REG);
222 if (rtstatus != true) {
223 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!"));
224 return false;
225 }
226 if (rtlphy->rf_type == RF_1T2R) {
227 _rtl92c_phy_bb_config_1t(hw);
228 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n"));
229 }
230 if (rtlefuse->autoload_failflag == false) {
231 rtlphy->pwrgroup_cnt = 0;
Larry Finger1472d3a2011-02-23 10:24:58 -0600232 rtstatus = rtlpriv->cfg->ops->config_bb_with_pgheaderfile(hw,
Larry Finger4295cd22011-02-19 16:29:12 -0600233 BASEBAND_CONFIG_PHY_REG);
234 }
235 if (rtstatus != true) {
236 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!"));
237 return false;
238 }
Larry Finger1472d3a2011-02-23 10:24:58 -0600239 rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw,
Larry Finger4295cd22011-02-19 16:29:12 -0600240 BASEBAND_CONFIG_AGC_TAB);
241 if (rtstatus != true) {
242 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n"));
243 return false;
244 }
245 rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
246 RFPGA0_XA_HSSIPARAMETER2,
247 0x200));
Chaoming_Lic07ccff2011-04-25 12:53:45 -0500248
Larry Finger4295cd22011-02-19 16:29:12 -0600249 return true;
250}
Larry Finger1472d3a2011-02-23 10:24:58 -0600251EXPORT_SYMBOL(_rtl92c_phy_bb8192c_config_parafile);
Larry Finger4295cd22011-02-19 16:29:12 -0600252
Larry Finger1472d3a2011-02-23 10:24:58 -0600253void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw,
Larry Fingerd3bb1422011-04-25 13:23:20 -0500254 u32 regaddr, u32 bitmask,
255 u32 data)
Larry Finger4295cd22011-02-19 16:29:12 -0600256{
257 struct rtl_priv *rtlpriv = rtl_priv(hw);
258 struct rtl_phy *rtlphy = &(rtlpriv->phy);
259
260 if (regaddr == RTXAGC_A_RATE18_06) {
261 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0] = data;
262 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
263 ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",
264 rtlphy->pwrgroup_cnt,
265 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0]));
266 }
267 if (regaddr == RTXAGC_A_RATE54_24) {
268 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1] = data;
269 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
270 ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",
271 rtlphy->pwrgroup_cnt,
272 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1]));
273 }
274 if (regaddr == RTXAGC_A_CCK1_MCS32) {
275 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6] = data;
276 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
277 ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",
278 rtlphy->pwrgroup_cnt,
279 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6]));
280 }
281 if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) {
282 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7] = data;
283 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
284 ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",
285 rtlphy->pwrgroup_cnt,
286 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7]));
287 }
288 if (regaddr == RTXAGC_A_MCS03_MCS00) {
289 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2] = data;
290 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
291 ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",
292 rtlphy->pwrgroup_cnt,
293 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2]));
294 }
295 if (regaddr == RTXAGC_A_MCS07_MCS04) {
296 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3] = data;
297 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
298 ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",
299 rtlphy->pwrgroup_cnt,
300 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3]));
301 }
302 if (regaddr == RTXAGC_A_MCS11_MCS08) {
303 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4] = data;
304 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
305 ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",
306 rtlphy->pwrgroup_cnt,
307 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4]));
308 }
309 if (regaddr == RTXAGC_A_MCS15_MCS12) {
310 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5] = data;
311 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
312 ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",
313 rtlphy->pwrgroup_cnt,
314 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5]));
315 }
316 if (regaddr == RTXAGC_B_RATE18_06) {
317 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8] = data;
318 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
319 ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",
320 rtlphy->pwrgroup_cnt,
321 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8]));
322 }
323 if (regaddr == RTXAGC_B_RATE54_24) {
324 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9] = data;
Larry Finger4295cd22011-02-19 16:29:12 -0600325 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
326 ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
327 rtlphy->pwrgroup_cnt,
328 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9]));
329 }
Larry Finger4295cd22011-02-19 16:29:12 -0600330 if (regaddr == RTXAGC_B_CCK1_55_MCS32) {
331 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14] = data;
Larry Finger4295cd22011-02-19 16:29:12 -0600332 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
333 ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
334 rtlphy->pwrgroup_cnt,
335 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14]));
336 }
Larry Finger4295cd22011-02-19 16:29:12 -0600337 if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {
338 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15] = data;
Larry Finger4295cd22011-02-19 16:29:12 -0600339 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
340 ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
341 rtlphy->pwrgroup_cnt,
342 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15]));
343 }
Larry Finger4295cd22011-02-19 16:29:12 -0600344 if (regaddr == RTXAGC_B_MCS03_MCS00) {
345 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10] = data;
Larry Finger4295cd22011-02-19 16:29:12 -0600346 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
347 ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
348 rtlphy->pwrgroup_cnt,
349 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10]));
350 }
Larry Finger4295cd22011-02-19 16:29:12 -0600351 if (regaddr == RTXAGC_B_MCS07_MCS04) {
352 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11] = data;
Larry Finger4295cd22011-02-19 16:29:12 -0600353 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
354 ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
355 rtlphy->pwrgroup_cnt,
356 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11]));
357 }
Larry Finger4295cd22011-02-19 16:29:12 -0600358 if (regaddr == RTXAGC_B_MCS11_MCS08) {
359 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12] = data;
Larry Finger4295cd22011-02-19 16:29:12 -0600360 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
361 ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
362 rtlphy->pwrgroup_cnt,
363 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12]));
364 }
Larry Finger4295cd22011-02-19 16:29:12 -0600365 if (regaddr == RTXAGC_B_MCS15_MCS12) {
366 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13] = data;
Larry Finger4295cd22011-02-19 16:29:12 -0600367 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
368 ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
369 rtlphy->pwrgroup_cnt,
370 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13]));
371
372 rtlphy->pwrgroup_cnt++;
373 }
374}
Larry Finger1472d3a2011-02-23 10:24:58 -0600375EXPORT_SYMBOL(_rtl92c_store_pwrIndex_diffrate_offset);
Larry Finger4295cd22011-02-19 16:29:12 -0600376
377void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
378{
379 struct rtl_priv *rtlpriv = rtl_priv(hw);
380 struct rtl_phy *rtlphy = &(rtlpriv->phy);
381
382 rtlphy->default_initialgain[0] =
383 (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
384 rtlphy->default_initialgain[1] =
385 (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
386 rtlphy->default_initialgain[2] =
387 (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
388 rtlphy->default_initialgain[3] =
389 (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
390
391 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
392 ("Default initial gain (c50=0x%x, "
393 "c58=0x%x, c60=0x%x, c68=0x%x\n",
394 rtlphy->default_initialgain[0],
395 rtlphy->default_initialgain[1],
396 rtlphy->default_initialgain[2],
397 rtlphy->default_initialgain[3]));
398
399 rtlphy->framesync = (u8) rtl_get_bbreg(hw,
400 ROFDM0_RXDETECTOR3, MASKBYTE0);
401 rtlphy->framesync_c34 = rtl_get_bbreg(hw,
402 ROFDM0_RXDETECTOR2, MASKDWORD);
403
404 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
405 ("Default framesync (0x%x) = 0x%x\n",
406 ROFDM0_RXDETECTOR3, rtlphy->framesync));
407}
408
Larry Finger1472d3a2011-02-23 10:24:58 -0600409void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
Larry Finger4295cd22011-02-19 16:29:12 -0600410{
411 struct rtl_priv *rtlpriv = rtl_priv(hw);
412 struct rtl_phy *rtlphy = &(rtlpriv->phy);
413
414 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
415 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
416 rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
417 rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
418
419 rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
420 rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
421 rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
422 rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
423
424 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
425 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
426
427 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
428 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
429
430 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
431 RFPGA0_XA_LSSIPARAMETER;
432 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
433 RFPGA0_XB_LSSIPARAMETER;
434
435 rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER;
436 rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER;
437 rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER;
438 rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER;
439
440 rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
441 rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
442 rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
443 rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
444
445 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
446 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
447
448 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
449 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
450
451 rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control =
452 RFPGA0_XAB_SWITCHCONTROL;
453 rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control =
454 RFPGA0_XAB_SWITCHCONTROL;
455 rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control =
456 RFPGA0_XCD_SWITCHCONTROL;
457 rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control =
458 RFPGA0_XCD_SWITCHCONTROL;
459
460 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
461 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
462 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
463 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
464
465 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
466 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
467 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
468 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
469
470 rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance =
471 ROFDM0_XARXIQIMBALANCE;
472 rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance =
473 ROFDM0_XBRXIQIMBALANCE;
474 rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance =
475 ROFDM0_XCRXIQIMBANLANCE;
476 rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance =
477 ROFDM0_XDRXIQIMBALANCE;
478
479 rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
480 rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
481 rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
482 rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
483
484 rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance =
485 ROFDM0_XATXIQIMBALANCE;
486 rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance =
487 ROFDM0_XBTXIQIMBALANCE;
488 rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance =
489 ROFDM0_XCTXIQIMBALANCE;
490 rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance =
491 ROFDM0_XDTXIQIMBALANCE;
492
493 rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
494 rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
495 rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
496 rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
497
498 rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback =
499 RFPGA0_XA_LSSIREADBACK;
500 rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback =
501 RFPGA0_XB_LSSIREADBACK;
502 rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback =
503 RFPGA0_XC_LSSIREADBACK;
504 rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback =
505 RFPGA0_XD_LSSIREADBACK;
506
507 rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi =
508 TRANSCEIVEA_HSPI_READBACK;
509 rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi =
510 TRANSCEIVEB_HSPI_READBACK;
511
512}
Larry Finger1472d3a2011-02-23 10:24:58 -0600513EXPORT_SYMBOL(_rtl92c_phy_init_bb_rf_register_definition);
Larry Finger4295cd22011-02-19 16:29:12 -0600514
515void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
516{
517 struct rtl_priv *rtlpriv = rtl_priv(hw);
518 struct rtl_phy *rtlphy = &(rtlpriv->phy);
519 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
520 u8 txpwr_level;
521 long txpwr_dbm;
522
523 txpwr_level = rtlphy->cur_cck_txpwridx;
524 txpwr_dbm = _rtl92c_phy_txpwr_idx_to_dbm(hw,
525 WIRELESS_MODE_B, txpwr_level);
526 txpwr_level = rtlphy->cur_ofdm24g_txpwridx +
527 rtlefuse->legacy_ht_txpowerdiff;
528 if (_rtl92c_phy_txpwr_idx_to_dbm(hw,
529 WIRELESS_MODE_G,
530 txpwr_level) > txpwr_dbm)
531 txpwr_dbm =
532 _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
533 txpwr_level);
534 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
535 if (_rtl92c_phy_txpwr_idx_to_dbm(hw,
536 WIRELESS_MODE_N_24G,
537 txpwr_level) > txpwr_dbm)
538 txpwr_dbm =
539 _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
540 txpwr_level);
541 *powerlevel = txpwr_dbm;
542}
543
544static void _rtl92c_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
545 u8 *cckpowerlevel, u8 *ofdmpowerlevel)
546{
547 struct rtl_priv *rtlpriv = rtl_priv(hw);
548 struct rtl_phy *rtlphy = &(rtlpriv->phy);
549 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
550 u8 index = (channel - 1);
551
552 cckpowerlevel[RF90_PATH_A] =
553 rtlefuse->txpwrlevel_cck[RF90_PATH_A][index];
554 cckpowerlevel[RF90_PATH_B] =
555 rtlefuse->txpwrlevel_cck[RF90_PATH_B][index];
556 if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) {
557 ofdmpowerlevel[RF90_PATH_A] =
558 rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index];
559 ofdmpowerlevel[RF90_PATH_B] =
560 rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index];
561 } else if (get_rf_type(rtlphy) == RF_2T2R) {
562 ofdmpowerlevel[RF90_PATH_A] =
563 rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index];
564 ofdmpowerlevel[RF90_PATH_B] =
565 rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index];
566 }
567}
568
569static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw,
570 u8 channel, u8 *cckpowerlevel,
571 u8 *ofdmpowerlevel)
572{
573 struct rtl_priv *rtlpriv = rtl_priv(hw);
574 struct rtl_phy *rtlphy = &(rtlpriv->phy);
575
576 rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
577 rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
Chaoming_Lic07ccff2011-04-25 12:53:45 -0500578
Larry Finger4295cd22011-02-19 16:29:12 -0600579}
580
581void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
582{
Larry Finger1472d3a2011-02-23 10:24:58 -0600583 struct rtl_priv *rtlpriv = rtl_priv(hw);
584 struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
Larry Finger4295cd22011-02-19 16:29:12 -0600585 u8 cckpowerlevel[2], ofdmpowerlevel[2];
586
587 if (rtlefuse->txpwr_fromeprom == false)
588 return;
589 _rtl92c_get_txpower_index(hw, channel,
590 &cckpowerlevel[0], &ofdmpowerlevel[0]);
591 _rtl92c_ccxpower_index_check(hw,
592 channel, &cckpowerlevel[0],
593 &ofdmpowerlevel[0]);
Larry Finger1472d3a2011-02-23 10:24:58 -0600594 rtlpriv->cfg->ops->phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]);
595 rtlpriv->cfg->ops->phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0],
596 channel);
Larry Finger4295cd22011-02-19 16:29:12 -0600597}
Larry Finger1472d3a2011-02-23 10:24:58 -0600598EXPORT_SYMBOL(rtl92c_phy_set_txpower_level);
Larry Finger4295cd22011-02-19 16:29:12 -0600599
600bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm)
601{
602 struct rtl_priv *rtlpriv = rtl_priv(hw);
603 struct rtl_phy *rtlphy = &(rtlpriv->phy);
604 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
605 u8 idx;
606 u8 rf_path;
Larry Finger4295cd22011-02-19 16:29:12 -0600607 u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw,
608 WIRELESS_MODE_B,
609 power_indbm);
610 u8 ofdmtxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw,
611 WIRELESS_MODE_N_24G,
612 power_indbm);
613 if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0)
614 ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff;
615 else
616 ofdmtxpwridx = 0;
617 RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE,
618 ("%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n",
619 power_indbm, ccktxpwridx, ofdmtxpwridx));
620 for (idx = 0; idx < 14; idx++) {
621 for (rf_path = 0; rf_path < 2; rf_path++) {
622 rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx;
623 rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] =
624 ofdmtxpwridx;
625 rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] =
626 ofdmtxpwridx;
627 }
628 }
629 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
630 return true;
631}
Larry Finger1472d3a2011-02-23 10:24:58 -0600632EXPORT_SYMBOL(rtl92c_phy_update_txpower_dbm);
Larry Finger4295cd22011-02-19 16:29:12 -0600633
Johannes Berg41cae2d2011-02-24 20:39:05 +0100634u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
635 enum wireless_mode wirelessmode,
636 long power_indbm)
Larry Finger4295cd22011-02-19 16:29:12 -0600637{
638 u8 txpwridx;
639 long offset;
640
641 switch (wirelessmode) {
642 case WIRELESS_MODE_B:
643 offset = -7;
644 break;
645 case WIRELESS_MODE_G:
646 case WIRELESS_MODE_N_24G:
647 offset = -8;
648 break;
649 default:
650 offset = -8;
651 break;
652 }
653
654 if ((power_indbm - offset) > 0)
655 txpwridx = (u8) ((power_indbm - offset) * 2);
656 else
657 txpwridx = 0;
658
659 if (txpwridx > MAX_TXPWR_IDX_NMODE_92S)
660 txpwridx = MAX_TXPWR_IDX_NMODE_92S;
661
662 return txpwridx;
663}
Larry Finger1472d3a2011-02-23 10:24:58 -0600664EXPORT_SYMBOL(_rtl92c_phy_dbm_to_txpwr_Idx);
Larry Finger4295cd22011-02-19 16:29:12 -0600665
Johannes Berg41cae2d2011-02-24 20:39:05 +0100666long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
667 enum wireless_mode wirelessmode,
668 u8 txpwridx)
Larry Finger4295cd22011-02-19 16:29:12 -0600669{
670 long offset;
671 long pwrout_dbm;
672
673 switch (wirelessmode) {
674 case WIRELESS_MODE_B:
675 offset = -7;
676 break;
677 case WIRELESS_MODE_G:
678 case WIRELESS_MODE_N_24G:
679 offset = -8;
680 break;
681 default:
682 offset = -8;
683 break;
684 }
685 pwrout_dbm = txpwridx / 2 + offset;
686 return pwrout_dbm;
687}
Larry Finger1472d3a2011-02-23 10:24:58 -0600688EXPORT_SYMBOL(_rtl92c_phy_txpwr_idx_to_dbm);
Larry Finger4295cd22011-02-19 16:29:12 -0600689
690void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
691{
692 struct rtl_priv *rtlpriv = rtl_priv(hw);
693 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
694 enum io_type iotype;
695
696 if (!is_hal_stop(rtlhal)) {
697 switch (operation) {
698 case SCAN_OPT_BACKUP:
699 iotype = IO_CMD_PAUSE_DM_BY_SCAN;
700 rtlpriv->cfg->ops->set_hw_reg(hw,
701 HW_VAR_IO_CMD,
702 (u8 *)&iotype);
703
704 break;
705 case SCAN_OPT_RESTORE:
706 iotype = IO_CMD_RESUME_DM_BY_SCAN;
707 rtlpriv->cfg->ops->set_hw_reg(hw,
708 HW_VAR_IO_CMD,
709 (u8 *)&iotype);
710 break;
711 default:
712 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
713 ("Unknown Scan Backup operation.\n"));
714 break;
715 }
716 }
717}
Larry Finger1472d3a2011-02-23 10:24:58 -0600718EXPORT_SYMBOL(rtl92c_phy_scan_operation_backup);
Larry Finger4295cd22011-02-19 16:29:12 -0600719
720void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
721 enum nl80211_channel_type ch_type)
722{
723 struct rtl_priv *rtlpriv = rtl_priv(hw);
724 struct rtl_phy *rtlphy = &(rtlpriv->phy);
725 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
726 u8 tmp_bw = rtlphy->current_chan_bw;
727
728 if (rtlphy->set_bwmode_inprogress)
729 return;
730 rtlphy->set_bwmode_inprogress = true;
Chaoming_Lic07ccff2011-04-25 12:53:45 -0500731 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
Larry Finger099fb8a2011-05-14 10:15:17 -0500732 rtlpriv->cfg->ops->phy_set_bw_mode_callback(hw);
Chaoming_Lic07ccff2011-04-25 12:53:45 -0500733 } else {
Larry Finger4295cd22011-02-19 16:29:12 -0600734 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
735 ("FALSE driver sleep or unload\n"));
736 rtlphy->set_bwmode_inprogress = false;
737 rtlphy->current_chan_bw = tmp_bw;
738 }
739}
Larry Finger1472d3a2011-02-23 10:24:58 -0600740EXPORT_SYMBOL(rtl92c_phy_set_bw_mode);
Larry Finger4295cd22011-02-19 16:29:12 -0600741
742void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw)
743{
744 struct rtl_priv *rtlpriv = rtl_priv(hw);
745 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
746 struct rtl_phy *rtlphy = &(rtlpriv->phy);
747 u32 delay;
748
749 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
750 ("switch to channel%d\n", rtlphy->current_channel));
751 if (is_hal_stop(rtlhal))
752 return;
753 do {
754 if (!rtlphy->sw_chnl_inprogress)
755 break;
756 if (!_rtl92c_phy_sw_chnl_step_by_step
757 (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage,
758 &rtlphy->sw_chnl_step, &delay)) {
759 if (delay > 0)
760 mdelay(delay);
761 else
762 continue;
Chaoming_Lic07ccff2011-04-25 12:53:45 -0500763 } else {
Larry Finger4295cd22011-02-19 16:29:12 -0600764 rtlphy->sw_chnl_inprogress = false;
Chaoming_Lic07ccff2011-04-25 12:53:45 -0500765 }
Larry Finger4295cd22011-02-19 16:29:12 -0600766 break;
767 } while (true);
768 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
769}
Larry Finger1472d3a2011-02-23 10:24:58 -0600770EXPORT_SYMBOL(rtl92c_phy_sw_chnl_callback);
Larry Finger4295cd22011-02-19 16:29:12 -0600771
772u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw)
773{
774 struct rtl_priv *rtlpriv = rtl_priv(hw);
775 struct rtl_phy *rtlphy = &(rtlpriv->phy);
776 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
777
778 if (rtlphy->sw_chnl_inprogress)
779 return 0;
780 if (rtlphy->set_bwmode_inprogress)
781 return 0;
782 RT_ASSERT((rtlphy->current_channel <= 14),
783 ("WIRELESS_MODE_G but channel>14"));
784 rtlphy->sw_chnl_inprogress = true;
785 rtlphy->sw_chnl_stage = 0;
786 rtlphy->sw_chnl_step = 0;
787 if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
788 rtl92c_phy_sw_chnl_callback(hw);
789 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
790 ("sw_chnl_inprogress false schdule workitem\n"));
791 rtlphy->sw_chnl_inprogress = false;
792 } else {
793 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
794 ("sw_chnl_inprogress false driver sleep or"
795 " unload\n"));
796 rtlphy->sw_chnl_inprogress = false;
797 }
798 return 1;
799}
Larry Finger1472d3a2011-02-23 10:24:58 -0600800EXPORT_SYMBOL(rtl92c_phy_sw_chnl);
Larry Finger4295cd22011-02-19 16:29:12 -0600801
Chaoming_Lic07ccff2011-04-25 12:53:45 -0500802static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
803 u32 cmdtableidx, u32 cmdtablesz,
804 enum swchnlcmd_id cmdid,
805 u32 para1, u32 para2, u32 msdelay)
806{
807 struct swchnlcmd *pcmd;
808
809 if (cmdtable == NULL) {
810 RT_ASSERT(false, ("cmdtable cannot be NULL.\n"));
811 return false;
812 }
813
814 if (cmdtableidx >= cmdtablesz)
815 return false;
816
817 pcmd = cmdtable + cmdtableidx;
818 pcmd->cmdid = cmdid;
819 pcmd->para1 = para1;
820 pcmd->para2 = para2;
821 pcmd->msdelay = msdelay;
822 return true;
823}
824
825bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
826 u8 channel, u8 *stage, u8 *step,
827 u32 *delay)
Larry Finger4295cd22011-02-19 16:29:12 -0600828{
829 struct rtl_priv *rtlpriv = rtl_priv(hw);
830 struct rtl_phy *rtlphy = &(rtlpriv->phy);
831 struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
832 u32 precommoncmdcnt;
833 struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
834 u32 postcommoncmdcnt;
835 struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
836 u32 rfdependcmdcnt;
837 struct swchnlcmd *currentcmd = NULL;
838 u8 rfpath;
839 u8 num_total_rfpath = rtlphy->num_total_rfpath;
840
841 precommoncmdcnt = 0;
842 _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
843 MAX_PRECMD_CNT,
844 CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
845 _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
846 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
847
848 postcommoncmdcnt = 0;
849
850 _rtl92c_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
851 MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
852
853 rfdependcmdcnt = 0;
854
855 RT_ASSERT((channel >= 1 && channel <= 14),
856 ("illegal channel for Zebra: %d\n", channel));
857
858 _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
859 MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
860 RF_CHNLBW, channel, 10);
861
862 _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
863 MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0,
864 0);
865
866 do {
867 switch (*stage) {
868 case 0:
869 currentcmd = &precommoncmd[*step];
870 break;
871 case 1:
872 currentcmd = &rfdependcmd[*step];
873 break;
874 case 2:
875 currentcmd = &postcommoncmd[*step];
876 break;
877 }
878
879 if (currentcmd->cmdid == CMDID_END) {
880 if ((*stage) == 2) {
881 return true;
882 } else {
883 (*stage)++;
884 (*step) = 0;
885 continue;
886 }
887 }
888
889 switch (currentcmd->cmdid) {
890 case CMDID_SET_TXPOWEROWER_LEVEL:
891 rtl92c_phy_set_txpower_level(hw, channel);
892 break;
893 case CMDID_WRITEPORT_ULONG:
894 rtl_write_dword(rtlpriv, currentcmd->para1,
895 currentcmd->para2);
896 break;
897 case CMDID_WRITEPORT_USHORT:
898 rtl_write_word(rtlpriv, currentcmd->para1,
899 (u16) currentcmd->para2);
900 break;
901 case CMDID_WRITEPORT_UCHAR:
902 rtl_write_byte(rtlpriv, currentcmd->para1,
903 (u8) currentcmd->para2);
904 break;
905 case CMDID_RF_WRITEREG:
906 for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
907 rtlphy->rfreg_chnlval[rfpath] =
908 ((rtlphy->rfreg_chnlval[rfpath] &
909 0xfffffc00) | currentcmd->para2);
910
911 rtl_set_rfreg(hw, (enum radio_path)rfpath,
912 currentcmd->para1,
913 RFREG_OFFSET_MASK,
914 rtlphy->rfreg_chnlval[rfpath]);
915 }
916 break;
917 default:
918 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
919 ("switch case not process\n"));
920 break;
921 }
922
923 break;
924 } while (true);
925
926 (*delay) = currentcmd->msdelay;
927 (*step)++;
928 return false;
929}
930
Larry Finger4295cd22011-02-19 16:29:12 -0600931bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath)
932{
933 return true;
934}
Larry Finger1472d3a2011-02-23 10:24:58 -0600935EXPORT_SYMBOL(rtl8192_phy_check_is_legal_rfpath);
Larry Finger4295cd22011-02-19 16:29:12 -0600936
937static u8 _rtl92c_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
938{
939 u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
940 u8 result = 0x00;
941
942 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f);
943 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f);
944 rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102);
945 rtl_set_bbreg(hw, 0xe3c, MASKDWORD,
946 config_pathb ? 0x28160202 : 0x28160502);
947
948 if (config_pathb) {
949 rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22);
950 rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22);
951 rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102);
952 rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202);
953 }
954
955 rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1);
956 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
957 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
958
959 mdelay(IQK_DELAY_TIME);
960
961 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
962 reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
963 reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
964 reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
965
966 if (!(reg_eac & BIT(28)) &&
967 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
968 (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
969 result |= 0x01;
970 else
971 return result;
972
973 if (!(reg_eac & BIT(27)) &&
974 (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
975 (((reg_eac & 0x03FF0000) >> 16) != 0x36))
976 result |= 0x02;
977 return result;
978}
979
980static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw)
981{
982 u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;
983 u8 result = 0x00;
984
985 rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002);
986 rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000);
987 mdelay(IQK_DELAY_TIME);
988 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
989 reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
990 reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
991 reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
992 reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
Chaoming_Lic07ccff2011-04-25 12:53:45 -0500993
Larry Finger4295cd22011-02-19 16:29:12 -0600994 if (!(reg_eac & BIT(31)) &&
995 (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
996 (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
997 result |= 0x01;
998 else
999 return result;
Larry Finger4295cd22011-02-19 16:29:12 -06001000 if (!(reg_eac & BIT(30)) &&
1001 (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
1002 (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
1003 result |= 0x02;
1004 return result;
1005}
1006
1007static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw,
1008 bool iqk_ok, long result[][8],
1009 u8 final_candidate, bool btxonly)
1010{
1011 u32 oldval_0, x, tx0_a, reg;
1012 long y, tx0_c;
1013
Chaoming_Lic07ccff2011-04-25 12:53:45 -05001014 if (final_candidate == 0xFF) {
Larry Finger4295cd22011-02-19 16:29:12 -06001015 return;
Chaoming_Lic07ccff2011-04-25 12:53:45 -05001016 } else if (iqk_ok) {
Larry Finger4295cd22011-02-19 16:29:12 -06001017 oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
1018 MASKDWORD) >> 22) & 0x3FF;
1019 x = result[final_candidate][0];
1020 if ((x & 0x00000200) != 0)
1021 x = x | 0xFFFFFC00;
1022 tx0_a = (x * oldval_0) >> 8;
1023 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a);
1024 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31),
1025 ((x * oldval_0 >> 7) & 0x1));
1026 y = result[final_candidate][1];
1027 if ((y & 0x00000200) != 0)
1028 y = y | 0xFFFFFC00;
1029 tx0_c = (y * oldval_0) >> 8;
1030 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000,
1031 ((tx0_c & 0x3C0) >> 6));
1032 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000,
1033 (tx0_c & 0x3F));
1034 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29),
1035 ((y * oldval_0 >> 7) & 0x1));
1036 if (btxonly)
1037 return;
1038 reg = result[final_candidate][2];
1039 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
1040 reg = result[final_candidate][3] & 0x3F;
1041 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
1042 reg = (result[final_candidate][3] >> 6) & 0xF;
1043 rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg);
1044 }
1045}
1046
1047static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,
1048 bool iqk_ok, long result[][8],
1049 u8 final_candidate, bool btxonly)
1050{
1051 u32 oldval_1, x, tx1_a, reg;
1052 long y, tx1_c;
1053
Chaoming_Lic07ccff2011-04-25 12:53:45 -05001054 if (final_candidate == 0xFF) {
Larry Finger4295cd22011-02-19 16:29:12 -06001055 return;
Chaoming_Lic07ccff2011-04-25 12:53:45 -05001056 } else if (iqk_ok) {
Larry Finger4295cd22011-02-19 16:29:12 -06001057 oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
1058 MASKDWORD) >> 22) & 0x3FF;
1059 x = result[final_candidate][4];
1060 if ((x & 0x00000200) != 0)
1061 x = x | 0xFFFFFC00;
1062 tx1_a = (x * oldval_1) >> 8;
1063 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a);
1064 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27),
1065 ((x * oldval_1 >> 7) & 0x1));
1066 y = result[final_candidate][5];
1067 if ((y & 0x00000200) != 0)
1068 y = y | 0xFFFFFC00;
1069 tx1_c = (y * oldval_1) >> 8;
1070 rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000,
1071 ((tx1_c & 0x3C0) >> 6));
1072 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000,
1073 (tx1_c & 0x3F));
1074 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25),
1075 ((y * oldval_1 >> 7) & 0x1));
1076 if (btxonly)
1077 return;
1078 reg = result[final_candidate][6];
1079 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
1080 reg = result[final_candidate][7] & 0x3F;
1081 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
1082 reg = (result[final_candidate][7] >> 6) & 0xF;
1083 rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg);
1084 }
1085}
1086
1087static void _rtl92c_phy_save_adda_registers(struct ieee80211_hw *hw,
1088 u32 *addareg, u32 *addabackup,
1089 u32 registernum)
1090{
1091 u32 i;
1092
1093 for (i = 0; i < registernum; i++)
1094 addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD);
1095}
1096
1097static void _rtl92c_phy_save_mac_registers(struct ieee80211_hw *hw,
1098 u32 *macreg, u32 *macbackup)
1099{
1100 struct rtl_priv *rtlpriv = rtl_priv(hw);
1101 u32 i;
1102
1103 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1104 macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
1105 macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
1106}
1107
1108static void _rtl92c_phy_reload_adda_registers(struct ieee80211_hw *hw,
1109 u32 *addareg, u32 *addabackup,
1110 u32 regiesternum)
1111{
1112 u32 i;
1113
1114 for (i = 0; i < regiesternum; i++)
1115 rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]);
1116}
1117
1118static void _rtl92c_phy_reload_mac_registers(struct ieee80211_hw *hw,
1119 u32 *macreg, u32 *macbackup)
1120{
1121 struct rtl_priv *rtlpriv = rtl_priv(hw);
1122 u32 i;
1123
1124 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
1125 rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]);
1126 rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
1127}
1128
1129static void _rtl92c_phy_path_adda_on(struct ieee80211_hw *hw,
1130 u32 *addareg, bool is_patha_on, bool is2t)
1131{
1132 u32 pathOn;
1133 u32 i;
1134
1135 pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4;
1136 if (false == is2t) {
1137 pathOn = 0x0bdb25a0;
1138 rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0);
1139 } else {
1140 rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn);
1141 }
1142
1143 for (i = 1; i < IQK_ADDA_REG_NUM; i++)
1144 rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn);
1145}
1146
1147static void _rtl92c_phy_mac_setting_calibration(struct ieee80211_hw *hw,
1148 u32 *macreg, u32 *macbackup)
1149{
1150 struct rtl_priv *rtlpriv = rtl_priv(hw);
1151 u32 i;
1152
1153 rtl_write_byte(rtlpriv, macreg[0], 0x3F);
1154
1155 for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++)
1156 rtl_write_byte(rtlpriv, macreg[i],
1157 (u8) (macbackup[i] & (~BIT(3))));
1158 rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5))));
1159}
1160
1161static void _rtl92c_phy_path_a_standby(struct ieee80211_hw *hw)
1162{
1163 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
1164 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1165 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1166}
1167
1168static void _rtl92c_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode)
1169{
1170 u32 mode;
1171
1172 mode = pi_mode ? 0x01000100 : 0x01000000;
1173 rtl_set_bbreg(hw, 0x820, MASKDWORD, mode);
1174 rtl_set_bbreg(hw, 0x828, MASKDWORD, mode);
1175}
1176
1177static bool _rtl92c_phy_simularity_compare(struct ieee80211_hw *hw,
1178 long result[][8], u8 c1, u8 c2)
1179{
1180 u32 i, j, diff, simularity_bitmap, bound;
1181 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1182
1183 u8 final_candidate[2] = { 0xFF, 0xFF };
1184 bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version);
1185
1186 if (is2t)
1187 bound = 8;
1188 else
1189 bound = 4;
1190
1191 simularity_bitmap = 0;
1192
1193 for (i = 0; i < bound; i++) {
1194 diff = (result[c1][i] > result[c2][i]) ?
1195 (result[c1][i] - result[c2][i]) :
1196 (result[c2][i] - result[c1][i]);
1197
1198 if (diff > MAX_TOLERANCE) {
1199 if ((i == 2 || i == 6) && !simularity_bitmap) {
1200 if (result[c1][i] + result[c1][i + 1] == 0)
1201 final_candidate[(i / 4)] = c2;
1202 else if (result[c2][i] + result[c2][i + 1] == 0)
1203 final_candidate[(i / 4)] = c1;
1204 else
1205 simularity_bitmap = simularity_bitmap |
1206 (1 << i);
1207 } else
1208 simularity_bitmap =
1209 simularity_bitmap | (1 << i);
1210 }
1211 }
1212
1213 if (simularity_bitmap == 0) {
1214 for (i = 0; i < (bound / 4); i++) {
1215 if (final_candidate[i] != 0xFF) {
1216 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1217 result[3][j] =
1218 result[final_candidate[i]][j];
1219 bresult = false;
1220 }
1221 }
1222 return bresult;
1223 } else if (!(simularity_bitmap & 0x0F)) {
1224 for (i = 0; i < 4; i++)
1225 result[3][i] = result[c1][i];
1226 return false;
1227 } else if (!(simularity_bitmap & 0xF0) && is2t) {
1228 for (i = 4; i < 8; i++)
1229 result[3][i] = result[c1][i];
1230 return false;
1231 } else {
1232 return false;
1233 }
1234
1235}
1236
1237static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
1238 long result[][8], u8 t, bool is2t)
1239{
1240 struct rtl_priv *rtlpriv = rtl_priv(hw);
1241 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1242 u32 i;
1243 u8 patha_ok, pathb_ok;
1244 u32 adda_reg[IQK_ADDA_REG_NUM] = {
1245 0x85c, 0xe6c, 0xe70, 0xe74,
1246 0xe78, 0xe7c, 0xe80, 0xe84,
1247 0xe88, 0xe8c, 0xed0, 0xed4,
1248 0xed8, 0xedc, 0xee0, 0xeec
1249 };
1250
1251 u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1252 0x522, 0x550, 0x551, 0x040
1253 };
1254
1255 const u32 retrycount = 2;
1256
Larry Finger4295cd22011-02-19 16:29:12 -06001257 if (t == 0) {
Larry Fingerc0fda682011-05-22 20:54:34 -05001258 /* dummy read */
1259 rtl_get_bbreg(hw, 0x800, MASKDWORD);
Larry Finger4295cd22011-02-19 16:29:12 -06001260
1261 _rtl92c_phy_save_adda_registers(hw, adda_reg,
1262 rtlphy->adda_backup, 16);
1263 _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg,
1264 rtlphy->iqk_mac_backup);
1265 }
1266 _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t);
1267 if (t == 0) {
1268 rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
1269 RFPGA0_XA_HSSIPARAMETER1,
1270 BIT(8));
1271 }
Chaoming_Lic07ccff2011-04-25 12:53:45 -05001272
Larry Finger4295cd22011-02-19 16:29:12 -06001273 if (!rtlphy->rfpi_enable)
1274 _rtl92c_phy_pi_mode_switch(hw, true);
1275 if (t == 0) {
1276 rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD);
1277 rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD);
1278 rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD);
1279 }
1280 rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1281 rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1282 rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1283 if (is2t) {
1284 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1285 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
1286 }
1287 _rtl92c_phy_mac_setting_calibration(hw, iqk_mac_reg,
1288 rtlphy->iqk_mac_backup);
1289 rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000);
1290 if (is2t)
1291 rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000);
1292 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1293 rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
1294 rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800);
1295 for (i = 0; i < retrycount; i++) {
1296 patha_ok = _rtl92c_phy_path_a_iqk(hw, is2t);
1297 if (patha_ok == 0x03) {
1298 result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1299 0x3FF0000) >> 16;
1300 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1301 0x3FF0000) >> 16;
1302 result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
1303 0x3FF0000) >> 16;
1304 result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
1305 0x3FF0000) >> 16;
1306 break;
1307 } else if (i == (retrycount - 1) && patha_ok == 0x01)
Chaoming_Lic07ccff2011-04-25 12:53:45 -05001308
Larry Finger4295cd22011-02-19 16:29:12 -06001309 result[t][0] = (rtl_get_bbreg(hw, 0xe94,
1310 MASKDWORD) & 0x3FF0000) >>
Chaoming_Lic07ccff2011-04-25 12:53:45 -05001311 16;
Larry Finger4295cd22011-02-19 16:29:12 -06001312 result[t][1] =
1313 (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16;
1314
1315 }
1316
1317 if (is2t) {
1318 _rtl92c_phy_path_a_standby(hw);
1319 _rtl92c_phy_path_adda_on(hw, adda_reg, false, is2t);
1320 for (i = 0; i < retrycount; i++) {
1321 pathb_ok = _rtl92c_phy_path_b_iqk(hw);
1322 if (pathb_ok == 0x03) {
1323 result[t][4] = (rtl_get_bbreg(hw,
1324 0xeb4,
1325 MASKDWORD) &
1326 0x3FF0000) >> 16;
1327 result[t][5] =
1328 (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1329 0x3FF0000) >> 16;
1330 result[t][6] =
1331 (rtl_get_bbreg(hw, 0xec4, MASKDWORD) &
1332 0x3FF0000) >> 16;
1333 result[t][7] =
1334 (rtl_get_bbreg(hw, 0xecc, MASKDWORD) &
1335 0x3FF0000) >> 16;
1336 break;
1337 } else if (i == (retrycount - 1) && pathb_ok == 0x01) {
1338 result[t][4] = (rtl_get_bbreg(hw,
1339 0xeb4,
1340 MASKDWORD) &
1341 0x3FF0000) >> 16;
1342 }
1343 result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1344 0x3FF0000) >> 16;
1345 }
1346 }
1347 rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04);
1348 rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874);
1349 rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08);
1350 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1351 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
1352 if (is2t)
1353 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
1354 if (t != 0) {
1355 if (!rtlphy->rfpi_enable)
1356 _rtl92c_phy_pi_mode_switch(hw, false);
1357 _rtl92c_phy_reload_adda_registers(hw, adda_reg,
1358 rtlphy->adda_backup, 16);
1359 _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg,
1360 rtlphy->iqk_mac_backup);
1361 }
1362}
1363
1364static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw,
1365 char delta, bool is2t)
1366{
Chaoming_Li76c34f92011-04-25 12:54:05 -05001367#if 0 /* This routine is deliberately dummied out for later fixes */
Larry Finger4295cd22011-02-19 16:29:12 -06001368 struct rtl_priv *rtlpriv = rtl_priv(hw);
1369 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1370 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1371
1372 u32 reg_d[PATH_NUM];
1373 u32 tmpreg, index, offset, path, i, pathbound = PATH_NUM, apkbound;
1374
1375 u32 bb_backup[APK_BB_REG_NUM];
1376 u32 bb_reg[APK_BB_REG_NUM] = {
1377 0x904, 0xc04, 0x800, 0xc08, 0x874
1378 };
1379 u32 bb_ap_mode[APK_BB_REG_NUM] = {
1380 0x00000020, 0x00a05430, 0x02040000,
1381 0x000800e4, 0x00204000
1382 };
1383 u32 bb_normal_ap_mode[APK_BB_REG_NUM] = {
1384 0x00000020, 0x00a05430, 0x02040000,
1385 0x000800e4, 0x22204000
1386 };
1387
1388 u32 afe_backup[APK_AFE_REG_NUM];
1389 u32 afe_reg[APK_AFE_REG_NUM] = {
1390 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78,
1391 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c,
1392 0xed0, 0xed4, 0xed8, 0xedc, 0xee0,
1393 0xeec
1394 };
1395
1396 u32 mac_backup[IQK_MAC_REG_NUM];
1397 u32 mac_reg[IQK_MAC_REG_NUM] = {
1398 0x522, 0x550, 0x551, 0x040
1399 };
1400
1401 u32 apk_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = {
1402 {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c},
1403 {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e}
1404 };
1405
1406 u32 apk_normal_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = {
1407 {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c},
1408 {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c}
1409 };
1410
1411 u32 apk_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = {
1412 {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d},
1413 {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050}
1414 };
1415
1416 u32 apk_normal_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = {
1417 {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a},
1418 {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}
1419 };
1420
1421 u32 afe_on_off[PATH_NUM] = {
1422 0x04db25a4, 0x0b1b25a4
1423 };
1424
Chaoming_Lic07ccff2011-04-25 12:53:45 -05001425 const u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c };
Larry Finger4295cd22011-02-19 16:29:12 -06001426
1427 u32 apk_normal_offset[PATH_NUM] = { 0xb28, 0xb98 };
1428
1429 u32 apk_value[PATH_NUM] = { 0x92fc0000, 0x12fc0000 };
1430
1431 u32 apk_normal_value[PATH_NUM] = { 0x92680000, 0x12680000 };
1432
1433 const char apk_delta_mapping[APK_BB_REG_NUM][13] = {
1434 {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
1435 {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
1436 {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6},
1437 {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6},
1438 {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0}
1439 };
1440
1441 const u32 apk_normal_setting_value_1[13] = {
1442 0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28,
1443 0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3,
1444 0x12680000, 0x00880000, 0x00880000
1445 };
1446
1447 const u32 apk_normal_setting_value_2[16] = {
1448 0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3,
1449 0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025,
1450 0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008,
1451 0x00050006
1452 };
1453
Chaoming_Lic07ccff2011-04-25 12:53:45 -05001454 u32 apk_result[PATH_NUM][APK_BB_REG_NUM];
Larry Finger4295cd22011-02-19 16:29:12 -06001455
1456 long bb_offset, delta_v, delta_offset;
1457
1458 if (!is2t)
1459 pathbound = 1;
1460
Chaoming_Lic07ccff2011-04-25 12:53:45 -05001461 return;
1462
Larry Finger4295cd22011-02-19 16:29:12 -06001463 for (index = 0; index < PATH_NUM; index++) {
1464 apk_offset[index] = apk_normal_offset[index];
1465 apk_value[index] = apk_normal_value[index];
1466 afe_on_off[index] = 0x6fdb25a4;
1467 }
1468
1469 for (index = 0; index < APK_BB_REG_NUM; index++) {
1470 for (path = 0; path < pathbound; path++) {
1471 apk_rf_init_value[path][index] =
1472 apk_normal_rf_init_value[path][index];
1473 apk_rf_value_0[path][index] =
1474 apk_normal_rf_value_0[path][index];
1475 }
1476 bb_ap_mode[index] = bb_normal_ap_mode[index];
1477
1478 apkbound = 6;
1479 }
1480
1481 for (index = 0; index < APK_BB_REG_NUM; index++) {
1482 if (index == 0)
1483 continue;
1484 bb_backup[index] = rtl_get_bbreg(hw, bb_reg[index], MASKDWORD);
1485 }
1486
1487 _rtl92c_phy_save_mac_registers(hw, mac_reg, mac_backup);
1488
1489 _rtl92c_phy_save_adda_registers(hw, afe_reg, afe_backup, 16);
1490
1491 for (path = 0; path < pathbound; path++) {
1492 if (path == RF90_PATH_A) {
1493 offset = 0xb00;
1494 for (index = 0; index < 11; index++) {
1495 rtl_set_bbreg(hw, offset, MASKDWORD,
1496 apk_normal_setting_value_1
1497 [index]);
1498
1499 offset += 0x04;
1500 }
1501
1502 rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000);
1503
1504 offset = 0xb68;
1505 for (; index < 13; index++) {
1506 rtl_set_bbreg(hw, offset, MASKDWORD,
1507 apk_normal_setting_value_1
1508 [index]);
1509
1510 offset += 0x04;
1511 }
1512
1513 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000);
1514
1515 offset = 0xb00;
1516 for (index = 0; index < 16; index++) {
1517 rtl_set_bbreg(hw, offset, MASKDWORD,
1518 apk_normal_setting_value_2
1519 [index]);
1520
1521 offset += 0x04;
1522 }
1523 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000);
1524 } else if (path == RF90_PATH_B) {
1525 offset = 0xb70;
1526 for (index = 0; index < 10; index++) {
1527 rtl_set_bbreg(hw, offset, MASKDWORD,
1528 apk_normal_setting_value_1
1529 [index]);
1530
1531 offset += 0x04;
1532 }
1533 rtl_set_bbreg(hw, 0xb28, MASKDWORD, 0x12680000);
1534 rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000);
1535
1536 offset = 0xb68;
1537 index = 11;
1538 for (; index < 13; index++) {
1539 rtl_set_bbreg(hw, offset, MASKDWORD,
1540 apk_normal_setting_value_1
1541 [index]);
1542
1543 offset += 0x04;
1544 }
1545
1546 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000);
1547
1548 offset = 0xb60;
1549 for (index = 0; index < 16; index++) {
1550 rtl_set_bbreg(hw, offset, MASKDWORD,
1551 apk_normal_setting_value_2
1552 [index]);
1553
1554 offset += 0x04;
1555 }
1556 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000);
1557 }
1558
1559 reg_d[path] = rtl_get_rfreg(hw, (enum radio_path)path,
1560 0xd, MASKDWORD);
1561
1562 for (index = 0; index < APK_AFE_REG_NUM; index++)
1563 rtl_set_bbreg(hw, afe_reg[index], MASKDWORD,
1564 afe_on_off[path]);
1565
1566 if (path == RF90_PATH_A) {
1567 for (index = 0; index < APK_BB_REG_NUM; index++) {
1568 if (index == 0)
1569 continue;
1570 rtl_set_bbreg(hw, bb_reg[index], MASKDWORD,
1571 bb_ap_mode[index]);
1572 }
1573 }
1574
1575 _rtl92c_phy_mac_setting_calibration(hw, mac_reg, mac_backup);
1576
1577 if (path == 0) {
1578 rtl_set_rfreg(hw, RF90_PATH_B, 0x0, MASKDWORD, 0x10000);
1579 } else {
1580 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASKDWORD,
1581 0x10000);
1582 rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD,
1583 0x1000f);
1584 rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD,
1585 0x20103);
1586 }
1587
1588 delta_offset = ((delta + 14) / 2);
1589 if (delta_offset < 0)
1590 delta_offset = 0;
1591 else if (delta_offset > 12)
1592 delta_offset = 12;
1593
1594 for (index = 0; index < APK_BB_REG_NUM; index++) {
1595 if (index != 1)
1596 continue;
1597
1598 tmpreg = apk_rf_init_value[path][index];
1599
1600 if (!rtlefuse->apk_thermalmeterignore) {
1601 bb_offset = (tmpreg & 0xF0000) >> 16;
1602
1603 if (!(tmpreg & BIT(15)))
1604 bb_offset = -bb_offset;
1605
1606 delta_v =
1607 apk_delta_mapping[index][delta_offset];
1608
1609 bb_offset += delta_v;
1610
1611 if (bb_offset < 0) {
1612 tmpreg = tmpreg & (~BIT(15));
1613 bb_offset = -bb_offset;
1614 } else {
1615 tmpreg = tmpreg | BIT(15);
1616 }
1617
1618 tmpreg =
1619 (tmpreg & 0xFFF0FFFF) | (bb_offset << 16);
1620 }
1621
1622 rtl_set_rfreg(hw, (enum radio_path)path, 0xc,
1623 MASKDWORD, 0x8992e);
1624 rtl_set_rfreg(hw, (enum radio_path)path, 0x0,
1625 MASKDWORD, apk_rf_value_0[path][index]);
1626 rtl_set_rfreg(hw, (enum radio_path)path, 0xd,
1627 MASKDWORD, tmpreg);
1628
1629 i = 0;
1630 do {
1631 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80000000);
1632 rtl_set_bbreg(hw, apk_offset[path],
1633 MASKDWORD, apk_value[0]);
1634 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1635 ("PHY_APCalibrate() offset 0x%x "
1636 "value 0x%x\n",
1637 apk_offset[path],
1638 rtl_get_bbreg(hw, apk_offset[path],
1639 MASKDWORD)));
1640
1641 mdelay(3);
1642
1643 rtl_set_bbreg(hw, apk_offset[path],
1644 MASKDWORD, apk_value[1]);
1645 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1646 ("PHY_APCalibrate() offset 0x%x "
1647 "value 0x%x\n",
1648 apk_offset[path],
1649 rtl_get_bbreg(hw, apk_offset[path],
1650 MASKDWORD)));
1651
1652 mdelay(20);
1653
1654 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000);
1655
1656 if (path == RF90_PATH_A)
1657 tmpreg = rtl_get_bbreg(hw, 0xbd8,
1658 0x03E00000);
1659 else
1660 tmpreg = rtl_get_bbreg(hw, 0xbd8,
1661 0xF8000000);
1662
1663 RTPRINT(rtlpriv, FINIT, INIT_IQK,
1664 ("PHY_APCalibrate() offset "
1665 "0xbd8[25:21] %x\n", tmpreg));
1666
1667 i++;
1668
1669 } while (tmpreg > apkbound && i < 4);
1670
1671 apk_result[path][index] = tmpreg;
1672 }
1673 }
1674
1675 _rtl92c_phy_reload_mac_registers(hw, mac_reg, mac_backup);
1676
1677 for (index = 0; index < APK_BB_REG_NUM; index++) {
1678 if (index == 0)
1679 continue;
1680 rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, bb_backup[index]);
1681 }
1682
1683 _rtl92c_phy_reload_adda_registers(hw, afe_reg, afe_backup, 16);
1684
1685 for (path = 0; path < pathbound; path++) {
1686 rtl_set_rfreg(hw, (enum radio_path)path, 0xd,
1687 MASKDWORD, reg_d[path]);
1688
1689 if (path == RF90_PATH_B) {
1690 rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD,
1691 0x1000f);
1692 rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD,
1693 0x20101);
1694 }
1695
1696 if (apk_result[path][1] > 6)
1697 apk_result[path][1] = 6;
1698 }
1699
1700 for (path = 0; path < pathbound; path++) {
1701 rtl_set_rfreg(hw, (enum radio_path)path, 0x3, MASKDWORD,
1702 ((apk_result[path][1] << 15) |
1703 (apk_result[path][1] << 10) |
1704 (apk_result[path][1] << 5) |
1705 apk_result[path][1]));
1706
1707 if (path == RF90_PATH_A)
1708 rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD,
1709 ((apk_result[path][1] << 15) |
1710 (apk_result[path][1] << 10) |
1711 (0x00 << 5) | 0x05));
1712 else
1713 rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD,
1714 ((apk_result[path][1] << 15) |
1715 (apk_result[path][1] << 10) |
1716 (0x02 << 5) | 0x05));
1717
1718 rtl_set_rfreg(hw, (enum radio_path)path, 0xe, MASKDWORD,
1719 ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) |
1720 0x08));
1721
1722 }
Chaoming_Lic07ccff2011-04-25 12:53:45 -05001723 rtlphy->b_apk_done = true;
Larry Finger4295cd22011-02-19 16:29:12 -06001724#endif
1725}
1726
1727static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw,
1728 bool bmain, bool is2t)
1729{
1730 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1731
1732 if (is_hal_stop(rtlhal)) {
1733 rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01);
1734 rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
1735 }
1736 if (is2t) {
1737 if (bmain)
1738 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1739 BIT(5) | BIT(6), 0x1);
1740 else
1741 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1742 BIT(5) | BIT(6), 0x2);
1743 } else {
1744 if (bmain)
1745 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2);
1746 else
1747 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1);
1748
1749 }
Chaoming_Lic07ccff2011-04-25 12:53:45 -05001750
Larry Finger4295cd22011-02-19 16:29:12 -06001751}
1752
1753#undef IQK_ADDA_REG_NUM
1754#undef IQK_DELAY_TIME
1755
1756void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
1757{
1758 struct rtl_priv *rtlpriv = rtl_priv(hw);
1759 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1760 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1761
1762 long result[4][8];
1763 u8 i, final_candidate;
1764 bool patha_ok, pathb_ok;
Larry Fingerc0fda682011-05-22 20:54:34 -05001765 long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_ec4, reg_tmp = 0;
Larry Finger4295cd22011-02-19 16:29:12 -06001766 bool is12simular, is13simular, is23simular;
1767 bool start_conttx = false, singletone = false;
1768 u32 iqk_bb_reg[10] = {
1769 ROFDM0_XARXIQIMBALANCE,
1770 ROFDM0_XBRXIQIMBALANCE,
1771 ROFDM0_ECCATHRESHOLD,
1772 ROFDM0_AGCRSSITABLE,
1773 ROFDM0_XATXIQIMBALANCE,
1774 ROFDM0_XBTXIQIMBALANCE,
1775 ROFDM0_XCTXIQIMBALANCE,
1776 ROFDM0_XCTXAFE,
1777 ROFDM0_XDTXAFE,
1778 ROFDM0_RXIQEXTANTA
1779 };
1780
1781 if (recovery) {
1782 _rtl92c_phy_reload_adda_registers(hw,
1783 iqk_bb_reg,
1784 rtlphy->iqk_bb_backup, 10);
1785 return;
1786 }
1787 if (start_conttx || singletone)
1788 return;
1789 for (i = 0; i < 8; i++) {
1790 result[0][i] = 0;
1791 result[1][i] = 0;
1792 result[2][i] = 0;
1793 result[3][i] = 0;
1794 }
1795 final_candidate = 0xff;
1796 patha_ok = false;
1797 pathb_ok = false;
1798 is12simular = false;
1799 is23simular = false;
1800 is13simular = false;
1801 for (i = 0; i < 3; i++) {
1802 if (IS_92C_SERIAL(rtlhal->version))
1803 _rtl92c_phy_iq_calibrate(hw, result, i, true);
1804 else
1805 _rtl92c_phy_iq_calibrate(hw, result, i, false);
1806 if (i == 1) {
1807 is12simular = _rtl92c_phy_simularity_compare(hw,
1808 result, 0,
1809 1);
1810 if (is12simular) {
1811 final_candidate = 0;
1812 break;
1813 }
1814 }
1815 if (i == 2) {
1816 is13simular = _rtl92c_phy_simularity_compare(hw,
1817 result, 0,
1818 2);
1819 if (is13simular) {
1820 final_candidate = 0;
1821 break;
1822 }
1823 is23simular = _rtl92c_phy_simularity_compare(hw,
1824 result, 1,
1825 2);
1826 if (is23simular)
1827 final_candidate = 1;
1828 else {
1829 for (i = 0; i < 8; i++)
1830 reg_tmp += result[3][i];
1831
1832 if (reg_tmp != 0)
1833 final_candidate = 3;
1834 else
1835 final_candidate = 0xFF;
1836 }
1837 }
1838 }
1839 for (i = 0; i < 4; i++) {
1840 reg_e94 = result[i][0];
1841 reg_e9c = result[i][1];
1842 reg_ea4 = result[i][2];
Larry Finger4295cd22011-02-19 16:29:12 -06001843 reg_eb4 = result[i][4];
1844 reg_ebc = result[i][5];
1845 reg_ec4 = result[i][6];
Larry Finger4295cd22011-02-19 16:29:12 -06001846 }
1847 if (final_candidate != 0xff) {
1848 rtlphy->reg_e94 = reg_e94 = result[final_candidate][0];
1849 rtlphy->reg_e9c = reg_e9c = result[final_candidate][1];
1850 reg_ea4 = result[final_candidate][2];
Larry Finger4295cd22011-02-19 16:29:12 -06001851 rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4];
1852 rtlphy->reg_ebc = reg_ebc = result[final_candidate][5];
1853 reg_ec4 = result[final_candidate][6];
Larry Finger4295cd22011-02-19 16:29:12 -06001854 patha_ok = pathb_ok = true;
1855 } else {
1856 rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100;
1857 rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0;
1858 }
1859 if (reg_e94 != 0) /*&&(reg_ea4 != 0) */
1860 _rtl92c_phy_path_a_fill_iqk_matrix(hw, patha_ok, result,
1861 final_candidate,
1862 (reg_ea4 == 0));
1863 if (IS_92C_SERIAL(rtlhal->version)) {
1864 if (reg_eb4 != 0) /*&&(reg_ec4 != 0) */
1865 _rtl92c_phy_path_b_fill_iqk_matrix(hw, pathb_ok,
1866 result,
1867 final_candidate,
1868 (reg_ec4 == 0));
1869 }
1870 _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg,
1871 rtlphy->iqk_bb_backup, 10);
1872}
Larry Finger1472d3a2011-02-23 10:24:58 -06001873EXPORT_SYMBOL(rtl92c_phy_iq_calibrate);
Larry Finger4295cd22011-02-19 16:29:12 -06001874
1875void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw)
1876{
Larry Finger1472d3a2011-02-23 10:24:58 -06001877 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger4295cd22011-02-19 16:29:12 -06001878 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1879 bool start_conttx = false, singletone = false;
1880
1881 if (start_conttx || singletone)
1882 return;
1883 if (IS_92C_SERIAL(rtlhal->version))
Larry Finger1472d3a2011-02-23 10:24:58 -06001884 rtlpriv->cfg->ops->phy_lc_calibrate(hw, true);
Larry Finger4295cd22011-02-19 16:29:12 -06001885 else
Larry Finger1472d3a2011-02-23 10:24:58 -06001886 rtlpriv->cfg->ops->phy_lc_calibrate(hw, false);
Larry Finger4295cd22011-02-19 16:29:12 -06001887}
Larry Finger1472d3a2011-02-23 10:24:58 -06001888EXPORT_SYMBOL(rtl92c_phy_lc_calibrate);
Larry Finger4295cd22011-02-19 16:29:12 -06001889
1890void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
1891{
1892 struct rtl_priv *rtlpriv = rtl_priv(hw);
1893 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1894 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1895
1896 if (rtlphy->apk_done)
1897 return;
1898 if (IS_92C_SERIAL(rtlhal->version))
1899 _rtl92c_phy_ap_calibrate(hw, delta, true);
1900 else
1901 _rtl92c_phy_ap_calibrate(hw, delta, false);
1902}
Larry Finger1472d3a2011-02-23 10:24:58 -06001903EXPORT_SYMBOL(rtl92c_phy_ap_calibrate);
Larry Finger4295cd22011-02-19 16:29:12 -06001904
1905void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
1906{
1907 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1908
1909 if (IS_92C_SERIAL(rtlhal->version))
1910 _rtl92c_phy_set_rfpath_switch(hw, bmain, true);
1911 else
1912 _rtl92c_phy_set_rfpath_switch(hw, bmain, false);
1913}
Larry Finger1472d3a2011-02-23 10:24:58 -06001914EXPORT_SYMBOL(rtl92c_phy_set_rfpath_switch);
Larry Finger4295cd22011-02-19 16:29:12 -06001915
1916bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
1917{
1918 struct rtl_priv *rtlpriv = rtl_priv(hw);
1919 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1920 bool postprocessing = false;
1921
1922 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1923 ("-->IO Cmd(%#x), set_io_inprogress(%d)\n",
1924 iotype, rtlphy->set_io_inprogress));
1925 do {
1926 switch (iotype) {
1927 case IO_CMD_RESUME_DM_BY_SCAN:
1928 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1929 ("[IO CMD] Resume DM after scan.\n"));
1930 postprocessing = true;
1931 break;
1932 case IO_CMD_PAUSE_DM_BY_SCAN:
1933 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1934 ("[IO CMD] Pause DM before scan.\n"));
1935 postprocessing = true;
1936 break;
1937 default:
1938 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1939 ("switch case not process\n"));
1940 break;
1941 }
1942 } while (false);
1943 if (postprocessing && !rtlphy->set_io_inprogress) {
1944 rtlphy->set_io_inprogress = true;
1945 rtlphy->current_io_type = iotype;
1946 } else {
1947 return false;
1948 }
1949 rtl92c_phy_set_io(hw);
1950 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype));
1951 return true;
1952}
Larry Finger1472d3a2011-02-23 10:24:58 -06001953EXPORT_SYMBOL(rtl92c_phy_set_io_cmd);
Larry Finger4295cd22011-02-19 16:29:12 -06001954
1955void rtl92c_phy_set_io(struct ieee80211_hw *hw)
1956{
1957 struct rtl_priv *rtlpriv = rtl_priv(hw);
1958 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1959
1960 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1961 ("--->Cmd(%#x), set_io_inprogress(%d)\n",
1962 rtlphy->current_io_type, rtlphy->set_io_inprogress));
1963 switch (rtlphy->current_io_type) {
1964 case IO_CMD_RESUME_DM_BY_SCAN:
1965 dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1;
1966 rtl92c_dm_write_dig(hw);
1967 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
1968 break;
1969 case IO_CMD_PAUSE_DM_BY_SCAN:
1970 rtlphy->initgain_backup.xaagccore1 = dm_digtable.cur_igvalue;
1971 dm_digtable.cur_igvalue = 0x17;
1972 rtl92c_dm_write_dig(hw);
1973 break;
1974 default:
1975 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1976 ("switch case not process\n"));
1977 break;
1978 }
1979 rtlphy->set_io_inprogress = false;
1980 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1981 ("<---(%#x)\n", rtlphy->current_io_type));
1982}
Larry Finger1472d3a2011-02-23 10:24:58 -06001983EXPORT_SYMBOL(rtl92c_phy_set_io);
Larry Finger4295cd22011-02-19 16:29:12 -06001984
1985void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw)
1986{
1987 struct rtl_priv *rtlpriv = rtl_priv(hw);
1988
1989 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
1990 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1991 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
1992 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1993 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1994 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1995}
Larry Finger1472d3a2011-02-23 10:24:58 -06001996EXPORT_SYMBOL(rtl92ce_phy_set_rf_on);
Larry Finger4295cd22011-02-19 16:29:12 -06001997
Larry Finger1472d3a2011-02-23 10:24:58 -06001998void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw)
Larry Finger4295cd22011-02-19 16:29:12 -06001999{
2000 u32 u4b_tmp;
2001 u8 delay = 5;
2002 struct rtl_priv *rtlpriv = rtl_priv(hw);
2003
2004 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2005 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2006 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
2007 u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
2008 while (u4b_tmp != 0 && delay > 0) {
2009 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
2010 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2011 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
2012 u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
2013 delay--;
2014 }
2015 if (delay == 0) {
2016 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
2017 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2018 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2019 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2020 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
2021 ("Switch RF timeout !!!.\n"));
2022 return;
2023 }
2024 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2025 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2026}
Larry Finger1472d3a2011-02-23 10:24:58 -06002027EXPORT_SYMBOL(_rtl92c_phy_set_rf_sleep);