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