Merge tag 'trace-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux...
[deliverable/linux.git] / drivers / net / wireless / rtlwifi / rtl8192se / phy.c
CommitLineData
d1585316
CL
1/******************************************************************************
2 *
ca742cd9 3 * Copyright(c) 2009-2012 Realtek Corporation.
d1585316
CL
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
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 "fw.h"
39#include "hw.h"
40#include "table.h"
41
42static u32 _rtl92s_phy_calculate_bit_shift(u32 bitmask)
43{
44 u32 i;
45
46 for (i = 0; i <= 31; i++) {
47 if (((bitmask >> i) & 0x1) == 1)
48 break;
49 }
50
51 return i;
52}
53
54u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
55{
56 struct rtl_priv *rtlpriv = rtl_priv(hw);
57 u32 returnvalue = 0, originalvalue, bitshift;
58
f30d7507
JP
59 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n",
60 regaddr, bitmask);
d1585316
CL
61
62 originalvalue = rtl_read_dword(rtlpriv, regaddr);
63 bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
64 returnvalue = (originalvalue & bitmask) >> bitshift;
65
f30d7507
JP
66 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
67 bitmask, regaddr, originalvalue);
d1585316
CL
68
69 return returnvalue;
70
71}
72
73void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
74 u32 data)
75{
76 struct rtl_priv *rtlpriv = rtl_priv(hw);
77 u32 originalvalue, bitshift;
78
f30d7507
JP
79 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
80 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
81 regaddr, bitmask, data);
d1585316
CL
82
83 if (bitmask != MASKDWORD) {
84 originalvalue = rtl_read_dword(rtlpriv, regaddr);
85 bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
86 data = ((originalvalue & (~bitmask)) | (data << bitshift));
87 }
88
89 rtl_write_dword(rtlpriv, regaddr, data);
90
f30d7507
JP
91 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
92 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
93 regaddr, bitmask, data);
d1585316
CL
94
95}
96
97static u32 _rtl92s_phy_rf_serial_read(struct ieee80211_hw *hw,
98 enum radio_path rfpath, u32 offset)
99{
100
101 struct rtl_priv *rtlpriv = rtl_priv(hw);
102 struct rtl_phy *rtlphy = &(rtlpriv->phy);
103 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
104 u32 newoffset;
105 u32 tmplong, tmplong2;
106 u8 rfpi_enable = 0;
107 u32 retvalue = 0;
108
109 offset &= 0x3f;
110 newoffset = offset;
111
112 tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
113
114 if (rfpath == RF90_PATH_A)
115 tmplong2 = tmplong;
116 else
117 tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
118
119 tmplong2 = (tmplong2 & (~BLSSI_READADDRESS)) | (newoffset << 23) |
120 BLSSI_READEDGE;
121
122 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
123 tmplong & (~BLSSI_READEDGE));
124
125 mdelay(1);
126
127 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
128 mdelay(1);
129
130 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, tmplong |
131 BLSSI_READEDGE);
132 mdelay(1);
133
134 if (rfpath == RF90_PATH_A)
135 rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
136 BIT(8));
137 else if (rfpath == RF90_PATH_B)
138 rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
139 BIT(8));
140
141 if (rfpi_enable)
da17fcff 142 retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi,
d1585316
CL
143 BLSSI_READBACK_DATA);
144 else
da17fcff 145 retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb,
d1585316
CL
146 BLSSI_READBACK_DATA);
147
da17fcff 148 retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb,
d1585316
CL
149 BLSSI_READBACK_DATA);
150
f30d7507 151 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n",
da17fcff 152 rfpath, pphyreg->rf_rb, retvalue);
d1585316
CL
153
154 return retvalue;
155
156}
157
158static void _rtl92s_phy_rf_serial_write(struct ieee80211_hw *hw,
159 enum radio_path rfpath, u32 offset,
160 u32 data)
161{
162 struct rtl_priv *rtlpriv = rtl_priv(hw);
163 struct rtl_phy *rtlphy = &(rtlpriv->phy);
164 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
165 u32 data_and_addr = 0;
166 u32 newoffset;
167
168 offset &= 0x3f;
169 newoffset = offset;
170
171 data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
172 rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
173
f30d7507
JP
174 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n",
175 rfpath, pphyreg->rf3wire_offset, data_and_addr);
d1585316
CL
176}
177
178
179u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
180 u32 regaddr, u32 bitmask)
181{
182 struct rtl_priv *rtlpriv = rtl_priv(hw);
183 u32 original_value, readback_value, bitshift;
d1585316 184
f30d7507
JP
185 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
186 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
187 regaddr, rfpath, bitmask);
d1585316 188
312d5479 189 spin_lock(&rtlpriv->locks.rf_lock);
d1585316
CL
190
191 original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr);
192
193 bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
194 readback_value = (original_value & bitmask) >> bitshift;
195
312d5479 196 spin_unlock(&rtlpriv->locks.rf_lock);
d1585316 197
f30d7507
JP
198 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
199 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
200 regaddr, rfpath, bitmask, original_value);
d1585316
CL
201
202 return readback_value;
203}
204
205void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
206 u32 regaddr, u32 bitmask, u32 data)
207{
208 struct rtl_priv *rtlpriv = rtl_priv(hw);
209 struct rtl_phy *rtlphy = &(rtlpriv->phy);
210 u32 original_value, bitshift;
d1585316
CL
211
212 if (!((rtlphy->rf_pathmap >> rfpath) & 0x1))
213 return;
214
f30d7507
JP
215 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
216 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
217 regaddr, bitmask, data, rfpath);
d1585316 218
312d5479 219 spin_lock(&rtlpriv->locks.rf_lock);
d1585316
CL
220
221 if (bitmask != RFREG_OFFSET_MASK) {
222 original_value = _rtl92s_phy_rf_serial_read(hw, rfpath,
223 regaddr);
224 bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
225 data = ((original_value & (~bitmask)) | (data << bitshift));
226 }
227
228 _rtl92s_phy_rf_serial_write(hw, rfpath, regaddr, data);
229
312d5479 230 spin_unlock(&rtlpriv->locks.rf_lock);
d1585316 231
f30d7507
JP
232 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
233 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
234 regaddr, bitmask, data, rfpath);
d1585316
CL
235
236}
237
238void rtl92s_phy_scan_operation_backup(struct ieee80211_hw *hw,
239 u8 operation)
240{
241 struct rtl_priv *rtlpriv = rtl_priv(hw);
242 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
243
244 if (!is_hal_stop(rtlhal)) {
245 switch (operation) {
246 case SCAN_OPT_BACKUP:
247 rtl92s_phy_set_fw_cmd(hw, FW_CMD_PAUSE_DM_BY_SCAN);
248 break;
249 case SCAN_OPT_RESTORE:
250 rtl92s_phy_set_fw_cmd(hw, FW_CMD_RESUME_DM_BY_SCAN);
251 break;
252 default:
253 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
f30d7507 254 "Unknown operation\n");
d1585316
CL
255 break;
256 }
257 }
258}
259
260void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw,
261 enum nl80211_channel_type ch_type)
262{
263 struct rtl_priv *rtlpriv = rtl_priv(hw);
264 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
265 struct rtl_phy *rtlphy = &(rtlpriv->phy);
266 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
267 u8 reg_bw_opmode;
d1585316 268
f30d7507
JP
269 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n",
270 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
271 "20MHz" : "40MHz");
d1585316
CL
272
273 if (rtlphy->set_bwmode_inprogress)
274 return;
275 if (is_hal_stop(rtlhal))
276 return;
277
278 rtlphy->set_bwmode_inprogress = true;
279
280 reg_bw_opmode = rtl_read_byte(rtlpriv, BW_OPMODE);
78d57372
LF
281 /* dummy read */
282 rtl_read_byte(rtlpriv, RRSR + 2);
d1585316
CL
283
284 switch (rtlphy->current_chan_bw) {
285 case HT_CHANNEL_WIDTH_20:
286 reg_bw_opmode |= BW_OPMODE_20MHZ;
287 rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode);
288 break;
289 case HT_CHANNEL_WIDTH_20_40:
290 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
291 rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode);
292 break;
293 default:
294 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
f30d7507 295 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
d1585316
CL
296 break;
297 }
298
299 switch (rtlphy->current_chan_bw) {
300 case HT_CHANNEL_WIDTH_20:
301 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
302 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
303
304 if (rtlhal->version >= VERSION_8192S_BCUT)
305 rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x58);
306 break;
307 case HT_CHANNEL_WIDTH_20_40:
308 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
309 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
310
311 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
312 (mac->cur_40_prime_sc >> 1));
313 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
314
315 if (rtlhal->version >= VERSION_8192S_BCUT)
316 rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x18);
317 break;
318 default:
319 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
f30d7507 320 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
d1585316
CL
321 break;
322 }
323
324 rtl92s_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
325 rtlphy->set_bwmode_inprogress = false;
f30d7507 326 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
d1585316
CL
327}
328
329static bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
330 u32 cmdtableidx, u32 cmdtablesz, enum swchnlcmd_id cmdid,
331 u32 para1, u32 para2, u32 msdelay)
332{
333 struct swchnlcmd *pcmd;
334
335 if (cmdtable == NULL) {
9d833ed7 336 RT_ASSERT(false, "cmdtable cannot be NULL\n");
d1585316
CL
337 return false;
338 }
339
340 if (cmdtableidx >= cmdtablesz)
341 return false;
342
343 pcmd = cmdtable + cmdtableidx;
344 pcmd->cmdid = cmdid;
345 pcmd->para1 = para1;
346 pcmd->para2 = para2;
347 pcmd->msdelay = msdelay;
348
349 return true;
350}
351
352static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
353 u8 channel, u8 *stage, u8 *step, u32 *delay)
354{
355 struct rtl_priv *rtlpriv = rtl_priv(hw);
356 struct rtl_phy *rtlphy = &(rtlpriv->phy);
357 struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
358 u32 precommoncmdcnt;
359 struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
360 u32 postcommoncmdcnt;
361 struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
362 u32 rfdependcmdcnt;
363 struct swchnlcmd *currentcmd = NULL;
364 u8 rfpath;
365 u8 num_total_rfpath = rtlphy->num_total_rfpath;
366
367 precommoncmdcnt = 0;
368 _rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
369 MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
370 _rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
371 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
372
373 postcommoncmdcnt = 0;
374
375 _rtl92s_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
376 MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
377
378 rfdependcmdcnt = 0;
379
380 RT_ASSERT((channel >= 1 && channel <= 14),
9d833ed7 381 "invalid channel for Zebra: %d\n", channel);
d1585316
CL
382
383 _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
384 MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
385 RF_CHNLBW, channel, 10);
386
387 _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
388 MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0);
389
390 do {
391 switch (*stage) {
392 case 0:
393 currentcmd = &precommoncmd[*step];
394 break;
395 case 1:
396 currentcmd = &rfdependcmd[*step];
397 break;
398 case 2:
399 currentcmd = &postcommoncmd[*step];
400 break;
401 }
402
403 if (currentcmd->cmdid == CMDID_END) {
404 if ((*stage) == 2) {
405 return true;
406 } else {
407 (*stage)++;
408 (*step) = 0;
409 continue;
410 }
411 }
412
413 switch (currentcmd->cmdid) {
414 case CMDID_SET_TXPOWEROWER_LEVEL:
415 rtl92s_phy_set_txpower(hw, channel);
416 break;
417 case CMDID_WRITEPORT_ULONG:
418 rtl_write_dword(rtlpriv, currentcmd->para1,
419 currentcmd->para2);
420 break;
421 case CMDID_WRITEPORT_USHORT:
422 rtl_write_word(rtlpriv, currentcmd->para1,
423 (u16)currentcmd->para2);
424 break;
425 case CMDID_WRITEPORT_UCHAR:
426 rtl_write_byte(rtlpriv, currentcmd->para1,
427 (u8)currentcmd->para2);
428 break;
429 case CMDID_RF_WRITEREG:
430 for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
431 rtlphy->rfreg_chnlval[rfpath] =
432 ((rtlphy->rfreg_chnlval[rfpath] &
433 0xfffffc00) | currentcmd->para2);
434 rtl_set_rfreg(hw, (enum radio_path)rfpath,
435 currentcmd->para1,
436 RFREG_OFFSET_MASK,
437 rtlphy->rfreg_chnlval[rfpath]);
438 }
439 break;
440 default:
441 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
f30d7507 442 "switch case not processed\n");
d1585316
CL
443 break;
444 }
445
446 break;
447 } while (true);
448
449 (*delay) = currentcmd->msdelay;
450 (*step)++;
451 return false;
452}
453
454u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw)
455{
456 struct rtl_priv *rtlpriv = rtl_priv(hw);
457 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
458 struct rtl_phy *rtlphy = &(rtlpriv->phy);
459 u32 delay;
460 bool ret;
461
f30d7507
JP
462 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "switch to channel%d\n",
463 rtlphy->current_channel);
d1585316
CL
464
465 if (rtlphy->sw_chnl_inprogress)
466 return 0;
467
468 if (rtlphy->set_bwmode_inprogress)
469 return 0;
470
471 if (is_hal_stop(rtlhal))
472 return 0;
473
474 rtlphy->sw_chnl_inprogress = true;
475 rtlphy->sw_chnl_stage = 0;
476 rtlphy->sw_chnl_step = 0;
477
478 do {
479 if (!rtlphy->sw_chnl_inprogress)
480 break;
481
482 ret = _rtl92s_phy_sw_chnl_step_by_step(hw,
483 rtlphy->current_channel,
484 &rtlphy->sw_chnl_stage,
485 &rtlphy->sw_chnl_step, &delay);
486 if (!ret) {
487 if (delay > 0)
488 mdelay(delay);
489 else
490 continue;
491 } else {
492 rtlphy->sw_chnl_inprogress = false;
493 }
494 break;
495 } while (true);
496
497 rtlphy->sw_chnl_inprogress = false;
498
f30d7507 499 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
d1585316
CL
500
501 return 1;
502}
503
504static void _rtl92se_phy_set_rf_sleep(struct ieee80211_hw *hw)
505{
506 struct rtl_priv *rtlpriv = rtl_priv(hw);
507 u8 u1btmp;
508
509 u1btmp = rtl_read_byte(rtlpriv, LDOV12D_CTRL);
510 u1btmp |= BIT(0);
511
512 rtl_write_byte(rtlpriv, LDOV12D_CTRL, u1btmp);
513 rtl_write_byte(rtlpriv, SPS1_CTRL, 0x0);
514 rtl_write_byte(rtlpriv, TXPAUSE, 0xFF);
515 rtl_write_word(rtlpriv, CMDR, 0x57FC);
516 udelay(100);
517
518 rtl_write_word(rtlpriv, CMDR, 0x77FC);
519 rtl_write_byte(rtlpriv, PHY_CCA, 0x0);
520 udelay(10);
521
522 rtl_write_word(rtlpriv, CMDR, 0x37FC);
523 udelay(10);
524
525 rtl_write_word(rtlpriv, CMDR, 0x77FC);
526 udelay(10);
527
528 rtl_write_word(rtlpriv, CMDR, 0x57FC);
529
530 /* we should chnge GPIO to input mode
531 * this will drop away current about 25mA*/
532 rtl8192se_gpiobit3_cfg_inputmode(hw);
533}
534
535bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw,
536 enum rf_pwrstate rfpwr_state)
537{
538 struct rtl_priv *rtlpriv = rtl_priv(hw);
539 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
540 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
541 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
542 bool bresult = true;
543 u8 i, queue_id;
544 struct rtl8192_tx_ring *ring = NULL;
545
546 if (rfpwr_state == ppsc->rfpwr_state)
547 return false;
548
d1585316
CL
549 switch (rfpwr_state) {
550 case ERFON:{
551 if ((ppsc->rfpwr_state == ERFOFF) &&
552 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
553
554 bool rtstatus;
555 u32 InitializeCount = 0;
556 do {
557 InitializeCount++;
558 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
f30d7507 559 "IPS Set eRf nic enable\n");
d1585316 560 rtstatus = rtl_ps_enable_nic(hw);
23677ce3 561 } while (!rtstatus && (InitializeCount < 10));
d1585316
CL
562
563 RT_CLEAR_PS_LEVEL(ppsc,
564 RT_RF_OFF_LEVL_HALT_NIC);
565 } else {
566 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
f30d7507
JP
567 "awake, sleeped:%d ms state_inap:%x\n",
568 jiffies_to_msecs(jiffies -
569 ppsc->
570 last_sleep_jiffies),
571 rtlpriv->psc.state_inap);
d1585316
CL
572 ppsc->last_awake_jiffies = jiffies;
573 rtl_write_word(rtlpriv, CMDR, 0x37FC);
574 rtl_write_byte(rtlpriv, TXPAUSE, 0x00);
575 rtl_write_byte(rtlpriv, PHY_CCA, 0x3);
576 }
577
578 if (mac->link_state == MAC80211_LINKED)
579 rtlpriv->cfg->ops->led_control(hw,
580 LED_CTL_LINK);
581 else
582 rtlpriv->cfg->ops->led_control(hw,
583 LED_CTL_NO_LINK);
584 break;
585 }
586 case ERFOFF:{
587 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
588 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
f30d7507 589 "IPS Set eRf nic disable\n");
d1585316
CL
590 rtl_ps_disable_nic(hw);
591 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
592 } else {
593 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
594 rtlpriv->cfg->ops->led_control(hw,
595 LED_CTL_NO_LINK);
596 else
597 rtlpriv->cfg->ops->led_control(hw,
598 LED_CTL_POWER_OFF);
599 }
600 break;
601 }
602 case ERFSLEEP:
603 if (ppsc->rfpwr_state == ERFOFF)
91ddff8a 604 return false;
d1585316
CL
605
606 for (queue_id = 0, i = 0;
607 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
608 ring = &pcipriv->dev.tx_ring[queue_id];
609 if (skb_queue_len(&ring->queue) == 0 ||
610 queue_id == BEACON_QUEUE) {
611 queue_id++;
612 continue;
613 } else {
614 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
f30d7507
JP
615 "eRf Off/Sleep: %d times TcbBusyQueue[%d] = %d before doze!\n",
616 i + 1, queue_id,
617 skb_queue_len(&ring->queue));
d1585316
CL
618
619 udelay(10);
620 i++;
621 }
622
623 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
624 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
f30d7507 625 "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n",
d1585316
CL
626 MAX_DOZE_WAITING_TIMES_9x,
627 queue_id,
f30d7507 628 skb_queue_len(&ring->queue));
d1585316
CL
629 break;
630 }
631 }
632
633 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
f30d7507 634 "Set ERFSLEEP awaked:%d ms\n",
d1585316 635 jiffies_to_msecs(jiffies -
f30d7507 636 ppsc->last_awake_jiffies));
d1585316
CL
637
638 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
f30d7507
JP
639 "sleep awaked:%d ms state_inap:%x\n",
640 jiffies_to_msecs(jiffies -
641 ppsc->last_awake_jiffies),
642 rtlpriv->psc.state_inap);
d1585316
CL
643 ppsc->last_sleep_jiffies = jiffies;
644 _rtl92se_phy_set_rf_sleep(hw);
645 break;
646 default:
647 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
f30d7507 648 "switch case not processed\n");
d1585316
CL
649 bresult = false;
650 break;
651 }
652
653 if (bresult)
654 ppsc->rfpwr_state = rfpwr_state;
655
d1585316
CL
656 return bresult;
657}
658
659static bool _rtl92s_phy_config_rfpa_bias_current(struct ieee80211_hw *hw,
660 enum radio_path rfpath)
661{
662 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
663 bool rtstatus = true;
664 u32 tmpval = 0;
665
666 /* If inferiority IC, we have to increase the PA bias current */
667 if (rtlhal->ic_class != IC_INFERIORITY_A) {
668 tmpval = rtl92s_phy_query_rf_reg(hw, rfpath, RF_IPA, 0xf);
669 rtl92s_phy_set_rf_reg(hw, rfpath, RF_IPA, 0xf, tmpval + 1);
670 }
671
672 return rtstatus;
673}
674
675static void _rtl92s_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw,
676 u32 reg_addr, u32 bitmask, u32 data)
677{
678 struct rtl_priv *rtlpriv = rtl_priv(hw);
679 struct rtl_phy *rtlphy = &(rtlpriv->phy);
02b6ab0a 680 int index;
d1585316
CL
681
682 if (reg_addr == RTXAGC_RATE18_06)
02b6ab0a
LF
683 index = 0;
684 else if (reg_addr == RTXAGC_RATE54_24)
685 index = 1;
686 else if (reg_addr == RTXAGC_CCK_MCS32)
687 index = 6;
688 else if (reg_addr == RTXAGC_MCS03_MCS00)
689 index = 2;
690 else if (reg_addr == RTXAGC_MCS07_MCS04)
691 index = 3;
692 else if (reg_addr == RTXAGC_MCS11_MCS08)
693 index = 4;
694 else if (reg_addr == RTXAGC_MCS15_MCS12)
695 index = 5;
696 else
697 return;
698
da17fcff 699 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index] = data;
02b6ab0a 700 if (index == 5)
d1585316 701 rtlphy->pwrgroup_cnt++;
d1585316
CL
702}
703
704static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw)
705{
706 struct rtl_priv *rtlpriv = rtl_priv(hw);
707 struct rtl_phy *rtlphy = &(rtlpriv->phy);
708
709 /*RF Interface Sowrtware Control */
710 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
711 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
712 rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
713 rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
714
715 /* RF Interface Readback Value */
716 rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
717 rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
718 rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
719 rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
720
721 /* RF Interface Output (and Enable) */
722 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
723 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
724 rtlphy->phyreg_def[RF90_PATH_C].rfintfo = RFPGA0_XC_RFINTERFACEOE;
725 rtlphy->phyreg_def[RF90_PATH_D].rfintfo = RFPGA0_XD_RFINTERFACEOE;
726
727 /* RF Interface (Output and) Enable */
728 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
729 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
730 rtlphy->phyreg_def[RF90_PATH_C].rfintfe = RFPGA0_XC_RFINTERFACEOE;
731 rtlphy->phyreg_def[RF90_PATH_D].rfintfe = RFPGA0_XD_RFINTERFACEOE;
732
733 /* Addr of LSSI. Wirte RF register by driver */
734 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
735 RFPGA0_XA_LSSIPARAMETER;
736 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
737 RFPGA0_XB_LSSIPARAMETER;
738 rtlphy->phyreg_def[RF90_PATH_C].rf3wire_offset =
739 RFPGA0_XC_LSSIPARAMETER;
740 rtlphy->phyreg_def[RF90_PATH_D].rf3wire_offset =
741 RFPGA0_XD_LSSIPARAMETER;
742
743 /* RF parameter */
744 rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER;
745 rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER;
746 rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER;
747 rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER;
748
749 /* Tx AGC Gain Stage (same for all path. Should we remove this?) */
750 rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
751 rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
752 rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
753 rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
754
755 /* Tranceiver A~D HSSI Parameter-1 */
756 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
757 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
758 rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para1 = RFPGA0_XC_HSSIPARAMETER1;
759 rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para1 = RFPGA0_XD_HSSIPARAMETER1;
760
761 /* Tranceiver A~D HSSI Parameter-2 */
762 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
763 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
764 rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para2 = RFPGA0_XC_HSSIPARAMETER2;
765 rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para2 = RFPGA0_XD_HSSIPARAMETER2;
766
767 /* RF switch Control */
da17fcff
LF
768 rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
769 rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
770 rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
771 rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
d1585316
CL
772
773 /* AGC control 1 */
774 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
775 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
776 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
777 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
778
779 /* AGC control 2 */
780 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
781 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
782 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
783 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
784
785 /* RX AFE control 1 */
da17fcff
LF
786 rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE;
787 rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE;
788 rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBALANCE;
789 rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE;
d1585316
CL
790
791 /* RX AFE control 1 */
792 rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
793 rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
794 rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
795 rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
796
797 /* Tx AFE control 1 */
da17fcff
LF
798 rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE;
799 rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE;
800 rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE;
801 rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE;
d1585316
CL
802
803 /* Tx AFE control 2 */
804 rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
805 rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
806 rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
807 rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
808
809 /* Tranceiver LSSI Readback */
da17fcff
LF
810 rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK;
811 rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK;
812 rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK;
813 rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK;
d1585316
CL
814
815 /* Tranceiver LSSI Readback PI mode */
da17fcff
LF
816 rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVERA_HSPI_READBACK;
817 rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVERB_HSPI_READBACK;
d1585316
CL
818}
819
820
821static bool _rtl92s_phy_config_bb(struct ieee80211_hw *hw, u8 configtype)
822{
823 int i;
824 u32 *phy_reg_table;
825 u32 *agc_table;
826 u16 phy_reg_len, agc_len;
827
828 agc_len = AGCTAB_ARRAYLENGTH;
829 agc_table = rtl8192seagctab_array;
830 /* Default RF_type: 2T2R */
831 phy_reg_len = PHY_REG_2T2RARRAYLENGTH;
832 phy_reg_table = rtl8192sephy_reg_2t2rarray;
833
834 if (configtype == BASEBAND_CONFIG_PHY_REG) {
835 for (i = 0; i < phy_reg_len; i = i + 2) {
836 if (phy_reg_table[i] == 0xfe)
837 mdelay(50);
838 else if (phy_reg_table[i] == 0xfd)
839 mdelay(5);
840 else if (phy_reg_table[i] == 0xfc)
841 mdelay(1);
842 else if (phy_reg_table[i] == 0xfb)
843 udelay(50);
844 else if (phy_reg_table[i] == 0xfa)
845 udelay(5);
846 else if (phy_reg_table[i] == 0xf9)
847 udelay(1);
848
849 /* Add delay for ECS T20 & LG malow platform, */
850 udelay(1);
851
852 rtl92s_phy_set_bb_reg(hw, phy_reg_table[i], MASKDWORD,
853 phy_reg_table[i + 1]);
854 }
855 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
856 for (i = 0; i < agc_len; i = i + 2) {
857 rtl92s_phy_set_bb_reg(hw, agc_table[i], MASKDWORD,
858 agc_table[i + 1]);
859
860 /* Add delay for ECS T20 & LG malow platform */
861 udelay(1);
862 }
863 }
864
865 return true;
866}
867
868static bool _rtl92s_phy_set_bb_to_diff_rf(struct ieee80211_hw *hw,
869 u8 configtype)
870{
871 struct rtl_priv *rtlpriv = rtl_priv(hw);
872 struct rtl_phy *rtlphy = &(rtlpriv->phy);
873 u32 *phy_regarray2xtxr_table;
874 u16 phy_regarray2xtxr_len;
875 int i;
876
877 if (rtlphy->rf_type == RF_1T1R) {
878 phy_regarray2xtxr_table = rtl8192sephy_changeto_1t1rarray;
879 phy_regarray2xtxr_len = PHY_CHANGETO_1T1RARRAYLENGTH;
880 } else if (rtlphy->rf_type == RF_1T2R) {
881 phy_regarray2xtxr_table = rtl8192sephy_changeto_1t2rarray;
882 phy_regarray2xtxr_len = PHY_CHANGETO_1T2RARRAYLENGTH;
883 } else {
884 return false;
885 }
886
887 if (configtype == BASEBAND_CONFIG_PHY_REG) {
888 for (i = 0; i < phy_regarray2xtxr_len; i = i + 3) {
889 if (phy_regarray2xtxr_table[i] == 0xfe)
890 mdelay(50);
891 else if (phy_regarray2xtxr_table[i] == 0xfd)
892 mdelay(5);
893 else if (phy_regarray2xtxr_table[i] == 0xfc)
894 mdelay(1);
895 else if (phy_regarray2xtxr_table[i] == 0xfb)
896 udelay(50);
897 else if (phy_regarray2xtxr_table[i] == 0xfa)
898 udelay(5);
899 else if (phy_regarray2xtxr_table[i] == 0xf9)
900 udelay(1);
901
902 rtl92s_phy_set_bb_reg(hw, phy_regarray2xtxr_table[i],
903 phy_regarray2xtxr_table[i + 1],
904 phy_regarray2xtxr_table[i + 2]);
905 }
906 }
907
908 return true;
909}
910
911static bool _rtl92s_phy_config_bb_with_pg(struct ieee80211_hw *hw,
912 u8 configtype)
913{
914 int i;
915 u32 *phy_table_pg;
916 u16 phy_pg_len;
917
918 phy_pg_len = PHY_REG_ARRAY_PGLENGTH;
919 phy_table_pg = rtl8192sephy_reg_array_pg;
920
921 if (configtype == BASEBAND_CONFIG_PHY_REG) {
922 for (i = 0; i < phy_pg_len; i = i + 3) {
923 if (phy_table_pg[i] == 0xfe)
924 mdelay(50);
925 else if (phy_table_pg[i] == 0xfd)
926 mdelay(5);
927 else if (phy_table_pg[i] == 0xfc)
928 mdelay(1);
929 else if (phy_table_pg[i] == 0xfb)
930 udelay(50);
931 else if (phy_table_pg[i] == 0xfa)
932 udelay(5);
933 else if (phy_table_pg[i] == 0xf9)
934 udelay(1);
935
936 _rtl92s_store_pwrindex_diffrate_offset(hw,
937 phy_table_pg[i],
938 phy_table_pg[i + 1],
939 phy_table_pg[i + 2]);
940 rtl92s_phy_set_bb_reg(hw, phy_table_pg[i],
941 phy_table_pg[i + 1],
942 phy_table_pg[i + 2]);
943 }
944 }
945
946 return true;
947}
948
949static bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw)
950{
951 struct rtl_priv *rtlpriv = rtl_priv(hw);
952 struct rtl_phy *rtlphy = &(rtlpriv->phy);
953 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
954 bool rtstatus = true;
955
956 /* 1. Read PHY_REG.TXT BB INIT!! */
957 /* We will separate as 1T1R/1T2R/1T2R_GREEN/2T2R */
958 if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_2T2R ||
959 rtlphy->rf_type == RF_1T1R || rtlphy->rf_type == RF_2T2R_GREEN) {
960 rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_PHY_REG);
961
962 if (rtlphy->rf_type != RF_2T2R &&
963 rtlphy->rf_type != RF_2T2R_GREEN)
964 /* so we should reconfig BB reg with the right
965 * PHY parameters. */
966 rtstatus = _rtl92s_phy_set_bb_to_diff_rf(hw,
967 BASEBAND_CONFIG_PHY_REG);
968 } else {
969 rtstatus = false;
970 }
971
23677ce3 972 if (!rtstatus) {
d1585316 973 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
f30d7507 974 "Write BB Reg Fail!!\n");
d1585316
CL
975 goto phy_BB8190_Config_ParaFile_Fail;
976 }
977
978 /* 2. If EEPROM or EFUSE autoload OK, We must config by
979 * PHY_REG_PG.txt */
980 if (rtlefuse->autoload_failflag == false) {
981 rtlphy->pwrgroup_cnt = 0;
982
983 rtstatus = _rtl92s_phy_config_bb_with_pg(hw,
984 BASEBAND_CONFIG_PHY_REG);
985 }
23677ce3 986 if (!rtstatus) {
d1585316 987 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
f30d7507 988 "_rtl92s_phy_bb_config_parafile(): BB_PG Reg Fail!!\n");
d1585316
CL
989 goto phy_BB8190_Config_ParaFile_Fail;
990 }
991
992 /* 3. BB AGC table Initialization */
993 rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_AGC_TAB);
994
23677ce3 995 if (!rtstatus) {
292b1192 996 pr_err("%s(): AGC Table Fail\n", __func__);
d1585316
CL
997 goto phy_BB8190_Config_ParaFile_Fail;
998 }
999
1000 /* Check if the CCK HighPower is turned ON. */
1001 /* This is used to calculate PWDB. */
1002 rtlphy->cck_high_power = (bool)(rtl92s_phy_query_bb_reg(hw,
1003 RFPGA0_XA_HSSIPARAMETER2, 0x200));
1004
1005phy_BB8190_Config_ParaFile_Fail:
1006 return rtstatus;
1007}
1008
1009u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath)
1010{
1011 struct rtl_priv *rtlpriv = rtl_priv(hw);
1012 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1013 int i;
1014 bool rtstatus = true;
1015 u32 *radio_a_table;
1016 u32 *radio_b_table;
1017 u16 radio_a_tblen, radio_b_tblen;
1018
1019 radio_a_tblen = RADIOA_1T_ARRAYLENGTH;
1020 radio_a_table = rtl8192seradioa_1t_array;
1021
1022 /* Using Green mode array table for RF_2T2R_GREEN */
1023 if (rtlphy->rf_type == RF_2T2R_GREEN) {
1024 radio_b_table = rtl8192seradiob_gm_array;
1025 radio_b_tblen = RADIOB_GM_ARRAYLENGTH;
1026 } else {
1027 radio_b_table = rtl8192seradiob_array;
1028 radio_b_tblen = RADIOB_ARRAYLENGTH;
1029 }
1030
f30d7507 1031 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
d1585316
CL
1032 rtstatus = true;
1033
1034 switch (rfpath) {
1035 case RF90_PATH_A:
1036 for (i = 0; i < radio_a_tblen; i = i + 2) {
1037 if (radio_a_table[i] == 0xfe)
1038 /* Delay specific ms. Only RF configuration
1039 * requires delay. */
1040 mdelay(50);
1041 else if (radio_a_table[i] == 0xfd)
1042 mdelay(5);
1043 else if (radio_a_table[i] == 0xfc)
1044 mdelay(1);
1045 else if (radio_a_table[i] == 0xfb)
1046 udelay(50);
1047 else if (radio_a_table[i] == 0xfa)
1048 udelay(5);
1049 else if (radio_a_table[i] == 0xf9)
1050 udelay(1);
1051 else
1052 rtl92s_phy_set_rf_reg(hw, rfpath,
1053 radio_a_table[i],
1054 MASK20BITS,
1055 radio_a_table[i + 1]);
1056
1057 /* Add delay for ECS T20 & LG malow platform */
1058 udelay(1);
1059 }
1060
1061 /* PA Bias current for inferiority IC */
1062 _rtl92s_phy_config_rfpa_bias_current(hw, rfpath);
1063 break;
1064 case RF90_PATH_B:
1065 for (i = 0; i < radio_b_tblen; i = i + 2) {
1066 if (radio_b_table[i] == 0xfe)
1067 /* Delay specific ms. Only RF configuration
1068 * requires delay.*/
1069 mdelay(50);
1070 else if (radio_b_table[i] == 0xfd)
1071 mdelay(5);
1072 else if (radio_b_table[i] == 0xfc)
1073 mdelay(1);
1074 else if (radio_b_table[i] == 0xfb)
1075 udelay(50);
1076 else if (radio_b_table[i] == 0xfa)
1077 udelay(5);
1078 else if (radio_b_table[i] == 0xf9)
1079 udelay(1);
1080 else
1081 rtl92s_phy_set_rf_reg(hw, rfpath,
1082 radio_b_table[i],
1083 MASK20BITS,
1084 radio_b_table[i + 1]);
1085
1086 /* Add delay for ECS T20 & LG malow platform */
1087 udelay(1);
1088 }
1089 break;
1090 case RF90_PATH_C:
1091 ;
1092 break;
1093 case RF90_PATH_D:
1094 ;
1095 break;
1096 default:
1097 break;
1098 }
1099
1100 return rtstatus;
1101}
1102
1103
1104bool rtl92s_phy_mac_config(struct ieee80211_hw *hw)
1105{
1106 struct rtl_priv *rtlpriv = rtl_priv(hw);
1107 u32 i;
1108 u32 arraylength;
1109 u32 *ptraArray;
1110
1111 arraylength = MAC_2T_ARRAYLENGTH;
1112 ptraArray = rtl8192semac_2t_array;
1113
1114 for (i = 0; i < arraylength; i = i + 2)
1115 rtl_write_byte(rtlpriv, ptraArray[i], (u8)ptraArray[i + 1]);
1116
1117 return true;
1118}
1119
1120
1121bool rtl92s_phy_bb_config(struct ieee80211_hw *hw)
1122{
1123 struct rtl_priv *rtlpriv = rtl_priv(hw);
1124 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1125 bool rtstatus = true;
1126 u8 pathmap, index, rf_num = 0;
1127 u8 path1, path2;
1128
1129 _rtl92s_phy_init_register_definition(hw);
1130
1131 /* Config BB and AGC */
1132 rtstatus = _rtl92s_phy_bb_config_parafile(hw);
1133
1134
1135 /* Check BB/RF confiuration setting. */
1136 /* We only need to configure RF which is turned on. */
1137 path1 = (u8)(rtl92s_phy_query_bb_reg(hw, RFPGA0_TXINFO, 0xf));
1138 mdelay(10);
1139 path2 = (u8)(rtl92s_phy_query_bb_reg(hw, ROFDM0_TRXPATHENABLE, 0xf));
1140 pathmap = path1 | path2;
1141
1142 rtlphy->rf_pathmap = pathmap;
1143 for (index = 0; index < 4; index++) {
1144 if ((pathmap >> index) & 0x1)
1145 rf_num++;
1146 }
1147
1148 if ((rtlphy->rf_type == RF_1T1R && rf_num != 1) ||
1149 (rtlphy->rf_type == RF_1T2R && rf_num != 2) ||
1150 (rtlphy->rf_type == RF_2T2R && rf_num != 2) ||
1151 (rtlphy->rf_type == RF_2T2R_GREEN && rf_num != 2)) {
1152 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
f30d7507
JP
1153 "RF_Type(%x) does not match RF_Num(%x)!!\n",
1154 rtlphy->rf_type, rf_num);
d1585316 1155 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
f30d7507
JP
1156 "path1 0x%x, path2 0x%x, pathmap 0x%x\n",
1157 path1, path2, pathmap);
d1585316
CL
1158 }
1159
1160 return rtstatus;
1161}
1162
1163bool rtl92s_phy_rf_config(struct ieee80211_hw *hw)
1164{
1165 struct rtl_priv *rtlpriv = rtl_priv(hw);
1166 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1167
1168 /* Initialize general global value */
1169 if (rtlphy->rf_type == RF_1T1R)
1170 rtlphy->num_total_rfpath = 1;
1171 else
1172 rtlphy->num_total_rfpath = 2;
1173
1174 /* Config BB and RF */
1175 return rtl92s_phy_rf6052_config(hw);
1176}
1177
1178void rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
1179{
1180 struct rtl_priv *rtlpriv = rtl_priv(hw);
1181 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1182
1183 /* read rx initial gain */
1184 rtlphy->default_initialgain[0] = rtl_get_bbreg(hw,
1185 ROFDM0_XAAGCCORE1, MASKBYTE0);
1186 rtlphy->default_initialgain[1] = rtl_get_bbreg(hw,
1187 ROFDM0_XBAGCCORE1, MASKBYTE0);
1188 rtlphy->default_initialgain[2] = rtl_get_bbreg(hw,
1189 ROFDM0_XCAGCCORE1, MASKBYTE0);
1190 rtlphy->default_initialgain[3] = rtl_get_bbreg(hw,
1191 ROFDM0_XDAGCCORE1, MASKBYTE0);
f30d7507
JP
1192 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1193 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n",
d1585316
CL
1194 rtlphy->default_initialgain[0],
1195 rtlphy->default_initialgain[1],
1196 rtlphy->default_initialgain[2],
f30d7507 1197 rtlphy->default_initialgain[3]);
d1585316
CL
1198
1199 /* read framesync */
1200 rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0);
1201 rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
1202 MASKDWORD);
1203 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
f30d7507
JP
1204 "Default framesync (0x%x) = 0x%x\n",
1205 ROFDM0_RXDETECTOR3, rtlphy->framesync);
d1585316
CL
1206
1207}
1208
1209static void _rtl92s_phy_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
1210 u8 *cckpowerlevel, u8 *ofdmpowerLevel)
1211{
1212 struct rtl_priv *rtlpriv = rtl_priv(hw);
1213 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1214 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1215 u8 index = (channel - 1);
1216
1217 /* 1. CCK */
1218 /* RF-A */
1219 cckpowerlevel[0] = rtlefuse->txpwrlevel_cck[0][index];
1220 /* RF-B */
1221 cckpowerlevel[1] = rtlefuse->txpwrlevel_cck[1][index];
1222
1223 /* 2. OFDM for 1T or 2T */
1224 if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_1T1R) {
1225 /* Read HT 40 OFDM TX power */
1226 ofdmpowerLevel[0] = rtlefuse->txpwrlevel_ht40_1s[0][index];
1227 ofdmpowerLevel[1] = rtlefuse->txpwrlevel_ht40_1s[1][index];
1228 } else if (rtlphy->rf_type == RF_2T2R) {
1229 /* Read HT 40 OFDM TX power */
1230 ofdmpowerLevel[0] = rtlefuse->txpwrlevel_ht40_2s[0][index];
1231 ofdmpowerLevel[1] = rtlefuse->txpwrlevel_ht40_2s[1][index];
f761b694
LF
1232 } else {
1233 ofdmpowerLevel[0] = 0;
1234 ofdmpowerLevel[1] = 0;
d1585316
CL
1235 }
1236}
1237
1238static void _rtl92s_phy_ccxpower_indexcheck(struct ieee80211_hw *hw,
1239 u8 channel, u8 *cckpowerlevel, u8 *ofdmpowerlevel)
1240{
1241 struct rtl_priv *rtlpriv = rtl_priv(hw);
1242 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1243
1244 rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
1245 rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
1246}
1247
1248void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8 channel)
1249{
1250 struct rtl_priv *rtlpriv = rtl_priv(hw);
1251 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1252 /* [0]:RF-A, [1]:RF-B */
1253 u8 cckpowerlevel[2], ofdmpowerLevel[2];
1254
23677ce3 1255 if (!rtlefuse->txpwr_fromeprom)
d1585316
CL
1256 return;
1257
1258 /* Mainly we use RF-A Tx Power to write the Tx Power registers,
1259 * but the RF-B Tx Power must be calculated by the antenna diff.
1260 * So we have to rewrite Antenna gain offset register here.
1261 * Please refer to BB register 0x80c
1262 * 1. For CCK.
1263 * 2. For OFDM 1T or 2T */
1264 _rtl92s_phy_get_txpower_index(hw, channel, &cckpowerlevel[0],
1265 &ofdmpowerLevel[0]);
1266
1267 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
f30d7507
JP
1268 "Channel-%d, cckPowerLevel (A / B) = 0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n",
1269 channel, cckpowerlevel[0], cckpowerlevel[1],
1270 ofdmpowerLevel[0], ofdmpowerLevel[1]);
d1585316
CL
1271
1272 _rtl92s_phy_ccxpower_indexcheck(hw, channel, &cckpowerlevel[0],
1273 &ofdmpowerLevel[0]);
1274
1275 rtl92s_phy_rf6052_set_ccktxpower(hw, cckpowerlevel[0]);
1276 rtl92s_phy_rf6052_set_ofdmtxpower(hw, &ofdmpowerLevel[0], channel);
1277
1278}
1279
1280void rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw)
1281{
1282 struct rtl_priv *rtlpriv = rtl_priv(hw);
1283 u16 pollingcnt = 10000;
1284 u32 tmpvalue;
1285
1286 /* Make sure that CMD IO has be accepted by FW. */
1287 do {
1288 udelay(10);
1289
1290 tmpvalue = rtl_read_dword(rtlpriv, WFM5);
1291 if (tmpvalue == 0)
1292 break;
1293 } while (--pollingcnt);
1294
1295 if (pollingcnt == 0)
f30d7507 1296 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Set FW Cmd fail!!\n");
d1585316
CL
1297}
1298
1299
1300static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw)
1301{
1302 struct rtl_priv *rtlpriv = rtl_priv(hw);
1303 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1304 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1305 u32 input, current_aid = 0;
1306
1307 if (is_hal_stop(rtlhal))
1308 return;
1309
2455c92c
LF
1310 if (hal_get_firmwareversion(rtlpriv) < 0x34)
1311 goto skip;
d1585316
CL
1312 /* We re-map RA related CMD IO to combinational ones */
1313 /* if FW version is v.52 or later. */
1314 switch (rtlhal->current_fwcmd_io) {
1315 case FW_CMD_RA_REFRESH_N:
1316 rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_N_COMB;
1317 break;
1318 case FW_CMD_RA_REFRESH_BG:
1319 rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_BG_COMB;
1320 break;
1321 default:
1322 break;
1323 }
1324
2455c92c 1325skip:
d1585316
CL
1326 switch (rtlhal->current_fwcmd_io) {
1327 case FW_CMD_RA_RESET:
f30d7507 1328 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_RESET\n");
d1585316
CL
1329 rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET);
1330 rtl92s_phy_chk_fwcmd_iodone(hw);
1331 break;
1332 case FW_CMD_RA_ACTIVE:
f30d7507 1333 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_ACTIVE\n");
d1585316
CL
1334 rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE);
1335 rtl92s_phy_chk_fwcmd_iodone(hw);
1336 break;
1337 case FW_CMD_RA_REFRESH_N:
f30d7507 1338 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_REFRESH_N\n");
d1585316
CL
1339 input = FW_RA_REFRESH;
1340 rtl_write_dword(rtlpriv, WFM5, input);
1341 rtl92s_phy_chk_fwcmd_iodone(hw);
1342 rtl_write_dword(rtlpriv, WFM5, FW_RA_ENABLE_RSSI_MASK);
1343 rtl92s_phy_chk_fwcmd_iodone(hw);
1344 break;
1345 case FW_CMD_RA_REFRESH_BG:
1346 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
f30d7507 1347 "FW_CMD_RA_REFRESH_BG\n");
d1585316
CL
1348 rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH);
1349 rtl92s_phy_chk_fwcmd_iodone(hw);
1350 rtl_write_dword(rtlpriv, WFM5, FW_RA_DISABLE_RSSI_MASK);
1351 rtl92s_phy_chk_fwcmd_iodone(hw);
1352 break;
1353 case FW_CMD_RA_REFRESH_N_COMB:
1354 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
f30d7507 1355 "FW_CMD_RA_REFRESH_N_COMB\n");
d1585316
CL
1356 input = FW_RA_IOT_N_COMB;
1357 rtl_write_dword(rtlpriv, WFM5, input);
1358 rtl92s_phy_chk_fwcmd_iodone(hw);
1359 break;
1360 case FW_CMD_RA_REFRESH_BG_COMB:
1361 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
f30d7507 1362 "FW_CMD_RA_REFRESH_BG_COMB\n");
d1585316
CL
1363 input = FW_RA_IOT_BG_COMB;
1364 rtl_write_dword(rtlpriv, WFM5, input);
1365 rtl92s_phy_chk_fwcmd_iodone(hw);
1366 break;
1367 case FW_CMD_IQK_ENABLE:
f30d7507 1368 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_IQK_ENABLE\n");
d1585316
CL
1369 rtl_write_dword(rtlpriv, WFM5, FW_IQK_ENABLE);
1370 rtl92s_phy_chk_fwcmd_iodone(hw);
1371 break;
1372 case FW_CMD_PAUSE_DM_BY_SCAN:
1373 /* Lower initial gain */
1374 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17);
1375 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17);
1376 /* CCA threshold */
1377 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40);
1378 break;
1379 case FW_CMD_RESUME_DM_BY_SCAN:
1380 /* CCA threshold */
1381 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
1382 rtl92s_phy_set_txpower(hw, rtlphy->current_channel);
1383 break;
1384 case FW_CMD_HIGH_PWR_DISABLE:
1385 if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE)
1386 break;
1387
1388 /* Lower initial gain */
1389 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17);
1390 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17);
1391 /* CCA threshold */
1392 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40);
1393 break;
1394 case FW_CMD_HIGH_PWR_ENABLE:
1395 if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) ||
e10542c4 1396 rtlpriv->dm.dynamic_txpower_enable)
d1585316
CL
1397 break;
1398
1399 /* CCA threshold */
1400 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
1401 break;
1402 case FW_CMD_LPS_ENTER:
f30d7507 1403 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_ENTER\n");
d1585316
CL
1404 current_aid = rtlpriv->mac80211.assoc_id;
1405 rtl_write_dword(rtlpriv, WFM5, (FW_LPS_ENTER |
1406 ((current_aid | 0xc000) << 8)));
1407 rtl92s_phy_chk_fwcmd_iodone(hw);
1408 /* FW set TXOP disable here, so disable EDCA
1409 * turbo mode until driver leave LPS */
1410 break;
1411 case FW_CMD_LPS_LEAVE:
f30d7507 1412 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_LEAVE\n");
d1585316
CL
1413 rtl_write_dword(rtlpriv, WFM5, FW_LPS_LEAVE);
1414 rtl92s_phy_chk_fwcmd_iodone(hw);
1415 break;
1416 case FW_CMD_ADD_A2_ENTRY:
f30d7507 1417 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_ADD_A2_ENTRY\n");
d1585316
CL
1418 rtl_write_dword(rtlpriv, WFM5, FW_ADD_A2_ENTRY);
1419 rtl92s_phy_chk_fwcmd_iodone(hw);
1420 break;
1421 case FW_CMD_CTRL_DM_BY_DRIVER:
1422 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
f30d7507 1423 "FW_CMD_CTRL_DM_BY_DRIVER\n");
d1585316
CL
1424 rtl_write_dword(rtlpriv, WFM5, FW_CTRL_DM_BY_DRIVER);
1425 rtl92s_phy_chk_fwcmd_iodone(hw);
1426 break;
1427
1428 default:
1429 break;
1430 }
1431
1432 rtl92s_phy_chk_fwcmd_iodone(hw);
1433
1434 /* Clear FW CMD operation flag. */
1435 rtlhal->set_fwcmd_inprogress = false;
1436}
1437
1438bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
1439{
1440 struct rtl_priv *rtlpriv = rtl_priv(hw);
e0602750 1441 struct dig_t *digtable = &rtlpriv->dm_digtable;
d1585316
CL
1442 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1443 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1444 u32 fw_param = FW_CMD_IO_PARA_QUERY(rtlpriv);
1445 u16 fw_cmdmap = FW_CMD_IO_QUERY(rtlpriv);
2455c92c 1446 bool postprocessing = false;
d1585316
CL
1447
1448 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
f30d7507
JP
1449 "Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n",
1450 fw_cmdio, rtlhal->set_fwcmd_inprogress);
d1585316
CL
1451
1452 do {
1453 /* We re-map to combined FW CMD ones if firmware version */
1454 /* is v.53 or later. */
2455c92c
LF
1455 if (hal_get_firmwareversion(rtlpriv) >= 0x35) {
1456 switch (fw_cmdio) {
1457 case FW_CMD_RA_REFRESH_N:
1458 fw_cmdio = FW_CMD_RA_REFRESH_N_COMB;
1459 break;
1460 case FW_CMD_RA_REFRESH_BG:
1461 fw_cmdio = FW_CMD_RA_REFRESH_BG_COMB;
1462 break;
1463 default:
1464 break;
1465 }
1466 } else {
1467 if ((fw_cmdio == FW_CMD_IQK_ENABLE) ||
1468 (fw_cmdio == FW_CMD_RA_REFRESH_N) ||
1469 (fw_cmdio == FW_CMD_RA_REFRESH_BG)) {
1470 postprocessing = true;
1471 break;
1472 }
d1585316
CL
1473 }
1474
1475 /* If firmware version is v.62 or later,
1476 * use FW_CMD_IO_SET for FW_CMD_CTRL_DM_BY_DRIVER */
1477 if (hal_get_firmwareversion(rtlpriv) >= 0x3E) {
1478 if (fw_cmdio == FW_CMD_CTRL_DM_BY_DRIVER)
1479 fw_cmdio = FW_CMD_CTRL_DM_BY_DRIVER_NEW;
1480 }
1481
1482
1483 /* We shall revise all FW Cmd IO into Reg0x364
1484 * DM map table in the future. */
1485 switch (fw_cmdio) {
1486 case FW_CMD_RA_INIT:
f30d7507 1487 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "RA init!!\n");
d1585316
CL
1488 fw_cmdmap |= FW_RA_INIT_CTL;
1489 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1490 /* Clear control flag to sync with FW. */
1491 FW_CMD_IO_CLR(rtlpriv, FW_RA_INIT_CTL);
1492 break;
1493 case FW_CMD_DIG_DISABLE:
1494 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
f30d7507 1495 "Set DIG disable!!\n");
d1585316
CL
1496 fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1497 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1498 break;
1499 case FW_CMD_DIG_ENABLE:
1500 case FW_CMD_DIG_RESUME:
1501 if (!(rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE)) {
1502 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
f30d7507 1503 "Set DIG enable or resume!!\n");
d1585316
CL
1504 fw_cmdmap |= (FW_DIG_ENABLE_CTL | FW_SS_CTL);
1505 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1506 }
1507 break;
1508 case FW_CMD_DIG_HALT:
1509 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
f30d7507 1510 "Set DIG halt!!\n");
d1585316
CL
1511 fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | FW_SS_CTL);
1512 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1513 break;
1514 case FW_CMD_TXPWR_TRACK_THERMAL: {
1515 u8 thermalval = 0;
1516 fw_cmdmap |= FW_PWR_TRK_CTL;
1517
1518 /* Clear FW parameter in terms of thermal parts. */
1519 fw_param &= FW_PWR_TRK_PARAM_CLR;
1520
1521 thermalval = rtlpriv->dm.thermalvalue;
1522 fw_param |= ((thermalval << 24) |
1523 (rtlefuse->thermalmeter[0] << 16));
1524
1525 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
f30d7507
JP
1526 "Set TxPwr tracking!! FwCmdMap(%#x), FwParam(%#x)\n",
1527 fw_cmdmap, fw_param);
d1585316
CL
1528
1529 FW_CMD_PARA_SET(rtlpriv, fw_param);
1530 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1531
1532 /* Clear control flag to sync with FW. */
1533 FW_CMD_IO_CLR(rtlpriv, FW_PWR_TRK_CTL);
1534 }
1535 break;
1536 /* The following FW CMDs are only compatible to
1537 * v.53 or later. */
1538 case FW_CMD_RA_REFRESH_N_COMB:
1539 fw_cmdmap |= FW_RA_N_CTL;
1540
1541 /* Clear RA BG mode control. */
1542 fw_cmdmap &= ~(FW_RA_BG_CTL | FW_RA_INIT_CTL);
1543
1544 /* Clear FW parameter in terms of RA parts. */
1545 fw_param &= FW_RA_PARAM_CLR;
1546
1547 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
f30d7507
JP
1548 "[FW CMD] [New Version] Set RA/IOT Comb in n mode!! FwCmdMap(%#x), FwParam(%#x)\n",
1549 fw_cmdmap, fw_param);
d1585316
CL
1550
1551 FW_CMD_PARA_SET(rtlpriv, fw_param);
1552 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1553
1554 /* Clear control flag to sync with FW. */
1555 FW_CMD_IO_CLR(rtlpriv, FW_RA_N_CTL);
1556 break;
1557 case FW_CMD_RA_REFRESH_BG_COMB:
1558 fw_cmdmap |= FW_RA_BG_CTL;
1559
1560 /* Clear RA n-mode control. */
1561 fw_cmdmap &= ~(FW_RA_N_CTL | FW_RA_INIT_CTL);
1562 /* Clear FW parameter in terms of RA parts. */
1563 fw_param &= FW_RA_PARAM_CLR;
1564
1565 FW_CMD_PARA_SET(rtlpriv, fw_param);
1566 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1567
1568 /* Clear control flag to sync with FW. */
1569 FW_CMD_IO_CLR(rtlpriv, FW_RA_BG_CTL);
1570 break;
1571 case FW_CMD_IQK_ENABLE:
1572 fw_cmdmap |= FW_IQK_CTL;
1573 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1574 /* Clear control flag to sync with FW. */
1575 FW_CMD_IO_CLR(rtlpriv, FW_IQK_CTL);
1576 break;
1577 /* The following FW CMD is compatible to v.62 or later. */
1578 case FW_CMD_CTRL_DM_BY_DRIVER_NEW:
1579 fw_cmdmap |= FW_DRIVER_CTRL_DM_CTL;
1580 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1581 break;
1582 /* The followed FW Cmds needs post-processing later. */
1583 case FW_CMD_RESUME_DM_BY_SCAN:
1584 fw_cmdmap |= (FW_DIG_ENABLE_CTL |
1585 FW_HIGH_PWR_ENABLE_CTL |
1586 FW_SS_CTL);
1587
1588 if (rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE ||
e0602750 1589 !digtable->dig_enable_flag)
d1585316
CL
1590 fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1591
1592 if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) ||
e10542c4 1593 rtlpriv->dm.dynamic_txpower_enable)
d1585316
CL
1594 fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL;
1595
e0602750 1596 if ((digtable->dig_ext_port_stage ==
d1585316 1597 DIG_EXT_PORT_STAGE_0) ||
e0602750 1598 (digtable->dig_ext_port_stage ==
d1585316
CL
1599 DIG_EXT_PORT_STAGE_1))
1600 fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1601
1602 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
2455c92c 1603 postprocessing = true;
d1585316
CL
1604 break;
1605 case FW_CMD_PAUSE_DM_BY_SCAN:
1606 fw_cmdmap &= ~(FW_DIG_ENABLE_CTL |
1607 FW_HIGH_PWR_ENABLE_CTL |
1608 FW_SS_CTL);
1609 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
2455c92c 1610 postprocessing = true;
d1585316
CL
1611 break;
1612 case FW_CMD_HIGH_PWR_DISABLE:
1613 fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL;
1614 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
2455c92c 1615 postprocessing = true;
d1585316
CL
1616 break;
1617 case FW_CMD_HIGH_PWR_ENABLE:
1618 if (!(rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) &&
23677ce3 1619 !rtlpriv->dm.dynamic_txpower_enable) {
d1585316
CL
1620 fw_cmdmap |= (FW_HIGH_PWR_ENABLE_CTL |
1621 FW_SS_CTL);
1622 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
2455c92c 1623 postprocessing = true;
d1585316
CL
1624 }
1625 break;
1626 case FW_CMD_DIG_MODE_FA:
1627 fw_cmdmap |= FW_FA_CTL;
1628 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1629 break;
1630 case FW_CMD_DIG_MODE_SS:
1631 fw_cmdmap &= ~FW_FA_CTL;
1632 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1633 break;
1634 case FW_CMD_PAPE_CONTROL:
1635 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
f30d7507 1636 "[FW CMD] Set PAPE Control\n");
d1585316
CL
1637 fw_cmdmap &= ~FW_PAPE_CTL_BY_SW_HW;
1638
1639 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1640 break;
1641 default:
1642 /* Pass to original FW CMD processing callback
1643 * routine. */
2455c92c 1644 postprocessing = true;
d1585316
CL
1645 break;
1646 }
1647 } while (false);
1648
1649 /* We shall post processing these FW CMD if
2455c92c
LF
1650 * variable postprocessing is set.
1651 */
1652 if (postprocessing && !rtlhal->set_fwcmd_inprogress) {
d1585316
CL
1653 rtlhal->set_fwcmd_inprogress = true;
1654 /* Update current FW Cmd for callback use. */
1655 rtlhal->current_fwcmd_io = fw_cmdio;
1656 } else {
1657 return false;
1658 }
1659
1660 _rtl92s_phy_set_fwcmd_io(hw);
1661 return true;
1662}
1663
1664static void _rtl92s_phy_check_ephy_switchready(struct ieee80211_hw *hw)
1665{
1666 struct rtl_priv *rtlpriv = rtl_priv(hw);
1667 u32 delay = 100;
1668 u8 regu1;
1669
1670 regu1 = rtl_read_byte(rtlpriv, 0x554);
1671 while ((regu1 & BIT(5)) && (delay > 0)) {
1672 regu1 = rtl_read_byte(rtlpriv, 0x554);
1673 delay--;
1674 /* We delay only 50us to prevent
1675 * being scheduled out. */
1676 udelay(50);
1677 }
1678}
1679
1680void rtl92s_phy_switch_ephy_parameter(struct ieee80211_hw *hw)
1681{
1682 struct rtl_priv *rtlpriv = rtl_priv(hw);
1683 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1684
1685 /* The way to be capable to switch clock request
1686 * when the PG setting does not support clock request.
1687 * This is the backdoor solution to switch clock
1688 * request before ASPM or D3. */
1689 rtl_write_dword(rtlpriv, 0x540, 0x73c11);
1690 rtl_write_dword(rtlpriv, 0x548, 0x2407c);
1691
1692 /* Switch EPHY parameter!!!! */
1693 rtl_write_word(rtlpriv, 0x550, 0x1000);
1694 rtl_write_byte(rtlpriv, 0x554, 0x20);
1695 _rtl92s_phy_check_ephy_switchready(hw);
1696
1697 rtl_write_word(rtlpriv, 0x550, 0xa0eb);
1698 rtl_write_byte(rtlpriv, 0x554, 0x3e);
1699 _rtl92s_phy_check_ephy_switchready(hw);
1700
1701 rtl_write_word(rtlpriv, 0x550, 0xff80);
1702 rtl_write_byte(rtlpriv, 0x554, 0x39);
1703 _rtl92s_phy_check_ephy_switchready(hw);
1704
1705 /* Delay L1 enter time */
1706 if (ppsc->support_aspm && !ppsc->support_backdoor)
1707 rtl_write_byte(rtlpriv, 0x560, 0x40);
1708 else
1709 rtl_write_byte(rtlpriv, 0x560, 0x00);
1710
1711}
1712
2455c92c 1713void rtl92s_phy_set_beacon_hwreg(struct ieee80211_hw *hw, u16 beaconinterval)
d1585316
CL
1714{
1715 struct rtl_priv *rtlpriv = rtl_priv(hw);
2455c92c
LF
1716 u32 new_bcn_num = 0;
1717
1718 if (hal_get_firmwareversion(rtlpriv) >= 0x33) {
1719 /* Fw v.51 and later. */
1720 rtl_write_dword(rtlpriv, WFM5, 0xF1000000 |
1721 (beaconinterval << 8));
1722 } else {
1723 new_bcn_num = beaconinterval * 32 - 64;
1724 rtl_write_dword(rtlpriv, WFM3 + 4, new_bcn_num);
1725 rtl_write_dword(rtlpriv, WFM3, 0xB026007C);
1726 }
d1585316 1727}
This page took 0.314485 seconds and 5 git commands to generate.