spi-topcliff-pch: add recovery processing in case wait-event timeout
[zen-stable.git] / drivers / net / wireless / rtlwifi / rtl8192se / phy.c
blobf10ac1ad9087e594747d9e4c71b29863fe623da8
1 /******************************************************************************
3 * Copyright(c) 2009-2010 Realtek Corporation.
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.
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.
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
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
26 * Larry Finger <Larry.Finger@lwfinger.net>
28 *****************************************************************************/
30 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
32 #include "../wifi.h"
33 #include "../pci.h"
34 #include "../ps.h"
35 #include "reg.h"
36 #include "def.h"
37 #include "phy.h"
38 #include "rf.h"
39 #include "dm.h"
40 #include "fw.h"
41 #include "hw.h"
42 #include "table.h"
44 static u32 _rtl92s_phy_calculate_bit_shift(u32 bitmask)
46 u32 i;
48 for (i = 0; i <= 31; i++) {
49 if (((bitmask >> i) & 0x1) == 1)
50 break;
53 return i;
56 u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
58 struct rtl_priv *rtlpriv = rtl_priv(hw);
59 u32 returnvalue = 0, originalvalue, bitshift;
61 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)\n",
62 regaddr, bitmask));
64 originalvalue = rtl_read_dword(rtlpriv, regaddr);
65 bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
66 returnvalue = (originalvalue & bitmask) >> bitshift;
68 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
69 ("BBR MASK=0x%x Addr[0x%x]=0x%x\n",
70 bitmask, regaddr, originalvalue));
72 return returnvalue;
76 void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
77 u32 data)
79 struct rtl_priv *rtlpriv = rtl_priv(hw);
80 u32 originalvalue, bitshift;
82 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
83 " data(%#x)\n", regaddr, bitmask, data));
85 if (bitmask != MASKDWORD) {
86 originalvalue = rtl_read_dword(rtlpriv, regaddr);
87 bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
88 data = ((originalvalue & (~bitmask)) | (data << bitshift));
91 rtl_write_dword(rtlpriv, regaddr, data);
93 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
94 " data(%#x)\n", regaddr, bitmask, data));
98 static u32 _rtl92s_phy_rf_serial_read(struct ieee80211_hw *hw,
99 enum radio_path rfpath, u32 offset)
102 struct rtl_priv *rtlpriv = rtl_priv(hw);
103 struct rtl_phy *rtlphy = &(rtlpriv->phy);
104 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
105 u32 newoffset;
106 u32 tmplong, tmplong2;
107 u8 rfpi_enable = 0;
108 u32 retvalue = 0;
110 offset &= 0x3f;
111 newoffset = offset;
113 tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
115 if (rfpath == RF90_PATH_A)
116 tmplong2 = tmplong;
117 else
118 tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
120 tmplong2 = (tmplong2 & (~BLSSI_READADDRESS)) | (newoffset << 23) |
121 BLSSI_READEDGE;
123 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
124 tmplong & (~BLSSI_READEDGE));
126 mdelay(1);
128 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
129 mdelay(1);
131 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, tmplong |
132 BLSSI_READEDGE);
133 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));
142 if (rfpi_enable)
143 retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi,
144 BLSSI_READBACK_DATA);
145 else
146 retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
147 BLSSI_READBACK_DATA);
149 retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
150 BLSSI_READBACK_DATA);
152 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n",
153 rfpath, pphyreg->rflssi_readback, retvalue));
155 return retvalue;
159 static void _rtl92s_phy_rf_serial_write(struct ieee80211_hw *hw,
160 enum radio_path rfpath, u32 offset,
161 u32 data)
163 struct rtl_priv *rtlpriv = rtl_priv(hw);
164 struct rtl_phy *rtlphy = &(rtlpriv->phy);
165 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
166 u32 data_and_addr = 0;
167 u32 newoffset;
169 offset &= 0x3f;
170 newoffset = offset;
172 data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
173 rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
175 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n",
176 rfpath, pphyreg->rf3wire_offset, data_and_addr));
180 u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
181 u32 regaddr, u32 bitmask)
183 struct rtl_priv *rtlpriv = rtl_priv(hw);
184 u32 original_value, readback_value, bitshift;
186 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), "
187 "bitmask(%#x)\n", regaddr, rfpath, bitmask));
189 spin_lock(&rtlpriv->locks.rf_lock);
191 original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr);
193 bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
194 readback_value = (original_value & bitmask) >> bitshift;
196 spin_unlock(&rtlpriv->locks.rf_lock);
198 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), "
199 "bitmask(%#x), original_value(%#x)\n", regaddr, rfpath,
200 bitmask, original_value));
202 return readback_value;
205 void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
206 u32 regaddr, u32 bitmask, u32 data)
208 struct rtl_priv *rtlpriv = rtl_priv(hw);
209 struct rtl_phy *rtlphy = &(rtlpriv->phy);
210 u32 original_value, bitshift;
212 if (!((rtlphy->rf_pathmap >> rfpath) & 0x1))
213 return;
215 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
216 " data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath));
218 spin_lock(&rtlpriv->locks.rf_lock);
220 if (bitmask != RFREG_OFFSET_MASK) {
221 original_value = _rtl92s_phy_rf_serial_read(hw, rfpath,
222 regaddr);
223 bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
224 data = ((original_value & (~bitmask)) | (data << bitshift));
227 _rtl92s_phy_rf_serial_write(hw, rfpath, regaddr, data);
229 spin_unlock(&rtlpriv->locks.rf_lock);
231 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x), "
232 "data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath));
236 void rtl92s_phy_scan_operation_backup(struct ieee80211_hw *hw,
237 u8 operation)
239 struct rtl_priv *rtlpriv = rtl_priv(hw);
240 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
242 if (!is_hal_stop(rtlhal)) {
243 switch (operation) {
244 case SCAN_OPT_BACKUP:
245 rtl92s_phy_set_fw_cmd(hw, FW_CMD_PAUSE_DM_BY_SCAN);
246 break;
247 case SCAN_OPT_RESTORE:
248 rtl92s_phy_set_fw_cmd(hw, FW_CMD_RESUME_DM_BY_SCAN);
249 break;
250 default:
251 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
252 ("Unknown operation.\n"));
253 break;
258 void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw,
259 enum nl80211_channel_type ch_type)
261 struct rtl_priv *rtlpriv = rtl_priv(hw);
262 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
263 struct rtl_phy *rtlphy = &(rtlpriv->phy);
264 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
265 u8 reg_bw_opmode;
267 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("Switch to %s bandwidth\n",
268 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
269 "20MHz" : "40MHz"));
271 if (rtlphy->set_bwmode_inprogress)
272 return;
273 if (is_hal_stop(rtlhal))
274 return;
276 rtlphy->set_bwmode_inprogress = true;
278 reg_bw_opmode = rtl_read_byte(rtlpriv, BW_OPMODE);
279 /* dummy read */
280 rtl_read_byte(rtlpriv, RRSR + 2);
282 switch (rtlphy->current_chan_bw) {
283 case HT_CHANNEL_WIDTH_20:
284 reg_bw_opmode |= BW_OPMODE_20MHZ;
285 rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode);
286 break;
287 case HT_CHANNEL_WIDTH_20_40:
288 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
289 rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode);
290 break;
291 default:
292 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
293 ("unknown bandwidth: %#X\n",
294 rtlphy->current_chan_bw));
295 break;
298 switch (rtlphy->current_chan_bw) {
299 case HT_CHANNEL_WIDTH_20:
300 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
301 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
303 if (rtlhal->version >= VERSION_8192S_BCUT)
304 rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x58);
305 break;
306 case HT_CHANNEL_WIDTH_20_40:
307 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
308 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
310 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
311 (mac->cur_40_prime_sc >> 1));
312 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
314 if (rtlhal->version >= VERSION_8192S_BCUT)
315 rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x18);
316 break;
317 default:
318 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
319 ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
320 break;
323 rtl92s_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
324 rtlphy->set_bwmode_inprogress = false;
325 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
328 static bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
329 u32 cmdtableidx, u32 cmdtablesz, enum swchnlcmd_id cmdid,
330 u32 para1, u32 para2, u32 msdelay)
332 struct swchnlcmd *pcmd;
334 if (cmdtable == NULL) {
335 RT_ASSERT(false, ("cmdtable cannot be NULL.\n"));
336 return false;
339 if (cmdtableidx >= cmdtablesz)
340 return false;
342 pcmd = cmdtable + cmdtableidx;
343 pcmd->cmdid = cmdid;
344 pcmd->para1 = para1;
345 pcmd->para2 = para2;
346 pcmd->msdelay = msdelay;
348 return true;
351 static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
352 u8 channel, u8 *stage, u8 *step, u32 *delay)
354 struct rtl_priv *rtlpriv = rtl_priv(hw);
355 struct rtl_phy *rtlphy = &(rtlpriv->phy);
356 struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
357 u32 precommoncmdcnt;
358 struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
359 u32 postcommoncmdcnt;
360 struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
361 u32 rfdependcmdcnt;
362 struct swchnlcmd *currentcmd = NULL;
363 u8 rfpath;
364 u8 num_total_rfpath = rtlphy->num_total_rfpath;
366 precommoncmdcnt = 0;
367 _rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
368 MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
369 _rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
370 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
372 postcommoncmdcnt = 0;
374 _rtl92s_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
375 MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
377 rfdependcmdcnt = 0;
379 RT_ASSERT((channel >= 1 && channel <= 14),
380 ("illegal channel for Zebra: %d\n", channel));
382 _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
383 MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
384 RF_CHNLBW, channel, 10);
386 _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
387 MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0);
389 do {
390 switch (*stage) {
391 case 0:
392 currentcmd = &precommoncmd[*step];
393 break;
394 case 1:
395 currentcmd = &rfdependcmd[*step];
396 break;
397 case 2:
398 currentcmd = &postcommoncmd[*step];
399 break;
402 if (currentcmd->cmdid == CMDID_END) {
403 if ((*stage) == 2) {
404 return true;
405 } else {
406 (*stage)++;
407 (*step) = 0;
408 continue;
412 switch (currentcmd->cmdid) {
413 case CMDID_SET_TXPOWEROWER_LEVEL:
414 rtl92s_phy_set_txpower(hw, channel);
415 break;
416 case CMDID_WRITEPORT_ULONG:
417 rtl_write_dword(rtlpriv, currentcmd->para1,
418 currentcmd->para2);
419 break;
420 case CMDID_WRITEPORT_USHORT:
421 rtl_write_word(rtlpriv, currentcmd->para1,
422 (u16)currentcmd->para2);
423 break;
424 case CMDID_WRITEPORT_UCHAR:
425 rtl_write_byte(rtlpriv, currentcmd->para1,
426 (u8)currentcmd->para2);
427 break;
428 case CMDID_RF_WRITEREG:
429 for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
430 rtlphy->rfreg_chnlval[rfpath] =
431 ((rtlphy->rfreg_chnlval[rfpath] &
432 0xfffffc00) | currentcmd->para2);
433 rtl_set_rfreg(hw, (enum radio_path)rfpath,
434 currentcmd->para1,
435 RFREG_OFFSET_MASK,
436 rtlphy->rfreg_chnlval[rfpath]);
438 break;
439 default:
440 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
441 ("switch case not process\n"));
442 break;
445 break;
446 } while (true);
448 (*delay) = currentcmd->msdelay;
449 (*step)++;
450 return false;
453 u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw)
455 struct rtl_priv *rtlpriv = rtl_priv(hw);
456 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
457 struct rtl_phy *rtlphy = &(rtlpriv->phy);
458 u32 delay;
459 bool ret;
461 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
462 ("switch to channel%d\n",
463 rtlphy->current_channel));
465 if (rtlphy->sw_chnl_inprogress)
466 return 0;
468 if (rtlphy->set_bwmode_inprogress)
469 return 0;
471 if (is_hal_stop(rtlhal))
472 return 0;
474 rtlphy->sw_chnl_inprogress = true;
475 rtlphy->sw_chnl_stage = 0;
476 rtlphy->sw_chnl_step = 0;
478 do {
479 if (!rtlphy->sw_chnl_inprogress)
480 break;
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;
494 break;
495 } while (true);
497 rtlphy->sw_chnl_inprogress = false;
499 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
501 return 1;
504 static void _rtl92se_phy_set_rf_sleep(struct ieee80211_hw *hw)
506 struct rtl_priv *rtlpriv = rtl_priv(hw);
507 u8 u1btmp;
509 u1btmp = rtl_read_byte(rtlpriv, LDOV12D_CTRL);
510 u1btmp |= BIT(0);
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);
518 rtl_write_word(rtlpriv, CMDR, 0x77FC);
519 rtl_write_byte(rtlpriv, PHY_CCA, 0x0);
520 udelay(10);
522 rtl_write_word(rtlpriv, CMDR, 0x37FC);
523 udelay(10);
525 rtl_write_word(rtlpriv, CMDR, 0x77FC);
526 udelay(10);
528 rtl_write_word(rtlpriv, CMDR, 0x57FC);
530 /* we should chnge GPIO to input mode
531 * this will drop away current about 25mA*/
532 rtl8192se_gpiobit3_cfg_inputmode(hw);
535 bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw,
536 enum rf_pwrstate rfpwr_state)
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;
546 if (rfpwr_state == ppsc->rfpwr_state)
547 return false;
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)) {
554 bool rtstatus;
555 u32 InitializeCount = 0;
556 do {
557 InitializeCount++;
558 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
559 ("IPS Set eRf nic enable\n"));
560 rtstatus = rtl_ps_enable_nic(hw);
561 } while ((rtstatus != true) &&
562 (InitializeCount < 10));
564 RT_CLEAR_PS_LEVEL(ppsc,
565 RT_RF_OFF_LEVL_HALT_NIC);
566 } else {
567 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
568 ("awake, sleeped:%d ms "
569 "state_inap:%x\n",
570 jiffies_to_msecs(jiffies -
571 ppsc->last_sleep_jiffies),
572 rtlpriv->psc.state_inap));
573 ppsc->last_awake_jiffies = jiffies;
574 rtl_write_word(rtlpriv, CMDR, 0x37FC);
575 rtl_write_byte(rtlpriv, TXPAUSE, 0x00);
576 rtl_write_byte(rtlpriv, PHY_CCA, 0x3);
579 if (mac->link_state == MAC80211_LINKED)
580 rtlpriv->cfg->ops->led_control(hw,
581 LED_CTL_LINK);
582 else
583 rtlpriv->cfg->ops->led_control(hw,
584 LED_CTL_NO_LINK);
585 break;
587 case ERFOFF:{
588 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
589 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
590 ("IPS Set eRf nic disable\n"));
591 rtl_ps_disable_nic(hw);
592 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
593 } else {
594 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
595 rtlpriv->cfg->ops->led_control(hw,
596 LED_CTL_NO_LINK);
597 else
598 rtlpriv->cfg->ops->led_control(hw,
599 LED_CTL_POWER_OFF);
601 break;
603 case ERFSLEEP:
604 if (ppsc->rfpwr_state == ERFOFF)
605 return false;
607 for (queue_id = 0, i = 0;
608 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
609 ring = &pcipriv->dev.tx_ring[queue_id];
610 if (skb_queue_len(&ring->queue) == 0 ||
611 queue_id == BEACON_QUEUE) {
612 queue_id++;
613 continue;
614 } else {
615 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
616 ("eRf Off/Sleep: "
617 "%d times TcbBusyQueue[%d] = "
618 "%d before doze!\n",
619 (i + 1), queue_id,
620 skb_queue_len(&ring->queue)));
622 udelay(10);
623 i++;
626 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
627 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
628 ("\nERFOFF: %d times"
629 "TcbBusyQueue[%d] = %d !\n",
630 MAX_DOZE_WAITING_TIMES_9x,
631 queue_id,
632 skb_queue_len(&ring->queue)));
633 break;
637 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
638 ("Set ERFSLEEP awaked:%d ms\n",
639 jiffies_to_msecs(jiffies -
640 ppsc->last_awake_jiffies)));
642 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
643 ("sleep awaked:%d ms "
644 "state_inap:%x\n", jiffies_to_msecs(jiffies -
645 ppsc->last_awake_jiffies),
646 rtlpriv->psc.state_inap));
647 ppsc->last_sleep_jiffies = jiffies;
648 _rtl92se_phy_set_rf_sleep(hw);
649 break;
650 default:
651 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
652 ("switch case not process\n"));
653 bresult = false;
654 break;
657 if (bresult)
658 ppsc->rfpwr_state = rfpwr_state;
660 return bresult;
663 static bool _rtl92s_phy_config_rfpa_bias_current(struct ieee80211_hw *hw,
664 enum radio_path rfpath)
666 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
667 bool rtstatus = true;
668 u32 tmpval = 0;
670 /* If inferiority IC, we have to increase the PA bias current */
671 if (rtlhal->ic_class != IC_INFERIORITY_A) {
672 tmpval = rtl92s_phy_query_rf_reg(hw, rfpath, RF_IPA, 0xf);
673 rtl92s_phy_set_rf_reg(hw, rfpath, RF_IPA, 0xf, tmpval + 1);
676 return rtstatus;
679 static void _rtl92s_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw,
680 u32 reg_addr, u32 bitmask, u32 data)
682 struct rtl_priv *rtlpriv = rtl_priv(hw);
683 struct rtl_phy *rtlphy = &(rtlpriv->phy);
685 if (reg_addr == RTXAGC_RATE18_06)
686 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] =
687 data;
688 if (reg_addr == RTXAGC_RATE54_24)
689 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] =
690 data;
691 if (reg_addr == RTXAGC_CCK_MCS32)
692 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] =
693 data;
694 if (reg_addr == RTXAGC_MCS03_MCS00)
695 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] =
696 data;
697 if (reg_addr == RTXAGC_MCS07_MCS04)
698 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] =
699 data;
700 if (reg_addr == RTXAGC_MCS11_MCS08)
701 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] =
702 data;
703 if (reg_addr == RTXAGC_MCS15_MCS12) {
704 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] =
705 data;
706 rtlphy->pwrgroup_cnt++;
710 static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw)
712 struct rtl_priv *rtlpriv = rtl_priv(hw);
713 struct rtl_phy *rtlphy = &(rtlpriv->phy);
715 /*RF Interface Sowrtware Control */
716 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
717 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
718 rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
719 rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
721 /* RF Interface Readback Value */
722 rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
723 rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
724 rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
725 rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
727 /* RF Interface Output (and Enable) */
728 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
729 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
730 rtlphy->phyreg_def[RF90_PATH_C].rfintfo = RFPGA0_XC_RFINTERFACEOE;
731 rtlphy->phyreg_def[RF90_PATH_D].rfintfo = RFPGA0_XD_RFINTERFACEOE;
733 /* RF Interface (Output and) Enable */
734 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
735 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
736 rtlphy->phyreg_def[RF90_PATH_C].rfintfe = RFPGA0_XC_RFINTERFACEOE;
737 rtlphy->phyreg_def[RF90_PATH_D].rfintfe = RFPGA0_XD_RFINTERFACEOE;
739 /* Addr of LSSI. Wirte RF register by driver */
740 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
741 RFPGA0_XA_LSSIPARAMETER;
742 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
743 RFPGA0_XB_LSSIPARAMETER;
744 rtlphy->phyreg_def[RF90_PATH_C].rf3wire_offset =
745 RFPGA0_XC_LSSIPARAMETER;
746 rtlphy->phyreg_def[RF90_PATH_D].rf3wire_offset =
747 RFPGA0_XD_LSSIPARAMETER;
749 /* RF parameter */
750 rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER;
751 rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER;
752 rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER;
753 rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER;
755 /* Tx AGC Gain Stage (same for all path. Should we remove this?) */
756 rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
757 rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
758 rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
759 rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
761 /* Tranceiver A~D HSSI Parameter-1 */
762 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
763 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
764 rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para1 = RFPGA0_XC_HSSIPARAMETER1;
765 rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para1 = RFPGA0_XD_HSSIPARAMETER1;
767 /* Tranceiver A~D HSSI Parameter-2 */
768 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
769 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
770 rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para2 = RFPGA0_XC_HSSIPARAMETER2;
771 rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para2 = RFPGA0_XD_HSSIPARAMETER2;
773 /* RF switch Control */
774 rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control =
775 RFPGA0_XAB_SWITCHCONTROL;
776 rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control =
777 RFPGA0_XAB_SWITCHCONTROL;
778 rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control =
779 RFPGA0_XCD_SWITCHCONTROL;
780 rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control =
781 RFPGA0_XCD_SWITCHCONTROL;
783 /* AGC control 1 */
784 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
785 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
786 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
787 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
789 /* AGC control 2 */
790 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
791 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
792 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
793 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
795 /* RX AFE control 1 */
796 rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance =
797 ROFDM0_XARXIQIMBALANCE;
798 rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance =
799 ROFDM0_XBRXIQIMBALANCE;
800 rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance =
801 ROFDM0_XCRXIQIMBALANCE;
802 rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance =
803 ROFDM0_XDRXIQIMBALANCE;
805 /* RX AFE control 1 */
806 rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
807 rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
808 rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
809 rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
811 /* Tx AFE control 1 */
812 rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance =
813 ROFDM0_XATXIQIMBALANCE;
814 rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance =
815 ROFDM0_XBTXIQIMBALANCE;
816 rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance =
817 ROFDM0_XCTXIQIMBALANCE;
818 rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance =
819 ROFDM0_XDTXIQIMBALANCE;
821 /* Tx AFE control 2 */
822 rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
823 rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
824 rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
825 rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
827 /* Tranceiver LSSI Readback */
828 rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback =
829 RFPGA0_XA_LSSIREADBACK;
830 rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback =
831 RFPGA0_XB_LSSIREADBACK;
832 rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback =
833 RFPGA0_XC_LSSIREADBACK;
834 rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback =
835 RFPGA0_XD_LSSIREADBACK;
837 /* Tranceiver LSSI Readback PI mode */
838 rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi =
839 TRANSCEIVERA_HSPI_READBACK;
840 rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi =
841 TRANSCEIVERB_HSPI_READBACK;
845 static bool _rtl92s_phy_config_bb(struct ieee80211_hw *hw, u8 configtype)
847 int i;
848 u32 *phy_reg_table;
849 u32 *agc_table;
850 u16 phy_reg_len, agc_len;
852 agc_len = AGCTAB_ARRAYLENGTH;
853 agc_table = rtl8192seagctab_array;
854 /* Default RF_type: 2T2R */
855 phy_reg_len = PHY_REG_2T2RARRAYLENGTH;
856 phy_reg_table = rtl8192sephy_reg_2t2rarray;
858 if (configtype == BASEBAND_CONFIG_PHY_REG) {
859 for (i = 0; i < phy_reg_len; i = i + 2) {
860 if (phy_reg_table[i] == 0xfe)
861 mdelay(50);
862 else if (phy_reg_table[i] == 0xfd)
863 mdelay(5);
864 else if (phy_reg_table[i] == 0xfc)
865 mdelay(1);
866 else if (phy_reg_table[i] == 0xfb)
867 udelay(50);
868 else if (phy_reg_table[i] == 0xfa)
869 udelay(5);
870 else if (phy_reg_table[i] == 0xf9)
871 udelay(1);
873 /* Add delay for ECS T20 & LG malow platform, */
874 udelay(1);
876 rtl92s_phy_set_bb_reg(hw, phy_reg_table[i], MASKDWORD,
877 phy_reg_table[i + 1]);
879 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
880 for (i = 0; i < agc_len; i = i + 2) {
881 rtl92s_phy_set_bb_reg(hw, agc_table[i], MASKDWORD,
882 agc_table[i + 1]);
884 /* Add delay for ECS T20 & LG malow platform */
885 udelay(1);
889 return true;
892 static bool _rtl92s_phy_set_bb_to_diff_rf(struct ieee80211_hw *hw,
893 u8 configtype)
895 struct rtl_priv *rtlpriv = rtl_priv(hw);
896 struct rtl_phy *rtlphy = &(rtlpriv->phy);
897 u32 *phy_regarray2xtxr_table;
898 u16 phy_regarray2xtxr_len;
899 int i;
901 if (rtlphy->rf_type == RF_1T1R) {
902 phy_regarray2xtxr_table = rtl8192sephy_changeto_1t1rarray;
903 phy_regarray2xtxr_len = PHY_CHANGETO_1T1RARRAYLENGTH;
904 } else if (rtlphy->rf_type == RF_1T2R) {
905 phy_regarray2xtxr_table = rtl8192sephy_changeto_1t2rarray;
906 phy_regarray2xtxr_len = PHY_CHANGETO_1T2RARRAYLENGTH;
907 } else {
908 return false;
911 if (configtype == BASEBAND_CONFIG_PHY_REG) {
912 for (i = 0; i < phy_regarray2xtxr_len; i = i + 3) {
913 if (phy_regarray2xtxr_table[i] == 0xfe)
914 mdelay(50);
915 else if (phy_regarray2xtxr_table[i] == 0xfd)
916 mdelay(5);
917 else if (phy_regarray2xtxr_table[i] == 0xfc)
918 mdelay(1);
919 else if (phy_regarray2xtxr_table[i] == 0xfb)
920 udelay(50);
921 else if (phy_regarray2xtxr_table[i] == 0xfa)
922 udelay(5);
923 else if (phy_regarray2xtxr_table[i] == 0xf9)
924 udelay(1);
926 rtl92s_phy_set_bb_reg(hw, phy_regarray2xtxr_table[i],
927 phy_regarray2xtxr_table[i + 1],
928 phy_regarray2xtxr_table[i + 2]);
932 return true;
935 static bool _rtl92s_phy_config_bb_with_pg(struct ieee80211_hw *hw,
936 u8 configtype)
938 int i;
939 u32 *phy_table_pg;
940 u16 phy_pg_len;
942 phy_pg_len = PHY_REG_ARRAY_PGLENGTH;
943 phy_table_pg = rtl8192sephy_reg_array_pg;
945 if (configtype == BASEBAND_CONFIG_PHY_REG) {
946 for (i = 0; i < phy_pg_len; i = i + 3) {
947 if (phy_table_pg[i] == 0xfe)
948 mdelay(50);
949 else if (phy_table_pg[i] == 0xfd)
950 mdelay(5);
951 else if (phy_table_pg[i] == 0xfc)
952 mdelay(1);
953 else if (phy_table_pg[i] == 0xfb)
954 udelay(50);
955 else if (phy_table_pg[i] == 0xfa)
956 udelay(5);
957 else if (phy_table_pg[i] == 0xf9)
958 udelay(1);
960 _rtl92s_store_pwrindex_diffrate_offset(hw,
961 phy_table_pg[i],
962 phy_table_pg[i + 1],
963 phy_table_pg[i + 2]);
964 rtl92s_phy_set_bb_reg(hw, phy_table_pg[i],
965 phy_table_pg[i + 1],
966 phy_table_pg[i + 2]);
970 return true;
973 static bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw)
975 struct rtl_priv *rtlpriv = rtl_priv(hw);
976 struct rtl_phy *rtlphy = &(rtlpriv->phy);
977 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
978 bool rtstatus = true;
980 /* 1. Read PHY_REG.TXT BB INIT!! */
981 /* We will separate as 1T1R/1T2R/1T2R_GREEN/2T2R */
982 if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_2T2R ||
983 rtlphy->rf_type == RF_1T1R || rtlphy->rf_type == RF_2T2R_GREEN) {
984 rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_PHY_REG);
986 if (rtlphy->rf_type != RF_2T2R &&
987 rtlphy->rf_type != RF_2T2R_GREEN)
988 /* so we should reconfig BB reg with the right
989 * PHY parameters. */
990 rtstatus = _rtl92s_phy_set_bb_to_diff_rf(hw,
991 BASEBAND_CONFIG_PHY_REG);
992 } else {
993 rtstatus = false;
996 if (rtstatus != true) {
997 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
998 ("Write BB Reg Fail!!"));
999 goto phy_BB8190_Config_ParaFile_Fail;
1002 /* 2. If EEPROM or EFUSE autoload OK, We must config by
1003 * PHY_REG_PG.txt */
1004 if (rtlefuse->autoload_failflag == false) {
1005 rtlphy->pwrgroup_cnt = 0;
1007 rtstatus = _rtl92s_phy_config_bb_with_pg(hw,
1008 BASEBAND_CONFIG_PHY_REG);
1010 if (rtstatus != true) {
1011 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
1012 ("_rtl92s_phy_bb_config_parafile(): "
1013 "BB_PG Reg Fail!!"));
1014 goto phy_BB8190_Config_ParaFile_Fail;
1017 /* 3. BB AGC table Initialization */
1018 rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_AGC_TAB);
1020 if (rtstatus != true) {
1021 pr_err("%s(): AGC Table Fail\n", __func__);
1022 goto phy_BB8190_Config_ParaFile_Fail;
1025 /* Check if the CCK HighPower is turned ON. */
1026 /* This is used to calculate PWDB. */
1027 rtlphy->cck_high_power = (bool)(rtl92s_phy_query_bb_reg(hw,
1028 RFPGA0_XA_HSSIPARAMETER2, 0x200));
1030 phy_BB8190_Config_ParaFile_Fail:
1031 return rtstatus;
1034 u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath)
1036 struct rtl_priv *rtlpriv = rtl_priv(hw);
1037 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1038 int i;
1039 bool rtstatus = true;
1040 u32 *radio_a_table;
1041 u32 *radio_b_table;
1042 u16 radio_a_tblen, radio_b_tblen;
1044 radio_a_tblen = RADIOA_1T_ARRAYLENGTH;
1045 radio_a_table = rtl8192seradioa_1t_array;
1047 /* Using Green mode array table for RF_2T2R_GREEN */
1048 if (rtlphy->rf_type == RF_2T2R_GREEN) {
1049 radio_b_table = rtl8192seradiob_gm_array;
1050 radio_b_tblen = RADIOB_GM_ARRAYLENGTH;
1051 } else {
1052 radio_b_table = rtl8192seradiob_array;
1053 radio_b_tblen = RADIOB_ARRAYLENGTH;
1056 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Radio No %x\n", rfpath));
1057 rtstatus = true;
1059 switch (rfpath) {
1060 case RF90_PATH_A:
1061 for (i = 0; i < radio_a_tblen; i = i + 2) {
1062 if (radio_a_table[i] == 0xfe)
1063 /* Delay specific ms. Only RF configuration
1064 * requires delay. */
1065 mdelay(50);
1066 else if (radio_a_table[i] == 0xfd)
1067 mdelay(5);
1068 else if (radio_a_table[i] == 0xfc)
1069 mdelay(1);
1070 else if (radio_a_table[i] == 0xfb)
1071 udelay(50);
1072 else if (radio_a_table[i] == 0xfa)
1073 udelay(5);
1074 else if (radio_a_table[i] == 0xf9)
1075 udelay(1);
1076 else
1077 rtl92s_phy_set_rf_reg(hw, rfpath,
1078 radio_a_table[i],
1079 MASK20BITS,
1080 radio_a_table[i + 1]);
1082 /* Add delay for ECS T20 & LG malow platform */
1083 udelay(1);
1086 /* PA Bias current for inferiority IC */
1087 _rtl92s_phy_config_rfpa_bias_current(hw, rfpath);
1088 break;
1089 case RF90_PATH_B:
1090 for (i = 0; i < radio_b_tblen; i = i + 2) {
1091 if (radio_b_table[i] == 0xfe)
1092 /* Delay specific ms. Only RF configuration
1093 * requires delay.*/
1094 mdelay(50);
1095 else if (radio_b_table[i] == 0xfd)
1096 mdelay(5);
1097 else if (radio_b_table[i] == 0xfc)
1098 mdelay(1);
1099 else if (radio_b_table[i] == 0xfb)
1100 udelay(50);
1101 else if (radio_b_table[i] == 0xfa)
1102 udelay(5);
1103 else if (radio_b_table[i] == 0xf9)
1104 udelay(1);
1105 else
1106 rtl92s_phy_set_rf_reg(hw, rfpath,
1107 radio_b_table[i],
1108 MASK20BITS,
1109 radio_b_table[i + 1]);
1111 /* Add delay for ECS T20 & LG malow platform */
1112 udelay(1);
1114 break;
1115 case RF90_PATH_C:
1117 break;
1118 case RF90_PATH_D:
1120 break;
1121 default:
1122 break;
1125 return rtstatus;
1129 bool rtl92s_phy_mac_config(struct ieee80211_hw *hw)
1131 struct rtl_priv *rtlpriv = rtl_priv(hw);
1132 u32 i;
1133 u32 arraylength;
1134 u32 *ptraArray;
1136 arraylength = MAC_2T_ARRAYLENGTH;
1137 ptraArray = rtl8192semac_2t_array;
1139 for (i = 0; i < arraylength; i = i + 2)
1140 rtl_write_byte(rtlpriv, ptraArray[i], (u8)ptraArray[i + 1]);
1142 return true;
1146 bool rtl92s_phy_bb_config(struct ieee80211_hw *hw)
1148 struct rtl_priv *rtlpriv = rtl_priv(hw);
1149 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1150 bool rtstatus = true;
1151 u8 pathmap, index, rf_num = 0;
1152 u8 path1, path2;
1154 _rtl92s_phy_init_register_definition(hw);
1156 /* Config BB and AGC */
1157 rtstatus = _rtl92s_phy_bb_config_parafile(hw);
1160 /* Check BB/RF confiuration setting. */
1161 /* We only need to configure RF which is turned on. */
1162 path1 = (u8)(rtl92s_phy_query_bb_reg(hw, RFPGA0_TXINFO, 0xf));
1163 mdelay(10);
1164 path2 = (u8)(rtl92s_phy_query_bb_reg(hw, ROFDM0_TRXPATHENABLE, 0xf));
1165 pathmap = path1 | path2;
1167 rtlphy->rf_pathmap = pathmap;
1168 for (index = 0; index < 4; index++) {
1169 if ((pathmap >> index) & 0x1)
1170 rf_num++;
1173 if ((rtlphy->rf_type == RF_1T1R && rf_num != 1) ||
1174 (rtlphy->rf_type == RF_1T2R && rf_num != 2) ||
1175 (rtlphy->rf_type == RF_2T2R && rf_num != 2) ||
1176 (rtlphy->rf_type == RF_2T2R_GREEN && rf_num != 2)) {
1177 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
1178 ("RF_Type(%x) does not match "
1179 "RF_Num(%x)!!\n", rtlphy->rf_type, rf_num));
1180 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
1181 ("path1 0x%x, path2 0x%x, pathmap "
1182 "0x%x\n", path1, path2, pathmap));
1185 return rtstatus;
1188 bool rtl92s_phy_rf_config(struct ieee80211_hw *hw)
1190 struct rtl_priv *rtlpriv = rtl_priv(hw);
1191 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1193 /* Initialize general global value */
1194 if (rtlphy->rf_type == RF_1T1R)
1195 rtlphy->num_total_rfpath = 1;
1196 else
1197 rtlphy->num_total_rfpath = 2;
1199 /* Config BB and RF */
1200 return rtl92s_phy_rf6052_config(hw);
1203 void rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
1205 struct rtl_priv *rtlpriv = rtl_priv(hw);
1206 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1208 /* read rx initial gain */
1209 rtlphy->default_initialgain[0] = rtl_get_bbreg(hw,
1210 ROFDM0_XAAGCCORE1, MASKBYTE0);
1211 rtlphy->default_initialgain[1] = rtl_get_bbreg(hw,
1212 ROFDM0_XBAGCCORE1, MASKBYTE0);
1213 rtlphy->default_initialgain[2] = rtl_get_bbreg(hw,
1214 ROFDM0_XCAGCCORE1, MASKBYTE0);
1215 rtlphy->default_initialgain[3] = rtl_get_bbreg(hw,
1216 ROFDM0_XDAGCCORE1, MASKBYTE0);
1217 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Default initial gain "
1218 "(c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n",
1219 rtlphy->default_initialgain[0],
1220 rtlphy->default_initialgain[1],
1221 rtlphy->default_initialgain[2],
1222 rtlphy->default_initialgain[3]));
1224 /* read framesync */
1225 rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0);
1226 rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
1227 MASKDWORD);
1228 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1229 ("Default framesync (0x%x) = 0x%x\n",
1230 ROFDM0_RXDETECTOR3, rtlphy->framesync));
1234 static void _rtl92s_phy_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
1235 u8 *cckpowerlevel, u8 *ofdmpowerLevel)
1237 struct rtl_priv *rtlpriv = rtl_priv(hw);
1238 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1239 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1240 u8 index = (channel - 1);
1242 /* 1. CCK */
1243 /* RF-A */
1244 cckpowerlevel[0] = rtlefuse->txpwrlevel_cck[0][index];
1245 /* RF-B */
1246 cckpowerlevel[1] = rtlefuse->txpwrlevel_cck[1][index];
1248 /* 2. OFDM for 1T or 2T */
1249 if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_1T1R) {
1250 /* Read HT 40 OFDM TX power */
1251 ofdmpowerLevel[0] = rtlefuse->txpwrlevel_ht40_1s[0][index];
1252 ofdmpowerLevel[1] = rtlefuse->txpwrlevel_ht40_1s[1][index];
1253 } else if (rtlphy->rf_type == RF_2T2R) {
1254 /* Read HT 40 OFDM TX power */
1255 ofdmpowerLevel[0] = rtlefuse->txpwrlevel_ht40_2s[0][index];
1256 ofdmpowerLevel[1] = rtlefuse->txpwrlevel_ht40_2s[1][index];
1260 static void _rtl92s_phy_ccxpower_indexcheck(struct ieee80211_hw *hw,
1261 u8 channel, u8 *cckpowerlevel, u8 *ofdmpowerlevel)
1263 struct rtl_priv *rtlpriv = rtl_priv(hw);
1264 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1266 rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
1267 rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
1270 void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8 channel)
1272 struct rtl_priv *rtlpriv = rtl_priv(hw);
1273 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1274 /* [0]:RF-A, [1]:RF-B */
1275 u8 cckpowerlevel[2], ofdmpowerLevel[2];
1277 if (rtlefuse->txpwr_fromeprom == false)
1278 return;
1280 /* Mainly we use RF-A Tx Power to write the Tx Power registers,
1281 * but the RF-B Tx Power must be calculated by the antenna diff.
1282 * So we have to rewrite Antenna gain offset register here.
1283 * Please refer to BB register 0x80c
1284 * 1. For CCK.
1285 * 2. For OFDM 1T or 2T */
1286 _rtl92s_phy_get_txpower_index(hw, channel, &cckpowerlevel[0],
1287 &ofdmpowerLevel[0]);
1289 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1290 ("Channel-%d, cckPowerLevel (A / B) = "
1291 "0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n",
1292 channel, cckpowerlevel[0], cckpowerlevel[1],
1293 ofdmpowerLevel[0], ofdmpowerLevel[1]));
1295 _rtl92s_phy_ccxpower_indexcheck(hw, channel, &cckpowerlevel[0],
1296 &ofdmpowerLevel[0]);
1298 rtl92s_phy_rf6052_set_ccktxpower(hw, cckpowerlevel[0]);
1299 rtl92s_phy_rf6052_set_ofdmtxpower(hw, &ofdmpowerLevel[0], channel);
1303 void rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw)
1305 struct rtl_priv *rtlpriv = rtl_priv(hw);
1306 u16 pollingcnt = 10000;
1307 u32 tmpvalue;
1309 /* Make sure that CMD IO has be accepted by FW. */
1310 do {
1311 udelay(10);
1313 tmpvalue = rtl_read_dword(rtlpriv, WFM5);
1314 if (tmpvalue == 0)
1315 break;
1316 } while (--pollingcnt);
1318 if (pollingcnt == 0)
1319 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Set FW Cmd fail!!\n"));
1323 static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw)
1325 struct rtl_priv *rtlpriv = rtl_priv(hw);
1326 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1327 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1328 u32 input, current_aid = 0;
1330 if (is_hal_stop(rtlhal))
1331 return;
1333 /* We re-map RA related CMD IO to combinational ones */
1334 /* if FW version is v.52 or later. */
1335 switch (rtlhal->current_fwcmd_io) {
1336 case FW_CMD_RA_REFRESH_N:
1337 rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_N_COMB;
1338 break;
1339 case FW_CMD_RA_REFRESH_BG:
1340 rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_BG_COMB;
1341 break;
1342 default:
1343 break;
1346 switch (rtlhal->current_fwcmd_io) {
1347 case FW_CMD_RA_RESET:
1348 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1349 ("FW_CMD_RA_RESET\n"));
1350 rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET);
1351 rtl92s_phy_chk_fwcmd_iodone(hw);
1352 break;
1353 case FW_CMD_RA_ACTIVE:
1354 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1355 ("FW_CMD_RA_ACTIVE\n"));
1356 rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE);
1357 rtl92s_phy_chk_fwcmd_iodone(hw);
1358 break;
1359 case FW_CMD_RA_REFRESH_N:
1360 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1361 ("FW_CMD_RA_REFRESH_N\n"));
1362 input = FW_RA_REFRESH;
1363 rtl_write_dword(rtlpriv, WFM5, input);
1364 rtl92s_phy_chk_fwcmd_iodone(hw);
1365 rtl_write_dword(rtlpriv, WFM5, FW_RA_ENABLE_RSSI_MASK);
1366 rtl92s_phy_chk_fwcmd_iodone(hw);
1367 break;
1368 case FW_CMD_RA_REFRESH_BG:
1369 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1370 ("FW_CMD_RA_REFRESH_BG\n"));
1371 rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH);
1372 rtl92s_phy_chk_fwcmd_iodone(hw);
1373 rtl_write_dword(rtlpriv, WFM5, FW_RA_DISABLE_RSSI_MASK);
1374 rtl92s_phy_chk_fwcmd_iodone(hw);
1375 break;
1376 case FW_CMD_RA_REFRESH_N_COMB:
1377 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1378 ("FW_CMD_RA_REFRESH_N_COMB\n"));
1379 input = FW_RA_IOT_N_COMB;
1380 rtl_write_dword(rtlpriv, WFM5, input);
1381 rtl92s_phy_chk_fwcmd_iodone(hw);
1382 break;
1383 case FW_CMD_RA_REFRESH_BG_COMB:
1384 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1385 ("FW_CMD_RA_REFRESH_BG_COMB\n"));
1386 input = FW_RA_IOT_BG_COMB;
1387 rtl_write_dword(rtlpriv, WFM5, input);
1388 rtl92s_phy_chk_fwcmd_iodone(hw);
1389 break;
1390 case FW_CMD_IQK_ENABLE:
1391 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1392 ("FW_CMD_IQK_ENABLE\n"));
1393 rtl_write_dword(rtlpriv, WFM5, FW_IQK_ENABLE);
1394 rtl92s_phy_chk_fwcmd_iodone(hw);
1395 break;
1396 case FW_CMD_PAUSE_DM_BY_SCAN:
1397 /* Lower initial gain */
1398 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17);
1399 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17);
1400 /* CCA threshold */
1401 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40);
1402 break;
1403 case FW_CMD_RESUME_DM_BY_SCAN:
1404 /* CCA threshold */
1405 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
1406 rtl92s_phy_set_txpower(hw, rtlphy->current_channel);
1407 break;
1408 case FW_CMD_HIGH_PWR_DISABLE:
1409 if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE)
1410 break;
1412 /* Lower initial gain */
1413 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17);
1414 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17);
1415 /* CCA threshold */
1416 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40);
1417 break;
1418 case FW_CMD_HIGH_PWR_ENABLE:
1419 if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) ||
1420 rtlpriv->dm.dynamic_txpower_enable)
1421 break;
1423 /* CCA threshold */
1424 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
1425 break;
1426 case FW_CMD_LPS_ENTER:
1427 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1428 ("FW_CMD_LPS_ENTER\n"));
1429 current_aid = rtlpriv->mac80211.assoc_id;
1430 rtl_write_dword(rtlpriv, WFM5, (FW_LPS_ENTER |
1431 ((current_aid | 0xc000) << 8)));
1432 rtl92s_phy_chk_fwcmd_iodone(hw);
1433 /* FW set TXOP disable here, so disable EDCA
1434 * turbo mode until driver leave LPS */
1435 break;
1436 case FW_CMD_LPS_LEAVE:
1437 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1438 ("FW_CMD_LPS_LEAVE\n"));
1439 rtl_write_dword(rtlpriv, WFM5, FW_LPS_LEAVE);
1440 rtl92s_phy_chk_fwcmd_iodone(hw);
1441 break;
1442 case FW_CMD_ADD_A2_ENTRY:
1443 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1444 ("FW_CMD_ADD_A2_ENTRY\n"));
1445 rtl_write_dword(rtlpriv, WFM5, FW_ADD_A2_ENTRY);
1446 rtl92s_phy_chk_fwcmd_iodone(hw);
1447 break;
1448 case FW_CMD_CTRL_DM_BY_DRIVER:
1449 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1450 ("FW_CMD_CTRL_DM_BY_DRIVER\n"));
1451 rtl_write_dword(rtlpriv, WFM5, FW_CTRL_DM_BY_DRIVER);
1452 rtl92s_phy_chk_fwcmd_iodone(hw);
1453 break;
1455 default:
1456 break;
1459 rtl92s_phy_chk_fwcmd_iodone(hw);
1461 /* Clear FW CMD operation flag. */
1462 rtlhal->set_fwcmd_inprogress = false;
1465 bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
1467 struct rtl_priv *rtlpriv = rtl_priv(hw);
1468 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1469 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1470 u32 fw_param = FW_CMD_IO_PARA_QUERY(rtlpriv);
1471 u16 fw_cmdmap = FW_CMD_IO_QUERY(rtlpriv);
1472 bool bPostProcessing = false;
1474 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1475 ("Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n",
1476 fw_cmdio, rtlhal->set_fwcmd_inprogress));
1478 do {
1479 /* We re-map to combined FW CMD ones if firmware version */
1480 /* is v.53 or later. */
1481 switch (fw_cmdio) {
1482 case FW_CMD_RA_REFRESH_N:
1483 fw_cmdio = FW_CMD_RA_REFRESH_N_COMB;
1484 break;
1485 case FW_CMD_RA_REFRESH_BG:
1486 fw_cmdio = FW_CMD_RA_REFRESH_BG_COMB;
1487 break;
1488 default:
1489 break;
1492 /* If firmware version is v.62 or later,
1493 * use FW_CMD_IO_SET for FW_CMD_CTRL_DM_BY_DRIVER */
1494 if (hal_get_firmwareversion(rtlpriv) >= 0x3E) {
1495 if (fw_cmdio == FW_CMD_CTRL_DM_BY_DRIVER)
1496 fw_cmdio = FW_CMD_CTRL_DM_BY_DRIVER_NEW;
1500 /* We shall revise all FW Cmd IO into Reg0x364
1501 * DM map table in the future. */
1502 switch (fw_cmdio) {
1503 case FW_CMD_RA_INIT:
1504 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("RA init!!\n"));
1505 fw_cmdmap |= FW_RA_INIT_CTL;
1506 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1507 /* Clear control flag to sync with FW. */
1508 FW_CMD_IO_CLR(rtlpriv, FW_RA_INIT_CTL);
1509 break;
1510 case FW_CMD_DIG_DISABLE:
1511 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1512 ("Set DIG disable!!\n"));
1513 fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1514 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1515 break;
1516 case FW_CMD_DIG_ENABLE:
1517 case FW_CMD_DIG_RESUME:
1518 if (!(rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE)) {
1519 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1520 ("Set DIG enable or resume!!\n"));
1521 fw_cmdmap |= (FW_DIG_ENABLE_CTL | FW_SS_CTL);
1522 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1524 break;
1525 case FW_CMD_DIG_HALT:
1526 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1527 ("Set DIG halt!!\n"));
1528 fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | FW_SS_CTL);
1529 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1530 break;
1531 case FW_CMD_TXPWR_TRACK_THERMAL: {
1532 u8 thermalval = 0;
1533 fw_cmdmap |= FW_PWR_TRK_CTL;
1535 /* Clear FW parameter in terms of thermal parts. */
1536 fw_param &= FW_PWR_TRK_PARAM_CLR;
1538 thermalval = rtlpriv->dm.thermalvalue;
1539 fw_param |= ((thermalval << 24) |
1540 (rtlefuse->thermalmeter[0] << 16));
1542 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1543 ("Set TxPwr tracking!! "
1544 "FwCmdMap(%#x), FwParam(%#x)\n",
1545 fw_cmdmap, fw_param));
1547 FW_CMD_PARA_SET(rtlpriv, fw_param);
1548 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1550 /* Clear control flag to sync with FW. */
1551 FW_CMD_IO_CLR(rtlpriv, FW_PWR_TRK_CTL);
1553 break;
1554 /* The following FW CMDs are only compatible to
1555 * v.53 or later. */
1556 case FW_CMD_RA_REFRESH_N_COMB:
1557 fw_cmdmap |= FW_RA_N_CTL;
1559 /* Clear RA BG mode control. */
1560 fw_cmdmap &= ~(FW_RA_BG_CTL | FW_RA_INIT_CTL);
1562 /* Clear FW parameter in terms of RA parts. */
1563 fw_param &= FW_RA_PARAM_CLR;
1565 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1566 ("[FW CMD] [New Version] "
1567 "Set RA/IOT Comb in n mode!! FwCmdMap(%#x), "
1568 "FwParam(%#x)\n", fw_cmdmap, fw_param));
1570 FW_CMD_PARA_SET(rtlpriv, fw_param);
1571 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1573 /* Clear control flag to sync with FW. */
1574 FW_CMD_IO_CLR(rtlpriv, FW_RA_N_CTL);
1575 break;
1576 case FW_CMD_RA_REFRESH_BG_COMB:
1577 fw_cmdmap |= FW_RA_BG_CTL;
1579 /* Clear RA n-mode control. */
1580 fw_cmdmap &= ~(FW_RA_N_CTL | FW_RA_INIT_CTL);
1581 /* Clear FW parameter in terms of RA parts. */
1582 fw_param &= FW_RA_PARAM_CLR;
1584 FW_CMD_PARA_SET(rtlpriv, fw_param);
1585 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1587 /* Clear control flag to sync with FW. */
1588 FW_CMD_IO_CLR(rtlpriv, FW_RA_BG_CTL);
1589 break;
1590 case FW_CMD_IQK_ENABLE:
1591 fw_cmdmap |= FW_IQK_CTL;
1592 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1593 /* Clear control flag to sync with FW. */
1594 FW_CMD_IO_CLR(rtlpriv, FW_IQK_CTL);
1595 break;
1596 /* The following FW CMD is compatible to v.62 or later. */
1597 case FW_CMD_CTRL_DM_BY_DRIVER_NEW:
1598 fw_cmdmap |= FW_DRIVER_CTRL_DM_CTL;
1599 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1600 break;
1601 /* The followed FW Cmds needs post-processing later. */
1602 case FW_CMD_RESUME_DM_BY_SCAN:
1603 fw_cmdmap |= (FW_DIG_ENABLE_CTL |
1604 FW_HIGH_PWR_ENABLE_CTL |
1605 FW_SS_CTL);
1607 if (rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE ||
1608 !digtable.dig_enable_flag)
1609 fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1611 if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) ||
1612 rtlpriv->dm.dynamic_txpower_enable)
1613 fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL;
1615 if ((digtable.dig_ext_port_stage ==
1616 DIG_EXT_PORT_STAGE_0) ||
1617 (digtable.dig_ext_port_stage ==
1618 DIG_EXT_PORT_STAGE_1))
1619 fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1621 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1622 bPostProcessing = true;
1623 break;
1624 case FW_CMD_PAUSE_DM_BY_SCAN:
1625 fw_cmdmap &= ~(FW_DIG_ENABLE_CTL |
1626 FW_HIGH_PWR_ENABLE_CTL |
1627 FW_SS_CTL);
1628 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1629 bPostProcessing = true;
1630 break;
1631 case FW_CMD_HIGH_PWR_DISABLE:
1632 fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL;
1633 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1634 bPostProcessing = true;
1635 break;
1636 case FW_CMD_HIGH_PWR_ENABLE:
1637 if (!(rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) &&
1638 (rtlpriv->dm.dynamic_txpower_enable != true)) {
1639 fw_cmdmap |= (FW_HIGH_PWR_ENABLE_CTL |
1640 FW_SS_CTL);
1641 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1642 bPostProcessing = true;
1644 break;
1645 case FW_CMD_DIG_MODE_FA:
1646 fw_cmdmap |= FW_FA_CTL;
1647 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1648 break;
1649 case FW_CMD_DIG_MODE_SS:
1650 fw_cmdmap &= ~FW_FA_CTL;
1651 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1652 break;
1653 case FW_CMD_PAPE_CONTROL:
1654 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1655 ("[FW CMD] Set PAPE Control\n"));
1656 fw_cmdmap &= ~FW_PAPE_CTL_BY_SW_HW;
1658 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1659 break;
1660 default:
1661 /* Pass to original FW CMD processing callback
1662 * routine. */
1663 bPostProcessing = true;
1664 break;
1666 } while (false);
1668 /* We shall post processing these FW CMD if
1669 * variable bPostProcessing is set. */
1670 if (bPostProcessing && !rtlhal->set_fwcmd_inprogress) {
1671 rtlhal->set_fwcmd_inprogress = true;
1672 /* Update current FW Cmd for callback use. */
1673 rtlhal->current_fwcmd_io = fw_cmdio;
1674 } else {
1675 return false;
1678 _rtl92s_phy_set_fwcmd_io(hw);
1679 return true;
1682 static void _rtl92s_phy_check_ephy_switchready(struct ieee80211_hw *hw)
1684 struct rtl_priv *rtlpriv = rtl_priv(hw);
1685 u32 delay = 100;
1686 u8 regu1;
1688 regu1 = rtl_read_byte(rtlpriv, 0x554);
1689 while ((regu1 & BIT(5)) && (delay > 0)) {
1690 regu1 = rtl_read_byte(rtlpriv, 0x554);
1691 delay--;
1692 /* We delay only 50us to prevent
1693 * being scheduled out. */
1694 udelay(50);
1698 void rtl92s_phy_switch_ephy_parameter(struct ieee80211_hw *hw)
1700 struct rtl_priv *rtlpriv = rtl_priv(hw);
1701 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1703 /* The way to be capable to switch clock request
1704 * when the PG setting does not support clock request.
1705 * This is the backdoor solution to switch clock
1706 * request before ASPM or D3. */
1707 rtl_write_dword(rtlpriv, 0x540, 0x73c11);
1708 rtl_write_dword(rtlpriv, 0x548, 0x2407c);
1710 /* Switch EPHY parameter!!!! */
1711 rtl_write_word(rtlpriv, 0x550, 0x1000);
1712 rtl_write_byte(rtlpriv, 0x554, 0x20);
1713 _rtl92s_phy_check_ephy_switchready(hw);
1715 rtl_write_word(rtlpriv, 0x550, 0xa0eb);
1716 rtl_write_byte(rtlpriv, 0x554, 0x3e);
1717 _rtl92s_phy_check_ephy_switchready(hw);
1719 rtl_write_word(rtlpriv, 0x550, 0xff80);
1720 rtl_write_byte(rtlpriv, 0x554, 0x39);
1721 _rtl92s_phy_check_ephy_switchready(hw);
1723 /* Delay L1 enter time */
1724 if (ppsc->support_aspm && !ppsc->support_backdoor)
1725 rtl_write_byte(rtlpriv, 0x560, 0x40);
1726 else
1727 rtl_write_byte(rtlpriv, 0x560, 0x00);
1731 void rtl92s_phy_set_beacon_hwreg(struct ieee80211_hw *hw, u16 BeaconInterval)
1733 struct rtl_priv *rtlpriv = rtl_priv(hw);
1734 rtl_write_dword(rtlpriv, WFM5, 0xF1000000 | (BeaconInterval << 8));