sfc: Don't use enums as a bitmask.
[zen-stable.git] / drivers / net / wireless / rtlwifi / rtl8192se / phy.c
blob63b45e60a95e5c6a4a80b64acbac6febc3b26c6d
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 #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"
42 static u32 _rtl92s_phy_calculate_bit_shift(u32 bitmask)
44 u32 i;
46 for (i = 0; i <= 31; i++) {
47 if (((bitmask >> i) & 0x1) == 1)
48 break;
51 return i;
54 u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
56 struct rtl_priv *rtlpriv = rtl_priv(hw);
57 u32 returnvalue = 0, originalvalue, bitshift;
59 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)\n",
60 regaddr, bitmask));
62 originalvalue = rtl_read_dword(rtlpriv, regaddr);
63 bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
64 returnvalue = (originalvalue & bitmask) >> bitshift;
66 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
67 ("BBR MASK=0x%x Addr[0x%x]=0x%x\n",
68 bitmask, regaddr, originalvalue));
70 return returnvalue;
74 void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
75 u32 data)
77 struct rtl_priv *rtlpriv = rtl_priv(hw);
78 u32 originalvalue, bitshift;
80 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
81 " data(%#x)\n", regaddr, bitmask, data));
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));
89 rtl_write_dword(rtlpriv, regaddr, data);
91 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
92 " data(%#x)\n", regaddr, bitmask, data));
96 static u32 _rtl92s_phy_rf_serial_read(struct ieee80211_hw *hw,
97 enum radio_path rfpath, u32 offset)
100 struct rtl_priv *rtlpriv = rtl_priv(hw);
101 struct rtl_phy *rtlphy = &(rtlpriv->phy);
102 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
103 u32 newoffset;
104 u32 tmplong, tmplong2;
105 u8 rfpi_enable = 0;
106 u32 retvalue = 0;
108 offset &= 0x3f;
109 newoffset = offset;
111 tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
113 if (rfpath == RF90_PATH_A)
114 tmplong2 = tmplong;
115 else
116 tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
118 tmplong2 = (tmplong2 & (~BLSSI_READADDRESS)) | (newoffset << 23) |
119 BLSSI_READEDGE;
121 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
122 tmplong & (~BLSSI_READEDGE));
124 mdelay(1);
126 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
127 mdelay(1);
129 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, tmplong |
130 BLSSI_READEDGE);
131 mdelay(1);
133 if (rfpath == RF90_PATH_A)
134 rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
135 BIT(8));
136 else if (rfpath == RF90_PATH_B)
137 rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
138 BIT(8));
140 if (rfpi_enable)
141 retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi,
142 BLSSI_READBACK_DATA);
143 else
144 retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
145 BLSSI_READBACK_DATA);
147 retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
148 BLSSI_READBACK_DATA);
150 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n",
151 rfpath, pphyreg->rflssi_readback, retvalue));
153 return retvalue;
157 static void _rtl92s_phy_rf_serial_write(struct ieee80211_hw *hw,
158 enum radio_path rfpath, u32 offset,
159 u32 data)
161 struct rtl_priv *rtlpriv = rtl_priv(hw);
162 struct rtl_phy *rtlphy = &(rtlpriv->phy);
163 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
164 u32 data_and_addr = 0;
165 u32 newoffset;
167 offset &= 0x3f;
168 newoffset = offset;
170 data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
171 rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
173 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n",
174 rfpath, pphyreg->rf3wire_offset, data_and_addr));
178 u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
179 u32 regaddr, u32 bitmask)
181 struct rtl_priv *rtlpriv = rtl_priv(hw);
182 u32 original_value, readback_value, bitshift;
183 unsigned long flags;
185 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), "
186 "bitmask(%#x)\n", regaddr, rfpath, bitmask));
188 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
190 original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr);
192 bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
193 readback_value = (original_value & bitmask) >> bitshift;
195 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
197 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), "
198 "bitmask(%#x), original_value(%#x)\n", regaddr, rfpath,
199 bitmask, original_value));
201 return readback_value;
204 void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
205 u32 regaddr, u32 bitmask, u32 data)
207 struct rtl_priv *rtlpriv = rtl_priv(hw);
208 struct rtl_phy *rtlphy = &(rtlpriv->phy);
209 u32 original_value, bitshift;
210 unsigned long flags;
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_irqsave(&rtlpriv->locks.rf_lock, flags);
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_irqrestore(&rtlpriv->locks.rf_lock, flags);
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;
266 u8 reg_prsr_rsc;
268 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("Switch to %s bandwidth\n",
269 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
270 "20MHz" : "40MHz"));
272 if (rtlphy->set_bwmode_inprogress)
273 return;
274 if (is_hal_stop(rtlhal))
275 return;
277 rtlphy->set_bwmode_inprogress = true;
279 reg_bw_opmode = rtl_read_byte(rtlpriv, BW_OPMODE);
280 reg_prsr_rsc = 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 ppsc->set_rfpowerstate_inprogress = true;
551 switch (rfpwr_state) {
552 case ERFON:{
553 if ((ppsc->rfpwr_state == ERFOFF) &&
554 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
556 bool rtstatus;
557 u32 InitializeCount = 0;
558 do {
559 InitializeCount++;
560 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
561 ("IPS Set eRf nic enable\n"));
562 rtstatus = rtl_ps_enable_nic(hw);
563 } while ((rtstatus != true) &&
564 (InitializeCount < 10));
566 RT_CLEAR_PS_LEVEL(ppsc,
567 RT_RF_OFF_LEVL_HALT_NIC);
568 } else {
569 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
570 ("awake, sleeped:%d ms "
571 "state_inap:%x\n",
572 jiffies_to_msecs(jiffies -
573 ppsc->last_sleep_jiffies),
574 rtlpriv->psc.state_inap));
575 ppsc->last_awake_jiffies = jiffies;
576 rtl_write_word(rtlpriv, CMDR, 0x37FC);
577 rtl_write_byte(rtlpriv, TXPAUSE, 0x00);
578 rtl_write_byte(rtlpriv, PHY_CCA, 0x3);
581 if (mac->link_state == MAC80211_LINKED)
582 rtlpriv->cfg->ops->led_control(hw,
583 LED_CTL_LINK);
584 else
585 rtlpriv->cfg->ops->led_control(hw,
586 LED_CTL_NO_LINK);
587 break;
589 case ERFOFF:{
590 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
591 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
592 ("IPS Set eRf nic disable\n"));
593 rtl_ps_disable_nic(hw);
594 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
595 } else {
596 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
597 rtlpriv->cfg->ops->led_control(hw,
598 LED_CTL_NO_LINK);
599 else
600 rtlpriv->cfg->ops->led_control(hw,
601 LED_CTL_POWER_OFF);
603 break;
605 case ERFSLEEP:
606 if (ppsc->rfpwr_state == ERFOFF)
607 break;
609 for (queue_id = 0, i = 0;
610 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
611 ring = &pcipriv->dev.tx_ring[queue_id];
612 if (skb_queue_len(&ring->queue) == 0 ||
613 queue_id == BEACON_QUEUE) {
614 queue_id++;
615 continue;
616 } else {
617 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
618 ("eRf Off/Sleep: "
619 "%d times TcbBusyQueue[%d] = "
620 "%d before doze!\n",
621 (i + 1), queue_id,
622 skb_queue_len(&ring->queue)));
624 udelay(10);
625 i++;
628 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
629 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
630 ("\nERFOFF: %d times"
631 "TcbBusyQueue[%d] = %d !\n",
632 MAX_DOZE_WAITING_TIMES_9x,
633 queue_id,
634 skb_queue_len(&ring->queue)));
635 break;
639 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
640 ("Set ERFSLEEP awaked:%d ms\n",
641 jiffies_to_msecs(jiffies -
642 ppsc->last_awake_jiffies)));
644 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
645 ("sleep awaked:%d ms "
646 "state_inap:%x\n", jiffies_to_msecs(jiffies -
647 ppsc->last_awake_jiffies),
648 rtlpriv->psc.state_inap));
649 ppsc->last_sleep_jiffies = jiffies;
650 _rtl92se_phy_set_rf_sleep(hw);
651 break;
652 default:
653 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
654 ("switch case not process\n"));
655 bresult = false;
656 break;
659 if (bresult)
660 ppsc->rfpwr_state = rfpwr_state;
662 ppsc->set_rfpowerstate_inprogress = false;
664 return bresult;
667 static bool _rtl92s_phy_config_rfpa_bias_current(struct ieee80211_hw *hw,
668 enum radio_path rfpath)
670 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
671 bool rtstatus = true;
672 u32 tmpval = 0;
674 /* If inferiority IC, we have to increase the PA bias current */
675 if (rtlhal->ic_class != IC_INFERIORITY_A) {
676 tmpval = rtl92s_phy_query_rf_reg(hw, rfpath, RF_IPA, 0xf);
677 rtl92s_phy_set_rf_reg(hw, rfpath, RF_IPA, 0xf, tmpval + 1);
680 return rtstatus;
683 static void _rtl92s_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw,
684 u32 reg_addr, u32 bitmask, u32 data)
686 struct rtl_priv *rtlpriv = rtl_priv(hw);
687 struct rtl_phy *rtlphy = &(rtlpriv->phy);
689 if (reg_addr == RTXAGC_RATE18_06)
690 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] =
691 data;
692 if (reg_addr == RTXAGC_RATE54_24)
693 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] =
694 data;
695 if (reg_addr == RTXAGC_CCK_MCS32)
696 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] =
697 data;
698 if (reg_addr == RTXAGC_MCS03_MCS00)
699 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] =
700 data;
701 if (reg_addr == RTXAGC_MCS07_MCS04)
702 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] =
703 data;
704 if (reg_addr == RTXAGC_MCS11_MCS08)
705 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] =
706 data;
707 if (reg_addr == RTXAGC_MCS15_MCS12) {
708 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] =
709 data;
710 rtlphy->pwrgroup_cnt++;
714 static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw)
716 struct rtl_priv *rtlpriv = rtl_priv(hw);
717 struct rtl_phy *rtlphy = &(rtlpriv->phy);
719 /*RF Interface Sowrtware Control */
720 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
721 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
722 rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
723 rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
725 /* RF Interface Readback Value */
726 rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
727 rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
728 rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
729 rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
731 /* RF Interface Output (and Enable) */
732 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
733 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
734 rtlphy->phyreg_def[RF90_PATH_C].rfintfo = RFPGA0_XC_RFINTERFACEOE;
735 rtlphy->phyreg_def[RF90_PATH_D].rfintfo = RFPGA0_XD_RFINTERFACEOE;
737 /* RF Interface (Output and) Enable */
738 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
739 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
740 rtlphy->phyreg_def[RF90_PATH_C].rfintfe = RFPGA0_XC_RFINTERFACEOE;
741 rtlphy->phyreg_def[RF90_PATH_D].rfintfe = RFPGA0_XD_RFINTERFACEOE;
743 /* Addr of LSSI. Wirte RF register by driver */
744 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
745 RFPGA0_XA_LSSIPARAMETER;
746 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
747 RFPGA0_XB_LSSIPARAMETER;
748 rtlphy->phyreg_def[RF90_PATH_C].rf3wire_offset =
749 RFPGA0_XC_LSSIPARAMETER;
750 rtlphy->phyreg_def[RF90_PATH_D].rf3wire_offset =
751 RFPGA0_XD_LSSIPARAMETER;
753 /* RF parameter */
754 rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER;
755 rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER;
756 rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER;
757 rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER;
759 /* Tx AGC Gain Stage (same for all path. Should we remove this?) */
760 rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
761 rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
762 rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
763 rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
765 /* Tranceiver A~D HSSI Parameter-1 */
766 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
767 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
768 rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para1 = RFPGA0_XC_HSSIPARAMETER1;
769 rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para1 = RFPGA0_XD_HSSIPARAMETER1;
771 /* Tranceiver A~D HSSI Parameter-2 */
772 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
773 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
774 rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para2 = RFPGA0_XC_HSSIPARAMETER2;
775 rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para2 = RFPGA0_XD_HSSIPARAMETER2;
777 /* RF switch Control */
778 rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control =
779 RFPGA0_XAB_SWITCHCONTROL;
780 rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control =
781 RFPGA0_XAB_SWITCHCONTROL;
782 rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control =
783 RFPGA0_XCD_SWITCHCONTROL;
784 rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control =
785 RFPGA0_XCD_SWITCHCONTROL;
787 /* AGC control 1 */
788 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
789 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
790 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
791 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
793 /* AGC control 2 */
794 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
795 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
796 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
797 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
799 /* RX AFE control 1 */
800 rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance =
801 ROFDM0_XARXIQIMBALANCE;
802 rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance =
803 ROFDM0_XBRXIQIMBALANCE;
804 rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance =
805 ROFDM0_XCRXIQIMBALANCE;
806 rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance =
807 ROFDM0_XDRXIQIMBALANCE;
809 /* RX AFE control 1 */
810 rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
811 rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
812 rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
813 rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
815 /* Tx AFE control 1 */
816 rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance =
817 ROFDM0_XATXIQIMBALANCE;
818 rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance =
819 ROFDM0_XBTXIQIMBALANCE;
820 rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance =
821 ROFDM0_XCTXIQIMBALANCE;
822 rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance =
823 ROFDM0_XDTXIQIMBALANCE;
825 /* Tx AFE control 2 */
826 rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
827 rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
828 rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
829 rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
831 /* Tranceiver LSSI Readback */
832 rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback =
833 RFPGA0_XA_LSSIREADBACK;
834 rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback =
835 RFPGA0_XB_LSSIREADBACK;
836 rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback =
837 RFPGA0_XC_LSSIREADBACK;
838 rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback =
839 RFPGA0_XD_LSSIREADBACK;
841 /* Tranceiver LSSI Readback PI mode */
842 rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi =
843 TRANSCEIVERA_HSPI_READBACK;
844 rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi =
845 TRANSCEIVERB_HSPI_READBACK;
849 static bool _rtl92s_phy_config_bb(struct ieee80211_hw *hw, u8 configtype)
851 int i;
852 u32 *phy_reg_table;
853 u32 *agc_table;
854 u16 phy_reg_len, agc_len;
856 agc_len = AGCTAB_ARRAYLENGTH;
857 agc_table = rtl8192seagctab_array;
858 /* Default RF_type: 2T2R */
859 phy_reg_len = PHY_REG_2T2RARRAYLENGTH;
860 phy_reg_table = rtl8192sephy_reg_2t2rarray;
862 if (configtype == BASEBAND_CONFIG_PHY_REG) {
863 for (i = 0; i < phy_reg_len; i = i + 2) {
864 if (phy_reg_table[i] == 0xfe)
865 mdelay(50);
866 else if (phy_reg_table[i] == 0xfd)
867 mdelay(5);
868 else if (phy_reg_table[i] == 0xfc)
869 mdelay(1);
870 else if (phy_reg_table[i] == 0xfb)
871 udelay(50);
872 else if (phy_reg_table[i] == 0xfa)
873 udelay(5);
874 else if (phy_reg_table[i] == 0xf9)
875 udelay(1);
877 /* Add delay for ECS T20 & LG malow platform, */
878 udelay(1);
880 rtl92s_phy_set_bb_reg(hw, phy_reg_table[i], MASKDWORD,
881 phy_reg_table[i + 1]);
883 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
884 for (i = 0; i < agc_len; i = i + 2) {
885 rtl92s_phy_set_bb_reg(hw, agc_table[i], MASKDWORD,
886 agc_table[i + 1]);
888 /* Add delay for ECS T20 & LG malow platform */
889 udelay(1);
893 return true;
896 static bool _rtl92s_phy_set_bb_to_diff_rf(struct ieee80211_hw *hw,
897 u8 configtype)
899 struct rtl_priv *rtlpriv = rtl_priv(hw);
900 struct rtl_phy *rtlphy = &(rtlpriv->phy);
901 u32 *phy_regarray2xtxr_table;
902 u16 phy_regarray2xtxr_len;
903 int i;
905 if (rtlphy->rf_type == RF_1T1R) {
906 phy_regarray2xtxr_table = rtl8192sephy_changeto_1t1rarray;
907 phy_regarray2xtxr_len = PHY_CHANGETO_1T1RARRAYLENGTH;
908 } else if (rtlphy->rf_type == RF_1T2R) {
909 phy_regarray2xtxr_table = rtl8192sephy_changeto_1t2rarray;
910 phy_regarray2xtxr_len = PHY_CHANGETO_1T2RARRAYLENGTH;
911 } else {
912 return false;
915 if (configtype == BASEBAND_CONFIG_PHY_REG) {
916 for (i = 0; i < phy_regarray2xtxr_len; i = i + 3) {
917 if (phy_regarray2xtxr_table[i] == 0xfe)
918 mdelay(50);
919 else if (phy_regarray2xtxr_table[i] == 0xfd)
920 mdelay(5);
921 else if (phy_regarray2xtxr_table[i] == 0xfc)
922 mdelay(1);
923 else if (phy_regarray2xtxr_table[i] == 0xfb)
924 udelay(50);
925 else if (phy_regarray2xtxr_table[i] == 0xfa)
926 udelay(5);
927 else if (phy_regarray2xtxr_table[i] == 0xf9)
928 udelay(1);
930 rtl92s_phy_set_bb_reg(hw, phy_regarray2xtxr_table[i],
931 phy_regarray2xtxr_table[i + 1],
932 phy_regarray2xtxr_table[i + 2]);
936 return true;
939 static bool _rtl92s_phy_config_bb_with_pg(struct ieee80211_hw *hw,
940 u8 configtype)
942 int i;
943 u32 *phy_table_pg;
944 u16 phy_pg_len;
946 phy_pg_len = PHY_REG_ARRAY_PGLENGTH;
947 phy_table_pg = rtl8192sephy_reg_array_pg;
949 if (configtype == BASEBAND_CONFIG_PHY_REG) {
950 for (i = 0; i < phy_pg_len; i = i + 3) {
951 if (phy_table_pg[i] == 0xfe)
952 mdelay(50);
953 else if (phy_table_pg[i] == 0xfd)
954 mdelay(5);
955 else if (phy_table_pg[i] == 0xfc)
956 mdelay(1);
957 else if (phy_table_pg[i] == 0xfb)
958 udelay(50);
959 else if (phy_table_pg[i] == 0xfa)
960 udelay(5);
961 else if (phy_table_pg[i] == 0xf9)
962 udelay(1);
964 _rtl92s_store_pwrindex_diffrate_offset(hw,
965 phy_table_pg[i],
966 phy_table_pg[i + 1],
967 phy_table_pg[i + 2]);
968 rtl92s_phy_set_bb_reg(hw, phy_table_pg[i],
969 phy_table_pg[i + 1],
970 phy_table_pg[i + 2]);
974 return true;
977 static bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw)
979 struct rtl_priv *rtlpriv = rtl_priv(hw);
980 struct rtl_phy *rtlphy = &(rtlpriv->phy);
981 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
982 bool rtstatus = true;
984 /* 1. Read PHY_REG.TXT BB INIT!! */
985 /* We will separate as 1T1R/1T2R/1T2R_GREEN/2T2R */
986 if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_2T2R ||
987 rtlphy->rf_type == RF_1T1R || rtlphy->rf_type == RF_2T2R_GREEN) {
988 rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_PHY_REG);
990 if (rtlphy->rf_type != RF_2T2R &&
991 rtlphy->rf_type != RF_2T2R_GREEN)
992 /* so we should reconfig BB reg with the right
993 * PHY parameters. */
994 rtstatus = _rtl92s_phy_set_bb_to_diff_rf(hw,
995 BASEBAND_CONFIG_PHY_REG);
996 } else {
997 rtstatus = false;
1000 if (rtstatus != true) {
1001 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
1002 ("Write BB Reg Fail!!"));
1003 goto phy_BB8190_Config_ParaFile_Fail;
1006 /* 2. If EEPROM or EFUSE autoload OK, We must config by
1007 * PHY_REG_PG.txt */
1008 if (rtlefuse->autoload_failflag == false) {
1009 rtlphy->pwrgroup_cnt = 0;
1011 rtstatus = _rtl92s_phy_config_bb_with_pg(hw,
1012 BASEBAND_CONFIG_PHY_REG);
1014 if (rtstatus != true) {
1015 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
1016 ("_rtl92s_phy_bb_config_parafile(): "
1017 "BB_PG Reg Fail!!"));
1018 goto phy_BB8190_Config_ParaFile_Fail;
1021 /* 3. BB AGC table Initialization */
1022 rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_AGC_TAB);
1024 if (rtstatus != true) {
1025 printk(KERN_ERR "_rtl92s_phy_bb_config_parafile(): "
1026 "AGC Table Fail\n");
1027 goto phy_BB8190_Config_ParaFile_Fail;
1030 /* Check if the CCK HighPower is turned ON. */
1031 /* This is used to calculate PWDB. */
1032 rtlphy->cck_high_power = (bool)(rtl92s_phy_query_bb_reg(hw,
1033 RFPGA0_XA_HSSIPARAMETER2, 0x200));
1035 phy_BB8190_Config_ParaFile_Fail:
1036 return rtstatus;
1039 u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath)
1041 struct rtl_priv *rtlpriv = rtl_priv(hw);
1042 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1043 int i;
1044 bool rtstatus = true;
1045 u32 *radio_a_table;
1046 u32 *radio_b_table;
1047 u16 radio_a_tblen, radio_b_tblen;
1049 radio_a_tblen = RADIOA_1T_ARRAYLENGTH;
1050 radio_a_table = rtl8192seradioa_1t_array;
1052 /* Using Green mode array table for RF_2T2R_GREEN */
1053 if (rtlphy->rf_type == RF_2T2R_GREEN) {
1054 radio_b_table = rtl8192seradiob_gm_array;
1055 radio_b_tblen = RADIOB_GM_ARRAYLENGTH;
1056 } else {
1057 radio_b_table = rtl8192seradiob_array;
1058 radio_b_tblen = RADIOB_ARRAYLENGTH;
1061 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Radio No %x\n", rfpath));
1062 rtstatus = true;
1064 switch (rfpath) {
1065 case RF90_PATH_A:
1066 for (i = 0; i < radio_a_tblen; i = i + 2) {
1067 if (radio_a_table[i] == 0xfe)
1068 /* Delay specific ms. Only RF configuration
1069 * requires delay. */
1070 mdelay(50);
1071 else if (radio_a_table[i] == 0xfd)
1072 mdelay(5);
1073 else if (radio_a_table[i] == 0xfc)
1074 mdelay(1);
1075 else if (radio_a_table[i] == 0xfb)
1076 udelay(50);
1077 else if (radio_a_table[i] == 0xfa)
1078 udelay(5);
1079 else if (radio_a_table[i] == 0xf9)
1080 udelay(1);
1081 else
1082 rtl92s_phy_set_rf_reg(hw, rfpath,
1083 radio_a_table[i],
1084 MASK20BITS,
1085 radio_a_table[i + 1]);
1087 /* Add delay for ECS T20 & LG malow platform */
1088 udelay(1);
1091 /* PA Bias current for inferiority IC */
1092 _rtl92s_phy_config_rfpa_bias_current(hw, rfpath);
1093 break;
1094 case RF90_PATH_B:
1095 for (i = 0; i < radio_b_tblen; i = i + 2) {
1096 if (radio_b_table[i] == 0xfe)
1097 /* Delay specific ms. Only RF configuration
1098 * requires delay.*/
1099 mdelay(50);
1100 else if (radio_b_table[i] == 0xfd)
1101 mdelay(5);
1102 else if (radio_b_table[i] == 0xfc)
1103 mdelay(1);
1104 else if (radio_b_table[i] == 0xfb)
1105 udelay(50);
1106 else if (radio_b_table[i] == 0xfa)
1107 udelay(5);
1108 else if (radio_b_table[i] == 0xf9)
1109 udelay(1);
1110 else
1111 rtl92s_phy_set_rf_reg(hw, rfpath,
1112 radio_b_table[i],
1113 MASK20BITS,
1114 radio_b_table[i + 1]);
1116 /* Add delay for ECS T20 & LG malow platform */
1117 udelay(1);
1119 break;
1120 case RF90_PATH_C:
1122 break;
1123 case RF90_PATH_D:
1125 break;
1126 default:
1127 break;
1130 return rtstatus;
1134 bool rtl92s_phy_mac_config(struct ieee80211_hw *hw)
1136 struct rtl_priv *rtlpriv = rtl_priv(hw);
1137 u32 i;
1138 u32 arraylength;
1139 u32 *ptraArray;
1141 arraylength = MAC_2T_ARRAYLENGTH;
1142 ptraArray = rtl8192semac_2t_array;
1144 for (i = 0; i < arraylength; i = i + 2)
1145 rtl_write_byte(rtlpriv, ptraArray[i], (u8)ptraArray[i + 1]);
1147 return true;
1151 bool rtl92s_phy_bb_config(struct ieee80211_hw *hw)
1153 struct rtl_priv *rtlpriv = rtl_priv(hw);
1154 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1155 bool rtstatus = true;
1156 u8 pathmap, index, rf_num = 0;
1157 u8 path1, path2;
1159 _rtl92s_phy_init_register_definition(hw);
1161 /* Config BB and AGC */
1162 rtstatus = _rtl92s_phy_bb_config_parafile(hw);
1165 /* Check BB/RF confiuration setting. */
1166 /* We only need to configure RF which is turned on. */
1167 path1 = (u8)(rtl92s_phy_query_bb_reg(hw, RFPGA0_TXINFO, 0xf));
1168 mdelay(10);
1169 path2 = (u8)(rtl92s_phy_query_bb_reg(hw, ROFDM0_TRXPATHENABLE, 0xf));
1170 pathmap = path1 | path2;
1172 rtlphy->rf_pathmap = pathmap;
1173 for (index = 0; index < 4; index++) {
1174 if ((pathmap >> index) & 0x1)
1175 rf_num++;
1178 if ((rtlphy->rf_type == RF_1T1R && rf_num != 1) ||
1179 (rtlphy->rf_type == RF_1T2R && rf_num != 2) ||
1180 (rtlphy->rf_type == RF_2T2R && rf_num != 2) ||
1181 (rtlphy->rf_type == RF_2T2R_GREEN && rf_num != 2)) {
1182 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
1183 ("RF_Type(%x) does not match "
1184 "RF_Num(%x)!!\n", rtlphy->rf_type, rf_num));
1185 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
1186 ("path1 0x%x, path2 0x%x, pathmap "
1187 "0x%x\n", path1, path2, pathmap));
1190 return rtstatus;
1193 bool rtl92s_phy_rf_config(struct ieee80211_hw *hw)
1195 struct rtl_priv *rtlpriv = rtl_priv(hw);
1196 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1198 /* Initialize general global value */
1199 if (rtlphy->rf_type == RF_1T1R)
1200 rtlphy->num_total_rfpath = 1;
1201 else
1202 rtlphy->num_total_rfpath = 2;
1204 /* Config BB and RF */
1205 return rtl92s_phy_rf6052_config(hw);
1208 void rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
1210 struct rtl_priv *rtlpriv = rtl_priv(hw);
1211 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1213 /* read rx initial gain */
1214 rtlphy->default_initialgain[0] = rtl_get_bbreg(hw,
1215 ROFDM0_XAAGCCORE1, MASKBYTE0);
1216 rtlphy->default_initialgain[1] = rtl_get_bbreg(hw,
1217 ROFDM0_XBAGCCORE1, MASKBYTE0);
1218 rtlphy->default_initialgain[2] = rtl_get_bbreg(hw,
1219 ROFDM0_XCAGCCORE1, MASKBYTE0);
1220 rtlphy->default_initialgain[3] = rtl_get_bbreg(hw,
1221 ROFDM0_XDAGCCORE1, MASKBYTE0);
1222 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Default initial gain "
1223 "(c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n",
1224 rtlphy->default_initialgain[0],
1225 rtlphy->default_initialgain[1],
1226 rtlphy->default_initialgain[2],
1227 rtlphy->default_initialgain[3]));
1229 /* read framesync */
1230 rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0);
1231 rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
1232 MASKDWORD);
1233 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1234 ("Default framesync (0x%x) = 0x%x\n",
1235 ROFDM0_RXDETECTOR3, rtlphy->framesync));
1239 static void _rtl92s_phy_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
1240 u8 *cckpowerlevel, u8 *ofdmpowerLevel)
1242 struct rtl_priv *rtlpriv = rtl_priv(hw);
1243 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1244 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1245 u8 index = (channel - 1);
1247 /* 1. CCK */
1248 /* RF-A */
1249 cckpowerlevel[0] = rtlefuse->txpwrlevel_cck[0][index];
1250 /* RF-B */
1251 cckpowerlevel[1] = rtlefuse->txpwrlevel_cck[1][index];
1253 /* 2. OFDM for 1T or 2T */
1254 if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_1T1R) {
1255 /* Read HT 40 OFDM TX power */
1256 ofdmpowerLevel[0] = rtlefuse->txpwrlevel_ht40_1s[0][index];
1257 ofdmpowerLevel[1] = rtlefuse->txpwrlevel_ht40_1s[1][index];
1258 } else if (rtlphy->rf_type == RF_2T2R) {
1259 /* Read HT 40 OFDM TX power */
1260 ofdmpowerLevel[0] = rtlefuse->txpwrlevel_ht40_2s[0][index];
1261 ofdmpowerLevel[1] = rtlefuse->txpwrlevel_ht40_2s[1][index];
1265 static void _rtl92s_phy_ccxpower_indexcheck(struct ieee80211_hw *hw,
1266 u8 channel, u8 *cckpowerlevel, u8 *ofdmpowerlevel)
1268 struct rtl_priv *rtlpriv = rtl_priv(hw);
1269 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1271 rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
1272 rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
1275 void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8 channel)
1277 struct rtl_priv *rtlpriv = rtl_priv(hw);
1278 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1279 /* [0]:RF-A, [1]:RF-B */
1280 u8 cckpowerlevel[2], ofdmpowerLevel[2];
1282 if (rtlefuse->txpwr_fromeprom == false)
1283 return;
1285 /* Mainly we use RF-A Tx Power to write the Tx Power registers,
1286 * but the RF-B Tx Power must be calculated by the antenna diff.
1287 * So we have to rewrite Antenna gain offset register here.
1288 * Please refer to BB register 0x80c
1289 * 1. For CCK.
1290 * 2. For OFDM 1T or 2T */
1291 _rtl92s_phy_get_txpower_index(hw, channel, &cckpowerlevel[0],
1292 &ofdmpowerLevel[0]);
1294 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1295 ("Channel-%d, cckPowerLevel (A / B) = "
1296 "0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n",
1297 channel, cckpowerlevel[0], cckpowerlevel[1],
1298 ofdmpowerLevel[0], ofdmpowerLevel[1]));
1300 _rtl92s_phy_ccxpower_indexcheck(hw, channel, &cckpowerlevel[0],
1301 &ofdmpowerLevel[0]);
1303 rtl92s_phy_rf6052_set_ccktxpower(hw, cckpowerlevel[0]);
1304 rtl92s_phy_rf6052_set_ofdmtxpower(hw, &ofdmpowerLevel[0], channel);
1308 void rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw)
1310 struct rtl_priv *rtlpriv = rtl_priv(hw);
1311 u16 pollingcnt = 10000;
1312 u32 tmpvalue;
1314 /* Make sure that CMD IO has be accepted by FW. */
1315 do {
1316 udelay(10);
1318 tmpvalue = rtl_read_dword(rtlpriv, WFM5);
1319 if (tmpvalue == 0)
1320 break;
1321 } while (--pollingcnt);
1323 if (pollingcnt == 0)
1324 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Set FW Cmd fail!!\n"));
1328 static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw)
1330 struct rtl_priv *rtlpriv = rtl_priv(hw);
1331 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1332 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1333 u32 input, current_aid = 0;
1335 if (is_hal_stop(rtlhal))
1336 return;
1338 /* We re-map RA related CMD IO to combinational ones */
1339 /* if FW version is v.52 or later. */
1340 switch (rtlhal->current_fwcmd_io) {
1341 case FW_CMD_RA_REFRESH_N:
1342 rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_N_COMB;
1343 break;
1344 case FW_CMD_RA_REFRESH_BG:
1345 rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_BG_COMB;
1346 break;
1347 default:
1348 break;
1351 switch (rtlhal->current_fwcmd_io) {
1352 case FW_CMD_RA_RESET:
1353 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1354 ("FW_CMD_RA_RESET\n"));
1355 rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET);
1356 rtl92s_phy_chk_fwcmd_iodone(hw);
1357 break;
1358 case FW_CMD_RA_ACTIVE:
1359 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1360 ("FW_CMD_RA_ACTIVE\n"));
1361 rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE);
1362 rtl92s_phy_chk_fwcmd_iodone(hw);
1363 break;
1364 case FW_CMD_RA_REFRESH_N:
1365 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1366 ("FW_CMD_RA_REFRESH_N\n"));
1367 input = FW_RA_REFRESH;
1368 rtl_write_dword(rtlpriv, WFM5, input);
1369 rtl92s_phy_chk_fwcmd_iodone(hw);
1370 rtl_write_dword(rtlpriv, WFM5, FW_RA_ENABLE_RSSI_MASK);
1371 rtl92s_phy_chk_fwcmd_iodone(hw);
1372 break;
1373 case FW_CMD_RA_REFRESH_BG:
1374 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1375 ("FW_CMD_RA_REFRESH_BG\n"));
1376 rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH);
1377 rtl92s_phy_chk_fwcmd_iodone(hw);
1378 rtl_write_dword(rtlpriv, WFM5, FW_RA_DISABLE_RSSI_MASK);
1379 rtl92s_phy_chk_fwcmd_iodone(hw);
1380 break;
1381 case FW_CMD_RA_REFRESH_N_COMB:
1382 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1383 ("FW_CMD_RA_REFRESH_N_COMB\n"));
1384 input = FW_RA_IOT_N_COMB;
1385 rtl_write_dword(rtlpriv, WFM5, input);
1386 rtl92s_phy_chk_fwcmd_iodone(hw);
1387 break;
1388 case FW_CMD_RA_REFRESH_BG_COMB:
1389 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1390 ("FW_CMD_RA_REFRESH_BG_COMB\n"));
1391 input = FW_RA_IOT_BG_COMB;
1392 rtl_write_dword(rtlpriv, WFM5, input);
1393 rtl92s_phy_chk_fwcmd_iodone(hw);
1394 break;
1395 case FW_CMD_IQK_ENABLE:
1396 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1397 ("FW_CMD_IQK_ENABLE\n"));
1398 rtl_write_dword(rtlpriv, WFM5, FW_IQK_ENABLE);
1399 rtl92s_phy_chk_fwcmd_iodone(hw);
1400 break;
1401 case FW_CMD_PAUSE_DM_BY_SCAN:
1402 /* Lower initial gain */
1403 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17);
1404 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17);
1405 /* CCA threshold */
1406 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40);
1407 break;
1408 case FW_CMD_RESUME_DM_BY_SCAN:
1409 /* CCA threshold */
1410 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
1411 rtl92s_phy_set_txpower(hw, rtlphy->current_channel);
1412 break;
1413 case FW_CMD_HIGH_PWR_DISABLE:
1414 if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE)
1415 break;
1417 /* Lower initial gain */
1418 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17);
1419 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17);
1420 /* CCA threshold */
1421 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40);
1422 break;
1423 case FW_CMD_HIGH_PWR_ENABLE:
1424 if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) ||
1425 (rtlpriv->dm.dynamic_txpower_enable == true))
1426 break;
1428 /* CCA threshold */
1429 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
1430 break;
1431 case FW_CMD_LPS_ENTER:
1432 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1433 ("FW_CMD_LPS_ENTER\n"));
1434 current_aid = rtlpriv->mac80211.assoc_id;
1435 rtl_write_dword(rtlpriv, WFM5, (FW_LPS_ENTER |
1436 ((current_aid | 0xc000) << 8)));
1437 rtl92s_phy_chk_fwcmd_iodone(hw);
1438 /* FW set TXOP disable here, so disable EDCA
1439 * turbo mode until driver leave LPS */
1440 break;
1441 case FW_CMD_LPS_LEAVE:
1442 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1443 ("FW_CMD_LPS_LEAVE\n"));
1444 rtl_write_dword(rtlpriv, WFM5, FW_LPS_LEAVE);
1445 rtl92s_phy_chk_fwcmd_iodone(hw);
1446 break;
1447 case FW_CMD_ADD_A2_ENTRY:
1448 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1449 ("FW_CMD_ADD_A2_ENTRY\n"));
1450 rtl_write_dword(rtlpriv, WFM5, FW_ADD_A2_ENTRY);
1451 rtl92s_phy_chk_fwcmd_iodone(hw);
1452 break;
1453 case FW_CMD_CTRL_DM_BY_DRIVER:
1454 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1455 ("FW_CMD_CTRL_DM_BY_DRIVER\n"));
1456 rtl_write_dword(rtlpriv, WFM5, FW_CTRL_DM_BY_DRIVER);
1457 rtl92s_phy_chk_fwcmd_iodone(hw);
1458 break;
1460 default:
1461 break;
1464 rtl92s_phy_chk_fwcmd_iodone(hw);
1466 /* Clear FW CMD operation flag. */
1467 rtlhal->set_fwcmd_inprogress = false;
1470 bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
1472 struct rtl_priv *rtlpriv = rtl_priv(hw);
1473 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1474 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1475 u32 fw_param = FW_CMD_IO_PARA_QUERY(rtlpriv);
1476 u16 fw_cmdmap = FW_CMD_IO_QUERY(rtlpriv);
1477 bool bPostProcessing = false;
1479 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1480 ("Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n",
1481 fw_cmdio, rtlhal->set_fwcmd_inprogress));
1483 do {
1484 /* We re-map to combined FW CMD ones if firmware version */
1485 /* is v.53 or later. */
1486 switch (fw_cmdio) {
1487 case FW_CMD_RA_REFRESH_N:
1488 fw_cmdio = FW_CMD_RA_REFRESH_N_COMB;
1489 break;
1490 case FW_CMD_RA_REFRESH_BG:
1491 fw_cmdio = FW_CMD_RA_REFRESH_BG_COMB;
1492 break;
1493 default:
1494 break;
1497 /* If firmware version is v.62 or later,
1498 * use FW_CMD_IO_SET for FW_CMD_CTRL_DM_BY_DRIVER */
1499 if (hal_get_firmwareversion(rtlpriv) >= 0x3E) {
1500 if (fw_cmdio == FW_CMD_CTRL_DM_BY_DRIVER)
1501 fw_cmdio = FW_CMD_CTRL_DM_BY_DRIVER_NEW;
1505 /* We shall revise all FW Cmd IO into Reg0x364
1506 * DM map table in the future. */
1507 switch (fw_cmdio) {
1508 case FW_CMD_RA_INIT:
1509 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("RA init!!\n"));
1510 fw_cmdmap |= FW_RA_INIT_CTL;
1511 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1512 /* Clear control flag to sync with FW. */
1513 FW_CMD_IO_CLR(rtlpriv, FW_RA_INIT_CTL);
1514 break;
1515 case FW_CMD_DIG_DISABLE:
1516 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1517 ("Set DIG disable!!\n"));
1518 fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1519 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1520 break;
1521 case FW_CMD_DIG_ENABLE:
1522 case FW_CMD_DIG_RESUME:
1523 if (!(rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE)) {
1524 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1525 ("Set DIG enable or resume!!\n"));
1526 fw_cmdmap |= (FW_DIG_ENABLE_CTL | FW_SS_CTL);
1527 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1529 break;
1530 case FW_CMD_DIG_HALT:
1531 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1532 ("Set DIG halt!!\n"));
1533 fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | FW_SS_CTL);
1534 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1535 break;
1536 case FW_CMD_TXPWR_TRACK_THERMAL: {
1537 u8 thermalval = 0;
1538 fw_cmdmap |= FW_PWR_TRK_CTL;
1540 /* Clear FW parameter in terms of thermal parts. */
1541 fw_param &= FW_PWR_TRK_PARAM_CLR;
1543 thermalval = rtlpriv->dm.thermalvalue;
1544 fw_param |= ((thermalval << 24) |
1545 (rtlefuse->thermalmeter[0] << 16));
1547 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1548 ("Set TxPwr tracking!! "
1549 "FwCmdMap(%#x), FwParam(%#x)\n",
1550 fw_cmdmap, fw_param));
1552 FW_CMD_PARA_SET(rtlpriv, fw_param);
1553 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1555 /* Clear control flag to sync with FW. */
1556 FW_CMD_IO_CLR(rtlpriv, FW_PWR_TRK_CTL);
1558 break;
1559 /* The following FW CMDs are only compatible to
1560 * v.53 or later. */
1561 case FW_CMD_RA_REFRESH_N_COMB:
1562 fw_cmdmap |= FW_RA_N_CTL;
1564 /* Clear RA BG mode control. */
1565 fw_cmdmap &= ~(FW_RA_BG_CTL | FW_RA_INIT_CTL);
1567 /* Clear FW parameter in terms of RA parts. */
1568 fw_param &= FW_RA_PARAM_CLR;
1570 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1571 ("[FW CMD] [New Version] "
1572 "Set RA/IOT Comb in n mode!! FwCmdMap(%#x), "
1573 "FwParam(%#x)\n", fw_cmdmap, fw_param));
1575 FW_CMD_PARA_SET(rtlpriv, fw_param);
1576 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1578 /* Clear control flag to sync with FW. */
1579 FW_CMD_IO_CLR(rtlpriv, FW_RA_N_CTL);
1580 break;
1581 case FW_CMD_RA_REFRESH_BG_COMB:
1582 fw_cmdmap |= FW_RA_BG_CTL;
1584 /* Clear RA n-mode control. */
1585 fw_cmdmap &= ~(FW_RA_N_CTL | FW_RA_INIT_CTL);
1586 /* Clear FW parameter in terms of RA parts. */
1587 fw_param &= FW_RA_PARAM_CLR;
1589 FW_CMD_PARA_SET(rtlpriv, fw_param);
1590 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1592 /* Clear control flag to sync with FW. */
1593 FW_CMD_IO_CLR(rtlpriv, FW_RA_BG_CTL);
1594 break;
1595 case FW_CMD_IQK_ENABLE:
1596 fw_cmdmap |= FW_IQK_CTL;
1597 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1598 /* Clear control flag to sync with FW. */
1599 FW_CMD_IO_CLR(rtlpriv, FW_IQK_CTL);
1600 break;
1601 /* The following FW CMD is compatible to v.62 or later. */
1602 case FW_CMD_CTRL_DM_BY_DRIVER_NEW:
1603 fw_cmdmap |= FW_DRIVER_CTRL_DM_CTL;
1604 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1605 break;
1606 /* The followed FW Cmds needs post-processing later. */
1607 case FW_CMD_RESUME_DM_BY_SCAN:
1608 fw_cmdmap |= (FW_DIG_ENABLE_CTL |
1609 FW_HIGH_PWR_ENABLE_CTL |
1610 FW_SS_CTL);
1612 if (rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE ||
1613 !digtable.dig_enable_flag)
1614 fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1616 if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) ||
1617 (rtlpriv->dm.dynamic_txpower_enable == true))
1618 fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL;
1620 if ((digtable.dig_ext_port_stage ==
1621 DIG_EXT_PORT_STAGE_0) ||
1622 (digtable.dig_ext_port_stage ==
1623 DIG_EXT_PORT_STAGE_1))
1624 fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1626 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1627 bPostProcessing = true;
1628 break;
1629 case FW_CMD_PAUSE_DM_BY_SCAN:
1630 fw_cmdmap &= ~(FW_DIG_ENABLE_CTL |
1631 FW_HIGH_PWR_ENABLE_CTL |
1632 FW_SS_CTL);
1633 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1634 bPostProcessing = true;
1635 break;
1636 case FW_CMD_HIGH_PWR_DISABLE:
1637 fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL;
1638 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1639 bPostProcessing = true;
1640 break;
1641 case FW_CMD_HIGH_PWR_ENABLE:
1642 if (!(rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) &&
1643 (rtlpriv->dm.dynamic_txpower_enable != true)) {
1644 fw_cmdmap |= (FW_HIGH_PWR_ENABLE_CTL |
1645 FW_SS_CTL);
1646 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1647 bPostProcessing = true;
1649 break;
1650 case FW_CMD_DIG_MODE_FA:
1651 fw_cmdmap |= FW_FA_CTL;
1652 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1653 break;
1654 case FW_CMD_DIG_MODE_SS:
1655 fw_cmdmap &= ~FW_FA_CTL;
1656 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1657 break;
1658 case FW_CMD_PAPE_CONTROL:
1659 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1660 ("[FW CMD] Set PAPE Control\n"));
1661 fw_cmdmap &= ~FW_PAPE_CTL_BY_SW_HW;
1663 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1664 break;
1665 default:
1666 /* Pass to original FW CMD processing callback
1667 * routine. */
1668 bPostProcessing = true;
1669 break;
1671 } while (false);
1673 /* We shall post processing these FW CMD if
1674 * variable bPostProcessing is set. */
1675 if (bPostProcessing && !rtlhal->set_fwcmd_inprogress) {
1676 rtlhal->set_fwcmd_inprogress = true;
1677 /* Update current FW Cmd for callback use. */
1678 rtlhal->current_fwcmd_io = fw_cmdio;
1679 } else {
1680 return false;
1683 _rtl92s_phy_set_fwcmd_io(hw);
1684 return true;
1687 static void _rtl92s_phy_check_ephy_switchready(struct ieee80211_hw *hw)
1689 struct rtl_priv *rtlpriv = rtl_priv(hw);
1690 u32 delay = 100;
1691 u8 regu1;
1693 regu1 = rtl_read_byte(rtlpriv, 0x554);
1694 while ((regu1 & BIT(5)) && (delay > 0)) {
1695 regu1 = rtl_read_byte(rtlpriv, 0x554);
1696 delay--;
1697 /* We delay only 50us to prevent
1698 * being scheduled out. */
1699 udelay(50);
1703 void rtl92s_phy_switch_ephy_parameter(struct ieee80211_hw *hw)
1705 struct rtl_priv *rtlpriv = rtl_priv(hw);
1706 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1708 /* The way to be capable to switch clock request
1709 * when the PG setting does not support clock request.
1710 * This is the backdoor solution to switch clock
1711 * request before ASPM or D3. */
1712 rtl_write_dword(rtlpriv, 0x540, 0x73c11);
1713 rtl_write_dword(rtlpriv, 0x548, 0x2407c);
1715 /* Switch EPHY parameter!!!! */
1716 rtl_write_word(rtlpriv, 0x550, 0x1000);
1717 rtl_write_byte(rtlpriv, 0x554, 0x20);
1718 _rtl92s_phy_check_ephy_switchready(hw);
1720 rtl_write_word(rtlpriv, 0x550, 0xa0eb);
1721 rtl_write_byte(rtlpriv, 0x554, 0x3e);
1722 _rtl92s_phy_check_ephy_switchready(hw);
1724 rtl_write_word(rtlpriv, 0x550, 0xff80);
1725 rtl_write_byte(rtlpriv, 0x554, 0x39);
1726 _rtl92s_phy_check_ephy_switchready(hw);
1728 /* Delay L1 enter time */
1729 if (ppsc->support_aspm && !ppsc->support_backdoor)
1730 rtl_write_byte(rtlpriv, 0x560, 0x40);
1731 else
1732 rtl_write_byte(rtlpriv, 0x560, 0x00);
1736 void rtl92s_phy_set_beacon_hwreg(struct ieee80211_hw *hw, u16 BeaconInterval)
1738 struct rtl_priv *rtlpriv = rtl_priv(hw);
1739 rtl_write_dword(rtlpriv, WFM5, 0xF1000000 | (BeaconInterval << 8));