1 /******************************************************************************
3 * Copyright(c) 2009-2012 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
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 *****************************************************************************/
42 static u32 _rtl92s_phy_calculate_bit_shift(u32 bitmask)
46 for (i = 0; i <= 31; i++) {
47 if (((bitmask >> i) & 0x1) == 1)
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",
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, "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
67 bitmask, regaddr, originalvalue);
73 void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
76 struct rtl_priv *rtlpriv = rtl_priv(hw);
77 u32 originalvalue, bitshift;
79 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
80 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
81 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,
92 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
93 regaddr, bitmask, data);
97 static u32 _rtl92s_phy_rf_serial_read(struct ieee80211_hw *hw,
98 enum radio_path rfpath, u32 offset)
101 struct rtl_priv *rtlpriv = rtl_priv(hw);
102 struct rtl_phy *rtlphy = &(rtlpriv->phy);
103 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
105 u32 tmplong, tmplong2;
112 tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
114 if (rfpath == RF90_PATH_A)
117 tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
119 tmplong2 = (tmplong2 & (~BLSSI_READADDRESS)) | (newoffset << 23) |
122 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
123 tmplong & (~BLSSI_READEDGE));
127 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
130 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, tmplong |
134 if (rfpath == RF90_PATH_A)
135 rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
137 else if (rfpath == RF90_PATH_B)
138 rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
142 retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi,
143 BLSSI_READBACK_DATA);
145 retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb,
146 BLSSI_READBACK_DATA);
148 retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb,
149 BLSSI_READBACK_DATA);
151 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n",
152 rfpath, pphyreg->rf_rb, retvalue);
158 static void _rtl92s_phy_rf_serial_write(struct ieee80211_hw *hw,
159 enum radio_path rfpath, u32 offset,
162 struct rtl_priv *rtlpriv = rtl_priv(hw);
163 struct rtl_phy *rtlphy = &(rtlpriv->phy);
164 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
165 u32 data_and_addr = 0;
171 data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
172 rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
174 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n",
175 rfpath, pphyreg->rf3wire_offset, data_and_addr);
179 u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
180 u32 regaddr, u32 bitmask)
182 struct rtl_priv *rtlpriv = rtl_priv(hw);
183 u32 original_value, readback_value, bitshift;
185 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
186 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
187 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,
199 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
200 regaddr, rfpath, 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))
215 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
216 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
217 regaddr, bitmask, data, rfpath);
219 spin_lock(&rtlpriv->locks.rf_lock);
221 if (bitmask != RFREG_OFFSET_MASK) {
222 original_value = _rtl92s_phy_rf_serial_read(hw, rfpath,
224 bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
225 data = ((original_value & (~bitmask)) | (data << bitshift));
228 _rtl92s_phy_rf_serial_write(hw, rfpath, regaddr, data);
230 spin_unlock(&rtlpriv->locks.rf_lock);
232 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
233 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
234 regaddr, bitmask, data, rfpath);
238 void rtl92s_phy_scan_operation_backup(struct ieee80211_hw *hw,
241 struct rtl_priv *rtlpriv = rtl_priv(hw);
242 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
244 if (!is_hal_stop(rtlhal)) {
246 case SCAN_OPT_BACKUP:
247 rtl92s_phy_set_fw_cmd(hw, FW_CMD_PAUSE_DM_BY_SCAN);
249 case SCAN_OPT_RESTORE:
250 rtl92s_phy_set_fw_cmd(hw, FW_CMD_RESUME_DM_BY_SCAN);
253 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
254 "Unknown operation\n");
260 void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw,
261 enum nl80211_channel_type ch_type)
263 struct rtl_priv *rtlpriv = rtl_priv(hw);
264 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
265 struct rtl_phy *rtlphy = &(rtlpriv->phy);
266 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
269 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n",
270 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
273 if (rtlphy->set_bwmode_inprogress)
275 if (is_hal_stop(rtlhal))
278 rtlphy->set_bwmode_inprogress = true;
280 reg_bw_opmode = rtl_read_byte(rtlpriv, BW_OPMODE);
282 rtl_read_byte(rtlpriv, RRSR + 2);
284 switch (rtlphy->current_chan_bw) {
285 case HT_CHANNEL_WIDTH_20:
286 reg_bw_opmode |= BW_OPMODE_20MHZ;
287 rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode);
289 case HT_CHANNEL_WIDTH_20_40:
290 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
291 rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode);
294 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
295 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
299 switch (rtlphy->current_chan_bw) {
300 case HT_CHANNEL_WIDTH_20:
301 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
302 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
304 if (rtlhal->version >= VERSION_8192S_BCUT)
305 rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x58);
307 case HT_CHANNEL_WIDTH_20_40:
308 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
309 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
311 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
312 (mac->cur_40_prime_sc >> 1));
313 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
315 if (rtlhal->version >= VERSION_8192S_BCUT)
316 rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x18);
319 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
320 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
324 rtl92s_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
325 rtlphy->set_bwmode_inprogress = false;
326 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
329 static bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
330 u32 cmdtableidx, u32 cmdtablesz, enum swchnlcmd_id cmdid,
331 u32 para1, u32 para2, u32 msdelay)
333 struct swchnlcmd *pcmd;
335 if (cmdtable == NULL) {
336 RT_ASSERT(false, "cmdtable cannot be NULL\n");
340 if (cmdtableidx >= cmdtablesz)
343 pcmd = cmdtable + cmdtableidx;
347 pcmd->msdelay = msdelay;
352 static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
353 u8 channel, u8 *stage, u8 *step, u32 *delay)
355 struct rtl_priv *rtlpriv = rtl_priv(hw);
356 struct rtl_phy *rtlphy = &(rtlpriv->phy);
357 struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
359 struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
360 u32 postcommoncmdcnt;
361 struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
363 struct swchnlcmd *currentcmd = NULL;
365 u8 num_total_rfpath = rtlphy->num_total_rfpath;
368 _rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
369 MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
370 _rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
371 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
373 postcommoncmdcnt = 0;
375 _rtl92s_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
376 MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
380 RT_ASSERT((channel >= 1 && channel <= 14),
381 "invalid channel for Zebra: %d\n", channel);
383 _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
384 MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
385 RF_CHNLBW, channel, 10);
387 _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
388 MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0);
393 currentcmd = &precommoncmd[*step];
396 currentcmd = &rfdependcmd[*step];
399 currentcmd = &postcommoncmd[*step];
403 if (currentcmd->cmdid == CMDID_END) {
413 switch (currentcmd->cmdid) {
414 case CMDID_SET_TXPOWEROWER_LEVEL:
415 rtl92s_phy_set_txpower(hw, channel);
417 case CMDID_WRITEPORT_ULONG:
418 rtl_write_dword(rtlpriv, currentcmd->para1,
421 case CMDID_WRITEPORT_USHORT:
422 rtl_write_word(rtlpriv, currentcmd->para1,
423 (u16)currentcmd->para2);
425 case CMDID_WRITEPORT_UCHAR:
426 rtl_write_byte(rtlpriv, currentcmd->para1,
427 (u8)currentcmd->para2);
429 case CMDID_RF_WRITEREG:
430 for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
431 rtlphy->rfreg_chnlval[rfpath] =
432 ((rtlphy->rfreg_chnlval[rfpath] &
433 0xfffffc00) | currentcmd->para2);
434 rtl_set_rfreg(hw, (enum radio_path)rfpath,
437 rtlphy->rfreg_chnlval[rfpath]);
441 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
442 "switch case not processed\n");
449 (*delay) = currentcmd->msdelay;
454 u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw)
456 struct rtl_priv *rtlpriv = rtl_priv(hw);
457 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
458 struct rtl_phy *rtlphy = &(rtlpriv->phy);
462 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "switch to channel%d\n",
463 rtlphy->current_channel);
465 if (rtlphy->sw_chnl_inprogress)
468 if (rtlphy->set_bwmode_inprogress)
471 if (is_hal_stop(rtlhal))
474 rtlphy->sw_chnl_inprogress = true;
475 rtlphy->sw_chnl_stage = 0;
476 rtlphy->sw_chnl_step = 0;
479 if (!rtlphy->sw_chnl_inprogress)
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);
492 rtlphy->sw_chnl_inprogress = false;
497 rtlphy->sw_chnl_inprogress = false;
499 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
504 static void _rtl92se_phy_set_rf_sleep(struct ieee80211_hw *hw)
506 struct rtl_priv *rtlpriv = rtl_priv(hw);
509 u1btmp = rtl_read_byte(rtlpriv, LDOV12D_CTRL);
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);
518 rtl_write_word(rtlpriv, CMDR, 0x77FC);
519 rtl_write_byte(rtlpriv, PHY_CCA, 0x0);
522 rtl_write_word(rtlpriv, CMDR, 0x37FC);
525 rtl_write_word(rtlpriv, CMDR, 0x77FC);
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));
544 struct rtl8192_tx_ring *ring = NULL;
546 if (rfpwr_state == ppsc->rfpwr_state)
549 switch (rfpwr_state) {
551 if ((ppsc->rfpwr_state == ERFOFF) &&
552 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
555 u32 InitializeCount = 0;
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 && (InitializeCount < 10));
563 RT_CLEAR_PS_LEVEL(ppsc,
564 RT_RF_OFF_LEVL_HALT_NIC);
566 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
567 "awake, sleeped:%d ms state_inap:%x\n",
568 jiffies_to_msecs(jiffies -
571 rtlpriv->psc.state_inap);
572 ppsc->last_awake_jiffies = jiffies;
573 rtl_write_word(rtlpriv, CMDR, 0x37FC);
574 rtl_write_byte(rtlpriv, TXPAUSE, 0x00);
575 rtl_write_byte(rtlpriv, PHY_CCA, 0x3);
578 if (mac->link_state == MAC80211_LINKED)
579 rtlpriv->cfg->ops->led_control(hw,
582 rtlpriv->cfg->ops->led_control(hw,
587 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
588 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
589 "IPS Set eRf nic disable\n");
590 rtl_ps_disable_nic(hw);
591 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
593 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
594 rtlpriv->cfg->ops->led_control(hw,
597 rtlpriv->cfg->ops->led_control(hw,
603 if (ppsc->rfpwr_state == ERFOFF)
606 for (queue_id = 0, i = 0;
607 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
608 ring = &pcipriv->dev.tx_ring[queue_id];
609 if (skb_queue_len(&ring->queue) == 0 ||
610 queue_id == BEACON_QUEUE) {
614 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
615 "eRf Off/Sleep: %d times TcbBusyQueue[%d] = %d before doze!\n",
617 skb_queue_len(&ring->queue));
623 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
624 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
625 "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n",
626 MAX_DOZE_WAITING_TIMES_9x,
628 skb_queue_len(&ring->queue));
633 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
634 "Set ERFSLEEP awaked:%d ms\n",
635 jiffies_to_msecs(jiffies -
636 ppsc->last_awake_jiffies));
638 RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
639 "sleep awaked:%d ms state_inap:%x\n",
640 jiffies_to_msecs(jiffies -
641 ppsc->last_awake_jiffies),
642 rtlpriv->psc.state_inap);
643 ppsc->last_sleep_jiffies = jiffies;
644 _rtl92se_phy_set_rf_sleep(hw);
647 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
648 "switch case not processed\n");
654 ppsc->rfpwr_state = rfpwr_state;
659 static bool _rtl92s_phy_config_rfpa_bias_current(struct ieee80211_hw *hw,
660 enum radio_path rfpath)
662 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
663 bool rtstatus = true;
666 /* If inferiority IC, we have to increase the PA bias current */
667 if (rtlhal->ic_class != IC_INFERIORITY_A) {
668 tmpval = rtl92s_phy_query_rf_reg(hw, rfpath, RF_IPA, 0xf);
669 rtl92s_phy_set_rf_reg(hw, rfpath, RF_IPA, 0xf, tmpval + 1);
675 static void _rtl92s_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw,
676 u32 reg_addr, u32 bitmask, u32 data)
678 struct rtl_priv *rtlpriv = rtl_priv(hw);
679 struct rtl_phy *rtlphy = &(rtlpriv->phy);
682 if (reg_addr == RTXAGC_RATE18_06)
684 else if (reg_addr == RTXAGC_RATE54_24)
686 else if (reg_addr == RTXAGC_CCK_MCS32)
688 else if (reg_addr == RTXAGC_MCS03_MCS00)
690 else if (reg_addr == RTXAGC_MCS07_MCS04)
692 else if (reg_addr == RTXAGC_MCS11_MCS08)
694 else if (reg_addr == RTXAGC_MCS15_MCS12)
699 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index] = data;
701 rtlphy->pwrgroup_cnt++;
704 static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw)
706 struct rtl_priv *rtlpriv = rtl_priv(hw);
707 struct rtl_phy *rtlphy = &(rtlpriv->phy);
709 /*RF Interface Sowrtware Control */
710 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
711 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
712 rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
713 rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
715 /* RF Interface Readback Value */
716 rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
717 rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
718 rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
719 rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
721 /* RF Interface Output (and Enable) */
722 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
723 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
724 rtlphy->phyreg_def[RF90_PATH_C].rfintfo = RFPGA0_XC_RFINTERFACEOE;
725 rtlphy->phyreg_def[RF90_PATH_D].rfintfo = RFPGA0_XD_RFINTERFACEOE;
727 /* RF Interface (Output and) Enable */
728 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
729 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
730 rtlphy->phyreg_def[RF90_PATH_C].rfintfe = RFPGA0_XC_RFINTERFACEOE;
731 rtlphy->phyreg_def[RF90_PATH_D].rfintfe = RFPGA0_XD_RFINTERFACEOE;
733 /* Addr of LSSI. Wirte RF register by driver */
734 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
735 RFPGA0_XA_LSSIPARAMETER;
736 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
737 RFPGA0_XB_LSSIPARAMETER;
738 rtlphy->phyreg_def[RF90_PATH_C].rf3wire_offset =
739 RFPGA0_XC_LSSIPARAMETER;
740 rtlphy->phyreg_def[RF90_PATH_D].rf3wire_offset =
741 RFPGA0_XD_LSSIPARAMETER;
744 rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER;
745 rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER;
746 rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER;
747 rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER;
749 /* Tx AGC Gain Stage (same for all path. Should we remove this?) */
750 rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
751 rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
752 rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
753 rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
755 /* Tranceiver A~D HSSI Parameter-1 */
756 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
757 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
758 rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para1 = RFPGA0_XC_HSSIPARAMETER1;
759 rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para1 = RFPGA0_XD_HSSIPARAMETER1;
761 /* Tranceiver A~D HSSI Parameter-2 */
762 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
763 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
764 rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para2 = RFPGA0_XC_HSSIPARAMETER2;
765 rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para2 = RFPGA0_XD_HSSIPARAMETER2;
767 /* RF switch Control */
768 rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
769 rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL;
770 rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
771 rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL;
774 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
775 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
776 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
777 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
780 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
781 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
782 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
783 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
785 /* RX AFE control 1 */
786 rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE;
787 rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE;
788 rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBALANCE;
789 rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE;
791 /* RX AFE control 1 */
792 rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
793 rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
794 rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
795 rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
797 /* Tx AFE control 1 */
798 rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE;
799 rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE;
800 rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE;
801 rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE;
803 /* Tx AFE control 2 */
804 rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
805 rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
806 rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
807 rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
809 /* Tranceiver LSSI Readback */
810 rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK;
811 rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK;
812 rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK;
813 rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK;
815 /* Tranceiver LSSI Readback PI mode */
816 rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVERA_HSPI_READBACK;
817 rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVERB_HSPI_READBACK;
821 static bool _rtl92s_phy_config_bb(struct ieee80211_hw *hw, u8 configtype)
826 u16 phy_reg_len, agc_len;
828 agc_len = AGCTAB_ARRAYLENGTH;
829 agc_table = rtl8192seagctab_array;
830 /* Default RF_type: 2T2R */
831 phy_reg_len = PHY_REG_2T2RARRAYLENGTH;
832 phy_reg_table = rtl8192sephy_reg_2t2rarray;
834 if (configtype == BASEBAND_CONFIG_PHY_REG) {
835 for (i = 0; i < phy_reg_len; i = i + 2) {
836 if (phy_reg_table[i] == 0xfe)
838 else if (phy_reg_table[i] == 0xfd)
840 else if (phy_reg_table[i] == 0xfc)
842 else if (phy_reg_table[i] == 0xfb)
844 else if (phy_reg_table[i] == 0xfa)
846 else if (phy_reg_table[i] == 0xf9)
849 /* Add delay for ECS T20 & LG malow platform, */
852 rtl92s_phy_set_bb_reg(hw, phy_reg_table[i], MASKDWORD,
853 phy_reg_table[i + 1]);
855 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
856 for (i = 0; i < agc_len; i = i + 2) {
857 rtl92s_phy_set_bb_reg(hw, agc_table[i], MASKDWORD,
860 /* Add delay for ECS T20 & LG malow platform */
868 static bool _rtl92s_phy_set_bb_to_diff_rf(struct ieee80211_hw *hw,
871 struct rtl_priv *rtlpriv = rtl_priv(hw);
872 struct rtl_phy *rtlphy = &(rtlpriv->phy);
873 u32 *phy_regarray2xtxr_table;
874 u16 phy_regarray2xtxr_len;
877 if (rtlphy->rf_type == RF_1T1R) {
878 phy_regarray2xtxr_table = rtl8192sephy_changeto_1t1rarray;
879 phy_regarray2xtxr_len = PHY_CHANGETO_1T1RARRAYLENGTH;
880 } else if (rtlphy->rf_type == RF_1T2R) {
881 phy_regarray2xtxr_table = rtl8192sephy_changeto_1t2rarray;
882 phy_regarray2xtxr_len = PHY_CHANGETO_1T2RARRAYLENGTH;
887 if (configtype == BASEBAND_CONFIG_PHY_REG) {
888 for (i = 0; i < phy_regarray2xtxr_len; i = i + 3) {
889 if (phy_regarray2xtxr_table[i] == 0xfe)
891 else if (phy_regarray2xtxr_table[i] == 0xfd)
893 else if (phy_regarray2xtxr_table[i] == 0xfc)
895 else if (phy_regarray2xtxr_table[i] == 0xfb)
897 else if (phy_regarray2xtxr_table[i] == 0xfa)
899 else if (phy_regarray2xtxr_table[i] == 0xf9)
902 rtl92s_phy_set_bb_reg(hw, phy_regarray2xtxr_table[i],
903 phy_regarray2xtxr_table[i + 1],
904 phy_regarray2xtxr_table[i + 2]);
911 static bool _rtl92s_phy_config_bb_with_pg(struct ieee80211_hw *hw,
918 phy_pg_len = PHY_REG_ARRAY_PGLENGTH;
919 phy_table_pg = rtl8192sephy_reg_array_pg;
921 if (configtype == BASEBAND_CONFIG_PHY_REG) {
922 for (i = 0; i < phy_pg_len; i = i + 3) {
923 if (phy_table_pg[i] == 0xfe)
925 else if (phy_table_pg[i] == 0xfd)
927 else if (phy_table_pg[i] == 0xfc)
929 else if (phy_table_pg[i] == 0xfb)
931 else if (phy_table_pg[i] == 0xfa)
933 else if (phy_table_pg[i] == 0xf9)
936 _rtl92s_store_pwrindex_diffrate_offset(hw,
939 phy_table_pg[i + 2]);
940 rtl92s_phy_set_bb_reg(hw, phy_table_pg[i],
942 phy_table_pg[i + 2]);
949 static bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw)
951 struct rtl_priv *rtlpriv = rtl_priv(hw);
952 struct rtl_phy *rtlphy = &(rtlpriv->phy);
953 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
954 bool rtstatus = true;
956 /* 1. Read PHY_REG.TXT BB INIT!! */
957 /* We will separate as 1T1R/1T2R/1T2R_GREEN/2T2R */
958 if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_2T2R ||
959 rtlphy->rf_type == RF_1T1R || rtlphy->rf_type == RF_2T2R_GREEN) {
960 rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_PHY_REG);
962 if (rtlphy->rf_type != RF_2T2R &&
963 rtlphy->rf_type != RF_2T2R_GREEN)
964 /* so we should reconfig BB reg with the right
966 rtstatus = _rtl92s_phy_set_bb_to_diff_rf(hw,
967 BASEBAND_CONFIG_PHY_REG);
973 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
974 "Write BB Reg Fail!!\n");
975 goto phy_BB8190_Config_ParaFile_Fail;
978 /* 2. If EEPROM or EFUSE autoload OK, We must config by
980 if (rtlefuse->autoload_failflag == false) {
981 rtlphy->pwrgroup_cnt = 0;
983 rtstatus = _rtl92s_phy_config_bb_with_pg(hw,
984 BASEBAND_CONFIG_PHY_REG);
987 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
988 "_rtl92s_phy_bb_config_parafile(): BB_PG Reg Fail!!\n");
989 goto phy_BB8190_Config_ParaFile_Fail;
992 /* 3. BB AGC table Initialization */
993 rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_AGC_TAB);
996 pr_err("%s(): AGC Table Fail\n", __func__);
997 goto phy_BB8190_Config_ParaFile_Fail;
1000 /* Check if the CCK HighPower is turned ON. */
1001 /* This is used to calculate PWDB. */
1002 rtlphy->cck_high_power = (bool)(rtl92s_phy_query_bb_reg(hw,
1003 RFPGA0_XA_HSSIPARAMETER2, 0x200));
1005 phy_BB8190_Config_ParaFile_Fail:
1009 u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath)
1011 struct rtl_priv *rtlpriv = rtl_priv(hw);
1012 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1014 bool rtstatus = true;
1017 u16 radio_a_tblen, radio_b_tblen;
1019 radio_a_tblen = RADIOA_1T_ARRAYLENGTH;
1020 radio_a_table = rtl8192seradioa_1t_array;
1022 /* Using Green mode array table for RF_2T2R_GREEN */
1023 if (rtlphy->rf_type == RF_2T2R_GREEN) {
1024 radio_b_table = rtl8192seradiob_gm_array;
1025 radio_b_tblen = RADIOB_GM_ARRAYLENGTH;
1027 radio_b_table = rtl8192seradiob_array;
1028 radio_b_tblen = RADIOB_ARRAYLENGTH;
1031 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
1036 for (i = 0; i < radio_a_tblen; i = i + 2) {
1037 if (radio_a_table[i] == 0xfe)
1038 /* Delay specific ms. Only RF configuration
1039 * requires delay. */
1041 else if (radio_a_table[i] == 0xfd)
1043 else if (radio_a_table[i] == 0xfc)
1045 else if (radio_a_table[i] == 0xfb)
1047 else if (radio_a_table[i] == 0xfa)
1049 else if (radio_a_table[i] == 0xf9)
1052 rtl92s_phy_set_rf_reg(hw, rfpath,
1055 radio_a_table[i + 1]);
1057 /* Add delay for ECS T20 & LG malow platform */
1061 /* PA Bias current for inferiority IC */
1062 _rtl92s_phy_config_rfpa_bias_current(hw, rfpath);
1065 for (i = 0; i < radio_b_tblen; i = i + 2) {
1066 if (radio_b_table[i] == 0xfe)
1067 /* Delay specific ms. Only RF configuration
1070 else if (radio_b_table[i] == 0xfd)
1072 else if (radio_b_table[i] == 0xfc)
1074 else if (radio_b_table[i] == 0xfb)
1076 else if (radio_b_table[i] == 0xfa)
1078 else if (radio_b_table[i] == 0xf9)
1081 rtl92s_phy_set_rf_reg(hw, rfpath,
1084 radio_b_table[i + 1]);
1086 /* Add delay for ECS T20 & LG malow platform */
1104 bool rtl92s_phy_mac_config(struct ieee80211_hw *hw)
1106 struct rtl_priv *rtlpriv = rtl_priv(hw);
1111 arraylength = MAC_2T_ARRAYLENGTH;
1112 ptraArray = rtl8192semac_2t_array;
1114 for (i = 0; i < arraylength; i = i + 2)
1115 rtl_write_byte(rtlpriv, ptraArray[i], (u8)ptraArray[i + 1]);
1121 bool rtl92s_phy_bb_config(struct ieee80211_hw *hw)
1123 struct rtl_priv *rtlpriv = rtl_priv(hw);
1124 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1125 bool rtstatus = true;
1126 u8 pathmap, index, rf_num = 0;
1129 _rtl92s_phy_init_register_definition(hw);
1131 /* Config BB and AGC */
1132 rtstatus = _rtl92s_phy_bb_config_parafile(hw);
1135 /* Check BB/RF confiuration setting. */
1136 /* We only need to configure RF which is turned on. */
1137 path1 = (u8)(rtl92s_phy_query_bb_reg(hw, RFPGA0_TXINFO, 0xf));
1139 path2 = (u8)(rtl92s_phy_query_bb_reg(hw, ROFDM0_TRXPATHENABLE, 0xf));
1140 pathmap = path1 | path2;
1142 rtlphy->rf_pathmap = pathmap;
1143 for (index = 0; index < 4; index++) {
1144 if ((pathmap >> index) & 0x1)
1148 if ((rtlphy->rf_type == RF_1T1R && rf_num != 1) ||
1149 (rtlphy->rf_type == RF_1T2R && rf_num != 2) ||
1150 (rtlphy->rf_type == RF_2T2R && rf_num != 2) ||
1151 (rtlphy->rf_type == RF_2T2R_GREEN && rf_num != 2)) {
1152 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
1153 "RF_Type(%x) does not match RF_Num(%x)!!\n",
1154 rtlphy->rf_type, rf_num);
1155 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
1156 "path1 0x%x, path2 0x%x, pathmap 0x%x\n",
1157 path1, path2, pathmap);
1163 bool rtl92s_phy_rf_config(struct ieee80211_hw *hw)
1165 struct rtl_priv *rtlpriv = rtl_priv(hw);
1166 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1168 /* Initialize general global value */
1169 if (rtlphy->rf_type == RF_1T1R)
1170 rtlphy->num_total_rfpath = 1;
1172 rtlphy->num_total_rfpath = 2;
1174 /* Config BB and RF */
1175 return rtl92s_phy_rf6052_config(hw);
1178 void rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
1180 struct rtl_priv *rtlpriv = rtl_priv(hw);
1181 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1183 /* read rx initial gain */
1184 rtlphy->default_initialgain[0] = rtl_get_bbreg(hw,
1185 ROFDM0_XAAGCCORE1, MASKBYTE0);
1186 rtlphy->default_initialgain[1] = rtl_get_bbreg(hw,
1187 ROFDM0_XBAGCCORE1, MASKBYTE0);
1188 rtlphy->default_initialgain[2] = rtl_get_bbreg(hw,
1189 ROFDM0_XCAGCCORE1, MASKBYTE0);
1190 rtlphy->default_initialgain[3] = rtl_get_bbreg(hw,
1191 ROFDM0_XDAGCCORE1, MASKBYTE0);
1192 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1193 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n",
1194 rtlphy->default_initialgain[0],
1195 rtlphy->default_initialgain[1],
1196 rtlphy->default_initialgain[2],
1197 rtlphy->default_initialgain[3]);
1199 /* read framesync */
1200 rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0);
1201 rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
1203 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1204 "Default framesync (0x%x) = 0x%x\n",
1205 ROFDM0_RXDETECTOR3, rtlphy->framesync);
1209 static void _rtl92s_phy_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
1210 u8 *cckpowerlevel, u8 *ofdmpowerLevel)
1212 struct rtl_priv *rtlpriv = rtl_priv(hw);
1213 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1214 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1215 u8 index = (channel - 1);
1219 cckpowerlevel[0] = rtlefuse->txpwrlevel_cck[0][index];
1221 cckpowerlevel[1] = rtlefuse->txpwrlevel_cck[1][index];
1223 /* 2. OFDM for 1T or 2T */
1224 if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_1T1R) {
1225 /* Read HT 40 OFDM TX power */
1226 ofdmpowerLevel[0] = rtlefuse->txpwrlevel_ht40_1s[0][index];
1227 ofdmpowerLevel[1] = rtlefuse->txpwrlevel_ht40_1s[1][index];
1228 } else if (rtlphy->rf_type == RF_2T2R) {
1229 /* Read HT 40 OFDM TX power */
1230 ofdmpowerLevel[0] = rtlefuse->txpwrlevel_ht40_2s[0][index];
1231 ofdmpowerLevel[1] = rtlefuse->txpwrlevel_ht40_2s[1][index];
1233 ofdmpowerLevel[0] = 0;
1234 ofdmpowerLevel[1] = 0;
1238 static void _rtl92s_phy_ccxpower_indexcheck(struct ieee80211_hw *hw,
1239 u8 channel, u8 *cckpowerlevel, u8 *ofdmpowerlevel)
1241 struct rtl_priv *rtlpriv = rtl_priv(hw);
1242 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1244 rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
1245 rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
1248 void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8 channel)
1250 struct rtl_priv *rtlpriv = rtl_priv(hw);
1251 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1252 /* [0]:RF-A, [1]:RF-B */
1253 u8 cckpowerlevel[2], ofdmpowerLevel[2];
1255 if (!rtlefuse->txpwr_fromeprom)
1258 /* Mainly we use RF-A Tx Power to write the Tx Power registers,
1259 * but the RF-B Tx Power must be calculated by the antenna diff.
1260 * So we have to rewrite Antenna gain offset register here.
1261 * Please refer to BB register 0x80c
1263 * 2. For OFDM 1T or 2T */
1264 _rtl92s_phy_get_txpower_index(hw, channel, &cckpowerlevel[0],
1265 &ofdmpowerLevel[0]);
1267 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1268 "Channel-%d, cckPowerLevel (A / B) = 0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n",
1269 channel, cckpowerlevel[0], cckpowerlevel[1],
1270 ofdmpowerLevel[0], ofdmpowerLevel[1]);
1272 _rtl92s_phy_ccxpower_indexcheck(hw, channel, &cckpowerlevel[0],
1273 &ofdmpowerLevel[0]);
1275 rtl92s_phy_rf6052_set_ccktxpower(hw, cckpowerlevel[0]);
1276 rtl92s_phy_rf6052_set_ofdmtxpower(hw, &ofdmpowerLevel[0], channel);
1280 void rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw)
1282 struct rtl_priv *rtlpriv = rtl_priv(hw);
1283 u16 pollingcnt = 10000;
1286 /* Make sure that CMD IO has be accepted by FW. */
1290 tmpvalue = rtl_read_dword(rtlpriv, WFM5);
1293 } while (--pollingcnt);
1295 if (pollingcnt == 0)
1296 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Set FW Cmd fail!!\n");
1300 static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw)
1302 struct rtl_priv *rtlpriv = rtl_priv(hw);
1303 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1304 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1305 u32 input, current_aid = 0;
1307 if (is_hal_stop(rtlhal))
1310 /* We re-map RA related CMD IO to combinational ones */
1311 /* if FW version is v.52 or later. */
1312 switch (rtlhal->current_fwcmd_io) {
1313 case FW_CMD_RA_REFRESH_N:
1314 rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_N_COMB;
1316 case FW_CMD_RA_REFRESH_BG:
1317 rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_BG_COMB;
1323 switch (rtlhal->current_fwcmd_io) {
1324 case FW_CMD_RA_RESET:
1325 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_RESET\n");
1326 rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET);
1327 rtl92s_phy_chk_fwcmd_iodone(hw);
1329 case FW_CMD_RA_ACTIVE:
1330 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_ACTIVE\n");
1331 rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE);
1332 rtl92s_phy_chk_fwcmd_iodone(hw);
1334 case FW_CMD_RA_REFRESH_N:
1335 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_REFRESH_N\n");
1336 input = FW_RA_REFRESH;
1337 rtl_write_dword(rtlpriv, WFM5, input);
1338 rtl92s_phy_chk_fwcmd_iodone(hw);
1339 rtl_write_dword(rtlpriv, WFM5, FW_RA_ENABLE_RSSI_MASK);
1340 rtl92s_phy_chk_fwcmd_iodone(hw);
1342 case FW_CMD_RA_REFRESH_BG:
1343 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1344 "FW_CMD_RA_REFRESH_BG\n");
1345 rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH);
1346 rtl92s_phy_chk_fwcmd_iodone(hw);
1347 rtl_write_dword(rtlpriv, WFM5, FW_RA_DISABLE_RSSI_MASK);
1348 rtl92s_phy_chk_fwcmd_iodone(hw);
1350 case FW_CMD_RA_REFRESH_N_COMB:
1351 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1352 "FW_CMD_RA_REFRESH_N_COMB\n");
1353 input = FW_RA_IOT_N_COMB;
1354 rtl_write_dword(rtlpriv, WFM5, input);
1355 rtl92s_phy_chk_fwcmd_iodone(hw);
1357 case FW_CMD_RA_REFRESH_BG_COMB:
1358 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1359 "FW_CMD_RA_REFRESH_BG_COMB\n");
1360 input = FW_RA_IOT_BG_COMB;
1361 rtl_write_dword(rtlpriv, WFM5, input);
1362 rtl92s_phy_chk_fwcmd_iodone(hw);
1364 case FW_CMD_IQK_ENABLE:
1365 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_IQK_ENABLE\n");
1366 rtl_write_dword(rtlpriv, WFM5, FW_IQK_ENABLE);
1367 rtl92s_phy_chk_fwcmd_iodone(hw);
1369 case FW_CMD_PAUSE_DM_BY_SCAN:
1370 /* Lower initial gain */
1371 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17);
1372 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17);
1374 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40);
1376 case FW_CMD_RESUME_DM_BY_SCAN:
1378 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
1379 rtl92s_phy_set_txpower(hw, rtlphy->current_channel);
1381 case FW_CMD_HIGH_PWR_DISABLE:
1382 if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE)
1385 /* Lower initial gain */
1386 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17);
1387 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17);
1389 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40);
1391 case FW_CMD_HIGH_PWR_ENABLE:
1392 if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) ||
1393 rtlpriv->dm.dynamic_txpower_enable)
1397 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
1399 case FW_CMD_LPS_ENTER:
1400 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_ENTER\n");
1401 current_aid = rtlpriv->mac80211.assoc_id;
1402 rtl_write_dword(rtlpriv, WFM5, (FW_LPS_ENTER |
1403 ((current_aid | 0xc000) << 8)));
1404 rtl92s_phy_chk_fwcmd_iodone(hw);
1405 /* FW set TXOP disable here, so disable EDCA
1406 * turbo mode until driver leave LPS */
1408 case FW_CMD_LPS_LEAVE:
1409 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_LEAVE\n");
1410 rtl_write_dword(rtlpriv, WFM5, FW_LPS_LEAVE);
1411 rtl92s_phy_chk_fwcmd_iodone(hw);
1413 case FW_CMD_ADD_A2_ENTRY:
1414 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_ADD_A2_ENTRY\n");
1415 rtl_write_dword(rtlpriv, WFM5, FW_ADD_A2_ENTRY);
1416 rtl92s_phy_chk_fwcmd_iodone(hw);
1418 case FW_CMD_CTRL_DM_BY_DRIVER:
1419 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1420 "FW_CMD_CTRL_DM_BY_DRIVER\n");
1421 rtl_write_dword(rtlpriv, WFM5, FW_CTRL_DM_BY_DRIVER);
1422 rtl92s_phy_chk_fwcmd_iodone(hw);
1429 rtl92s_phy_chk_fwcmd_iodone(hw);
1431 /* Clear FW CMD operation flag. */
1432 rtlhal->set_fwcmd_inprogress = false;
1435 bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
1437 struct rtl_priv *rtlpriv = rtl_priv(hw);
1438 struct dig_t *digtable = &rtlpriv->dm_digtable;
1439 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1440 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1441 u32 fw_param = FW_CMD_IO_PARA_QUERY(rtlpriv);
1442 u16 fw_cmdmap = FW_CMD_IO_QUERY(rtlpriv);
1443 bool bPostProcessing = false;
1445 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1446 "Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n",
1447 fw_cmdio, rtlhal->set_fwcmd_inprogress);
1450 /* We re-map to combined FW CMD ones if firmware version */
1451 /* is v.53 or later. */
1453 case FW_CMD_RA_REFRESH_N:
1454 fw_cmdio = FW_CMD_RA_REFRESH_N_COMB;
1456 case FW_CMD_RA_REFRESH_BG:
1457 fw_cmdio = FW_CMD_RA_REFRESH_BG_COMB;
1463 /* If firmware version is v.62 or later,
1464 * use FW_CMD_IO_SET for FW_CMD_CTRL_DM_BY_DRIVER */
1465 if (hal_get_firmwareversion(rtlpriv) >= 0x3E) {
1466 if (fw_cmdio == FW_CMD_CTRL_DM_BY_DRIVER)
1467 fw_cmdio = FW_CMD_CTRL_DM_BY_DRIVER_NEW;
1471 /* We shall revise all FW Cmd IO into Reg0x364
1472 * DM map table in the future. */
1474 case FW_CMD_RA_INIT:
1475 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "RA init!!\n");
1476 fw_cmdmap |= FW_RA_INIT_CTL;
1477 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1478 /* Clear control flag to sync with FW. */
1479 FW_CMD_IO_CLR(rtlpriv, FW_RA_INIT_CTL);
1481 case FW_CMD_DIG_DISABLE:
1482 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1483 "Set DIG disable!!\n");
1484 fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1485 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1487 case FW_CMD_DIG_ENABLE:
1488 case FW_CMD_DIG_RESUME:
1489 if (!(rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE)) {
1490 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1491 "Set DIG enable or resume!!\n");
1492 fw_cmdmap |= (FW_DIG_ENABLE_CTL | FW_SS_CTL);
1493 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1496 case FW_CMD_DIG_HALT:
1497 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1498 "Set DIG halt!!\n");
1499 fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | FW_SS_CTL);
1500 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1502 case FW_CMD_TXPWR_TRACK_THERMAL: {
1504 fw_cmdmap |= FW_PWR_TRK_CTL;
1506 /* Clear FW parameter in terms of thermal parts. */
1507 fw_param &= FW_PWR_TRK_PARAM_CLR;
1509 thermalval = rtlpriv->dm.thermalvalue;
1510 fw_param |= ((thermalval << 24) |
1511 (rtlefuse->thermalmeter[0] << 16));
1513 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1514 "Set TxPwr tracking!! FwCmdMap(%#x), FwParam(%#x)\n",
1515 fw_cmdmap, fw_param);
1517 FW_CMD_PARA_SET(rtlpriv, fw_param);
1518 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1520 /* Clear control flag to sync with FW. */
1521 FW_CMD_IO_CLR(rtlpriv, FW_PWR_TRK_CTL);
1524 /* The following FW CMDs are only compatible to
1526 case FW_CMD_RA_REFRESH_N_COMB:
1527 fw_cmdmap |= FW_RA_N_CTL;
1529 /* Clear RA BG mode control. */
1530 fw_cmdmap &= ~(FW_RA_BG_CTL | FW_RA_INIT_CTL);
1532 /* Clear FW parameter in terms of RA parts. */
1533 fw_param &= FW_RA_PARAM_CLR;
1535 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1536 "[FW CMD] [New Version] Set RA/IOT Comb in n mode!! FwCmdMap(%#x), FwParam(%#x)\n",
1537 fw_cmdmap, fw_param);
1539 FW_CMD_PARA_SET(rtlpriv, fw_param);
1540 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1542 /* Clear control flag to sync with FW. */
1543 FW_CMD_IO_CLR(rtlpriv, FW_RA_N_CTL);
1545 case FW_CMD_RA_REFRESH_BG_COMB:
1546 fw_cmdmap |= FW_RA_BG_CTL;
1548 /* Clear RA n-mode control. */
1549 fw_cmdmap &= ~(FW_RA_N_CTL | FW_RA_INIT_CTL);
1550 /* Clear FW parameter in terms of RA parts. */
1551 fw_param &= FW_RA_PARAM_CLR;
1553 FW_CMD_PARA_SET(rtlpriv, fw_param);
1554 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1556 /* Clear control flag to sync with FW. */
1557 FW_CMD_IO_CLR(rtlpriv, FW_RA_BG_CTL);
1559 case FW_CMD_IQK_ENABLE:
1560 fw_cmdmap |= FW_IQK_CTL;
1561 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1562 /* Clear control flag to sync with FW. */
1563 FW_CMD_IO_CLR(rtlpriv, FW_IQK_CTL);
1565 /* The following FW CMD is compatible to v.62 or later. */
1566 case FW_CMD_CTRL_DM_BY_DRIVER_NEW:
1567 fw_cmdmap |= FW_DRIVER_CTRL_DM_CTL;
1568 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1570 /* The followed FW Cmds needs post-processing later. */
1571 case FW_CMD_RESUME_DM_BY_SCAN:
1572 fw_cmdmap |= (FW_DIG_ENABLE_CTL |
1573 FW_HIGH_PWR_ENABLE_CTL |
1576 if (rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE ||
1577 !digtable->dig_enable_flag)
1578 fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1580 if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) ||
1581 rtlpriv->dm.dynamic_txpower_enable)
1582 fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL;
1584 if ((digtable->dig_ext_port_stage ==
1585 DIG_EXT_PORT_STAGE_0) ||
1586 (digtable->dig_ext_port_stage ==
1587 DIG_EXT_PORT_STAGE_1))
1588 fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1590 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1591 bPostProcessing = true;
1593 case FW_CMD_PAUSE_DM_BY_SCAN:
1594 fw_cmdmap &= ~(FW_DIG_ENABLE_CTL |
1595 FW_HIGH_PWR_ENABLE_CTL |
1597 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1598 bPostProcessing = true;
1600 case FW_CMD_HIGH_PWR_DISABLE:
1601 fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL;
1602 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1603 bPostProcessing = true;
1605 case FW_CMD_HIGH_PWR_ENABLE:
1606 if (!(rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) &&
1607 !rtlpriv->dm.dynamic_txpower_enable) {
1608 fw_cmdmap |= (FW_HIGH_PWR_ENABLE_CTL |
1610 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1611 bPostProcessing = true;
1614 case FW_CMD_DIG_MODE_FA:
1615 fw_cmdmap |= FW_FA_CTL;
1616 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1618 case FW_CMD_DIG_MODE_SS:
1619 fw_cmdmap &= ~FW_FA_CTL;
1620 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1622 case FW_CMD_PAPE_CONTROL:
1623 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1624 "[FW CMD] Set PAPE Control\n");
1625 fw_cmdmap &= ~FW_PAPE_CTL_BY_SW_HW;
1627 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1630 /* Pass to original FW CMD processing callback
1632 bPostProcessing = true;
1637 /* We shall post processing these FW CMD if
1638 * variable bPostProcessing is set. */
1639 if (bPostProcessing && !rtlhal->set_fwcmd_inprogress) {
1640 rtlhal->set_fwcmd_inprogress = true;
1641 /* Update current FW Cmd for callback use. */
1642 rtlhal->current_fwcmd_io = fw_cmdio;
1647 _rtl92s_phy_set_fwcmd_io(hw);
1651 static void _rtl92s_phy_check_ephy_switchready(struct ieee80211_hw *hw)
1653 struct rtl_priv *rtlpriv = rtl_priv(hw);
1657 regu1 = rtl_read_byte(rtlpriv, 0x554);
1658 while ((regu1 & BIT(5)) && (delay > 0)) {
1659 regu1 = rtl_read_byte(rtlpriv, 0x554);
1661 /* We delay only 50us to prevent
1662 * being scheduled out. */
1667 void rtl92s_phy_switch_ephy_parameter(struct ieee80211_hw *hw)
1669 struct rtl_priv *rtlpriv = rtl_priv(hw);
1670 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1672 /* The way to be capable to switch clock request
1673 * when the PG setting does not support clock request.
1674 * This is the backdoor solution to switch clock
1675 * request before ASPM or D3. */
1676 rtl_write_dword(rtlpriv, 0x540, 0x73c11);
1677 rtl_write_dword(rtlpriv, 0x548, 0x2407c);
1679 /* Switch EPHY parameter!!!! */
1680 rtl_write_word(rtlpriv, 0x550, 0x1000);
1681 rtl_write_byte(rtlpriv, 0x554, 0x20);
1682 _rtl92s_phy_check_ephy_switchready(hw);
1684 rtl_write_word(rtlpriv, 0x550, 0xa0eb);
1685 rtl_write_byte(rtlpriv, 0x554, 0x3e);
1686 _rtl92s_phy_check_ephy_switchready(hw);
1688 rtl_write_word(rtlpriv, 0x550, 0xff80);
1689 rtl_write_byte(rtlpriv, 0x554, 0x39);
1690 _rtl92s_phy_check_ephy_switchready(hw);
1692 /* Delay L1 enter time */
1693 if (ppsc->support_aspm && !ppsc->support_backdoor)
1694 rtl_write_byte(rtlpriv, 0x560, 0x40);
1696 rtl_write_byte(rtlpriv, 0x560, 0x00);
1700 void rtl92s_phy_set_beacon_hwreg(struct ieee80211_hw *hw, u16 BeaconInterval)
1702 struct rtl_priv *rtlpriv = rtl_priv(hw);
1703 rtl_write_dword(rtlpriv, WFM5, 0xF1000000 | (BeaconInterval << 8));