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 if (hal_get_firmwareversion(rtlpriv) < 0x34)
1312 /* We re-map RA related CMD IO to combinational ones */
1313 /* if FW version is v.52 or later. */
1314 switch (rtlhal->current_fwcmd_io) {
1315 case FW_CMD_RA_REFRESH_N:
1316 rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_N_COMB;
1318 case FW_CMD_RA_REFRESH_BG:
1319 rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_BG_COMB;
1326 switch (rtlhal->current_fwcmd_io) {
1327 case FW_CMD_RA_RESET:
1328 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_RESET\n");
1329 rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET);
1330 rtl92s_phy_chk_fwcmd_iodone(hw);
1332 case FW_CMD_RA_ACTIVE:
1333 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_ACTIVE\n");
1334 rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE);
1335 rtl92s_phy_chk_fwcmd_iodone(hw);
1337 case FW_CMD_RA_REFRESH_N:
1338 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_REFRESH_N\n");
1339 input = FW_RA_REFRESH;
1340 rtl_write_dword(rtlpriv, WFM5, input);
1341 rtl92s_phy_chk_fwcmd_iodone(hw);
1342 rtl_write_dword(rtlpriv, WFM5, FW_RA_ENABLE_RSSI_MASK);
1343 rtl92s_phy_chk_fwcmd_iodone(hw);
1345 case FW_CMD_RA_REFRESH_BG:
1346 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1347 "FW_CMD_RA_REFRESH_BG\n");
1348 rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH);
1349 rtl92s_phy_chk_fwcmd_iodone(hw);
1350 rtl_write_dword(rtlpriv, WFM5, FW_RA_DISABLE_RSSI_MASK);
1351 rtl92s_phy_chk_fwcmd_iodone(hw);
1353 case FW_CMD_RA_REFRESH_N_COMB:
1354 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1355 "FW_CMD_RA_REFRESH_N_COMB\n");
1356 input = FW_RA_IOT_N_COMB;
1357 rtl_write_dword(rtlpriv, WFM5, input);
1358 rtl92s_phy_chk_fwcmd_iodone(hw);
1360 case FW_CMD_RA_REFRESH_BG_COMB:
1361 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
1362 "FW_CMD_RA_REFRESH_BG_COMB\n");
1363 input = FW_RA_IOT_BG_COMB;
1364 rtl_write_dword(rtlpriv, WFM5, input);
1365 rtl92s_phy_chk_fwcmd_iodone(hw);
1367 case FW_CMD_IQK_ENABLE:
1368 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_IQK_ENABLE\n");
1369 rtl_write_dword(rtlpriv, WFM5, FW_IQK_ENABLE);
1370 rtl92s_phy_chk_fwcmd_iodone(hw);
1372 case FW_CMD_PAUSE_DM_BY_SCAN:
1373 /* Lower initial gain */
1374 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17);
1375 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17);
1377 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40);
1379 case FW_CMD_RESUME_DM_BY_SCAN:
1381 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
1382 rtl92s_phy_set_txpower(hw, rtlphy->current_channel);
1384 case FW_CMD_HIGH_PWR_DISABLE:
1385 if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE)
1388 /* Lower initial gain */
1389 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17);
1390 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17);
1392 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40);
1394 case FW_CMD_HIGH_PWR_ENABLE:
1395 if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) ||
1396 rtlpriv->dm.dynamic_txpower_enable)
1400 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
1402 case FW_CMD_LPS_ENTER:
1403 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_ENTER\n");
1404 current_aid = rtlpriv->mac80211.assoc_id;
1405 rtl_write_dword(rtlpriv, WFM5, (FW_LPS_ENTER |
1406 ((current_aid | 0xc000) << 8)));
1407 rtl92s_phy_chk_fwcmd_iodone(hw);
1408 /* FW set TXOP disable here, so disable EDCA
1409 * turbo mode until driver leave LPS */
1411 case FW_CMD_LPS_LEAVE:
1412 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_LEAVE\n");
1413 rtl_write_dword(rtlpriv, WFM5, FW_LPS_LEAVE);
1414 rtl92s_phy_chk_fwcmd_iodone(hw);
1416 case FW_CMD_ADD_A2_ENTRY:
1417 RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_ADD_A2_ENTRY\n");
1418 rtl_write_dword(rtlpriv, WFM5, FW_ADD_A2_ENTRY);
1419 rtl92s_phy_chk_fwcmd_iodone(hw);
1421 case FW_CMD_CTRL_DM_BY_DRIVER:
1422 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1423 "FW_CMD_CTRL_DM_BY_DRIVER\n");
1424 rtl_write_dword(rtlpriv, WFM5, FW_CTRL_DM_BY_DRIVER);
1425 rtl92s_phy_chk_fwcmd_iodone(hw);
1432 rtl92s_phy_chk_fwcmd_iodone(hw);
1434 /* Clear FW CMD operation flag. */
1435 rtlhal->set_fwcmd_inprogress = false;
1438 bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
1440 struct rtl_priv *rtlpriv = rtl_priv(hw);
1441 struct dig_t *digtable = &rtlpriv->dm_digtable;
1442 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1443 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1444 u32 fw_param = FW_CMD_IO_PARA_QUERY(rtlpriv);
1445 u16 fw_cmdmap = FW_CMD_IO_QUERY(rtlpriv);
1446 bool postprocessing = false;
1448 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1449 "Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n",
1450 fw_cmdio, rtlhal->set_fwcmd_inprogress);
1453 /* We re-map to combined FW CMD ones if firmware version */
1454 /* is v.53 or later. */
1455 if (hal_get_firmwareversion(rtlpriv) >= 0x35) {
1457 case FW_CMD_RA_REFRESH_N:
1458 fw_cmdio = FW_CMD_RA_REFRESH_N_COMB;
1460 case FW_CMD_RA_REFRESH_BG:
1461 fw_cmdio = FW_CMD_RA_REFRESH_BG_COMB;
1467 if ((fw_cmdio == FW_CMD_IQK_ENABLE) ||
1468 (fw_cmdio == FW_CMD_RA_REFRESH_N) ||
1469 (fw_cmdio == FW_CMD_RA_REFRESH_BG)) {
1470 postprocessing = true;
1475 /* If firmware version is v.62 or later,
1476 * use FW_CMD_IO_SET for FW_CMD_CTRL_DM_BY_DRIVER */
1477 if (hal_get_firmwareversion(rtlpriv) >= 0x3E) {
1478 if (fw_cmdio == FW_CMD_CTRL_DM_BY_DRIVER)
1479 fw_cmdio = FW_CMD_CTRL_DM_BY_DRIVER_NEW;
1483 /* We shall revise all FW Cmd IO into Reg0x364
1484 * DM map table in the future. */
1486 case FW_CMD_RA_INIT:
1487 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "RA init!!\n");
1488 fw_cmdmap |= FW_RA_INIT_CTL;
1489 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1490 /* Clear control flag to sync with FW. */
1491 FW_CMD_IO_CLR(rtlpriv, FW_RA_INIT_CTL);
1493 case FW_CMD_DIG_DISABLE:
1494 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1495 "Set DIG disable!!\n");
1496 fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1497 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1499 case FW_CMD_DIG_ENABLE:
1500 case FW_CMD_DIG_RESUME:
1501 if (!(rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE)) {
1502 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1503 "Set DIG enable or resume!!\n");
1504 fw_cmdmap |= (FW_DIG_ENABLE_CTL | FW_SS_CTL);
1505 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1508 case FW_CMD_DIG_HALT:
1509 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1510 "Set DIG halt!!\n");
1511 fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | FW_SS_CTL);
1512 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1514 case FW_CMD_TXPWR_TRACK_THERMAL: {
1516 fw_cmdmap |= FW_PWR_TRK_CTL;
1518 /* Clear FW parameter in terms of thermal parts. */
1519 fw_param &= FW_PWR_TRK_PARAM_CLR;
1521 thermalval = rtlpriv->dm.thermalvalue;
1522 fw_param |= ((thermalval << 24) |
1523 (rtlefuse->thermalmeter[0] << 16));
1525 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1526 "Set TxPwr tracking!! FwCmdMap(%#x), FwParam(%#x)\n",
1527 fw_cmdmap, fw_param);
1529 FW_CMD_PARA_SET(rtlpriv, fw_param);
1530 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1532 /* Clear control flag to sync with FW. */
1533 FW_CMD_IO_CLR(rtlpriv, FW_PWR_TRK_CTL);
1536 /* The following FW CMDs are only compatible to
1538 case FW_CMD_RA_REFRESH_N_COMB:
1539 fw_cmdmap |= FW_RA_N_CTL;
1541 /* Clear RA BG mode control. */
1542 fw_cmdmap &= ~(FW_RA_BG_CTL | FW_RA_INIT_CTL);
1544 /* Clear FW parameter in terms of RA parts. */
1545 fw_param &= FW_RA_PARAM_CLR;
1547 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1548 "[FW CMD] [New Version] Set RA/IOT Comb in n mode!! FwCmdMap(%#x), FwParam(%#x)\n",
1549 fw_cmdmap, fw_param);
1551 FW_CMD_PARA_SET(rtlpriv, fw_param);
1552 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1554 /* Clear control flag to sync with FW. */
1555 FW_CMD_IO_CLR(rtlpriv, FW_RA_N_CTL);
1557 case FW_CMD_RA_REFRESH_BG_COMB:
1558 fw_cmdmap |= FW_RA_BG_CTL;
1560 /* Clear RA n-mode control. */
1561 fw_cmdmap &= ~(FW_RA_N_CTL | FW_RA_INIT_CTL);
1562 /* Clear FW parameter in terms of RA parts. */
1563 fw_param &= FW_RA_PARAM_CLR;
1565 FW_CMD_PARA_SET(rtlpriv, fw_param);
1566 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1568 /* Clear control flag to sync with FW. */
1569 FW_CMD_IO_CLR(rtlpriv, FW_RA_BG_CTL);
1571 case FW_CMD_IQK_ENABLE:
1572 fw_cmdmap |= FW_IQK_CTL;
1573 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1574 /* Clear control flag to sync with FW. */
1575 FW_CMD_IO_CLR(rtlpriv, FW_IQK_CTL);
1577 /* The following FW CMD is compatible to v.62 or later. */
1578 case FW_CMD_CTRL_DM_BY_DRIVER_NEW:
1579 fw_cmdmap |= FW_DRIVER_CTRL_DM_CTL;
1580 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1582 /* The followed FW Cmds needs post-processing later. */
1583 case FW_CMD_RESUME_DM_BY_SCAN:
1584 fw_cmdmap |= (FW_DIG_ENABLE_CTL |
1585 FW_HIGH_PWR_ENABLE_CTL |
1588 if (rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE ||
1589 !digtable->dig_enable_flag)
1590 fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1592 if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) ||
1593 rtlpriv->dm.dynamic_txpower_enable)
1594 fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL;
1596 if ((digtable->dig_ext_port_stage ==
1597 DIG_EXT_PORT_STAGE_0) ||
1598 (digtable->dig_ext_port_stage ==
1599 DIG_EXT_PORT_STAGE_1))
1600 fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
1602 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1603 postprocessing = true;
1605 case FW_CMD_PAUSE_DM_BY_SCAN:
1606 fw_cmdmap &= ~(FW_DIG_ENABLE_CTL |
1607 FW_HIGH_PWR_ENABLE_CTL |
1609 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1610 postprocessing = true;
1612 case FW_CMD_HIGH_PWR_DISABLE:
1613 fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL;
1614 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1615 postprocessing = true;
1617 case FW_CMD_HIGH_PWR_ENABLE:
1618 if (!(rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) &&
1619 !rtlpriv->dm.dynamic_txpower_enable) {
1620 fw_cmdmap |= (FW_HIGH_PWR_ENABLE_CTL |
1622 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1623 postprocessing = true;
1626 case FW_CMD_DIG_MODE_FA:
1627 fw_cmdmap |= FW_FA_CTL;
1628 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1630 case FW_CMD_DIG_MODE_SS:
1631 fw_cmdmap &= ~FW_FA_CTL;
1632 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1634 case FW_CMD_PAPE_CONTROL:
1635 RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
1636 "[FW CMD] Set PAPE Control\n");
1637 fw_cmdmap &= ~FW_PAPE_CTL_BY_SW_HW;
1639 FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
1642 /* Pass to original FW CMD processing callback
1644 postprocessing = true;
1649 /* We shall post processing these FW CMD if
1650 * variable postprocessing is set.
1652 if (postprocessing && !rtlhal->set_fwcmd_inprogress) {
1653 rtlhal->set_fwcmd_inprogress = true;
1654 /* Update current FW Cmd for callback use. */
1655 rtlhal->current_fwcmd_io = fw_cmdio;
1660 _rtl92s_phy_set_fwcmd_io(hw);
1664 static void _rtl92s_phy_check_ephy_switchready(struct ieee80211_hw *hw)
1666 struct rtl_priv *rtlpriv = rtl_priv(hw);
1670 regu1 = rtl_read_byte(rtlpriv, 0x554);
1671 while ((regu1 & BIT(5)) && (delay > 0)) {
1672 regu1 = rtl_read_byte(rtlpriv, 0x554);
1674 /* We delay only 50us to prevent
1675 * being scheduled out. */
1680 void rtl92s_phy_switch_ephy_parameter(struct ieee80211_hw *hw)
1682 struct rtl_priv *rtlpriv = rtl_priv(hw);
1683 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1685 /* The way to be capable to switch clock request
1686 * when the PG setting does not support clock request.
1687 * This is the backdoor solution to switch clock
1688 * request before ASPM or D3. */
1689 rtl_write_dword(rtlpriv, 0x540, 0x73c11);
1690 rtl_write_dword(rtlpriv, 0x548, 0x2407c);
1692 /* Switch EPHY parameter!!!! */
1693 rtl_write_word(rtlpriv, 0x550, 0x1000);
1694 rtl_write_byte(rtlpriv, 0x554, 0x20);
1695 _rtl92s_phy_check_ephy_switchready(hw);
1697 rtl_write_word(rtlpriv, 0x550, 0xa0eb);
1698 rtl_write_byte(rtlpriv, 0x554, 0x3e);
1699 _rtl92s_phy_check_ephy_switchready(hw);
1701 rtl_write_word(rtlpriv, 0x550, 0xff80);
1702 rtl_write_byte(rtlpriv, 0x554, 0x39);
1703 _rtl92s_phy_check_ephy_switchready(hw);
1705 /* Delay L1 enter time */
1706 if (ppsc->support_aspm && !ppsc->support_backdoor)
1707 rtl_write_byte(rtlpriv, 0x560, 0x40);
1709 rtl_write_byte(rtlpriv, 0x560, 0x00);
1713 void rtl92s_phy_set_beacon_hwreg(struct ieee80211_hw *hw, u16 beaconinterval)
1715 struct rtl_priv *rtlpriv = rtl_priv(hw);
1716 u32 new_bcn_num = 0;
1718 if (hal_get_firmwareversion(rtlpriv) >= 0x33) {
1719 /* Fw v.51 and later. */
1720 rtl_write_dword(rtlpriv, WFM5, 0xF1000000 |
1721 (beaconinterval << 8));
1723 new_bcn_num = beaconinterval * 32 - 64;
1724 rtl_write_dword(rtlpriv, WFM3 + 4, new_bcn_num);
1725 rtl_write_dword(rtlpriv, WFM3, 0xB026007C);