18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/* Copyright(c) 2009-2013  Realtek Corporation.*/
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci#include "../wifi.h"
58c2ecf20Sopenharmony_ci#include "../efuse.h"
68c2ecf20Sopenharmony_ci#include "../base.h"
78c2ecf20Sopenharmony_ci#include "../regd.h"
88c2ecf20Sopenharmony_ci#include "../cam.h"
98c2ecf20Sopenharmony_ci#include "../ps.h"
108c2ecf20Sopenharmony_ci#include "../pci.h"
118c2ecf20Sopenharmony_ci#include "../pwrseqcmd.h"
128c2ecf20Sopenharmony_ci#include "reg.h"
138c2ecf20Sopenharmony_ci#include "def.h"
148c2ecf20Sopenharmony_ci#include "phy.h"
158c2ecf20Sopenharmony_ci#include "dm.h"
168c2ecf20Sopenharmony_ci#include "fw.h"
178c2ecf20Sopenharmony_ci#include "led.h"
188c2ecf20Sopenharmony_ci#include "hw.h"
198c2ecf20Sopenharmony_ci#include "pwrseq.h"
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci#define LLT_CONFIG		5
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_cistatic void _rtl88ee_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
248c2ecf20Sopenharmony_ci				      u8 set_bits, u8 clear_bits)
258c2ecf20Sopenharmony_ci{
268c2ecf20Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
278c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci	rtlpci->reg_bcn_ctrl_val |= set_bits;
308c2ecf20Sopenharmony_ci	rtlpci->reg_bcn_ctrl_val &= ~clear_bits;
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val);
338c2ecf20Sopenharmony_ci}
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_cistatic void _rtl88ee_stop_tx_beacon(struct ieee80211_hw *hw)
368c2ecf20Sopenharmony_ci{
378c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
388c2ecf20Sopenharmony_ci	u8 tmp1byte;
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci	tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
418c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6)));
428c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64);
438c2ecf20Sopenharmony_ci	tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
448c2ecf20Sopenharmony_ci	tmp1byte &= ~(BIT(0));
458c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
468c2ecf20Sopenharmony_ci}
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_cistatic void _rtl88ee_resume_tx_beacon(struct ieee80211_hw *hw)
498c2ecf20Sopenharmony_ci{
508c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
518c2ecf20Sopenharmony_ci	u8 tmp1byte;
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci	tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
548c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6));
558c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
568c2ecf20Sopenharmony_ci	tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
578c2ecf20Sopenharmony_ci	tmp1byte |= BIT(0);
588c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
598c2ecf20Sopenharmony_ci}
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_cistatic void _rtl88ee_enable_bcn_sub_func(struct ieee80211_hw *hw)
628c2ecf20Sopenharmony_ci{
638c2ecf20Sopenharmony_ci	_rtl88ee_set_bcn_ctrl_reg(hw, 0, BIT(1));
648c2ecf20Sopenharmony_ci}
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_cistatic void _rtl88ee_return_beacon_queue_skb(struct ieee80211_hw *hw)
678c2ecf20Sopenharmony_ci{
688c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
698c2ecf20Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
708c2ecf20Sopenharmony_ci	struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
718c2ecf20Sopenharmony_ci	struct sk_buff_head free_list;
728c2ecf20Sopenharmony_ci	unsigned long flags;
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci	skb_queue_head_init(&free_list);
758c2ecf20Sopenharmony_ci	spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
768c2ecf20Sopenharmony_ci	while (skb_queue_len(&ring->queue)) {
778c2ecf20Sopenharmony_ci		struct rtl_tx_desc *entry = &ring->desc[ring->idx];
788c2ecf20Sopenharmony_ci		struct sk_buff *skb = __skb_dequeue(&ring->queue);
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci		dma_unmap_single(&rtlpci->pdev->dev,
818c2ecf20Sopenharmony_ci				 rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry,
828c2ecf20Sopenharmony_ci						true, HW_DESC_TXBUFF_ADDR),
838c2ecf20Sopenharmony_ci				 skb->len, DMA_TO_DEVICE);
848c2ecf20Sopenharmony_ci		__skb_queue_tail(&free_list, skb);
858c2ecf20Sopenharmony_ci		ring->idx = (ring->idx + 1) % ring->entries;
868c2ecf20Sopenharmony_ci	}
878c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci	__skb_queue_purge(&free_list);
908c2ecf20Sopenharmony_ci}
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_cistatic void _rtl88ee_disable_bcn_sub_func(struct ieee80211_hw *hw)
938c2ecf20Sopenharmony_ci{
948c2ecf20Sopenharmony_ci	_rtl88ee_set_bcn_ctrl_reg(hw, BIT(1), 0);
958c2ecf20Sopenharmony_ci}
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_cistatic void _rtl88ee_set_fw_clock_on(struct ieee80211_hw *hw,
988c2ecf20Sopenharmony_ci				     u8 rpwm_val, bool b_need_turn_off_ckk)
998c2ecf20Sopenharmony_ci{
1008c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
1018c2ecf20Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1028c2ecf20Sopenharmony_ci	bool b_support_remote_wake_up;
1038c2ecf20Sopenharmony_ci	u32 count = 0, isr_regaddr, content;
1048c2ecf20Sopenharmony_ci	bool schedule_timer = b_need_turn_off_ckk;
1058c2ecf20Sopenharmony_ci	rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN,
1068c2ecf20Sopenharmony_ci					(u8 *)(&b_support_remote_wake_up));
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci	if (!rtlhal->fw_ready)
1098c2ecf20Sopenharmony_ci		return;
1108c2ecf20Sopenharmony_ci	if (!rtlpriv->psc.fw_current_inpsmode)
1118c2ecf20Sopenharmony_ci		return;
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci	while (1) {
1148c2ecf20Sopenharmony_ci		spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
1158c2ecf20Sopenharmony_ci		if (rtlhal->fw_clk_change_in_progress) {
1168c2ecf20Sopenharmony_ci			while (rtlhal->fw_clk_change_in_progress) {
1178c2ecf20Sopenharmony_ci				spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
1188c2ecf20Sopenharmony_ci				count++;
1198c2ecf20Sopenharmony_ci				udelay(100);
1208c2ecf20Sopenharmony_ci				if (count > 1000)
1218c2ecf20Sopenharmony_ci					return;
1228c2ecf20Sopenharmony_ci				spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
1238c2ecf20Sopenharmony_ci			}
1248c2ecf20Sopenharmony_ci			spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
1258c2ecf20Sopenharmony_ci		} else {
1268c2ecf20Sopenharmony_ci			rtlhal->fw_clk_change_in_progress = false;
1278c2ecf20Sopenharmony_ci			spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
1288c2ecf20Sopenharmony_ci			break;
1298c2ecf20Sopenharmony_ci		}
1308c2ecf20Sopenharmony_ci	}
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci	if (IS_IN_LOW_POWER_STATE_88E(rtlhal->fw_ps_state)) {
1338c2ecf20Sopenharmony_ci		rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);
1348c2ecf20Sopenharmony_ci		if (FW_PS_IS_ACK(rpwm_val)) {
1358c2ecf20Sopenharmony_ci			isr_regaddr = REG_HISR;
1368c2ecf20Sopenharmony_ci			content = rtl_read_dword(rtlpriv, isr_regaddr);
1378c2ecf20Sopenharmony_ci			while (!(content & IMR_CPWM) && (count < 500)) {
1388c2ecf20Sopenharmony_ci				udelay(50);
1398c2ecf20Sopenharmony_ci				count++;
1408c2ecf20Sopenharmony_ci				content = rtl_read_dword(rtlpriv, isr_regaddr);
1418c2ecf20Sopenharmony_ci			}
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci			if (content & IMR_CPWM) {
1448c2ecf20Sopenharmony_ci				rtl_write_word(rtlpriv, isr_regaddr, 0x0100);
1458c2ecf20Sopenharmony_ci				rtlhal->fw_ps_state = FW_PS_STATE_RF_ON_88E;
1468c2ecf20Sopenharmony_ci				rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
1478c2ecf20Sopenharmony_ci					"Receive CPWM INT!!! Set pHalData->FwPSState = %X\n",
1488c2ecf20Sopenharmony_ci					rtlhal->fw_ps_state);
1498c2ecf20Sopenharmony_ci			}
1508c2ecf20Sopenharmony_ci		}
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci		spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
1538c2ecf20Sopenharmony_ci		rtlhal->fw_clk_change_in_progress = false;
1548c2ecf20Sopenharmony_ci		spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
1558c2ecf20Sopenharmony_ci		if (schedule_timer) {
1568c2ecf20Sopenharmony_ci			mod_timer(&rtlpriv->works.fw_clockoff_timer,
1578c2ecf20Sopenharmony_ci				  jiffies + MSECS(10));
1588c2ecf20Sopenharmony_ci		}
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci	} else  {
1618c2ecf20Sopenharmony_ci		spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
1628c2ecf20Sopenharmony_ci		rtlhal->fw_clk_change_in_progress = false;
1638c2ecf20Sopenharmony_ci		spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
1648c2ecf20Sopenharmony_ci	}
1658c2ecf20Sopenharmony_ci}
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_cistatic void _rtl88ee_set_fw_clock_off(struct ieee80211_hw *hw,
1688c2ecf20Sopenharmony_ci				      u8 rpwm_val)
1698c2ecf20Sopenharmony_ci{
1708c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
1718c2ecf20Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1728c2ecf20Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1738c2ecf20Sopenharmony_ci	struct rtl8192_tx_ring *ring;
1748c2ecf20Sopenharmony_ci	enum rf_pwrstate rtstate;
1758c2ecf20Sopenharmony_ci	bool schedule_timer = false;
1768c2ecf20Sopenharmony_ci	u8 queue;
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci	if (!rtlhal->fw_ready)
1798c2ecf20Sopenharmony_ci		return;
1808c2ecf20Sopenharmony_ci	if (!rtlpriv->psc.fw_current_inpsmode)
1818c2ecf20Sopenharmony_ci		return;
1828c2ecf20Sopenharmony_ci	if (!rtlhal->allow_sw_to_change_hwclc)
1838c2ecf20Sopenharmony_ci		return;
1848c2ecf20Sopenharmony_ci	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, (u8 *)(&rtstate));
1858c2ecf20Sopenharmony_ci	if (rtstate == ERFOFF || rtlpriv->psc.inactive_pwrstate == ERFOFF)
1868c2ecf20Sopenharmony_ci		return;
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ci	for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) {
1898c2ecf20Sopenharmony_ci		ring = &rtlpci->tx_ring[queue];
1908c2ecf20Sopenharmony_ci		if (skb_queue_len(&ring->queue)) {
1918c2ecf20Sopenharmony_ci			schedule_timer = true;
1928c2ecf20Sopenharmony_ci			break;
1938c2ecf20Sopenharmony_ci		}
1948c2ecf20Sopenharmony_ci	}
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci	if (schedule_timer) {
1978c2ecf20Sopenharmony_ci		mod_timer(&rtlpriv->works.fw_clockoff_timer,
1988c2ecf20Sopenharmony_ci			  jiffies + MSECS(10));
1998c2ecf20Sopenharmony_ci		return;
2008c2ecf20Sopenharmony_ci	}
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci	if (FW_PS_STATE(rtlhal->fw_ps_state) !=
2038c2ecf20Sopenharmony_ci	    FW_PS_STATE_RF_OFF_LOW_PWR_88E) {
2048c2ecf20Sopenharmony_ci		spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
2058c2ecf20Sopenharmony_ci		if (!rtlhal->fw_clk_change_in_progress) {
2068c2ecf20Sopenharmony_ci			rtlhal->fw_clk_change_in_progress = true;
2078c2ecf20Sopenharmony_ci			spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
2088c2ecf20Sopenharmony_ci			rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val);
2098c2ecf20Sopenharmony_ci			rtl_write_word(rtlpriv, REG_HISR, 0x0100);
2108c2ecf20Sopenharmony_ci			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
2118c2ecf20Sopenharmony_ci						      &rpwm_val);
2128c2ecf20Sopenharmony_ci			spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
2138c2ecf20Sopenharmony_ci			rtlhal->fw_clk_change_in_progress = false;
2148c2ecf20Sopenharmony_ci			spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
2158c2ecf20Sopenharmony_ci		} else {
2168c2ecf20Sopenharmony_ci			spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
2178c2ecf20Sopenharmony_ci			mod_timer(&rtlpriv->works.fw_clockoff_timer,
2188c2ecf20Sopenharmony_ci				  jiffies + MSECS(10));
2198c2ecf20Sopenharmony_ci		}
2208c2ecf20Sopenharmony_ci	}
2218c2ecf20Sopenharmony_ci}
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_cistatic void _rtl88ee_set_fw_ps_rf_on(struct ieee80211_hw *hw)
2248c2ecf20Sopenharmony_ci{
2258c2ecf20Sopenharmony_ci	u8 rpwm_val = 0;
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_ci	rpwm_val |= (FW_PS_STATE_RF_OFF_88E | FW_PS_ACK);
2288c2ecf20Sopenharmony_ci	_rtl88ee_set_fw_clock_on(hw, rpwm_val, true);
2298c2ecf20Sopenharmony_ci}
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_cistatic void _rtl88ee_set_fw_ps_rf_off_low_power(struct ieee80211_hw *hw)
2328c2ecf20Sopenharmony_ci{
2338c2ecf20Sopenharmony_ci	u8 rpwm_val = 0;
2348c2ecf20Sopenharmony_ci	rpwm_val |= FW_PS_STATE_RF_OFF_LOW_PWR_88E;
2358c2ecf20Sopenharmony_ci	_rtl88ee_set_fw_clock_off(hw, rpwm_val);
2368c2ecf20Sopenharmony_ci}
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_civoid rtl88ee_fw_clk_off_timer_callback(struct timer_list *t)
2398c2ecf20Sopenharmony_ci{
2408c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = from_timer(rtlpriv, t,
2418c2ecf20Sopenharmony_ci					      works.fw_clockoff_timer);
2428c2ecf20Sopenharmony_ci	struct ieee80211_hw *hw = rtlpriv->hw;
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci	_rtl88ee_set_fw_ps_rf_off_low_power(hw);
2458c2ecf20Sopenharmony_ci}
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_cistatic void _rtl88ee_fwlps_leave(struct ieee80211_hw *hw)
2488c2ecf20Sopenharmony_ci{
2498c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
2508c2ecf20Sopenharmony_ci	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2518c2ecf20Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2528c2ecf20Sopenharmony_ci	bool fw_current_inps = false;
2538c2ecf20Sopenharmony_ci	u8 rpwm_val = 0, fw_pwrmode = FW_PS_ACTIVE_MODE;
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_ci	if (ppsc->low_power_enable) {
2568c2ecf20Sopenharmony_ci		rpwm_val = (FW_PS_STATE_ALL_ON_88E|FW_PS_ACK);/* RF on */
2578c2ecf20Sopenharmony_ci		_rtl88ee_set_fw_clock_on(hw, rpwm_val, false);
2588c2ecf20Sopenharmony_ci		rtlhal->allow_sw_to_change_hwclc = false;
2598c2ecf20Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
2608c2ecf20Sopenharmony_ci					      &fw_pwrmode);
2618c2ecf20Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
2628c2ecf20Sopenharmony_ci					      (u8 *)(&fw_current_inps));
2638c2ecf20Sopenharmony_ci	} else {
2648c2ecf20Sopenharmony_ci		rpwm_val = FW_PS_STATE_ALL_ON_88E;	/* RF on */
2658c2ecf20Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);
2668c2ecf20Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
2678c2ecf20Sopenharmony_ci					      &fw_pwrmode);
2688c2ecf20Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
2698c2ecf20Sopenharmony_ci					      (u8 *)(&fw_current_inps));
2708c2ecf20Sopenharmony_ci	}
2718c2ecf20Sopenharmony_ci}
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_cistatic void _rtl88ee_fwlps_enter(struct ieee80211_hw *hw)
2748c2ecf20Sopenharmony_ci{
2758c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
2768c2ecf20Sopenharmony_ci	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2778c2ecf20Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2788c2ecf20Sopenharmony_ci	bool fw_current_inps = true;
2798c2ecf20Sopenharmony_ci	u8 rpwm_val;
2808c2ecf20Sopenharmony_ci
2818c2ecf20Sopenharmony_ci	if (ppsc->low_power_enable) {
2828c2ecf20Sopenharmony_ci		rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR_88E;	/* RF off */
2838c2ecf20Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
2848c2ecf20Sopenharmony_ci					      (u8 *)(&fw_current_inps));
2858c2ecf20Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
2868c2ecf20Sopenharmony_ci					      &ppsc->fwctrl_psmode);
2878c2ecf20Sopenharmony_ci		rtlhal->allow_sw_to_change_hwclc = true;
2888c2ecf20Sopenharmony_ci		_rtl88ee_set_fw_clock_off(hw, rpwm_val);
2898c2ecf20Sopenharmony_ci	} else {
2908c2ecf20Sopenharmony_ci		rpwm_val = FW_PS_STATE_RF_OFF_88E;	/* RF off */
2918c2ecf20Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
2928c2ecf20Sopenharmony_ci					      (u8 *)(&fw_current_inps));
2938c2ecf20Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
2948c2ecf20Sopenharmony_ci					      &ppsc->fwctrl_psmode);
2958c2ecf20Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);
2968c2ecf20Sopenharmony_ci	}
2978c2ecf20Sopenharmony_ci}
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_civoid rtl88ee_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
3008c2ecf20Sopenharmony_ci{
3018c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
3028c2ecf20Sopenharmony_ci	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
3038c2ecf20Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
3048c2ecf20Sopenharmony_ci
3058c2ecf20Sopenharmony_ci	switch (variable) {
3068c2ecf20Sopenharmony_ci	case HW_VAR_RCR:
3078c2ecf20Sopenharmony_ci		*((u32 *)(val)) = rtlpci->receive_config;
3088c2ecf20Sopenharmony_ci		break;
3098c2ecf20Sopenharmony_ci	case HW_VAR_RF_STATE:
3108c2ecf20Sopenharmony_ci		*((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
3118c2ecf20Sopenharmony_ci		break;
3128c2ecf20Sopenharmony_ci	case HW_VAR_FWLPS_RF_ON:{
3138c2ecf20Sopenharmony_ci		enum rf_pwrstate rfstate;
3148c2ecf20Sopenharmony_ci		u32 val_rcr;
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_ci		rtlpriv->cfg->ops->get_hw_reg(hw,
3178c2ecf20Sopenharmony_ci					      HW_VAR_RF_STATE,
3188c2ecf20Sopenharmony_ci					      (u8 *)(&rfstate));
3198c2ecf20Sopenharmony_ci		if (rfstate == ERFOFF) {
3208c2ecf20Sopenharmony_ci			*((bool *)(val)) = true;
3218c2ecf20Sopenharmony_ci		} else {
3228c2ecf20Sopenharmony_ci			val_rcr = rtl_read_dword(rtlpriv, REG_RCR);
3238c2ecf20Sopenharmony_ci			val_rcr &= 0x00070000;
3248c2ecf20Sopenharmony_ci			if (val_rcr)
3258c2ecf20Sopenharmony_ci				*((bool *)(val)) = false;
3268c2ecf20Sopenharmony_ci			else
3278c2ecf20Sopenharmony_ci				*((bool *)(val)) = true;
3288c2ecf20Sopenharmony_ci		}
3298c2ecf20Sopenharmony_ci		break; }
3308c2ecf20Sopenharmony_ci	case HW_VAR_FW_PSMODE_STATUS:
3318c2ecf20Sopenharmony_ci		*((bool *)(val)) = ppsc->fw_current_inpsmode;
3328c2ecf20Sopenharmony_ci		break;
3338c2ecf20Sopenharmony_ci	case HW_VAR_CORRECT_TSF:{
3348c2ecf20Sopenharmony_ci		u64 tsf;
3358c2ecf20Sopenharmony_ci		u32 *ptsf_low = (u32 *)&tsf;
3368c2ecf20Sopenharmony_ci		u32 *ptsf_high = ((u32 *)&tsf) + 1;
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci		*ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4));
3398c2ecf20Sopenharmony_ci		*ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
3408c2ecf20Sopenharmony_ci
3418c2ecf20Sopenharmony_ci		*((u64 *)(val)) = tsf;
3428c2ecf20Sopenharmony_ci		break; }
3438c2ecf20Sopenharmony_ci	case HAL_DEF_WOWLAN:
3448c2ecf20Sopenharmony_ci		break;
3458c2ecf20Sopenharmony_ci	default:
3468c2ecf20Sopenharmony_ci		pr_err("switch case %#x not processed\n", variable);
3478c2ecf20Sopenharmony_ci		break;
3488c2ecf20Sopenharmony_ci	}
3498c2ecf20Sopenharmony_ci}
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_civoid rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
3528c2ecf20Sopenharmony_ci{
3538c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
3548c2ecf20Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
3558c2ecf20Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
3568c2ecf20Sopenharmony_ci	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
3578c2ecf20Sopenharmony_ci	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
3588c2ecf20Sopenharmony_ci	u8 idx;
3598c2ecf20Sopenharmony_ci
3608c2ecf20Sopenharmony_ci	switch (variable) {
3618c2ecf20Sopenharmony_ci	case HW_VAR_ETHER_ADDR:
3628c2ecf20Sopenharmony_ci		for (idx = 0; idx < ETH_ALEN; idx++) {
3638c2ecf20Sopenharmony_ci			rtl_write_byte(rtlpriv, (REG_MACID + idx),
3648c2ecf20Sopenharmony_ci				       val[idx]);
3658c2ecf20Sopenharmony_ci		}
3668c2ecf20Sopenharmony_ci		break;
3678c2ecf20Sopenharmony_ci	case HW_VAR_BASIC_RATE:{
3688c2ecf20Sopenharmony_ci		u16 b_rate_cfg = ((u16 *)val)[0];
3698c2ecf20Sopenharmony_ci		u8 rate_index = 0;
3708c2ecf20Sopenharmony_ci		b_rate_cfg = b_rate_cfg & 0x15f;
3718c2ecf20Sopenharmony_ci		b_rate_cfg |= 0x01;
3728c2ecf20Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff);
3738c2ecf20Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_RRSR + 1,
3748c2ecf20Sopenharmony_ci			       (b_rate_cfg >> 8) & 0xff);
3758c2ecf20Sopenharmony_ci		while (b_rate_cfg > 0x1) {
3768c2ecf20Sopenharmony_ci			b_rate_cfg = (b_rate_cfg >> 1);
3778c2ecf20Sopenharmony_ci			rate_index++;
3788c2ecf20Sopenharmony_ci		}
3798c2ecf20Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL,
3808c2ecf20Sopenharmony_ci			       rate_index);
3818c2ecf20Sopenharmony_ci		break;
3828c2ecf20Sopenharmony_ci		}
3838c2ecf20Sopenharmony_ci	case HW_VAR_BSSID:
3848c2ecf20Sopenharmony_ci		for (idx = 0; idx < ETH_ALEN; idx++) {
3858c2ecf20Sopenharmony_ci			rtl_write_byte(rtlpriv, (REG_BSSID + idx),
3868c2ecf20Sopenharmony_ci				       val[idx]);
3878c2ecf20Sopenharmony_ci		}
3888c2ecf20Sopenharmony_ci		break;
3898c2ecf20Sopenharmony_ci	case HW_VAR_SIFS:
3908c2ecf20Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]);
3918c2ecf20Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]);
3928c2ecf20Sopenharmony_ci
3938c2ecf20Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]);
3948c2ecf20Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
3958c2ecf20Sopenharmony_ci
3968c2ecf20Sopenharmony_ci		if (!mac->ht_enable)
3978c2ecf20Sopenharmony_ci			rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
3988c2ecf20Sopenharmony_ci				       0x0e0e);
3998c2ecf20Sopenharmony_ci		else
4008c2ecf20Sopenharmony_ci			rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
4018c2ecf20Sopenharmony_ci				       *((u16 *)val));
4028c2ecf20Sopenharmony_ci		break;
4038c2ecf20Sopenharmony_ci	case HW_VAR_SLOT_TIME:{
4048c2ecf20Sopenharmony_ci		u8 e_aci;
4058c2ecf20Sopenharmony_ci
4068c2ecf20Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD,
4078c2ecf20Sopenharmony_ci			"HW_VAR_SLOT_TIME %x\n", val[0]);
4088c2ecf20Sopenharmony_ci
4098c2ecf20Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci		for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
4128c2ecf20Sopenharmony_ci			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
4138c2ecf20Sopenharmony_ci						      &e_aci);
4148c2ecf20Sopenharmony_ci		}
4158c2ecf20Sopenharmony_ci		break;
4168c2ecf20Sopenharmony_ci		}
4178c2ecf20Sopenharmony_ci	case HW_VAR_ACK_PREAMBLE:{
4188c2ecf20Sopenharmony_ci		u8 reg_tmp;
4198c2ecf20Sopenharmony_ci		u8 short_preamble = (bool)*val;
4208c2ecf20Sopenharmony_ci		reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL+2);
4218c2ecf20Sopenharmony_ci		if (short_preamble) {
4228c2ecf20Sopenharmony_ci			reg_tmp |= 0x02;
4238c2ecf20Sopenharmony_ci			rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL +
4248c2ecf20Sopenharmony_ci				       2, reg_tmp);
4258c2ecf20Sopenharmony_ci		} else {
4268c2ecf20Sopenharmony_ci			reg_tmp |= 0xFD;
4278c2ecf20Sopenharmony_ci			rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL +
4288c2ecf20Sopenharmony_ci				       2, reg_tmp);
4298c2ecf20Sopenharmony_ci		}
4308c2ecf20Sopenharmony_ci		break; }
4318c2ecf20Sopenharmony_ci	case HW_VAR_WPA_CONFIG:
4328c2ecf20Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_SECCFG, *val);
4338c2ecf20Sopenharmony_ci		break;
4348c2ecf20Sopenharmony_ci	case HW_VAR_AMPDU_MIN_SPACE:{
4358c2ecf20Sopenharmony_ci		u8 min_spacing_to_set;
4368c2ecf20Sopenharmony_ci		u8 sec_min_space;
4378c2ecf20Sopenharmony_ci
4388c2ecf20Sopenharmony_ci		min_spacing_to_set = *val;
4398c2ecf20Sopenharmony_ci		if (min_spacing_to_set <= 7) {
4408c2ecf20Sopenharmony_ci			sec_min_space = 0;
4418c2ecf20Sopenharmony_ci
4428c2ecf20Sopenharmony_ci			if (min_spacing_to_set < sec_min_space)
4438c2ecf20Sopenharmony_ci				min_spacing_to_set = sec_min_space;
4448c2ecf20Sopenharmony_ci
4458c2ecf20Sopenharmony_ci			mac->min_space_cfg = ((mac->min_space_cfg &
4468c2ecf20Sopenharmony_ci					       0xf8) |
4478c2ecf20Sopenharmony_ci					      min_spacing_to_set);
4488c2ecf20Sopenharmony_ci
4498c2ecf20Sopenharmony_ci			*val = min_spacing_to_set;
4508c2ecf20Sopenharmony_ci
4518c2ecf20Sopenharmony_ci			rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD,
4528c2ecf20Sopenharmony_ci				"Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
4538c2ecf20Sopenharmony_ci				mac->min_space_cfg);
4548c2ecf20Sopenharmony_ci
4558c2ecf20Sopenharmony_ci			rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
4568c2ecf20Sopenharmony_ci				       mac->min_space_cfg);
4578c2ecf20Sopenharmony_ci		}
4588c2ecf20Sopenharmony_ci		break; }
4598c2ecf20Sopenharmony_ci	case HW_VAR_SHORTGI_DENSITY:{
4608c2ecf20Sopenharmony_ci		u8 density_to_set;
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_ci		density_to_set = *val;
4638c2ecf20Sopenharmony_ci		mac->min_space_cfg |= (density_to_set << 3);
4648c2ecf20Sopenharmony_ci
4658c2ecf20Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD,
4668c2ecf20Sopenharmony_ci			"Set HW_VAR_SHORTGI_DENSITY: %#x\n",
4678c2ecf20Sopenharmony_ci			mac->min_space_cfg);
4688c2ecf20Sopenharmony_ci
4698c2ecf20Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
4708c2ecf20Sopenharmony_ci			       mac->min_space_cfg);
4718c2ecf20Sopenharmony_ci		break;
4728c2ecf20Sopenharmony_ci		}
4738c2ecf20Sopenharmony_ci	case HW_VAR_AMPDU_FACTOR:{
4748c2ecf20Sopenharmony_ci		u8 regtoset_normal[4] = { 0x41, 0xa8, 0x72, 0xb9 };
4758c2ecf20Sopenharmony_ci		u8 factor_toset;
4768c2ecf20Sopenharmony_ci		u8 *p_regtoset = NULL;
4778c2ecf20Sopenharmony_ci		u8 index = 0;
4788c2ecf20Sopenharmony_ci
4798c2ecf20Sopenharmony_ci		p_regtoset = regtoset_normal;
4808c2ecf20Sopenharmony_ci
4818c2ecf20Sopenharmony_ci		factor_toset = *val;
4828c2ecf20Sopenharmony_ci		if (factor_toset <= 3) {
4838c2ecf20Sopenharmony_ci			factor_toset = (1 << (factor_toset + 2));
4848c2ecf20Sopenharmony_ci			if (factor_toset > 0xf)
4858c2ecf20Sopenharmony_ci				factor_toset = 0xf;
4868c2ecf20Sopenharmony_ci
4878c2ecf20Sopenharmony_ci			for (index = 0; index < 4; index++) {
4888c2ecf20Sopenharmony_ci				if ((p_regtoset[index] & 0xf0) >
4898c2ecf20Sopenharmony_ci				    (factor_toset << 4))
4908c2ecf20Sopenharmony_ci					p_regtoset[index] =
4918c2ecf20Sopenharmony_ci					    (p_regtoset[index] & 0x0f) |
4928c2ecf20Sopenharmony_ci					    (factor_toset << 4);
4938c2ecf20Sopenharmony_ci
4948c2ecf20Sopenharmony_ci				if ((p_regtoset[index] & 0x0f) >
4958c2ecf20Sopenharmony_ci				    factor_toset)
4968c2ecf20Sopenharmony_ci					p_regtoset[index] =
4978c2ecf20Sopenharmony_ci					    (p_regtoset[index] & 0xf0) |
4988c2ecf20Sopenharmony_ci					    (factor_toset);
4998c2ecf20Sopenharmony_ci
5008c2ecf20Sopenharmony_ci				rtl_write_byte(rtlpriv,
5018c2ecf20Sopenharmony_ci					       (REG_AGGLEN_LMT + index),
5028c2ecf20Sopenharmony_ci					       p_regtoset[index]);
5038c2ecf20Sopenharmony_ci
5048c2ecf20Sopenharmony_ci			}
5058c2ecf20Sopenharmony_ci
5068c2ecf20Sopenharmony_ci			rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD,
5078c2ecf20Sopenharmony_ci				"Set HW_VAR_AMPDU_FACTOR: %#x\n",
5088c2ecf20Sopenharmony_ci				factor_toset);
5098c2ecf20Sopenharmony_ci		}
5108c2ecf20Sopenharmony_ci		break; }
5118c2ecf20Sopenharmony_ci	case HW_VAR_AC_PARAM:{
5128c2ecf20Sopenharmony_ci		u8 e_aci = *val;
5138c2ecf20Sopenharmony_ci		rtl88e_dm_init_edca_turbo(hw);
5148c2ecf20Sopenharmony_ci
5158c2ecf20Sopenharmony_ci		if (rtlpci->acm_method != EACMWAY2_SW)
5168c2ecf20Sopenharmony_ci			rtlpriv->cfg->ops->set_hw_reg(hw,
5178c2ecf20Sopenharmony_ci						      HW_VAR_ACM_CTRL,
5188c2ecf20Sopenharmony_ci						      &e_aci);
5198c2ecf20Sopenharmony_ci		break; }
5208c2ecf20Sopenharmony_ci	case HW_VAR_ACM_CTRL:{
5218c2ecf20Sopenharmony_ci		u8 e_aci = *val;
5228c2ecf20Sopenharmony_ci		union aci_aifsn *p_aci_aifsn =
5238c2ecf20Sopenharmony_ci		    (union aci_aifsn *)(&(mac->ac[0].aifs));
5248c2ecf20Sopenharmony_ci		u8 acm = p_aci_aifsn->f.acm;
5258c2ecf20Sopenharmony_ci		u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);
5268c2ecf20Sopenharmony_ci
5278c2ecf20Sopenharmony_ci		acm_ctrl = acm_ctrl |
5288c2ecf20Sopenharmony_ci			   ((rtlpci->acm_method == 2) ? 0x0 : 0x1);
5298c2ecf20Sopenharmony_ci
5308c2ecf20Sopenharmony_ci		if (acm) {
5318c2ecf20Sopenharmony_ci			switch (e_aci) {
5328c2ecf20Sopenharmony_ci			case AC0_BE:
5338c2ecf20Sopenharmony_ci				acm_ctrl |= ACMHW_BEQEN;
5348c2ecf20Sopenharmony_ci				break;
5358c2ecf20Sopenharmony_ci			case AC2_VI:
5368c2ecf20Sopenharmony_ci				acm_ctrl |= ACMHW_VIQEN;
5378c2ecf20Sopenharmony_ci				break;
5388c2ecf20Sopenharmony_ci			case AC3_VO:
5398c2ecf20Sopenharmony_ci				acm_ctrl |= ACMHW_VOQEN;
5408c2ecf20Sopenharmony_ci				break;
5418c2ecf20Sopenharmony_ci			default:
5428c2ecf20Sopenharmony_ci				rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
5438c2ecf20Sopenharmony_ci					"HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
5448c2ecf20Sopenharmony_ci					acm);
5458c2ecf20Sopenharmony_ci				break;
5468c2ecf20Sopenharmony_ci			}
5478c2ecf20Sopenharmony_ci		} else {
5488c2ecf20Sopenharmony_ci			switch (e_aci) {
5498c2ecf20Sopenharmony_ci			case AC0_BE:
5508c2ecf20Sopenharmony_ci				acm_ctrl &= (~ACMHW_BEQEN);
5518c2ecf20Sopenharmony_ci				break;
5528c2ecf20Sopenharmony_ci			case AC2_VI:
5538c2ecf20Sopenharmony_ci				acm_ctrl &= (~ACMHW_VIQEN);
5548c2ecf20Sopenharmony_ci				break;
5558c2ecf20Sopenharmony_ci			case AC3_VO:
5568c2ecf20Sopenharmony_ci				acm_ctrl &= (~ACMHW_VOQEN);
5578c2ecf20Sopenharmony_ci				break;
5588c2ecf20Sopenharmony_ci			default:
5598c2ecf20Sopenharmony_ci				pr_err("switch case %#x not processed\n",
5608c2ecf20Sopenharmony_ci				       e_aci);
5618c2ecf20Sopenharmony_ci				break;
5628c2ecf20Sopenharmony_ci			}
5638c2ecf20Sopenharmony_ci		}
5648c2ecf20Sopenharmony_ci
5658c2ecf20Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_QOS, DBG_TRACE,
5668c2ecf20Sopenharmony_ci			"SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
5678c2ecf20Sopenharmony_ci			acm_ctrl);
5688c2ecf20Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
5698c2ecf20Sopenharmony_ci		break; }
5708c2ecf20Sopenharmony_ci	case HW_VAR_RCR:
5718c2ecf20Sopenharmony_ci		rtl_write_dword(rtlpriv, REG_RCR, ((u32 *)(val))[0]);
5728c2ecf20Sopenharmony_ci		rtlpci->receive_config = ((u32 *)(val))[0];
5738c2ecf20Sopenharmony_ci		break;
5748c2ecf20Sopenharmony_ci	case HW_VAR_RETRY_LIMIT:{
5758c2ecf20Sopenharmony_ci		u8 retry_limit = *val;
5768c2ecf20Sopenharmony_ci
5778c2ecf20Sopenharmony_ci		rtl_write_word(rtlpriv, REG_RL,
5788c2ecf20Sopenharmony_ci			       retry_limit << RETRY_LIMIT_SHORT_SHIFT |
5798c2ecf20Sopenharmony_ci			       retry_limit << RETRY_LIMIT_LONG_SHIFT);
5808c2ecf20Sopenharmony_ci		break; }
5818c2ecf20Sopenharmony_ci	case HW_VAR_DUAL_TSF_RST:
5828c2ecf20Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
5838c2ecf20Sopenharmony_ci		break;
5848c2ecf20Sopenharmony_ci	case HW_VAR_EFUSE_BYTES:
5858c2ecf20Sopenharmony_ci		rtlefuse->efuse_usedbytes = *((u16 *)val);
5868c2ecf20Sopenharmony_ci		break;
5878c2ecf20Sopenharmony_ci	case HW_VAR_EFUSE_USAGE:
5888c2ecf20Sopenharmony_ci		rtlefuse->efuse_usedpercentage = *val;
5898c2ecf20Sopenharmony_ci		break;
5908c2ecf20Sopenharmony_ci	case HW_VAR_IO_CMD:
5918c2ecf20Sopenharmony_ci		rtl88e_phy_set_io_cmd(hw, (*(enum io_type *)val));
5928c2ecf20Sopenharmony_ci		break;
5938c2ecf20Sopenharmony_ci	case HW_VAR_SET_RPWM:{
5948c2ecf20Sopenharmony_ci		u8 rpwm_val;
5958c2ecf20Sopenharmony_ci
5968c2ecf20Sopenharmony_ci		rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM);
5978c2ecf20Sopenharmony_ci		udelay(1);
5988c2ecf20Sopenharmony_ci
5998c2ecf20Sopenharmony_ci		if (rpwm_val & BIT(7)) {
6008c2ecf20Sopenharmony_ci			rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val);
6018c2ecf20Sopenharmony_ci		} else {
6028c2ecf20Sopenharmony_ci			rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val | BIT(7));
6038c2ecf20Sopenharmony_ci		}
6048c2ecf20Sopenharmony_ci		break; }
6058c2ecf20Sopenharmony_ci	case HW_VAR_H2C_FW_PWRMODE:
6068c2ecf20Sopenharmony_ci		rtl88e_set_fw_pwrmode_cmd(hw, *val);
6078c2ecf20Sopenharmony_ci		break;
6088c2ecf20Sopenharmony_ci	case HW_VAR_FW_PSMODE_STATUS:
6098c2ecf20Sopenharmony_ci		ppsc->fw_current_inpsmode = *((bool *)val);
6108c2ecf20Sopenharmony_ci		break;
6118c2ecf20Sopenharmony_ci	case HW_VAR_RESUME_CLK_ON:
6128c2ecf20Sopenharmony_ci		_rtl88ee_set_fw_ps_rf_on(hw);
6138c2ecf20Sopenharmony_ci		break;
6148c2ecf20Sopenharmony_ci	case HW_VAR_FW_LPS_ACTION:{
6158c2ecf20Sopenharmony_ci		bool enter_fwlps = *((bool *)val);
6168c2ecf20Sopenharmony_ci
6178c2ecf20Sopenharmony_ci		if (enter_fwlps)
6188c2ecf20Sopenharmony_ci			_rtl88ee_fwlps_enter(hw);
6198c2ecf20Sopenharmony_ci		 else
6208c2ecf20Sopenharmony_ci			_rtl88ee_fwlps_leave(hw);
6218c2ecf20Sopenharmony_ci
6228c2ecf20Sopenharmony_ci		 break; }
6238c2ecf20Sopenharmony_ci	case HW_VAR_H2C_FW_JOINBSSRPT:{
6248c2ecf20Sopenharmony_ci		u8 mstatus = *val;
6258c2ecf20Sopenharmony_ci		u8 tmp_regcr, tmp_reg422, bcnvalid_reg;
6268c2ecf20Sopenharmony_ci		u8 count = 0, dlbcn_count = 0;
6278c2ecf20Sopenharmony_ci		bool b_recover = false;
6288c2ecf20Sopenharmony_ci
6298c2ecf20Sopenharmony_ci		if (mstatus == RT_MEDIA_CONNECT) {
6308c2ecf20Sopenharmony_ci			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID,
6318c2ecf20Sopenharmony_ci						      NULL);
6328c2ecf20Sopenharmony_ci
6338c2ecf20Sopenharmony_ci			tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
6348c2ecf20Sopenharmony_ci			rtl_write_byte(rtlpriv, REG_CR + 1,
6358c2ecf20Sopenharmony_ci				       (tmp_regcr | BIT(0)));
6368c2ecf20Sopenharmony_ci
6378c2ecf20Sopenharmony_ci			_rtl88ee_set_bcn_ctrl_reg(hw, 0, BIT(3));
6388c2ecf20Sopenharmony_ci			_rtl88ee_set_bcn_ctrl_reg(hw, BIT(4), 0);
6398c2ecf20Sopenharmony_ci
6408c2ecf20Sopenharmony_ci			tmp_reg422 =
6418c2ecf20Sopenharmony_ci			    rtl_read_byte(rtlpriv,
6428c2ecf20Sopenharmony_ci					  REG_FWHW_TXQ_CTRL + 2);
6438c2ecf20Sopenharmony_ci			rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
6448c2ecf20Sopenharmony_ci				       tmp_reg422 & (~BIT(6)));
6458c2ecf20Sopenharmony_ci			if (tmp_reg422 & BIT(6))
6468c2ecf20Sopenharmony_ci				b_recover = true;
6478c2ecf20Sopenharmony_ci
6488c2ecf20Sopenharmony_ci			do {
6498c2ecf20Sopenharmony_ci				bcnvalid_reg = rtl_read_byte(rtlpriv,
6508c2ecf20Sopenharmony_ci							     REG_TDECTRL+2);
6518c2ecf20Sopenharmony_ci				rtl_write_byte(rtlpriv, REG_TDECTRL+2,
6528c2ecf20Sopenharmony_ci					       (bcnvalid_reg | BIT(0)));
6538c2ecf20Sopenharmony_ci				_rtl88ee_return_beacon_queue_skb(hw);
6548c2ecf20Sopenharmony_ci
6558c2ecf20Sopenharmony_ci				rtl88e_set_fw_rsvdpagepkt(hw, 0);
6568c2ecf20Sopenharmony_ci				bcnvalid_reg = rtl_read_byte(rtlpriv,
6578c2ecf20Sopenharmony_ci							     REG_TDECTRL+2);
6588c2ecf20Sopenharmony_ci				count = 0;
6598c2ecf20Sopenharmony_ci				while (!(bcnvalid_reg & BIT(0)) && count < 20) {
6608c2ecf20Sopenharmony_ci					count++;
6618c2ecf20Sopenharmony_ci					udelay(10);
6628c2ecf20Sopenharmony_ci					bcnvalid_reg =
6638c2ecf20Sopenharmony_ci					  rtl_read_byte(rtlpriv, REG_TDECTRL+2);
6648c2ecf20Sopenharmony_ci				}
6658c2ecf20Sopenharmony_ci				dlbcn_count++;
6668c2ecf20Sopenharmony_ci			} while (!(bcnvalid_reg & BIT(0)) && dlbcn_count < 5);
6678c2ecf20Sopenharmony_ci
6688c2ecf20Sopenharmony_ci			if (bcnvalid_reg & BIT(0))
6698c2ecf20Sopenharmony_ci				rtl_write_byte(rtlpriv, REG_TDECTRL+2, BIT(0));
6708c2ecf20Sopenharmony_ci
6718c2ecf20Sopenharmony_ci			_rtl88ee_set_bcn_ctrl_reg(hw, BIT(3), 0);
6728c2ecf20Sopenharmony_ci			_rtl88ee_set_bcn_ctrl_reg(hw, 0, BIT(4));
6738c2ecf20Sopenharmony_ci
6748c2ecf20Sopenharmony_ci			if (b_recover) {
6758c2ecf20Sopenharmony_ci				rtl_write_byte(rtlpriv,
6768c2ecf20Sopenharmony_ci					       REG_FWHW_TXQ_CTRL + 2,
6778c2ecf20Sopenharmony_ci					       tmp_reg422);
6788c2ecf20Sopenharmony_ci			}
6798c2ecf20Sopenharmony_ci
6808c2ecf20Sopenharmony_ci			rtl_write_byte(rtlpriv, REG_CR + 1,
6818c2ecf20Sopenharmony_ci				       (tmp_regcr & ~(BIT(0))));
6828c2ecf20Sopenharmony_ci		}
6838c2ecf20Sopenharmony_ci		rtl88e_set_fw_joinbss_report_cmd(hw, (*(u8 *)val));
6848c2ecf20Sopenharmony_ci		break; }
6858c2ecf20Sopenharmony_ci	case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
6868c2ecf20Sopenharmony_ci		rtl88e_set_p2p_ps_offload_cmd(hw, *val);
6878c2ecf20Sopenharmony_ci		break;
6888c2ecf20Sopenharmony_ci	case HW_VAR_AID:{
6898c2ecf20Sopenharmony_ci		u16 u2btmp;
6908c2ecf20Sopenharmony_ci
6918c2ecf20Sopenharmony_ci		u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
6928c2ecf20Sopenharmony_ci		u2btmp &= 0xC000;
6938c2ecf20Sopenharmony_ci		rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, (u2btmp |
6948c2ecf20Sopenharmony_ci			       mac->assoc_id));
6958c2ecf20Sopenharmony_ci		break; }
6968c2ecf20Sopenharmony_ci	case HW_VAR_CORRECT_TSF:{
6978c2ecf20Sopenharmony_ci		u8 btype_ibss = *val;
6988c2ecf20Sopenharmony_ci
6998c2ecf20Sopenharmony_ci		if (btype_ibss)
7008c2ecf20Sopenharmony_ci			_rtl88ee_stop_tx_beacon(hw);
7018c2ecf20Sopenharmony_ci
7028c2ecf20Sopenharmony_ci		_rtl88ee_set_bcn_ctrl_reg(hw, 0, BIT(3));
7038c2ecf20Sopenharmony_ci
7048c2ecf20Sopenharmony_ci		rtl_write_dword(rtlpriv, REG_TSFTR,
7058c2ecf20Sopenharmony_ci				(u32)(mac->tsf & 0xffffffff));
7068c2ecf20Sopenharmony_ci		rtl_write_dword(rtlpriv, REG_TSFTR + 4,
7078c2ecf20Sopenharmony_ci				(u32)((mac->tsf >> 32) & 0xffffffff));
7088c2ecf20Sopenharmony_ci
7098c2ecf20Sopenharmony_ci		_rtl88ee_set_bcn_ctrl_reg(hw, BIT(3), 0);
7108c2ecf20Sopenharmony_ci
7118c2ecf20Sopenharmony_ci		if (btype_ibss)
7128c2ecf20Sopenharmony_ci			_rtl88ee_resume_tx_beacon(hw);
7138c2ecf20Sopenharmony_ci		break; }
7148c2ecf20Sopenharmony_ci	case HW_VAR_KEEP_ALIVE: {
7158c2ecf20Sopenharmony_ci		u8 array[2];
7168c2ecf20Sopenharmony_ci
7178c2ecf20Sopenharmony_ci		array[0] = 0xff;
7188c2ecf20Sopenharmony_ci		array[1] = *((u8 *)val);
7198c2ecf20Sopenharmony_ci		rtl88e_fill_h2c_cmd(hw, H2C_88E_KEEP_ALIVE_CTRL,
7208c2ecf20Sopenharmony_ci				    2, array);
7218c2ecf20Sopenharmony_ci		break; }
7228c2ecf20Sopenharmony_ci	default:
7238c2ecf20Sopenharmony_ci		pr_err("switch case %#x not processed\n", variable);
7248c2ecf20Sopenharmony_ci		break;
7258c2ecf20Sopenharmony_ci	}
7268c2ecf20Sopenharmony_ci}
7278c2ecf20Sopenharmony_ci
7288c2ecf20Sopenharmony_cistatic bool _rtl88ee_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
7298c2ecf20Sopenharmony_ci{
7308c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
7318c2ecf20Sopenharmony_ci	bool status = true;
7328c2ecf20Sopenharmony_ci	long count = 0;
7338c2ecf20Sopenharmony_ci	u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) |
7348c2ecf20Sopenharmony_ci		    _LLT_OP(_LLT_WRITE_ACCESS);
7358c2ecf20Sopenharmony_ci
7368c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
7378c2ecf20Sopenharmony_ci
7388c2ecf20Sopenharmony_ci	do {
7398c2ecf20Sopenharmony_ci		value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
7408c2ecf20Sopenharmony_ci		if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
7418c2ecf20Sopenharmony_ci			break;
7428c2ecf20Sopenharmony_ci
7438c2ecf20Sopenharmony_ci		if (count > POLLING_LLT_THRESHOLD) {
7448c2ecf20Sopenharmony_ci			pr_err("Failed to polling write LLT done at address %d!\n",
7458c2ecf20Sopenharmony_ci			       address);
7468c2ecf20Sopenharmony_ci			status = false;
7478c2ecf20Sopenharmony_ci			break;
7488c2ecf20Sopenharmony_ci		}
7498c2ecf20Sopenharmony_ci	} while (++count);
7508c2ecf20Sopenharmony_ci
7518c2ecf20Sopenharmony_ci	return status;
7528c2ecf20Sopenharmony_ci}
7538c2ecf20Sopenharmony_ci
7548c2ecf20Sopenharmony_cistatic bool _rtl88ee_llt_table_init(struct ieee80211_hw *hw)
7558c2ecf20Sopenharmony_ci{
7568c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
7578c2ecf20Sopenharmony_ci	unsigned short i;
7588c2ecf20Sopenharmony_ci	u8 txpktbuf_bndy;
7598c2ecf20Sopenharmony_ci	u8 maxpage;
7608c2ecf20Sopenharmony_ci	bool status;
7618c2ecf20Sopenharmony_ci
7628c2ecf20Sopenharmony_ci	maxpage = 0xAF;
7638c2ecf20Sopenharmony_ci	txpktbuf_bndy = 0xAB;
7648c2ecf20Sopenharmony_ci
7658c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x01);
7668c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_RQPN, 0x80730d29);
7678c2ecf20Sopenharmony_ci
7688c2ecf20Sopenharmony_ci	/*0x2600   MaxRxBuff=10k-max(TxReportSize(64*8), WOLPattern(16*24)) */
7698c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_TRXFF_BNDY, (0x25FF0000 | txpktbuf_bndy));
7708c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy);
7718c2ecf20Sopenharmony_ci
7728c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
7738c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
7748c2ecf20Sopenharmony_ci
7758c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy);
7768c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_PBP, 0x11);
7778c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);
7788c2ecf20Sopenharmony_ci
7798c2ecf20Sopenharmony_ci	for (i = 0; i < (txpktbuf_bndy - 1); i++) {
7808c2ecf20Sopenharmony_ci		status = _rtl88ee_llt_write(hw, i, i + 1);
7818c2ecf20Sopenharmony_ci		if (!status)
7828c2ecf20Sopenharmony_ci			return status;
7838c2ecf20Sopenharmony_ci	}
7848c2ecf20Sopenharmony_ci
7858c2ecf20Sopenharmony_ci	status = _rtl88ee_llt_write(hw, (txpktbuf_bndy - 1), 0xFF);
7868c2ecf20Sopenharmony_ci	if (!status)
7878c2ecf20Sopenharmony_ci		return status;
7888c2ecf20Sopenharmony_ci
7898c2ecf20Sopenharmony_ci	for (i = txpktbuf_bndy; i < maxpage; i++) {
7908c2ecf20Sopenharmony_ci		status = _rtl88ee_llt_write(hw, i, (i + 1));
7918c2ecf20Sopenharmony_ci		if (!status)
7928c2ecf20Sopenharmony_ci			return status;
7938c2ecf20Sopenharmony_ci	}
7948c2ecf20Sopenharmony_ci
7958c2ecf20Sopenharmony_ci	status = _rtl88ee_llt_write(hw, maxpage, txpktbuf_bndy);
7968c2ecf20Sopenharmony_ci	if (!status)
7978c2ecf20Sopenharmony_ci		return status;
7988c2ecf20Sopenharmony_ci
7998c2ecf20Sopenharmony_ci	return true;
8008c2ecf20Sopenharmony_ci}
8018c2ecf20Sopenharmony_ci
8028c2ecf20Sopenharmony_cistatic void _rtl88ee_gen_refresh_led_state(struct ieee80211_hw *hw)
8038c2ecf20Sopenharmony_ci{
8048c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
8058c2ecf20Sopenharmony_ci	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
8068c2ecf20Sopenharmony_ci	struct rtl_led *pled0 = &rtlpriv->ledctl.sw_led0;
8078c2ecf20Sopenharmony_ci
8088c2ecf20Sopenharmony_ci	if (rtlpriv->rtlhal.up_first_time)
8098c2ecf20Sopenharmony_ci		return;
8108c2ecf20Sopenharmony_ci
8118c2ecf20Sopenharmony_ci	if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
8128c2ecf20Sopenharmony_ci		rtl88ee_sw_led_on(hw, pled0);
8138c2ecf20Sopenharmony_ci	else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT)
8148c2ecf20Sopenharmony_ci		rtl88ee_sw_led_on(hw, pled0);
8158c2ecf20Sopenharmony_ci	else
8168c2ecf20Sopenharmony_ci		rtl88ee_sw_led_off(hw, pled0);
8178c2ecf20Sopenharmony_ci}
8188c2ecf20Sopenharmony_ci
8198c2ecf20Sopenharmony_cistatic bool _rtl88ee_init_mac(struct ieee80211_hw *hw)
8208c2ecf20Sopenharmony_ci{
8218c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
8228c2ecf20Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
8238c2ecf20Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
8248c2ecf20Sopenharmony_ci
8258c2ecf20Sopenharmony_ci	u8 bytetmp;
8268c2ecf20Sopenharmony_ci	u16 wordtmp;
8278c2ecf20Sopenharmony_ci
8288c2ecf20Sopenharmony_ci	/*Disable XTAL OUTPUT for power saving. YJ,add,111206. */
8298c2ecf20Sopenharmony_ci	bytetmp = rtl_read_byte(rtlpriv, REG_XCK_OUT_CTRL) & (~BIT(0));
8308c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_XCK_OUT_CTRL, bytetmp);
8318c2ecf20Sopenharmony_ci	/*Auto Power Down to CHIP-off State*/
8328c2ecf20Sopenharmony_ci	bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) & (~BIT(7));
8338c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp);
8348c2ecf20Sopenharmony_ci
8358c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
8368c2ecf20Sopenharmony_ci	/* HW Power on sequence */
8378c2ecf20Sopenharmony_ci	if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK,
8388c2ecf20Sopenharmony_ci				      PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,
8398c2ecf20Sopenharmony_ci				      RTL8188EE_NIC_ENABLE_FLOW)) {
8408c2ecf20Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
8418c2ecf20Sopenharmony_ci			"init MAC Fail as rtl_hal_pwrseqcmdparsing\n");
8428c2ecf20Sopenharmony_ci		return false;
8438c2ecf20Sopenharmony_ci	}
8448c2ecf20Sopenharmony_ci
8458c2ecf20Sopenharmony_ci	bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO) | BIT(4);
8468c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_APS_FSMCO, bytetmp);
8478c2ecf20Sopenharmony_ci
8488c2ecf20Sopenharmony_ci	bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG+2);
8498c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+2, bytetmp|BIT(2));
8508c2ecf20Sopenharmony_ci
8518c2ecf20Sopenharmony_ci	bytetmp = rtl_read_byte(rtlpriv, REG_WATCH_DOG+1);
8528c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_WATCH_DOG+1, bytetmp|BIT(7));
8538c2ecf20Sopenharmony_ci
8548c2ecf20Sopenharmony_ci	bytetmp = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL_EXT+1);
8558c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL_EXT+1, bytetmp|BIT(1));
8568c2ecf20Sopenharmony_ci
8578c2ecf20Sopenharmony_ci	bytetmp = rtl_read_byte(rtlpriv, REG_TX_RPT_CTRL);
8588c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_TX_RPT_CTRL, bytetmp|BIT(1)|BIT(0));
8598c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_TX_RPT_CTRL+1, 2);
8608c2ecf20Sopenharmony_ci	rtl_write_word(rtlpriv, REG_TX_RPT_TIME, 0xcdf0);
8618c2ecf20Sopenharmony_ci
8628c2ecf20Sopenharmony_ci	/*Add for wake up online*/
8638c2ecf20Sopenharmony_ci	bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CLKR);
8648c2ecf20Sopenharmony_ci
8658c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_SYS_CLKR, bytetmp|BIT(3));
8668c2ecf20Sopenharmony_ci	bytetmp = rtl_read_byte(rtlpriv, REG_GPIO_MUXCFG+1);
8678c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG+1, (bytetmp & (~BIT(4))));
8688c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, 0x367, 0x80);
8698c2ecf20Sopenharmony_ci
8708c2ecf20Sopenharmony_ci	rtl_write_word(rtlpriv, REG_CR, 0x2ff);
8718c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_CR+1, 0x06);
8728c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, MSR, 0x00);
8738c2ecf20Sopenharmony_ci
8748c2ecf20Sopenharmony_ci	if (!rtlhal->mac_func_enable) {
8758c2ecf20Sopenharmony_ci		if (!_rtl88ee_llt_table_init(hw)) {
8768c2ecf20Sopenharmony_ci			rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
8778c2ecf20Sopenharmony_ci				"LLT table init fail\n");
8788c2ecf20Sopenharmony_ci			return false;
8798c2ecf20Sopenharmony_ci		}
8808c2ecf20Sopenharmony_ci	}
8818c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
8828c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_HISRE, 0xffffffff);
8838c2ecf20Sopenharmony_ci
8848c2ecf20Sopenharmony_ci	wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL);
8858c2ecf20Sopenharmony_ci	wordtmp &= 0xf;
8868c2ecf20Sopenharmony_ci	wordtmp |= 0xE771;
8878c2ecf20Sopenharmony_ci	rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp);
8888c2ecf20Sopenharmony_ci
8898c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
8908c2ecf20Sopenharmony_ci	rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xffff);
8918c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config);
8928c2ecf20Sopenharmony_ci
8938c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_BCNQ_DESA,
8948c2ecf20Sopenharmony_ci			((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) &
8958c2ecf20Sopenharmony_ci			DMA_BIT_MASK(32));
8968c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_MGQ_DESA,
8978c2ecf20Sopenharmony_ci			(u64) rtlpci->tx_ring[MGNT_QUEUE].dma &
8988c2ecf20Sopenharmony_ci			DMA_BIT_MASK(32));
8998c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_VOQ_DESA,
9008c2ecf20Sopenharmony_ci			(u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32));
9018c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_VIQ_DESA,
9028c2ecf20Sopenharmony_ci			(u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32));
9038c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_BEQ_DESA,
9048c2ecf20Sopenharmony_ci			(u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32));
9058c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_BKQ_DESA,
9068c2ecf20Sopenharmony_ci			(u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32));
9078c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_HQ_DESA,
9088c2ecf20Sopenharmony_ci			(u64) rtlpci->tx_ring[HIGH_QUEUE].dma &
9098c2ecf20Sopenharmony_ci			DMA_BIT_MASK(32));
9108c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_RX_DESA,
9118c2ecf20Sopenharmony_ci			(u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma &
9128c2ecf20Sopenharmony_ci			DMA_BIT_MASK(32));
9138c2ecf20Sopenharmony_ci
9148c2ecf20Sopenharmony_ci	/* if we want to support 64 bit DMA, we should set it here,
9158c2ecf20Sopenharmony_ci	 * but now we do not support 64 bit DMA
9168c2ecf20Sopenharmony_ci	 */
9178c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_INT_MIG, 0);
9188c2ecf20Sopenharmony_ci
9198c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0);
9208c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+1, 0);/*Enable RX DMA */
9218c2ecf20Sopenharmony_ci
9228c2ecf20Sopenharmony_ci	if (rtlhal->earlymode_enable) {/*Early mode enable*/
9238c2ecf20Sopenharmony_ci		bytetmp = rtl_read_byte(rtlpriv, REG_EARLY_MODE_CONTROL);
9248c2ecf20Sopenharmony_ci		bytetmp |= 0x1f;
9258c2ecf20Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, bytetmp);
9268c2ecf20Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL+3, 0x81);
9278c2ecf20Sopenharmony_ci	}
9288c2ecf20Sopenharmony_ci	_rtl88ee_gen_refresh_led_state(hw);
9298c2ecf20Sopenharmony_ci	return true;
9308c2ecf20Sopenharmony_ci}
9318c2ecf20Sopenharmony_ci
9328c2ecf20Sopenharmony_cistatic void _rtl88ee_hw_configure(struct ieee80211_hw *hw)
9338c2ecf20Sopenharmony_ci{
9348c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
9358c2ecf20Sopenharmony_ci	u32 reg_prsr;
9368c2ecf20Sopenharmony_ci
9378c2ecf20Sopenharmony_ci	reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
9388c2ecf20Sopenharmony_ci
9398c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_RRSR, reg_prsr);
9408c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF);
9418c2ecf20Sopenharmony_ci}
9428c2ecf20Sopenharmony_ci
9438c2ecf20Sopenharmony_cistatic void _rtl88ee_enable_aspm_back_door(struct ieee80211_hw *hw)
9448c2ecf20Sopenharmony_ci{
9458c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
9468c2ecf20Sopenharmony_ci	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
9478c2ecf20Sopenharmony_ci	u8 tmp1byte = 0;
9488c2ecf20Sopenharmony_ci	u32 tmp4byte = 0, count = 0;
9498c2ecf20Sopenharmony_ci
9508c2ecf20Sopenharmony_ci	rtl_write_word(rtlpriv, 0x354, 0x8104);
9518c2ecf20Sopenharmony_ci	rtl_write_word(rtlpriv, 0x358, 0x24);
9528c2ecf20Sopenharmony_ci
9538c2ecf20Sopenharmony_ci	rtl_write_word(rtlpriv, 0x350, 0x70c);
9548c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, 0x352, 0x2);
9558c2ecf20Sopenharmony_ci	tmp1byte = rtl_read_byte(rtlpriv, 0x352);
9568c2ecf20Sopenharmony_ci	count = 0;
9578c2ecf20Sopenharmony_ci	while (tmp1byte && count < 20) {
9588c2ecf20Sopenharmony_ci		udelay(10);
9598c2ecf20Sopenharmony_ci		tmp1byte = rtl_read_byte(rtlpriv, 0x352);
9608c2ecf20Sopenharmony_ci		count++;
9618c2ecf20Sopenharmony_ci	}
9628c2ecf20Sopenharmony_ci	if (0 == tmp1byte) {
9638c2ecf20Sopenharmony_ci		tmp4byte = rtl_read_dword(rtlpriv, 0x34c);
9648c2ecf20Sopenharmony_ci		rtl_write_dword(rtlpriv, 0x348, tmp4byte|BIT(31));
9658c2ecf20Sopenharmony_ci		rtl_write_word(rtlpriv, 0x350, 0xf70c);
9668c2ecf20Sopenharmony_ci		rtl_write_byte(rtlpriv, 0x352, 0x1);
9678c2ecf20Sopenharmony_ci	}
9688c2ecf20Sopenharmony_ci
9698c2ecf20Sopenharmony_ci	tmp1byte = rtl_read_byte(rtlpriv, 0x352);
9708c2ecf20Sopenharmony_ci	count = 0;
9718c2ecf20Sopenharmony_ci	while (tmp1byte && count < 20) {
9728c2ecf20Sopenharmony_ci		udelay(10);
9738c2ecf20Sopenharmony_ci		tmp1byte = rtl_read_byte(rtlpriv, 0x352);
9748c2ecf20Sopenharmony_ci		count++;
9758c2ecf20Sopenharmony_ci	}
9768c2ecf20Sopenharmony_ci
9778c2ecf20Sopenharmony_ci	rtl_write_word(rtlpriv, 0x350, 0x718);
9788c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, 0x352, 0x2);
9798c2ecf20Sopenharmony_ci	tmp1byte = rtl_read_byte(rtlpriv, 0x352);
9808c2ecf20Sopenharmony_ci	count = 0;
9818c2ecf20Sopenharmony_ci	while (tmp1byte && count < 20) {
9828c2ecf20Sopenharmony_ci		udelay(10);
9838c2ecf20Sopenharmony_ci		tmp1byte = rtl_read_byte(rtlpriv, 0x352);
9848c2ecf20Sopenharmony_ci		count++;
9858c2ecf20Sopenharmony_ci	}
9868c2ecf20Sopenharmony_ci
9878c2ecf20Sopenharmony_ci	if (ppsc->support_backdoor || (0 == tmp1byte)) {
9888c2ecf20Sopenharmony_ci		tmp4byte = rtl_read_dword(rtlpriv, 0x34c);
9898c2ecf20Sopenharmony_ci		rtl_write_dword(rtlpriv, 0x348, tmp4byte|BIT(11)|BIT(12));
9908c2ecf20Sopenharmony_ci		rtl_write_word(rtlpriv, 0x350, 0xf718);
9918c2ecf20Sopenharmony_ci		rtl_write_byte(rtlpriv, 0x352, 0x1);
9928c2ecf20Sopenharmony_ci	}
9938c2ecf20Sopenharmony_ci
9948c2ecf20Sopenharmony_ci	tmp1byte = rtl_read_byte(rtlpriv, 0x352);
9958c2ecf20Sopenharmony_ci	count = 0;
9968c2ecf20Sopenharmony_ci	while (tmp1byte && count < 20) {
9978c2ecf20Sopenharmony_ci		udelay(10);
9988c2ecf20Sopenharmony_ci		tmp1byte = rtl_read_byte(rtlpriv, 0x352);
9998c2ecf20Sopenharmony_ci		count++;
10008c2ecf20Sopenharmony_ci	}
10018c2ecf20Sopenharmony_ci}
10028c2ecf20Sopenharmony_ci
10038c2ecf20Sopenharmony_civoid rtl88ee_enable_hw_security_config(struct ieee80211_hw *hw)
10048c2ecf20Sopenharmony_ci{
10058c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
10068c2ecf20Sopenharmony_ci	u8 sec_reg_value;
10078c2ecf20Sopenharmony_ci
10088c2ecf20Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG,
10098c2ecf20Sopenharmony_ci		"PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
10108c2ecf20Sopenharmony_ci		rtlpriv->sec.pairwise_enc_algorithm,
10118c2ecf20Sopenharmony_ci		rtlpriv->sec.group_enc_algorithm);
10128c2ecf20Sopenharmony_ci
10138c2ecf20Sopenharmony_ci	if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
10148c2ecf20Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
10158c2ecf20Sopenharmony_ci			"not open hw encryption\n");
10168c2ecf20Sopenharmony_ci		return;
10178c2ecf20Sopenharmony_ci	}
10188c2ecf20Sopenharmony_ci
10198c2ecf20Sopenharmony_ci	sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE;
10208c2ecf20Sopenharmony_ci
10218c2ecf20Sopenharmony_ci	if (rtlpriv->sec.use_defaultkey) {
10228c2ecf20Sopenharmony_ci		sec_reg_value |= SCR_TXUSEDK;
10238c2ecf20Sopenharmony_ci		sec_reg_value |= SCR_RXUSEDK;
10248c2ecf20Sopenharmony_ci	}
10258c2ecf20Sopenharmony_ci
10268c2ecf20Sopenharmony_ci	sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
10278c2ecf20Sopenharmony_ci
10288c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
10298c2ecf20Sopenharmony_ci
10308c2ecf20Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
10318c2ecf20Sopenharmony_ci		"The SECR-value %x\n", sec_reg_value);
10328c2ecf20Sopenharmony_ci
10338c2ecf20Sopenharmony_ci	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
10348c2ecf20Sopenharmony_ci}
10358c2ecf20Sopenharmony_ci
10368c2ecf20Sopenharmony_ciint rtl88ee_hw_init(struct ieee80211_hw *hw)
10378c2ecf20Sopenharmony_ci{
10388c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
10398c2ecf20Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
10408c2ecf20Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
10418c2ecf20Sopenharmony_ci	struct rtl_phy *rtlphy = &(rtlpriv->phy);
10428c2ecf20Sopenharmony_ci	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
10438c2ecf20Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
10448c2ecf20Sopenharmony_ci	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
10458c2ecf20Sopenharmony_ci	bool rtstatus;
10468c2ecf20Sopenharmony_ci	int err = 0;
10478c2ecf20Sopenharmony_ci	u8 tmp_u1b, u1byte;
10488c2ecf20Sopenharmony_ci	unsigned long flags;
10498c2ecf20Sopenharmony_ci
10508c2ecf20Sopenharmony_ci	rtlpriv->rtlhal.being_init_adapter = true;
10518c2ecf20Sopenharmony_ci	/* As this function can take a very long time (up to 350 ms)
10528c2ecf20Sopenharmony_ci	 * and can be called with irqs disabled, reenable the irqs
10538c2ecf20Sopenharmony_ci	 * to let the other devices continue being serviced.
10548c2ecf20Sopenharmony_ci	 *
10558c2ecf20Sopenharmony_ci	 * It is safe doing so since our own interrupts will only be enabled
10568c2ecf20Sopenharmony_ci	 * in a subsequent step.
10578c2ecf20Sopenharmony_ci	 */
10588c2ecf20Sopenharmony_ci	local_save_flags(flags);
10598c2ecf20Sopenharmony_ci	local_irq_enable();
10608c2ecf20Sopenharmony_ci	rtlhal->fw_ready = false;
10618c2ecf20Sopenharmony_ci
10628c2ecf20Sopenharmony_ci	rtlpriv->intf_ops->disable_aspm(hw);
10638c2ecf20Sopenharmony_ci
10648c2ecf20Sopenharmony_ci	tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CLKR+1);
10658c2ecf20Sopenharmony_ci	u1byte = rtl_read_byte(rtlpriv, REG_CR);
10668c2ecf20Sopenharmony_ci	if ((tmp_u1b & BIT(3)) && (u1byte != 0 && u1byte != 0xEA)) {
10678c2ecf20Sopenharmony_ci		rtlhal->mac_func_enable = true;
10688c2ecf20Sopenharmony_ci	} else {
10698c2ecf20Sopenharmony_ci		rtlhal->mac_func_enable = false;
10708c2ecf20Sopenharmony_ci		rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_88E;
10718c2ecf20Sopenharmony_ci	}
10728c2ecf20Sopenharmony_ci
10738c2ecf20Sopenharmony_ci	rtstatus = _rtl88ee_init_mac(hw);
10748c2ecf20Sopenharmony_ci	if (!rtstatus) {
10758c2ecf20Sopenharmony_ci		pr_info("Init MAC failed\n");
10768c2ecf20Sopenharmony_ci		err = 1;
10778c2ecf20Sopenharmony_ci		goto exit;
10788c2ecf20Sopenharmony_ci	}
10798c2ecf20Sopenharmony_ci
10808c2ecf20Sopenharmony_ci	err = rtl88e_download_fw(hw, false);
10818c2ecf20Sopenharmony_ci	if (err) {
10828c2ecf20Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
10838c2ecf20Sopenharmony_ci			"Failed to download FW. Init HW without FW now..\n");
10848c2ecf20Sopenharmony_ci		err = 1;
10858c2ecf20Sopenharmony_ci		goto exit;
10868c2ecf20Sopenharmony_ci	}
10878c2ecf20Sopenharmony_ci	rtlhal->fw_ready = true;
10888c2ecf20Sopenharmony_ci	/*fw related variable initialize */
10898c2ecf20Sopenharmony_ci	rtlhal->last_hmeboxnum = 0;
10908c2ecf20Sopenharmony_ci	rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_88E;
10918c2ecf20Sopenharmony_ci	rtlhal->fw_clk_change_in_progress = false;
10928c2ecf20Sopenharmony_ci	rtlhal->allow_sw_to_change_hwclc = false;
10938c2ecf20Sopenharmony_ci	ppsc->fw_current_inpsmode = false;
10948c2ecf20Sopenharmony_ci
10958c2ecf20Sopenharmony_ci	rtl88e_phy_mac_config(hw);
10968c2ecf20Sopenharmony_ci	/* because last function modify RCR, so we update
10978c2ecf20Sopenharmony_ci	 * rcr var here, or TP will unstable for receive_config
10988c2ecf20Sopenharmony_ci	 * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx
10998c2ecf20Sopenharmony_ci	 * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252
11008c2ecf20Sopenharmony_ci	 */
11018c2ecf20Sopenharmony_ci	rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
11028c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
11038c2ecf20Sopenharmony_ci
11048c2ecf20Sopenharmony_ci	rtl88e_phy_bb_config(hw);
11058c2ecf20Sopenharmony_ci	rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
11068c2ecf20Sopenharmony_ci	rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
11078c2ecf20Sopenharmony_ci
11088c2ecf20Sopenharmony_ci	rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
11098c2ecf20Sopenharmony_ci	rtl88e_phy_rf_config(hw);
11108c2ecf20Sopenharmony_ci
11118c2ecf20Sopenharmony_ci	rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
11128c2ecf20Sopenharmony_ci						 RF_CHNLBW, RFREG_OFFSET_MASK);
11138c2ecf20Sopenharmony_ci	rtlphy->rfreg_chnlval[0] = rtlphy->rfreg_chnlval[0] & 0xfff00fff;
11148c2ecf20Sopenharmony_ci
11158c2ecf20Sopenharmony_ci	_rtl88ee_hw_configure(hw);
11168c2ecf20Sopenharmony_ci	rtl_cam_reset_all_entry(hw);
11178c2ecf20Sopenharmony_ci	rtl88ee_enable_hw_security_config(hw);
11188c2ecf20Sopenharmony_ci
11198c2ecf20Sopenharmony_ci	rtlhal->mac_func_enable = true;
11208c2ecf20Sopenharmony_ci	ppsc->rfpwr_state = ERFON;
11218c2ecf20Sopenharmony_ci
11228c2ecf20Sopenharmony_ci	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
11238c2ecf20Sopenharmony_ci	_rtl88ee_enable_aspm_back_door(hw);
11248c2ecf20Sopenharmony_ci	rtlpriv->intf_ops->enable_aspm(hw);
11258c2ecf20Sopenharmony_ci
11268c2ecf20Sopenharmony_ci	if (ppsc->rfpwr_state == ERFON) {
11278c2ecf20Sopenharmony_ci		if ((rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) ||
11288c2ecf20Sopenharmony_ci		    ((rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) &&
11298c2ecf20Sopenharmony_ci		     (rtlhal->oem_id == RT_CID_819X_HP))) {
11308c2ecf20Sopenharmony_ci			rtl88e_phy_set_rfpath_switch(hw, true);
11318c2ecf20Sopenharmony_ci			rtlpriv->dm.fat_table.rx_idle_ant = MAIN_ANT;
11328c2ecf20Sopenharmony_ci		} else {
11338c2ecf20Sopenharmony_ci			rtl88e_phy_set_rfpath_switch(hw, false);
11348c2ecf20Sopenharmony_ci			rtlpriv->dm.fat_table.rx_idle_ant = AUX_ANT;
11358c2ecf20Sopenharmony_ci		}
11368c2ecf20Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "rx idle ant %s\n",
11378c2ecf20Sopenharmony_ci			(rtlpriv->dm.fat_table.rx_idle_ant == MAIN_ANT) ?
11388c2ecf20Sopenharmony_ci			("MAIN_ANT") : ("AUX_ANT"));
11398c2ecf20Sopenharmony_ci
11408c2ecf20Sopenharmony_ci		if (rtlphy->iqk_initialized) {
11418c2ecf20Sopenharmony_ci			rtl88e_phy_iq_calibrate(hw, true);
11428c2ecf20Sopenharmony_ci		} else {
11438c2ecf20Sopenharmony_ci			rtl88e_phy_iq_calibrate(hw, false);
11448c2ecf20Sopenharmony_ci			rtlphy->iqk_initialized = true;
11458c2ecf20Sopenharmony_ci		}
11468c2ecf20Sopenharmony_ci
11478c2ecf20Sopenharmony_ci		rtl88e_dm_check_txpower_tracking(hw);
11488c2ecf20Sopenharmony_ci		rtl88e_phy_lc_calibrate(hw);
11498c2ecf20Sopenharmony_ci	}
11508c2ecf20Sopenharmony_ci
11518c2ecf20Sopenharmony_ci	tmp_u1b = efuse_read_1byte(hw, 0x1FA);
11528c2ecf20Sopenharmony_ci	if (!(tmp_u1b & BIT(0))) {
11538c2ecf20Sopenharmony_ci		rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05);
11548c2ecf20Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "PA BIAS path A\n");
11558c2ecf20Sopenharmony_ci	}
11568c2ecf20Sopenharmony_ci
11578c2ecf20Sopenharmony_ci	if (!(tmp_u1b & BIT(4))) {
11588c2ecf20Sopenharmony_ci		tmp_u1b = rtl_read_byte(rtlpriv, 0x16);
11598c2ecf20Sopenharmony_ci		tmp_u1b &= 0x0F;
11608c2ecf20Sopenharmony_ci		rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80);
11618c2ecf20Sopenharmony_ci		udelay(10);
11628c2ecf20Sopenharmony_ci		rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90);
11638c2ecf20Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "under 1.5V\n");
11648c2ecf20Sopenharmony_ci	}
11658c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_NAV_CTRL+2,  ((30000+127)/128));
11668c2ecf20Sopenharmony_ci	rtl88e_dm_init(hw);
11678c2ecf20Sopenharmony_ciexit:
11688c2ecf20Sopenharmony_ci	local_irq_restore(flags);
11698c2ecf20Sopenharmony_ci	rtlpriv->rtlhal.being_init_adapter = false;
11708c2ecf20Sopenharmony_ci	return err;
11718c2ecf20Sopenharmony_ci}
11728c2ecf20Sopenharmony_ci
11738c2ecf20Sopenharmony_cistatic enum version_8188e _rtl88ee_read_chip_version(struct ieee80211_hw *hw)
11748c2ecf20Sopenharmony_ci{
11758c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
11768c2ecf20Sopenharmony_ci	struct rtl_phy *rtlphy = &(rtlpriv->phy);
11778c2ecf20Sopenharmony_ci	enum version_8188e version = VERSION_UNKNOWN;
11788c2ecf20Sopenharmony_ci	u32 value32;
11798c2ecf20Sopenharmony_ci
11808c2ecf20Sopenharmony_ci	value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
11818c2ecf20Sopenharmony_ci	if (value32 & TRP_VAUX_EN) {
11828c2ecf20Sopenharmony_ci		version = (enum version_8188e) VERSION_TEST_CHIP_88E;
11838c2ecf20Sopenharmony_ci	} else {
11848c2ecf20Sopenharmony_ci		version = NORMAL_CHIP;
11858c2ecf20Sopenharmony_ci		version = version | ((value32 & TYPE_ID) ? RF_TYPE_2T2R : 0);
11868c2ecf20Sopenharmony_ci		version = version | ((value32 & VENDOR_ID) ?
11878c2ecf20Sopenharmony_ci			  CHIP_VENDOR_UMC : 0);
11888c2ecf20Sopenharmony_ci	}
11898c2ecf20Sopenharmony_ci
11908c2ecf20Sopenharmony_ci	rtlphy->rf_type = RF_1T1R;
11918c2ecf20Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
11928c2ecf20Sopenharmony_ci		"Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
11938c2ecf20Sopenharmony_ci		"RF_2T2R" : "RF_1T1R");
11948c2ecf20Sopenharmony_ci
11958c2ecf20Sopenharmony_ci	return version;
11968c2ecf20Sopenharmony_ci}
11978c2ecf20Sopenharmony_ci
11988c2ecf20Sopenharmony_cistatic int _rtl88ee_set_media_status(struct ieee80211_hw *hw,
11998c2ecf20Sopenharmony_ci				     enum nl80211_iftype type)
12008c2ecf20Sopenharmony_ci{
12018c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
12028c2ecf20Sopenharmony_ci	u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc;
12038c2ecf20Sopenharmony_ci	enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
12048c2ecf20Sopenharmony_ci	u8 mode = MSR_NOLINK;
12058c2ecf20Sopenharmony_ci
12068c2ecf20Sopenharmony_ci	switch (type) {
12078c2ecf20Sopenharmony_ci	case NL80211_IFTYPE_UNSPECIFIED:
12088c2ecf20Sopenharmony_ci		mode = MSR_NOLINK;
12098c2ecf20Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
12108c2ecf20Sopenharmony_ci			"Set Network type to NO LINK!\n");
12118c2ecf20Sopenharmony_ci		break;
12128c2ecf20Sopenharmony_ci	case NL80211_IFTYPE_ADHOC:
12138c2ecf20Sopenharmony_ci	case NL80211_IFTYPE_MESH_POINT:
12148c2ecf20Sopenharmony_ci		mode = MSR_ADHOC;
12158c2ecf20Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
12168c2ecf20Sopenharmony_ci			"Set Network type to Ad Hoc!\n");
12178c2ecf20Sopenharmony_ci		break;
12188c2ecf20Sopenharmony_ci	case NL80211_IFTYPE_STATION:
12198c2ecf20Sopenharmony_ci		mode = MSR_INFRA;
12208c2ecf20Sopenharmony_ci		ledaction = LED_CTL_LINK;
12218c2ecf20Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
12228c2ecf20Sopenharmony_ci			"Set Network type to STA!\n");
12238c2ecf20Sopenharmony_ci		break;
12248c2ecf20Sopenharmony_ci	case NL80211_IFTYPE_AP:
12258c2ecf20Sopenharmony_ci		mode = MSR_AP;
12268c2ecf20Sopenharmony_ci		ledaction = LED_CTL_LINK;
12278c2ecf20Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
12288c2ecf20Sopenharmony_ci			"Set Network type to AP!\n");
12298c2ecf20Sopenharmony_ci		break;
12308c2ecf20Sopenharmony_ci	default:
12318c2ecf20Sopenharmony_ci		pr_err("Network type %d not support!\n", type);
12328c2ecf20Sopenharmony_ci		return 1;
12338c2ecf20Sopenharmony_ci		break;
12348c2ecf20Sopenharmony_ci	}
12358c2ecf20Sopenharmony_ci
12368c2ecf20Sopenharmony_ci	/* MSR_INFRA == Link in infrastructure network;
12378c2ecf20Sopenharmony_ci	 * MSR_ADHOC == Link in ad hoc network;
12388c2ecf20Sopenharmony_ci	 * Therefore, check link state is necessary.
12398c2ecf20Sopenharmony_ci	 *
12408c2ecf20Sopenharmony_ci	 * MSR_AP == AP mode; link state is not cared here.
12418c2ecf20Sopenharmony_ci	 */
12428c2ecf20Sopenharmony_ci	if (mode != MSR_AP && rtlpriv->mac80211.link_state < MAC80211_LINKED) {
12438c2ecf20Sopenharmony_ci		mode = MSR_NOLINK;
12448c2ecf20Sopenharmony_ci		ledaction = LED_CTL_NO_LINK;
12458c2ecf20Sopenharmony_ci	}
12468c2ecf20Sopenharmony_ci
12478c2ecf20Sopenharmony_ci	if (mode == MSR_NOLINK || mode == MSR_INFRA) {
12488c2ecf20Sopenharmony_ci		_rtl88ee_stop_tx_beacon(hw);
12498c2ecf20Sopenharmony_ci		_rtl88ee_enable_bcn_sub_func(hw);
12508c2ecf20Sopenharmony_ci	} else if (mode == MSR_ADHOC || mode == MSR_AP) {
12518c2ecf20Sopenharmony_ci		_rtl88ee_resume_tx_beacon(hw);
12528c2ecf20Sopenharmony_ci		_rtl88ee_disable_bcn_sub_func(hw);
12538c2ecf20Sopenharmony_ci	} else {
12548c2ecf20Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
12558c2ecf20Sopenharmony_ci			"Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n",
12568c2ecf20Sopenharmony_ci			mode);
12578c2ecf20Sopenharmony_ci	}
12588c2ecf20Sopenharmony_ci
12598c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, MSR, bt_msr | mode);
12608c2ecf20Sopenharmony_ci	rtlpriv->cfg->ops->led_control(hw, ledaction);
12618c2ecf20Sopenharmony_ci	if (mode == MSR_AP)
12628c2ecf20Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
12638c2ecf20Sopenharmony_ci	else
12648c2ecf20Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
12658c2ecf20Sopenharmony_ci	return 0;
12668c2ecf20Sopenharmony_ci}
12678c2ecf20Sopenharmony_ci
12688c2ecf20Sopenharmony_civoid rtl88ee_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
12698c2ecf20Sopenharmony_ci{
12708c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
12718c2ecf20Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
12728c2ecf20Sopenharmony_ci	u32 reg_rcr = rtlpci->receive_config;
12738c2ecf20Sopenharmony_ci
12748c2ecf20Sopenharmony_ci	if (rtlpriv->psc.rfpwr_state != ERFON)
12758c2ecf20Sopenharmony_ci		return;
12768c2ecf20Sopenharmony_ci
12778c2ecf20Sopenharmony_ci	if (check_bssid == true) {
12788c2ecf20Sopenharmony_ci		reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
12798c2ecf20Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
12808c2ecf20Sopenharmony_ci					      (u8 *)(&reg_rcr));
12818c2ecf20Sopenharmony_ci		_rtl88ee_set_bcn_ctrl_reg(hw, 0, BIT(4));
12828c2ecf20Sopenharmony_ci	} else if (check_bssid == false) {
12838c2ecf20Sopenharmony_ci		reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
12848c2ecf20Sopenharmony_ci		_rtl88ee_set_bcn_ctrl_reg(hw, BIT(4), 0);
12858c2ecf20Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw,
12868c2ecf20Sopenharmony_ci			HW_VAR_RCR, (u8 *)(&reg_rcr));
12878c2ecf20Sopenharmony_ci	}
12888c2ecf20Sopenharmony_ci
12898c2ecf20Sopenharmony_ci}
12908c2ecf20Sopenharmony_ci
12918c2ecf20Sopenharmony_ciint rtl88ee_set_network_type(struct ieee80211_hw *hw,
12928c2ecf20Sopenharmony_ci			     enum nl80211_iftype type)
12938c2ecf20Sopenharmony_ci{
12948c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
12958c2ecf20Sopenharmony_ci
12968c2ecf20Sopenharmony_ci	if (_rtl88ee_set_media_status(hw, type))
12978c2ecf20Sopenharmony_ci		return -EOPNOTSUPP;
12988c2ecf20Sopenharmony_ci
12998c2ecf20Sopenharmony_ci	if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
13008c2ecf20Sopenharmony_ci		if (type != NL80211_IFTYPE_AP &&
13018c2ecf20Sopenharmony_ci		    type != NL80211_IFTYPE_MESH_POINT)
13028c2ecf20Sopenharmony_ci			rtl88ee_set_check_bssid(hw, true);
13038c2ecf20Sopenharmony_ci	} else {
13048c2ecf20Sopenharmony_ci		rtl88ee_set_check_bssid(hw, false);
13058c2ecf20Sopenharmony_ci	}
13068c2ecf20Sopenharmony_ci
13078c2ecf20Sopenharmony_ci	return 0;
13088c2ecf20Sopenharmony_ci}
13098c2ecf20Sopenharmony_ci
13108c2ecf20Sopenharmony_ci/* don't set REG_EDCA_BE_PARAM here
13118c2ecf20Sopenharmony_ci * because mac80211 will send pkt when scan
13128c2ecf20Sopenharmony_ci */
13138c2ecf20Sopenharmony_civoid rtl88ee_set_qos(struct ieee80211_hw *hw, int aci)
13148c2ecf20Sopenharmony_ci{
13158c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
13168c2ecf20Sopenharmony_ci	rtl88e_dm_init_edca_turbo(hw);
13178c2ecf20Sopenharmony_ci	switch (aci) {
13188c2ecf20Sopenharmony_ci	case AC1_BK:
13198c2ecf20Sopenharmony_ci		rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f);
13208c2ecf20Sopenharmony_ci		break;
13218c2ecf20Sopenharmony_ci	case AC0_BE:
13228c2ecf20Sopenharmony_ci		break;
13238c2ecf20Sopenharmony_ci	case AC2_VI:
13248c2ecf20Sopenharmony_ci		rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322);
13258c2ecf20Sopenharmony_ci		break;
13268c2ecf20Sopenharmony_ci	case AC3_VO:
13278c2ecf20Sopenharmony_ci		rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
13288c2ecf20Sopenharmony_ci		break;
13298c2ecf20Sopenharmony_ci	default:
13308c2ecf20Sopenharmony_ci		WARN_ONCE(true, "rtl8188ee: invalid aci: %d !\n", aci);
13318c2ecf20Sopenharmony_ci		break;
13328c2ecf20Sopenharmony_ci	}
13338c2ecf20Sopenharmony_ci}
13348c2ecf20Sopenharmony_ci
13358c2ecf20Sopenharmony_civoid rtl88ee_enable_interrupt(struct ieee80211_hw *hw)
13368c2ecf20Sopenharmony_ci{
13378c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
13388c2ecf20Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
13398c2ecf20Sopenharmony_ci
13408c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_HIMR,
13418c2ecf20Sopenharmony_ci			rtlpci->irq_mask[0] & 0xFFFFFFFF);
13428c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_HIMRE,
13438c2ecf20Sopenharmony_ci			rtlpci->irq_mask[1] & 0xFFFFFFFF);
13448c2ecf20Sopenharmony_ci	rtlpci->irq_enabled = true;
13458c2ecf20Sopenharmony_ci	/* there are some C2H CMDs have been sent
13468c2ecf20Sopenharmony_ci	 * before system interrupt is enabled, e.g., C2H, CPWM.
13478c2ecf20Sopenharmony_ci	 * So we need to clear all C2H events that FW has notified,
13488c2ecf20Sopenharmony_ci	 * otherwise FW won't schedule any commands anymore.
13498c2ecf20Sopenharmony_ci	 */
13508c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_C2HEVT_CLEAR, 0);
13518c2ecf20Sopenharmony_ci	/*enable system interrupt*/
13528c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_HSIMR,
13538c2ecf20Sopenharmony_ci			rtlpci->sys_irq_mask & 0xFFFFFFFF);
13548c2ecf20Sopenharmony_ci}
13558c2ecf20Sopenharmony_ci
13568c2ecf20Sopenharmony_civoid rtl88ee_disable_interrupt(struct ieee80211_hw *hw)
13578c2ecf20Sopenharmony_ci{
13588c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
13598c2ecf20Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
13608c2ecf20Sopenharmony_ci
13618c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_HIMR, IMR_DISABLED);
13628c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_HIMRE, IMR_DISABLED);
13638c2ecf20Sopenharmony_ci	rtlpci->irq_enabled = false;
13648c2ecf20Sopenharmony_ci	/*synchronize_irq(rtlpci->pdev->irq);*/
13658c2ecf20Sopenharmony_ci}
13668c2ecf20Sopenharmony_ci
13678c2ecf20Sopenharmony_cistatic void _rtl88ee_poweroff_adapter(struct ieee80211_hw *hw)
13688c2ecf20Sopenharmony_ci{
13698c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
13708c2ecf20Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
13718c2ecf20Sopenharmony_ci	u8 u1b_tmp;
13728c2ecf20Sopenharmony_ci	u32 count = 0;
13738c2ecf20Sopenharmony_ci	rtlhal->mac_func_enable = false;
13748c2ecf20Sopenharmony_ci	rtlpriv->intf_ops->enable_aspm(hw);
13758c2ecf20Sopenharmony_ci
13768c2ecf20Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "POWER OFF adapter\n");
13778c2ecf20Sopenharmony_ci	u1b_tmp = rtl_read_byte(rtlpriv, REG_TX_RPT_CTRL);
13788c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_TX_RPT_CTRL, u1b_tmp & (~BIT(1)));
13798c2ecf20Sopenharmony_ci
13808c2ecf20Sopenharmony_ci	u1b_tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
13818c2ecf20Sopenharmony_ci	while (!(u1b_tmp & BIT(1)) && (count++ < 100)) {
13828c2ecf20Sopenharmony_ci		udelay(10);
13838c2ecf20Sopenharmony_ci		u1b_tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
13848c2ecf20Sopenharmony_ci		count++;
13858c2ecf20Sopenharmony_ci	}
13868c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+1, 0xFF);
13878c2ecf20Sopenharmony_ci
13888c2ecf20Sopenharmony_ci	rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
13898c2ecf20Sopenharmony_ci				 PWR_INTF_PCI_MSK,
13908c2ecf20Sopenharmony_ci				 RTL8188EE_NIC_LPS_ENTER_FLOW);
13918c2ecf20Sopenharmony_ci
13928c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00);
13938c2ecf20Sopenharmony_ci
13948c2ecf20Sopenharmony_ci	if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->fw_ready)
13958c2ecf20Sopenharmony_ci		rtl88e_firmware_selfreset(hw);
13968c2ecf20Sopenharmony_ci
13978c2ecf20Sopenharmony_ci	u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1);
13988c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2))));
13998c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
14008c2ecf20Sopenharmony_ci
14018c2ecf20Sopenharmony_ci	u1b_tmp = rtl_read_byte(rtlpriv, REG_32K_CTRL);
14028c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_32K_CTRL, (u1b_tmp & (~BIT(0))));
14038c2ecf20Sopenharmony_ci
14048c2ecf20Sopenharmony_ci	rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
14058c2ecf20Sopenharmony_ci				 PWR_INTF_PCI_MSK, RTL8188EE_NIC_DISABLE_FLOW);
14068c2ecf20Sopenharmony_ci
14078c2ecf20Sopenharmony_ci	u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL+1);
14088c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_RSV_CTRL+1, (u1b_tmp & (~BIT(3))));
14098c2ecf20Sopenharmony_ci	u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL+1);
14108c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_RSV_CTRL+1, (u1b_tmp | BIT(3)));
14118c2ecf20Sopenharmony_ci
14128c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0E);
14138c2ecf20Sopenharmony_ci
14148c2ecf20Sopenharmony_ci	u1b_tmp = rtl_read_byte(rtlpriv, GPIO_IN);
14158c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, GPIO_OUT, u1b_tmp);
14168c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, GPIO_IO_SEL, 0x7F);
14178c2ecf20Sopenharmony_ci
14188c2ecf20Sopenharmony_ci	u1b_tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL);
14198c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL, (u1b_tmp << 4) | u1b_tmp);
14208c2ecf20Sopenharmony_ci	u1b_tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL+1);
14218c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL+1, u1b_tmp | 0x0F);
14228c2ecf20Sopenharmony_ci
14238c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_GPIO_IO_SEL_2+2, 0x00080808);
14248c2ecf20Sopenharmony_ci}
14258c2ecf20Sopenharmony_ci
14268c2ecf20Sopenharmony_civoid rtl88ee_card_disable(struct ieee80211_hw *hw)
14278c2ecf20Sopenharmony_ci{
14288c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
14298c2ecf20Sopenharmony_ci	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
14308c2ecf20Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
14318c2ecf20Sopenharmony_ci	enum nl80211_iftype opmode;
14328c2ecf20Sopenharmony_ci
14338c2ecf20Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "RTL8188ee card disable\n");
14348c2ecf20Sopenharmony_ci
14358c2ecf20Sopenharmony_ci	mac->link_state = MAC80211_NOLINK;
14368c2ecf20Sopenharmony_ci	opmode = NL80211_IFTYPE_UNSPECIFIED;
14378c2ecf20Sopenharmony_ci
14388c2ecf20Sopenharmony_ci	_rtl88ee_set_media_status(hw, opmode);
14398c2ecf20Sopenharmony_ci
14408c2ecf20Sopenharmony_ci	if (rtlpriv->rtlhal.driver_is_goingto_unload ||
14418c2ecf20Sopenharmony_ci	    ppsc->rfoff_reason > RF_CHANGE_BY_PS)
14428c2ecf20Sopenharmony_ci		rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
14438c2ecf20Sopenharmony_ci
14448c2ecf20Sopenharmony_ci	RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
14458c2ecf20Sopenharmony_ci	_rtl88ee_poweroff_adapter(hw);
14468c2ecf20Sopenharmony_ci
14478c2ecf20Sopenharmony_ci	/* after power off we should do iqk again */
14488c2ecf20Sopenharmony_ci	rtlpriv->phy.iqk_initialized = false;
14498c2ecf20Sopenharmony_ci}
14508c2ecf20Sopenharmony_ci
14518c2ecf20Sopenharmony_civoid rtl88ee_interrupt_recognized(struct ieee80211_hw *hw,
14528c2ecf20Sopenharmony_ci				  struct rtl_int *intvec)
14538c2ecf20Sopenharmony_ci{
14548c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
14558c2ecf20Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
14568c2ecf20Sopenharmony_ci
14578c2ecf20Sopenharmony_ci	intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0];
14588c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, ISR, intvec->inta);
14598c2ecf20Sopenharmony_ci
14608c2ecf20Sopenharmony_ci	intvec->intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1];
14618c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_HISRE, intvec->intb);
14628c2ecf20Sopenharmony_ci
14638c2ecf20Sopenharmony_ci}
14648c2ecf20Sopenharmony_ci
14658c2ecf20Sopenharmony_civoid rtl88ee_set_beacon_related_registers(struct ieee80211_hw *hw)
14668c2ecf20Sopenharmony_ci{
14678c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
14688c2ecf20Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
14698c2ecf20Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
14708c2ecf20Sopenharmony_ci	u16 bcn_interval, atim_window;
14718c2ecf20Sopenharmony_ci
14728c2ecf20Sopenharmony_ci	bcn_interval = mac->beacon_interval;
14738c2ecf20Sopenharmony_ci	atim_window = 2;	/*FIX MERGE */
14748c2ecf20Sopenharmony_ci	rtl88ee_disable_interrupt(hw);
14758c2ecf20Sopenharmony_ci	rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
14768c2ecf20Sopenharmony_ci	rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
14778c2ecf20Sopenharmony_ci	rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
14788c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18);
14798c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18);
14808c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, 0x606, 0x30);
14818c2ecf20Sopenharmony_ci	rtlpci->reg_bcn_ctrl_val |= BIT(3);
14828c2ecf20Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val);
14838c2ecf20Sopenharmony_ci	/*rtl88ee_enable_interrupt(hw);*/
14848c2ecf20Sopenharmony_ci}
14858c2ecf20Sopenharmony_ci
14868c2ecf20Sopenharmony_civoid rtl88ee_set_beacon_interval(struct ieee80211_hw *hw)
14878c2ecf20Sopenharmony_ci{
14888c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
14898c2ecf20Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
14908c2ecf20Sopenharmony_ci	u16 bcn_interval = mac->beacon_interval;
14918c2ecf20Sopenharmony_ci
14928c2ecf20Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_BEACON, DBG_DMESG,
14938c2ecf20Sopenharmony_ci		"beacon_interval:%d\n", bcn_interval);
14948c2ecf20Sopenharmony_ci	/*rtl88ee_disable_interrupt(hw);*/
14958c2ecf20Sopenharmony_ci	rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
14968c2ecf20Sopenharmony_ci	/*rtl88ee_enable_interrupt(hw);*/
14978c2ecf20Sopenharmony_ci}
14988c2ecf20Sopenharmony_ci
14998c2ecf20Sopenharmony_civoid rtl88ee_update_interrupt_mask(struct ieee80211_hw *hw,
15008c2ecf20Sopenharmony_ci				   u32 add_msr, u32 rm_msr)
15018c2ecf20Sopenharmony_ci{
15028c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
15038c2ecf20Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
15048c2ecf20Sopenharmony_ci
15058c2ecf20Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD,
15068c2ecf20Sopenharmony_ci		"add_msr:%x, rm_msr:%x\n", add_msr, rm_msr);
15078c2ecf20Sopenharmony_ci
15088c2ecf20Sopenharmony_ci	if (add_msr)
15098c2ecf20Sopenharmony_ci		rtlpci->irq_mask[0] |= add_msr;
15108c2ecf20Sopenharmony_ci	if (rm_msr)
15118c2ecf20Sopenharmony_ci		rtlpci->irq_mask[0] &= (~rm_msr);
15128c2ecf20Sopenharmony_ci	rtl88ee_disable_interrupt(hw);
15138c2ecf20Sopenharmony_ci	rtl88ee_enable_interrupt(hw);
15148c2ecf20Sopenharmony_ci}
15158c2ecf20Sopenharmony_ci
15168c2ecf20Sopenharmony_cistatic u8 _rtl88e_get_chnl_group(u8 chnl)
15178c2ecf20Sopenharmony_ci{
15188c2ecf20Sopenharmony_ci	u8 group = 0;
15198c2ecf20Sopenharmony_ci
15208c2ecf20Sopenharmony_ci	if (chnl < 3)
15218c2ecf20Sopenharmony_ci		group = 0;
15228c2ecf20Sopenharmony_ci	else if (chnl < 6)
15238c2ecf20Sopenharmony_ci		group = 1;
15248c2ecf20Sopenharmony_ci	else if (chnl < 9)
15258c2ecf20Sopenharmony_ci		group = 2;
15268c2ecf20Sopenharmony_ci	else if (chnl < 12)
15278c2ecf20Sopenharmony_ci		group = 3;
15288c2ecf20Sopenharmony_ci	else if (chnl < 14)
15298c2ecf20Sopenharmony_ci		group = 4;
15308c2ecf20Sopenharmony_ci	else if (chnl == 14)
15318c2ecf20Sopenharmony_ci		group = 5;
15328c2ecf20Sopenharmony_ci
15338c2ecf20Sopenharmony_ci	return group;
15348c2ecf20Sopenharmony_ci}
15358c2ecf20Sopenharmony_ci
15368c2ecf20Sopenharmony_cistatic void set_24g_base(struct txpower_info_2g *pwrinfo24g, u32 rfpath)
15378c2ecf20Sopenharmony_ci{
15388c2ecf20Sopenharmony_ci	int group, txcnt;
15398c2ecf20Sopenharmony_ci
15408c2ecf20Sopenharmony_ci	for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) {
15418c2ecf20Sopenharmony_ci		pwrinfo24g->index_cck_base[rfpath][group] = 0x2D;
15428c2ecf20Sopenharmony_ci		pwrinfo24g->index_bw40_base[rfpath][group] = 0x2D;
15438c2ecf20Sopenharmony_ci	}
15448c2ecf20Sopenharmony_ci	for (txcnt = 0; txcnt < MAX_TX_COUNT; txcnt++) {
15458c2ecf20Sopenharmony_ci		if (txcnt == 0) {
15468c2ecf20Sopenharmony_ci			pwrinfo24g->bw20_diff[rfpath][0] = 0x02;
15478c2ecf20Sopenharmony_ci			pwrinfo24g->ofdm_diff[rfpath][0] = 0x04;
15488c2ecf20Sopenharmony_ci		} else {
15498c2ecf20Sopenharmony_ci			pwrinfo24g->bw20_diff[rfpath][txcnt] = 0xFE;
15508c2ecf20Sopenharmony_ci			pwrinfo24g->bw40_diff[rfpath][txcnt] = 0xFE;
15518c2ecf20Sopenharmony_ci			pwrinfo24g->cck_diff[rfpath][txcnt] =	0xFE;
15528c2ecf20Sopenharmony_ci			pwrinfo24g->ofdm_diff[rfpath][txcnt] = 0xFE;
15538c2ecf20Sopenharmony_ci		}
15548c2ecf20Sopenharmony_ci	}
15558c2ecf20Sopenharmony_ci}
15568c2ecf20Sopenharmony_ci
15578c2ecf20Sopenharmony_cistatic void read_power_value_fromprom(struct ieee80211_hw *hw,
15588c2ecf20Sopenharmony_ci				      struct txpower_info_2g *pwrinfo24g,
15598c2ecf20Sopenharmony_ci				      struct txpower_info_5g *pwrinfo5g,
15608c2ecf20Sopenharmony_ci				      bool autoload_fail, u8 *hwinfo)
15618c2ecf20Sopenharmony_ci{
15628c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
15638c2ecf20Sopenharmony_ci	u32 rfpath, eeaddr = EEPROM_TX_PWR_INX, group, txcnt = 0;
15648c2ecf20Sopenharmony_ci
15658c2ecf20Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
15668c2ecf20Sopenharmony_ci		"hal_ReadPowerValueFromPROM88E():PROMContent[0x%x]=0x%x\n",
15678c2ecf20Sopenharmony_ci		(eeaddr + 1), hwinfo[eeaddr + 1]);
15688c2ecf20Sopenharmony_ci	if (0xFF == hwinfo[eeaddr+1])  /*YJ,add,120316*/
15698c2ecf20Sopenharmony_ci		autoload_fail = true;
15708c2ecf20Sopenharmony_ci
15718c2ecf20Sopenharmony_ci	if (autoload_fail) {
15728c2ecf20Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
15738c2ecf20Sopenharmony_ci			"auto load fail : Use Default value!\n");
15748c2ecf20Sopenharmony_ci		for (rfpath = 0 ; rfpath < MAX_RF_PATH ; rfpath++) {
15758c2ecf20Sopenharmony_ci			/* 2.4G default value */
15768c2ecf20Sopenharmony_ci			set_24g_base(pwrinfo24g, rfpath);
15778c2ecf20Sopenharmony_ci		}
15788c2ecf20Sopenharmony_ci		return;
15798c2ecf20Sopenharmony_ci	}
15808c2ecf20Sopenharmony_ci
15818c2ecf20Sopenharmony_ci	for (rfpath = 0 ; rfpath < MAX_RF_PATH ; rfpath++) {
15828c2ecf20Sopenharmony_ci		/*2.4G default value*/
15838c2ecf20Sopenharmony_ci		for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) {
15848c2ecf20Sopenharmony_ci			pwrinfo24g->index_cck_base[rfpath][group] =
15858c2ecf20Sopenharmony_ci			  hwinfo[eeaddr++];
15868c2ecf20Sopenharmony_ci			if (pwrinfo24g->index_cck_base[rfpath][group] == 0xFF)
15878c2ecf20Sopenharmony_ci				pwrinfo24g->index_cck_base[rfpath][group] =
15888c2ecf20Sopenharmony_ci				  0x2D;
15898c2ecf20Sopenharmony_ci		}
15908c2ecf20Sopenharmony_ci		for (group = 0 ; group < MAX_CHNL_GROUP_24G-1; group++) {
15918c2ecf20Sopenharmony_ci			pwrinfo24g->index_bw40_base[rfpath][group] =
15928c2ecf20Sopenharmony_ci				hwinfo[eeaddr++];
15938c2ecf20Sopenharmony_ci			if (pwrinfo24g->index_bw40_base[rfpath][group] == 0xFF)
15948c2ecf20Sopenharmony_ci				pwrinfo24g->index_bw40_base[rfpath][group] =
15958c2ecf20Sopenharmony_ci					0x2D;
15968c2ecf20Sopenharmony_ci		}
15978c2ecf20Sopenharmony_ci		pwrinfo24g->bw40_diff[rfpath][0] = 0;
15988c2ecf20Sopenharmony_ci		if (hwinfo[eeaddr] == 0xFF) {
15998c2ecf20Sopenharmony_ci			pwrinfo24g->bw20_diff[rfpath][0] = 0x02;
16008c2ecf20Sopenharmony_ci		} else {
16018c2ecf20Sopenharmony_ci			pwrinfo24g->bw20_diff[rfpath][0] =
16028c2ecf20Sopenharmony_ci				(hwinfo[eeaddr]&0xf0)>>4;
16038c2ecf20Sopenharmony_ci			/*bit sign number to 8 bit sign number*/
16048c2ecf20Sopenharmony_ci			if (pwrinfo24g->bw20_diff[rfpath][0] & BIT(3))
16058c2ecf20Sopenharmony_ci				pwrinfo24g->bw20_diff[rfpath][0] |= 0xF0;
16068c2ecf20Sopenharmony_ci		}
16078c2ecf20Sopenharmony_ci
16088c2ecf20Sopenharmony_ci		if (hwinfo[eeaddr] == 0xFF) {
16098c2ecf20Sopenharmony_ci			pwrinfo24g->ofdm_diff[rfpath][0] = 0x04;
16108c2ecf20Sopenharmony_ci		} else {
16118c2ecf20Sopenharmony_ci			pwrinfo24g->ofdm_diff[rfpath][0] =
16128c2ecf20Sopenharmony_ci				(hwinfo[eeaddr]&0x0f);
16138c2ecf20Sopenharmony_ci				/*bit sign number to 8 bit sign number*/
16148c2ecf20Sopenharmony_ci			if (pwrinfo24g->ofdm_diff[rfpath][0] & BIT(3))
16158c2ecf20Sopenharmony_ci				pwrinfo24g->ofdm_diff[rfpath][0] |= 0xF0;
16168c2ecf20Sopenharmony_ci		}
16178c2ecf20Sopenharmony_ci		pwrinfo24g->cck_diff[rfpath][0] = 0;
16188c2ecf20Sopenharmony_ci		eeaddr++;
16198c2ecf20Sopenharmony_ci		for (txcnt = 1; txcnt < MAX_TX_COUNT; txcnt++) {
16208c2ecf20Sopenharmony_ci			if (hwinfo[eeaddr] == 0xFF) {
16218c2ecf20Sopenharmony_ci				pwrinfo24g->bw40_diff[rfpath][txcnt] = 0xFE;
16228c2ecf20Sopenharmony_ci			} else {
16238c2ecf20Sopenharmony_ci				pwrinfo24g->bw40_diff[rfpath][txcnt] =
16248c2ecf20Sopenharmony_ci				  (hwinfo[eeaddr]&0xf0)>>4;
16258c2ecf20Sopenharmony_ci				if (pwrinfo24g->bw40_diff[rfpath][txcnt] &
16268c2ecf20Sopenharmony_ci				    BIT(3))
16278c2ecf20Sopenharmony_ci					pwrinfo24g->bw40_diff[rfpath][txcnt] |=
16288c2ecf20Sopenharmony_ci					  0xF0;
16298c2ecf20Sopenharmony_ci			}
16308c2ecf20Sopenharmony_ci
16318c2ecf20Sopenharmony_ci			if (hwinfo[eeaddr] == 0xFF) {
16328c2ecf20Sopenharmony_ci				pwrinfo24g->bw20_diff[rfpath][txcnt] =
16338c2ecf20Sopenharmony_ci					0xFE;
16348c2ecf20Sopenharmony_ci			} else {
16358c2ecf20Sopenharmony_ci				pwrinfo24g->bw20_diff[rfpath][txcnt] =
16368c2ecf20Sopenharmony_ci				  (hwinfo[eeaddr]&0x0f);
16378c2ecf20Sopenharmony_ci				if (pwrinfo24g->bw20_diff[rfpath][txcnt] &
16388c2ecf20Sopenharmony_ci				    BIT(3))
16398c2ecf20Sopenharmony_ci					pwrinfo24g->bw20_diff[rfpath][txcnt] |=
16408c2ecf20Sopenharmony_ci					  0xF0;
16418c2ecf20Sopenharmony_ci			}
16428c2ecf20Sopenharmony_ci			eeaddr++;
16438c2ecf20Sopenharmony_ci
16448c2ecf20Sopenharmony_ci			if (hwinfo[eeaddr] == 0xFF) {
16458c2ecf20Sopenharmony_ci				pwrinfo24g->ofdm_diff[rfpath][txcnt] = 0xFE;
16468c2ecf20Sopenharmony_ci			} else {
16478c2ecf20Sopenharmony_ci				pwrinfo24g->ofdm_diff[rfpath][txcnt] =
16488c2ecf20Sopenharmony_ci				  (hwinfo[eeaddr]&0xf0)>>4;
16498c2ecf20Sopenharmony_ci				if (pwrinfo24g->ofdm_diff[rfpath][txcnt] &
16508c2ecf20Sopenharmony_ci				    BIT(3))
16518c2ecf20Sopenharmony_ci					pwrinfo24g->ofdm_diff[rfpath][txcnt] |=
16528c2ecf20Sopenharmony_ci					  0xF0;
16538c2ecf20Sopenharmony_ci			}
16548c2ecf20Sopenharmony_ci
16558c2ecf20Sopenharmony_ci			if (hwinfo[eeaddr] == 0xFF) {
16568c2ecf20Sopenharmony_ci				pwrinfo24g->cck_diff[rfpath][txcnt] =	0xFE;
16578c2ecf20Sopenharmony_ci			} else {
16588c2ecf20Sopenharmony_ci				pwrinfo24g->cck_diff[rfpath][txcnt] =
16598c2ecf20Sopenharmony_ci				  (hwinfo[eeaddr]&0x0f);
16608c2ecf20Sopenharmony_ci				if (pwrinfo24g->cck_diff[rfpath][txcnt] &
16618c2ecf20Sopenharmony_ci				    BIT(3))
16628c2ecf20Sopenharmony_ci					pwrinfo24g->cck_diff[rfpath][txcnt] |=
16638c2ecf20Sopenharmony_ci					  0xF0;
16648c2ecf20Sopenharmony_ci			}
16658c2ecf20Sopenharmony_ci			eeaddr++;
16668c2ecf20Sopenharmony_ci		}
16678c2ecf20Sopenharmony_ci
16688c2ecf20Sopenharmony_ci		/*5G default value*/
16698c2ecf20Sopenharmony_ci		for (group = 0 ; group < MAX_CHNL_GROUP_5G; group++) {
16708c2ecf20Sopenharmony_ci			pwrinfo5g->index_bw40_base[rfpath][group] =
16718c2ecf20Sopenharmony_ci				hwinfo[eeaddr++];
16728c2ecf20Sopenharmony_ci			if (pwrinfo5g->index_bw40_base[rfpath][group] == 0xFF)
16738c2ecf20Sopenharmony_ci				pwrinfo5g->index_bw40_base[rfpath][group] =
16748c2ecf20Sopenharmony_ci				  0xFE;
16758c2ecf20Sopenharmony_ci		}
16768c2ecf20Sopenharmony_ci
16778c2ecf20Sopenharmony_ci		pwrinfo5g->bw40_diff[rfpath][0] = 0;
16788c2ecf20Sopenharmony_ci
16798c2ecf20Sopenharmony_ci		if (hwinfo[eeaddr] == 0xFF) {
16808c2ecf20Sopenharmony_ci			pwrinfo5g->bw20_diff[rfpath][0] = 0;
16818c2ecf20Sopenharmony_ci		} else {
16828c2ecf20Sopenharmony_ci			pwrinfo5g->bw20_diff[rfpath][0] =
16838c2ecf20Sopenharmony_ci			  (hwinfo[eeaddr]&0xf0)>>4;
16848c2ecf20Sopenharmony_ci			if (pwrinfo5g->bw20_diff[rfpath][0] & BIT(3))
16858c2ecf20Sopenharmony_ci				pwrinfo5g->bw20_diff[rfpath][0] |= 0xF0;
16868c2ecf20Sopenharmony_ci		}
16878c2ecf20Sopenharmony_ci
16888c2ecf20Sopenharmony_ci		if (hwinfo[eeaddr] == 0xFF) {
16898c2ecf20Sopenharmony_ci			pwrinfo5g->ofdm_diff[rfpath][0] = 0x04;
16908c2ecf20Sopenharmony_ci		} else {
16918c2ecf20Sopenharmony_ci			pwrinfo5g->ofdm_diff[rfpath][0] = (hwinfo[eeaddr]&0x0f);
16928c2ecf20Sopenharmony_ci			if (pwrinfo5g->ofdm_diff[rfpath][0] & BIT(3))
16938c2ecf20Sopenharmony_ci				pwrinfo5g->ofdm_diff[rfpath][0] |= 0xF0;
16948c2ecf20Sopenharmony_ci		}
16958c2ecf20Sopenharmony_ci		eeaddr++;
16968c2ecf20Sopenharmony_ci		for (txcnt = 1; txcnt < MAX_TX_COUNT; txcnt++) {
16978c2ecf20Sopenharmony_ci			if (hwinfo[eeaddr] == 0xFF) {
16988c2ecf20Sopenharmony_ci				pwrinfo5g->bw40_diff[rfpath][txcnt] =	0xFE;
16998c2ecf20Sopenharmony_ci			} else {
17008c2ecf20Sopenharmony_ci				pwrinfo5g->bw40_diff[rfpath][txcnt] =
17018c2ecf20Sopenharmony_ci				  (hwinfo[eeaddr]&0xf0)>>4;
17028c2ecf20Sopenharmony_ci				if (pwrinfo5g->bw40_diff[rfpath][txcnt] &
17038c2ecf20Sopenharmony_ci				    BIT(3))
17048c2ecf20Sopenharmony_ci					pwrinfo5g->bw40_diff[rfpath][txcnt] |=
17058c2ecf20Sopenharmony_ci					  0xF0;
17068c2ecf20Sopenharmony_ci			}
17078c2ecf20Sopenharmony_ci
17088c2ecf20Sopenharmony_ci			if (hwinfo[eeaddr] == 0xFF) {
17098c2ecf20Sopenharmony_ci				pwrinfo5g->bw20_diff[rfpath][txcnt] =	0xFE;
17108c2ecf20Sopenharmony_ci			} else {
17118c2ecf20Sopenharmony_ci				pwrinfo5g->bw20_diff[rfpath][txcnt] =
17128c2ecf20Sopenharmony_ci				  (hwinfo[eeaddr]&0x0f);
17138c2ecf20Sopenharmony_ci				if (pwrinfo5g->bw20_diff[rfpath][txcnt] &
17148c2ecf20Sopenharmony_ci				    BIT(3))
17158c2ecf20Sopenharmony_ci					pwrinfo5g->bw20_diff[rfpath][txcnt] |=
17168c2ecf20Sopenharmony_ci					  0xF0;
17178c2ecf20Sopenharmony_ci			}
17188c2ecf20Sopenharmony_ci			eeaddr++;
17198c2ecf20Sopenharmony_ci		}
17208c2ecf20Sopenharmony_ci
17218c2ecf20Sopenharmony_ci		if (hwinfo[eeaddr] == 0xFF) {
17228c2ecf20Sopenharmony_ci			pwrinfo5g->ofdm_diff[rfpath][1] = 0xFE;
17238c2ecf20Sopenharmony_ci			pwrinfo5g->ofdm_diff[rfpath][2] = 0xFE;
17248c2ecf20Sopenharmony_ci		} else {
17258c2ecf20Sopenharmony_ci			pwrinfo5g->ofdm_diff[rfpath][1] =
17268c2ecf20Sopenharmony_ci					(hwinfo[eeaddr]&0xf0)>>4;
17278c2ecf20Sopenharmony_ci			pwrinfo5g->ofdm_diff[rfpath][2] =
17288c2ecf20Sopenharmony_ci					(hwinfo[eeaddr]&0x0f);
17298c2ecf20Sopenharmony_ci		}
17308c2ecf20Sopenharmony_ci		eeaddr++;
17318c2ecf20Sopenharmony_ci
17328c2ecf20Sopenharmony_ci		if (hwinfo[eeaddr] == 0xFF)
17338c2ecf20Sopenharmony_ci			pwrinfo5g->ofdm_diff[rfpath][3] = 0xFE;
17348c2ecf20Sopenharmony_ci		else
17358c2ecf20Sopenharmony_ci			pwrinfo5g->ofdm_diff[rfpath][3] = (hwinfo[eeaddr]&0x0f);
17368c2ecf20Sopenharmony_ci		eeaddr++;
17378c2ecf20Sopenharmony_ci
17388c2ecf20Sopenharmony_ci		for (txcnt = 1; txcnt < MAX_TX_COUNT; txcnt++) {
17398c2ecf20Sopenharmony_ci			if (pwrinfo5g->ofdm_diff[rfpath][txcnt] == 0xFF)
17408c2ecf20Sopenharmony_ci				pwrinfo5g->ofdm_diff[rfpath][txcnt] =	0xFE;
17418c2ecf20Sopenharmony_ci			else if (pwrinfo5g->ofdm_diff[rfpath][txcnt] & BIT(3))
17428c2ecf20Sopenharmony_ci				pwrinfo5g->ofdm_diff[rfpath][txcnt] |= 0xF0;
17438c2ecf20Sopenharmony_ci		}
17448c2ecf20Sopenharmony_ci	}
17458c2ecf20Sopenharmony_ci}
17468c2ecf20Sopenharmony_ci
17478c2ecf20Sopenharmony_cistatic void _rtl88ee_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
17488c2ecf20Sopenharmony_ci						 bool autoload_fail,
17498c2ecf20Sopenharmony_ci						 u8 *hwinfo)
17508c2ecf20Sopenharmony_ci{
17518c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
17528c2ecf20Sopenharmony_ci	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
17538c2ecf20Sopenharmony_ci	struct txpower_info_2g pwrinfo24g;
17548c2ecf20Sopenharmony_ci	struct txpower_info_5g pwrinfo5g;
17558c2ecf20Sopenharmony_ci	u8 rf_path, index;
17568c2ecf20Sopenharmony_ci	u8 i;
17578c2ecf20Sopenharmony_ci
17588c2ecf20Sopenharmony_ci	read_power_value_fromprom(hw, &pwrinfo24g,
17598c2ecf20Sopenharmony_ci				  &pwrinfo5g, autoload_fail, hwinfo);
17608c2ecf20Sopenharmony_ci
17618c2ecf20Sopenharmony_ci	for (rf_path = 0; rf_path < 2; rf_path++) {
17628c2ecf20Sopenharmony_ci		for (i = 0; i < 14; i++) {
17638c2ecf20Sopenharmony_ci			index = _rtl88e_get_chnl_group(i+1);
17648c2ecf20Sopenharmony_ci
17658c2ecf20Sopenharmony_ci			rtlefuse->txpwrlevel_cck[rf_path][i] =
17668c2ecf20Sopenharmony_ci				pwrinfo24g.index_cck_base[rf_path][index];
17678c2ecf20Sopenharmony_ci			rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
17688c2ecf20Sopenharmony_ci				pwrinfo24g.index_bw40_base[rf_path][index];
17698c2ecf20Sopenharmony_ci			rtlefuse->txpwr_ht20diff[rf_path][i] =
17708c2ecf20Sopenharmony_ci				pwrinfo24g.bw20_diff[rf_path][0];
17718c2ecf20Sopenharmony_ci			rtlefuse->txpwr_legacyhtdiff[rf_path][i] =
17728c2ecf20Sopenharmony_ci				pwrinfo24g.ofdm_diff[rf_path][0];
17738c2ecf20Sopenharmony_ci		}
17748c2ecf20Sopenharmony_ci
17758c2ecf20Sopenharmony_ci		for (i = 0; i < 14; i++) {
17768c2ecf20Sopenharmony_ci			RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
17778c2ecf20Sopenharmony_ci				"RF(%d)-Ch(%d) [CCK / HT40_1S ] = [0x%x / 0x%x ]\n",
17788c2ecf20Sopenharmony_ci				rf_path, i,
17798c2ecf20Sopenharmony_ci				rtlefuse->txpwrlevel_cck[rf_path][i],
17808c2ecf20Sopenharmony_ci				rtlefuse->txpwrlevel_ht40_1s[rf_path][i]);
17818c2ecf20Sopenharmony_ci		}
17828c2ecf20Sopenharmony_ci	}
17838c2ecf20Sopenharmony_ci
17848c2ecf20Sopenharmony_ci	if (!autoload_fail)
17858c2ecf20Sopenharmony_ci		rtlefuse->eeprom_thermalmeter =
17868c2ecf20Sopenharmony_ci			hwinfo[EEPROM_THERMAL_METER_88E];
17878c2ecf20Sopenharmony_ci	else
17888c2ecf20Sopenharmony_ci		rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
17898c2ecf20Sopenharmony_ci
17908c2ecf20Sopenharmony_ci	if (rtlefuse->eeprom_thermalmeter == 0xff || autoload_fail) {
17918c2ecf20Sopenharmony_ci		rtlefuse->apk_thermalmeterignore = true;
17928c2ecf20Sopenharmony_ci		rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
17938c2ecf20Sopenharmony_ci	}
17948c2ecf20Sopenharmony_ci
17958c2ecf20Sopenharmony_ci	rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
17968c2ecf20Sopenharmony_ci	RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
17978c2ecf20Sopenharmony_ci		"thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
17988c2ecf20Sopenharmony_ci
17998c2ecf20Sopenharmony_ci	if (!autoload_fail) {
18008c2ecf20Sopenharmony_ci		rtlefuse->eeprom_regulatory =
18018c2ecf20Sopenharmony_ci			hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0x07;/*bit0~2*/
18028c2ecf20Sopenharmony_ci		if (hwinfo[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
18038c2ecf20Sopenharmony_ci			rtlefuse->eeprom_regulatory = 0;
18048c2ecf20Sopenharmony_ci	} else {
18058c2ecf20Sopenharmony_ci		rtlefuse->eeprom_regulatory = 0;
18068c2ecf20Sopenharmony_ci	}
18078c2ecf20Sopenharmony_ci	RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
18088c2ecf20Sopenharmony_ci		"eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
18098c2ecf20Sopenharmony_ci}
18108c2ecf20Sopenharmony_ci
18118c2ecf20Sopenharmony_cistatic void _rtl88ee_read_adapter_info(struct ieee80211_hw *hw)
18128c2ecf20Sopenharmony_ci{
18138c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
18148c2ecf20Sopenharmony_ci	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
18158c2ecf20Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
18168c2ecf20Sopenharmony_ci	int params[] = {RTL8188E_EEPROM_ID, EEPROM_VID, EEPROM_DID,
18178c2ecf20Sopenharmony_ci			EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR,
18188c2ecf20Sopenharmony_ci			EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID,
18198c2ecf20Sopenharmony_ci			COUNTRY_CODE_WORLD_WIDE_13};
18208c2ecf20Sopenharmony_ci	u8 *hwinfo;
18218c2ecf20Sopenharmony_ci
18228c2ecf20Sopenharmony_ci	hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL);
18238c2ecf20Sopenharmony_ci	if (!hwinfo)
18248c2ecf20Sopenharmony_ci		return;
18258c2ecf20Sopenharmony_ci
18268c2ecf20Sopenharmony_ci	if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params))
18278c2ecf20Sopenharmony_ci		goto exit;
18288c2ecf20Sopenharmony_ci
18298c2ecf20Sopenharmony_ci	if (rtlefuse->eeprom_oemid == 0xFF)
18308c2ecf20Sopenharmony_ci		rtlefuse->eeprom_oemid = 0;
18318c2ecf20Sopenharmony_ci
18328c2ecf20Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
18338c2ecf20Sopenharmony_ci		"EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid);
18348c2ecf20Sopenharmony_ci	/* set channel plan from efuse */
18358c2ecf20Sopenharmony_ci	rtlefuse->channel_plan = rtlefuse->eeprom_channelplan;
18368c2ecf20Sopenharmony_ci	/*tx power*/
18378c2ecf20Sopenharmony_ci	_rtl88ee_read_txpower_info_from_hwpg(hw,
18388c2ecf20Sopenharmony_ci					     rtlefuse->autoload_failflag,
18398c2ecf20Sopenharmony_ci					     hwinfo);
18408c2ecf20Sopenharmony_ci	rtlefuse->txpwr_fromeprom = true;
18418c2ecf20Sopenharmony_ci
18428c2ecf20Sopenharmony_ci	rtl8188ee_read_bt_coexist_info_from_hwpg(hw,
18438c2ecf20Sopenharmony_ci						 rtlefuse->autoload_failflag,
18448c2ecf20Sopenharmony_ci						 hwinfo);
18458c2ecf20Sopenharmony_ci
18468c2ecf20Sopenharmony_ci	/*board type*/
18478c2ecf20Sopenharmony_ci	rtlefuse->board_type =
18488c2ecf20Sopenharmony_ci		((hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0xE0) >> 5);
18498c2ecf20Sopenharmony_ci	rtlhal->board_type = rtlefuse->board_type;
18508c2ecf20Sopenharmony_ci	/*Wake on wlan*/
18518c2ecf20Sopenharmony_ci	rtlefuse->wowlan_enable =
18528c2ecf20Sopenharmony_ci		((hwinfo[EEPROM_RF_FEATURE_OPTION_88E] & 0x40) >> 6);
18538c2ecf20Sopenharmony_ci	/*parse xtal*/
18548c2ecf20Sopenharmony_ci	rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_88E];
18558c2ecf20Sopenharmony_ci	if (hwinfo[EEPROM_XTAL_88E])
18568c2ecf20Sopenharmony_ci		rtlefuse->crystalcap = 0x20;
18578c2ecf20Sopenharmony_ci	/*antenna diversity*/
18588c2ecf20Sopenharmony_ci	rtlefuse->antenna_div_cfg =
18598c2ecf20Sopenharmony_ci		(hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0x18) >> 3;
18608c2ecf20Sopenharmony_ci	if (hwinfo[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
18618c2ecf20Sopenharmony_ci		rtlefuse->antenna_div_cfg = 0;
18628c2ecf20Sopenharmony_ci	if (rtlpriv->btcoexist.eeprom_bt_coexist != 0 &&
18638c2ecf20Sopenharmony_ci	    rtlpriv->btcoexist.eeprom_bt_ant_num == ANT_X1)
18648c2ecf20Sopenharmony_ci		rtlefuse->antenna_div_cfg = 0;
18658c2ecf20Sopenharmony_ci
18668c2ecf20Sopenharmony_ci	rtlefuse->antenna_div_type = hwinfo[EEPROM_RF_ANTENNA_OPT_88E];
18678c2ecf20Sopenharmony_ci	if (rtlefuse->antenna_div_type == 0xFF)
18688c2ecf20Sopenharmony_ci		rtlefuse->antenna_div_type = 0x01;
18698c2ecf20Sopenharmony_ci	if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV ||
18708c2ecf20Sopenharmony_ci		rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
18718c2ecf20Sopenharmony_ci		rtlefuse->antenna_div_cfg = 1;
18728c2ecf20Sopenharmony_ci
18738c2ecf20Sopenharmony_ci	if (rtlhal->oem_id == RT_CID_DEFAULT) {
18748c2ecf20Sopenharmony_ci		switch (rtlefuse->eeprom_oemid) {
18758c2ecf20Sopenharmony_ci		case EEPROM_CID_DEFAULT:
18768c2ecf20Sopenharmony_ci			if (rtlefuse->eeprom_did == 0x8179) {
18778c2ecf20Sopenharmony_ci				if (rtlefuse->eeprom_svid == 0x1025) {
18788c2ecf20Sopenharmony_ci					rtlhal->oem_id = RT_CID_819X_ACER;
18798c2ecf20Sopenharmony_ci				} else if ((rtlefuse->eeprom_svid == 0x10EC &&
18808c2ecf20Sopenharmony_ci				     rtlefuse->eeprom_smid == 0x0179) ||
18818c2ecf20Sopenharmony_ci				     (rtlefuse->eeprom_svid == 0x17AA &&
18828c2ecf20Sopenharmony_ci				     rtlefuse->eeprom_smid == 0x0179)) {
18838c2ecf20Sopenharmony_ci					rtlhal->oem_id = RT_CID_819X_LENOVO;
18848c2ecf20Sopenharmony_ci				} else if (rtlefuse->eeprom_svid == 0x103c &&
18858c2ecf20Sopenharmony_ci					   rtlefuse->eeprom_smid == 0x197d) {
18868c2ecf20Sopenharmony_ci					rtlhal->oem_id = RT_CID_819X_HP;
18878c2ecf20Sopenharmony_ci				} else {
18888c2ecf20Sopenharmony_ci					rtlhal->oem_id = RT_CID_DEFAULT;
18898c2ecf20Sopenharmony_ci				}
18908c2ecf20Sopenharmony_ci			} else {
18918c2ecf20Sopenharmony_ci				rtlhal->oem_id = RT_CID_DEFAULT;
18928c2ecf20Sopenharmony_ci			}
18938c2ecf20Sopenharmony_ci			break;
18948c2ecf20Sopenharmony_ci		case EEPROM_CID_TOSHIBA:
18958c2ecf20Sopenharmony_ci			rtlhal->oem_id = RT_CID_TOSHIBA;
18968c2ecf20Sopenharmony_ci			break;
18978c2ecf20Sopenharmony_ci		case EEPROM_CID_QMI:
18988c2ecf20Sopenharmony_ci			rtlhal->oem_id = RT_CID_819X_QMI;
18998c2ecf20Sopenharmony_ci			break;
19008c2ecf20Sopenharmony_ci		case EEPROM_CID_WHQL:
19018c2ecf20Sopenharmony_ci		default:
19028c2ecf20Sopenharmony_ci			rtlhal->oem_id = RT_CID_DEFAULT;
19038c2ecf20Sopenharmony_ci			break;
19048c2ecf20Sopenharmony_ci
19058c2ecf20Sopenharmony_ci		}
19068c2ecf20Sopenharmony_ci	}
19078c2ecf20Sopenharmony_ciexit:
19088c2ecf20Sopenharmony_ci	kfree(hwinfo);
19098c2ecf20Sopenharmony_ci}
19108c2ecf20Sopenharmony_ci
19118c2ecf20Sopenharmony_cistatic void _rtl88ee_hal_customized_behavior(struct ieee80211_hw *hw)
19128c2ecf20Sopenharmony_ci{
19138c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
19148c2ecf20Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
19158c2ecf20Sopenharmony_ci
19168c2ecf20Sopenharmony_ci	rtlpriv->ledctl.led_opendrain = true;
19178c2ecf20Sopenharmony_ci
19188c2ecf20Sopenharmony_ci	switch (rtlhal->oem_id) {
19198c2ecf20Sopenharmony_ci	case RT_CID_819X_HP:
19208c2ecf20Sopenharmony_ci		rtlpriv->ledctl.led_opendrain = true;
19218c2ecf20Sopenharmony_ci		break;
19228c2ecf20Sopenharmony_ci	case RT_CID_819X_LENOVO:
19238c2ecf20Sopenharmony_ci	case RT_CID_DEFAULT:
19248c2ecf20Sopenharmony_ci	case RT_CID_TOSHIBA:
19258c2ecf20Sopenharmony_ci	case RT_CID_CCX:
19268c2ecf20Sopenharmony_ci	case RT_CID_819X_ACER:
19278c2ecf20Sopenharmony_ci	case RT_CID_WHQL:
19288c2ecf20Sopenharmony_ci	default:
19298c2ecf20Sopenharmony_ci		break;
19308c2ecf20Sopenharmony_ci	}
19318c2ecf20Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG,
19328c2ecf20Sopenharmony_ci		"RT Customized ID: 0x%02X\n", rtlhal->oem_id);
19338c2ecf20Sopenharmony_ci}
19348c2ecf20Sopenharmony_ci
19358c2ecf20Sopenharmony_civoid rtl88ee_read_eeprom_info(struct ieee80211_hw *hw)
19368c2ecf20Sopenharmony_ci{
19378c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
19388c2ecf20Sopenharmony_ci	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
19398c2ecf20Sopenharmony_ci	struct rtl_phy *rtlphy = &(rtlpriv->phy);
19408c2ecf20Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
19418c2ecf20Sopenharmony_ci	u8 tmp_u1b;
19428c2ecf20Sopenharmony_ci
19438c2ecf20Sopenharmony_ci	rtlhal->version = _rtl88ee_read_chip_version(hw);
19448c2ecf20Sopenharmony_ci	if (get_rf_type(rtlphy) == RF_1T1R)
19458c2ecf20Sopenharmony_ci		rtlpriv->dm.rfpath_rxenable[0] = true;
19468c2ecf20Sopenharmony_ci	else
19478c2ecf20Sopenharmony_ci		rtlpriv->dm.rfpath_rxenable[0] =
19488c2ecf20Sopenharmony_ci		    rtlpriv->dm.rfpath_rxenable[1] = true;
19498c2ecf20Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
19508c2ecf20Sopenharmony_ci		rtlhal->version);
19518c2ecf20Sopenharmony_ci	tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
19528c2ecf20Sopenharmony_ci	if (tmp_u1b & BIT(4)) {
19538c2ecf20Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
19548c2ecf20Sopenharmony_ci		rtlefuse->epromtype = EEPROM_93C46;
19558c2ecf20Sopenharmony_ci	} else {
19568c2ecf20Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
19578c2ecf20Sopenharmony_ci		rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
19588c2ecf20Sopenharmony_ci	}
19598c2ecf20Sopenharmony_ci	if (tmp_u1b & BIT(5)) {
19608c2ecf20Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
19618c2ecf20Sopenharmony_ci		rtlefuse->autoload_failflag = false;
19628c2ecf20Sopenharmony_ci		_rtl88ee_read_adapter_info(hw);
19638c2ecf20Sopenharmony_ci	} else {
19648c2ecf20Sopenharmony_ci		pr_err("Autoload ERR!!\n");
19658c2ecf20Sopenharmony_ci	}
19668c2ecf20Sopenharmony_ci	_rtl88ee_hal_customized_behavior(hw);
19678c2ecf20Sopenharmony_ci}
19688c2ecf20Sopenharmony_ci
19698c2ecf20Sopenharmony_cistatic void rtl88ee_update_hal_rate_table(struct ieee80211_hw *hw,
19708c2ecf20Sopenharmony_ci		struct ieee80211_sta *sta)
19718c2ecf20Sopenharmony_ci{
19728c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
19738c2ecf20Sopenharmony_ci	struct rtl_phy *rtlphy = &(rtlpriv->phy);
19748c2ecf20Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
19758c2ecf20Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
19768c2ecf20Sopenharmony_ci	u32 ratr_value;
19778c2ecf20Sopenharmony_ci	u8 ratr_index = 0;
19788c2ecf20Sopenharmony_ci	u8 b_nmode = mac->ht_enable;
19798c2ecf20Sopenharmony_ci	/*u8 mimo_ps = IEEE80211_SMPS_OFF;*/
19808c2ecf20Sopenharmony_ci	u16 shortgi_rate;
19818c2ecf20Sopenharmony_ci	u32 tmp_ratr_value;
19828c2ecf20Sopenharmony_ci	u8 curtxbw_40mhz = mac->bw_40;
19838c2ecf20Sopenharmony_ci	u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
19848c2ecf20Sopenharmony_ci				1 : 0;
19858c2ecf20Sopenharmony_ci	u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
19868c2ecf20Sopenharmony_ci				1 : 0;
19878c2ecf20Sopenharmony_ci	enum wireless_mode wirelessmode = mac->mode;
19888c2ecf20Sopenharmony_ci	u32 ratr_mask;
19898c2ecf20Sopenharmony_ci
19908c2ecf20Sopenharmony_ci	if (rtlhal->current_bandtype == BAND_ON_5G)
19918c2ecf20Sopenharmony_ci		ratr_value = sta->supp_rates[1] << 4;
19928c2ecf20Sopenharmony_ci	else
19938c2ecf20Sopenharmony_ci		ratr_value = sta->supp_rates[0];
19948c2ecf20Sopenharmony_ci	if (mac->opmode == NL80211_IFTYPE_ADHOC)
19958c2ecf20Sopenharmony_ci		ratr_value = 0xfff;
19968c2ecf20Sopenharmony_ci	ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
19978c2ecf20Sopenharmony_ci		       sta->ht_cap.mcs.rx_mask[0] << 12);
19988c2ecf20Sopenharmony_ci	switch (wirelessmode) {
19998c2ecf20Sopenharmony_ci	case WIRELESS_MODE_B:
20008c2ecf20Sopenharmony_ci		if (ratr_value & 0x0000000c)
20018c2ecf20Sopenharmony_ci			ratr_value &= 0x0000000d;
20028c2ecf20Sopenharmony_ci		else
20038c2ecf20Sopenharmony_ci			ratr_value &= 0x0000000f;
20048c2ecf20Sopenharmony_ci		break;
20058c2ecf20Sopenharmony_ci	case WIRELESS_MODE_G:
20068c2ecf20Sopenharmony_ci		ratr_value &= 0x00000FF5;
20078c2ecf20Sopenharmony_ci		break;
20088c2ecf20Sopenharmony_ci	case WIRELESS_MODE_N_24G:
20098c2ecf20Sopenharmony_ci	case WIRELESS_MODE_N_5G:
20108c2ecf20Sopenharmony_ci		b_nmode = 1;
20118c2ecf20Sopenharmony_ci		if (get_rf_type(rtlphy) == RF_1T2R ||
20128c2ecf20Sopenharmony_ci		    get_rf_type(rtlphy) == RF_1T1R)
20138c2ecf20Sopenharmony_ci			ratr_mask = 0x000ff005;
20148c2ecf20Sopenharmony_ci		else
20158c2ecf20Sopenharmony_ci			ratr_mask = 0x0f0ff005;
20168c2ecf20Sopenharmony_ci
20178c2ecf20Sopenharmony_ci		ratr_value &= ratr_mask;
20188c2ecf20Sopenharmony_ci		break;
20198c2ecf20Sopenharmony_ci	default:
20208c2ecf20Sopenharmony_ci		if (rtlphy->rf_type == RF_1T2R)
20218c2ecf20Sopenharmony_ci			ratr_value &= 0x000ff0ff;
20228c2ecf20Sopenharmony_ci		else
20238c2ecf20Sopenharmony_ci			ratr_value &= 0x0f0ff0ff;
20248c2ecf20Sopenharmony_ci
20258c2ecf20Sopenharmony_ci		break;
20268c2ecf20Sopenharmony_ci	}
20278c2ecf20Sopenharmony_ci
20288c2ecf20Sopenharmony_ci	if ((rtlpriv->btcoexist.bt_coexistence) &&
20298c2ecf20Sopenharmony_ci	    (rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC4) &&
20308c2ecf20Sopenharmony_ci	    (rtlpriv->btcoexist.bt_cur_state) &&
20318c2ecf20Sopenharmony_ci	    (rtlpriv->btcoexist.bt_ant_isolation) &&
20328c2ecf20Sopenharmony_ci	    ((rtlpriv->btcoexist.bt_service == BT_SCO) ||
20338c2ecf20Sopenharmony_ci	     (rtlpriv->btcoexist.bt_service == BT_BUSY)))
20348c2ecf20Sopenharmony_ci		ratr_value &= 0x0fffcfc0;
20358c2ecf20Sopenharmony_ci	else
20368c2ecf20Sopenharmony_ci		ratr_value &= 0x0FFFFFFF;
20378c2ecf20Sopenharmony_ci
20388c2ecf20Sopenharmony_ci	if (b_nmode &&
20398c2ecf20Sopenharmony_ci	    ((curtxbw_40mhz && curshortgi_40mhz) ||
20408c2ecf20Sopenharmony_ci	     (!curtxbw_40mhz && curshortgi_20mhz))) {
20418c2ecf20Sopenharmony_ci		ratr_value |= 0x10000000;
20428c2ecf20Sopenharmony_ci		tmp_ratr_value = (ratr_value >> 12);
20438c2ecf20Sopenharmony_ci
20448c2ecf20Sopenharmony_ci		for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
20458c2ecf20Sopenharmony_ci			if ((1 << shortgi_rate) & tmp_ratr_value)
20468c2ecf20Sopenharmony_ci				break;
20478c2ecf20Sopenharmony_ci		}
20488c2ecf20Sopenharmony_ci
20498c2ecf20Sopenharmony_ci		shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
20508c2ecf20Sopenharmony_ci		    (shortgi_rate << 4) | (shortgi_rate);
20518c2ecf20Sopenharmony_ci	}
20528c2ecf20Sopenharmony_ci
20538c2ecf20Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
20548c2ecf20Sopenharmony_ci
20558c2ecf20Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG,
20568c2ecf20Sopenharmony_ci		"%x\n", rtl_read_dword(rtlpriv, REG_ARFR0));
20578c2ecf20Sopenharmony_ci}
20588c2ecf20Sopenharmony_ci
20598c2ecf20Sopenharmony_cistatic void rtl88ee_update_hal_rate_mask(struct ieee80211_hw *hw,
20608c2ecf20Sopenharmony_ci		struct ieee80211_sta *sta, u8 rssi_level, bool update_bw)
20618c2ecf20Sopenharmony_ci{
20628c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
20638c2ecf20Sopenharmony_ci	struct rtl_phy *rtlphy = &(rtlpriv->phy);
20648c2ecf20Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
20658c2ecf20Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
20668c2ecf20Sopenharmony_ci	struct rtl_sta_info *sta_entry = NULL;
20678c2ecf20Sopenharmony_ci	u32 ratr_bitmap;
20688c2ecf20Sopenharmony_ci	u8 ratr_index;
20698c2ecf20Sopenharmony_ci	u8 curtxbw_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
20708c2ecf20Sopenharmony_ci				? 1 : 0;
20718c2ecf20Sopenharmony_ci	u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
20728c2ecf20Sopenharmony_ci				1 : 0;
20738c2ecf20Sopenharmony_ci	u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
20748c2ecf20Sopenharmony_ci				1 : 0;
20758c2ecf20Sopenharmony_ci	enum wireless_mode wirelessmode = 0;
20768c2ecf20Sopenharmony_ci	bool b_shortgi = false;
20778c2ecf20Sopenharmony_ci	u8 rate_mask[5];
20788c2ecf20Sopenharmony_ci	u8 macid = 0;
20798c2ecf20Sopenharmony_ci	/*u8 mimo_ps = IEEE80211_SMPS_OFF;*/
20808c2ecf20Sopenharmony_ci
20818c2ecf20Sopenharmony_ci	sta_entry = (struct rtl_sta_info *)sta->drv_priv;
20828c2ecf20Sopenharmony_ci	wirelessmode = sta_entry->wireless_mode;
20838c2ecf20Sopenharmony_ci	if (mac->opmode == NL80211_IFTYPE_STATION ||
20848c2ecf20Sopenharmony_ci		mac->opmode == NL80211_IFTYPE_MESH_POINT)
20858c2ecf20Sopenharmony_ci		curtxbw_40mhz = mac->bw_40;
20868c2ecf20Sopenharmony_ci	else if (mac->opmode == NL80211_IFTYPE_AP ||
20878c2ecf20Sopenharmony_ci		mac->opmode == NL80211_IFTYPE_ADHOC)
20888c2ecf20Sopenharmony_ci		macid = sta->aid + 1;
20898c2ecf20Sopenharmony_ci
20908c2ecf20Sopenharmony_ci	if (rtlhal->current_bandtype == BAND_ON_5G)
20918c2ecf20Sopenharmony_ci		ratr_bitmap = sta->supp_rates[1] << 4;
20928c2ecf20Sopenharmony_ci	else
20938c2ecf20Sopenharmony_ci		ratr_bitmap = sta->supp_rates[0];
20948c2ecf20Sopenharmony_ci	if (mac->opmode == NL80211_IFTYPE_ADHOC)
20958c2ecf20Sopenharmony_ci		ratr_bitmap = 0xfff;
20968c2ecf20Sopenharmony_ci	ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
20978c2ecf20Sopenharmony_ci			sta->ht_cap.mcs.rx_mask[0] << 12);
20988c2ecf20Sopenharmony_ci	switch (wirelessmode) {
20998c2ecf20Sopenharmony_ci	case WIRELESS_MODE_B:
21008c2ecf20Sopenharmony_ci		ratr_index = RATR_INX_WIRELESS_B;
21018c2ecf20Sopenharmony_ci		if (ratr_bitmap & 0x0000000c)
21028c2ecf20Sopenharmony_ci			ratr_bitmap &= 0x0000000d;
21038c2ecf20Sopenharmony_ci		else
21048c2ecf20Sopenharmony_ci			ratr_bitmap &= 0x0000000f;
21058c2ecf20Sopenharmony_ci		break;
21068c2ecf20Sopenharmony_ci	case WIRELESS_MODE_G:
21078c2ecf20Sopenharmony_ci		ratr_index = RATR_INX_WIRELESS_GB;
21088c2ecf20Sopenharmony_ci
21098c2ecf20Sopenharmony_ci		if (rssi_level == 1)
21108c2ecf20Sopenharmony_ci			ratr_bitmap &= 0x00000f00;
21118c2ecf20Sopenharmony_ci		else if (rssi_level == 2)
21128c2ecf20Sopenharmony_ci			ratr_bitmap &= 0x00000ff0;
21138c2ecf20Sopenharmony_ci		else
21148c2ecf20Sopenharmony_ci			ratr_bitmap &= 0x00000ff5;
21158c2ecf20Sopenharmony_ci		break;
21168c2ecf20Sopenharmony_ci	case WIRELESS_MODE_N_24G:
21178c2ecf20Sopenharmony_ci	case WIRELESS_MODE_N_5G:
21188c2ecf20Sopenharmony_ci		ratr_index = RATR_INX_WIRELESS_NGB;
21198c2ecf20Sopenharmony_ci		if (rtlphy->rf_type == RF_1T2R ||
21208c2ecf20Sopenharmony_ci		    rtlphy->rf_type == RF_1T1R) {
21218c2ecf20Sopenharmony_ci			if (curtxbw_40mhz) {
21228c2ecf20Sopenharmony_ci				if (rssi_level == 1)
21238c2ecf20Sopenharmony_ci					ratr_bitmap &= 0x000f0000;
21248c2ecf20Sopenharmony_ci				else if (rssi_level == 2)
21258c2ecf20Sopenharmony_ci					ratr_bitmap &= 0x000ff000;
21268c2ecf20Sopenharmony_ci				else
21278c2ecf20Sopenharmony_ci					ratr_bitmap &= 0x000ff015;
21288c2ecf20Sopenharmony_ci			} else {
21298c2ecf20Sopenharmony_ci				if (rssi_level == 1)
21308c2ecf20Sopenharmony_ci					ratr_bitmap &= 0x000f0000;
21318c2ecf20Sopenharmony_ci				else if (rssi_level == 2)
21328c2ecf20Sopenharmony_ci					ratr_bitmap &= 0x000ff000;
21338c2ecf20Sopenharmony_ci				else
21348c2ecf20Sopenharmony_ci					ratr_bitmap &= 0x000ff005;
21358c2ecf20Sopenharmony_ci			}
21368c2ecf20Sopenharmony_ci		} else {
21378c2ecf20Sopenharmony_ci			if (curtxbw_40mhz) {
21388c2ecf20Sopenharmony_ci				if (rssi_level == 1)
21398c2ecf20Sopenharmony_ci					ratr_bitmap &= 0x0f8f0000;
21408c2ecf20Sopenharmony_ci				else if (rssi_level == 2)
21418c2ecf20Sopenharmony_ci					ratr_bitmap &= 0x0f8ff000;
21428c2ecf20Sopenharmony_ci				else
21438c2ecf20Sopenharmony_ci					ratr_bitmap &= 0x0f8ff015;
21448c2ecf20Sopenharmony_ci			} else {
21458c2ecf20Sopenharmony_ci				if (rssi_level == 1)
21468c2ecf20Sopenharmony_ci					ratr_bitmap &= 0x0f8f0000;
21478c2ecf20Sopenharmony_ci				else if (rssi_level == 2)
21488c2ecf20Sopenharmony_ci					ratr_bitmap &= 0x0f8ff000;
21498c2ecf20Sopenharmony_ci				else
21508c2ecf20Sopenharmony_ci					ratr_bitmap &= 0x0f8ff005;
21518c2ecf20Sopenharmony_ci			}
21528c2ecf20Sopenharmony_ci		}
21538c2ecf20Sopenharmony_ci		/*}*/
21548c2ecf20Sopenharmony_ci
21558c2ecf20Sopenharmony_ci		if ((curtxbw_40mhz && curshortgi_40mhz) ||
21568c2ecf20Sopenharmony_ci		    (!curtxbw_40mhz && curshortgi_20mhz)) {
21578c2ecf20Sopenharmony_ci
21588c2ecf20Sopenharmony_ci			if (macid == 0)
21598c2ecf20Sopenharmony_ci				b_shortgi = true;
21608c2ecf20Sopenharmony_ci			else if (macid == 1)
21618c2ecf20Sopenharmony_ci				b_shortgi = false;
21628c2ecf20Sopenharmony_ci		}
21638c2ecf20Sopenharmony_ci		break;
21648c2ecf20Sopenharmony_ci	default:
21658c2ecf20Sopenharmony_ci		ratr_index = RATR_INX_WIRELESS_NGB;
21668c2ecf20Sopenharmony_ci
21678c2ecf20Sopenharmony_ci		if (rtlphy->rf_type == RF_1T2R)
21688c2ecf20Sopenharmony_ci			ratr_bitmap &= 0x000ff0ff;
21698c2ecf20Sopenharmony_ci		else
21708c2ecf20Sopenharmony_ci			ratr_bitmap &= 0x0f0ff0ff;
21718c2ecf20Sopenharmony_ci		break;
21728c2ecf20Sopenharmony_ci	}
21738c2ecf20Sopenharmony_ci	sta_entry->ratr_index = ratr_index;
21748c2ecf20Sopenharmony_ci
21758c2ecf20Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG,
21768c2ecf20Sopenharmony_ci		"ratr_bitmap :%x\n", ratr_bitmap);
21778c2ecf20Sopenharmony_ci	*(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
21788c2ecf20Sopenharmony_ci			     (ratr_index << 28);
21798c2ecf20Sopenharmony_ci	rate_mask[4] = macid | (b_shortgi ? 0x20 : 0x00) | 0x80;
21808c2ecf20Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG,
21818c2ecf20Sopenharmony_ci		"Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n",
21828c2ecf20Sopenharmony_ci		ratr_index, ratr_bitmap,
21838c2ecf20Sopenharmony_ci		rate_mask[0], rate_mask[1],
21848c2ecf20Sopenharmony_ci		rate_mask[2], rate_mask[3],
21858c2ecf20Sopenharmony_ci		rate_mask[4]);
21868c2ecf20Sopenharmony_ci	rtl88e_fill_h2c_cmd(hw, H2C_88E_RA_MASK, 5, rate_mask);
21878c2ecf20Sopenharmony_ci	_rtl88ee_set_bcn_ctrl_reg(hw, BIT(3), 0);
21888c2ecf20Sopenharmony_ci}
21898c2ecf20Sopenharmony_ci
21908c2ecf20Sopenharmony_civoid rtl88ee_update_hal_rate_tbl(struct ieee80211_hw *hw,
21918c2ecf20Sopenharmony_ci		struct ieee80211_sta *sta, u8 rssi_level, bool update_bw)
21928c2ecf20Sopenharmony_ci{
21938c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
21948c2ecf20Sopenharmony_ci
21958c2ecf20Sopenharmony_ci	if (rtlpriv->dm.useramask)
21968c2ecf20Sopenharmony_ci		rtl88ee_update_hal_rate_mask(hw, sta, rssi_level, update_bw);
21978c2ecf20Sopenharmony_ci	else
21988c2ecf20Sopenharmony_ci		rtl88ee_update_hal_rate_table(hw, sta);
21998c2ecf20Sopenharmony_ci}
22008c2ecf20Sopenharmony_ci
22018c2ecf20Sopenharmony_civoid rtl88ee_update_channel_access_setting(struct ieee80211_hw *hw)
22028c2ecf20Sopenharmony_ci{
22038c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
22048c2ecf20Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
22058c2ecf20Sopenharmony_ci	u16 sifs_timer;
22068c2ecf20Sopenharmony_ci
22078c2ecf20Sopenharmony_ci	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);
22088c2ecf20Sopenharmony_ci	if (!mac->ht_enable)
22098c2ecf20Sopenharmony_ci		sifs_timer = 0x0a0a;
22108c2ecf20Sopenharmony_ci	else
22118c2ecf20Sopenharmony_ci		sifs_timer = 0x0e0e;
22128c2ecf20Sopenharmony_ci	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
22138c2ecf20Sopenharmony_ci}
22148c2ecf20Sopenharmony_ci
22158c2ecf20Sopenharmony_cibool rtl88ee_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
22168c2ecf20Sopenharmony_ci{
22178c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
22188c2ecf20Sopenharmony_ci	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
22198c2ecf20Sopenharmony_ci	enum rf_pwrstate e_rfpowerstate_toset;
22208c2ecf20Sopenharmony_ci	u32 u4tmp;
22218c2ecf20Sopenharmony_ci	bool b_actuallyset = false;
22228c2ecf20Sopenharmony_ci
22238c2ecf20Sopenharmony_ci	if (rtlpriv->rtlhal.being_init_adapter)
22248c2ecf20Sopenharmony_ci		return false;
22258c2ecf20Sopenharmony_ci
22268c2ecf20Sopenharmony_ci	if (ppsc->swrf_processing)
22278c2ecf20Sopenharmony_ci		return false;
22288c2ecf20Sopenharmony_ci
22298c2ecf20Sopenharmony_ci	spin_lock(&rtlpriv->locks.rf_ps_lock);
22308c2ecf20Sopenharmony_ci	if (ppsc->rfchange_inprogress) {
22318c2ecf20Sopenharmony_ci		spin_unlock(&rtlpriv->locks.rf_ps_lock);
22328c2ecf20Sopenharmony_ci		return false;
22338c2ecf20Sopenharmony_ci	} else {
22348c2ecf20Sopenharmony_ci		ppsc->rfchange_inprogress = true;
22358c2ecf20Sopenharmony_ci		spin_unlock(&rtlpriv->locks.rf_ps_lock);
22368c2ecf20Sopenharmony_ci	}
22378c2ecf20Sopenharmony_ci
22388c2ecf20Sopenharmony_ci	u4tmp = rtl_read_dword(rtlpriv, REG_GPIO_OUTPUT);
22398c2ecf20Sopenharmony_ci	e_rfpowerstate_toset = (u4tmp & BIT(31)) ? ERFON : ERFOFF;
22408c2ecf20Sopenharmony_ci
22418c2ecf20Sopenharmony_ci	if (ppsc->hwradiooff && (e_rfpowerstate_toset == ERFON)) {
22428c2ecf20Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
22438c2ecf20Sopenharmony_ci			"GPIOChangeRF  - HW Radio ON, RF ON\n");
22448c2ecf20Sopenharmony_ci
22458c2ecf20Sopenharmony_ci		e_rfpowerstate_toset = ERFON;
22468c2ecf20Sopenharmony_ci		ppsc->hwradiooff = false;
22478c2ecf20Sopenharmony_ci		b_actuallyset = true;
22488c2ecf20Sopenharmony_ci	} else if ((!ppsc->hwradiooff) &&
22498c2ecf20Sopenharmony_ci		   (e_rfpowerstate_toset == ERFOFF)) {
22508c2ecf20Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
22518c2ecf20Sopenharmony_ci			"GPIOChangeRF  - HW Radio OFF, RF OFF\n");
22528c2ecf20Sopenharmony_ci
22538c2ecf20Sopenharmony_ci		e_rfpowerstate_toset = ERFOFF;
22548c2ecf20Sopenharmony_ci		ppsc->hwradiooff = true;
22558c2ecf20Sopenharmony_ci		b_actuallyset = true;
22568c2ecf20Sopenharmony_ci	}
22578c2ecf20Sopenharmony_ci
22588c2ecf20Sopenharmony_ci	if (b_actuallyset) {
22598c2ecf20Sopenharmony_ci		spin_lock(&rtlpriv->locks.rf_ps_lock);
22608c2ecf20Sopenharmony_ci		ppsc->rfchange_inprogress = false;
22618c2ecf20Sopenharmony_ci		spin_unlock(&rtlpriv->locks.rf_ps_lock);
22628c2ecf20Sopenharmony_ci	} else {
22638c2ecf20Sopenharmony_ci		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
22648c2ecf20Sopenharmony_ci			RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
22658c2ecf20Sopenharmony_ci
22668c2ecf20Sopenharmony_ci		spin_lock(&rtlpriv->locks.rf_ps_lock);
22678c2ecf20Sopenharmony_ci		ppsc->rfchange_inprogress = false;
22688c2ecf20Sopenharmony_ci		spin_unlock(&rtlpriv->locks.rf_ps_lock);
22698c2ecf20Sopenharmony_ci	}
22708c2ecf20Sopenharmony_ci
22718c2ecf20Sopenharmony_ci	*valid = 1;
22728c2ecf20Sopenharmony_ci	return !ppsc->hwradiooff;
22738c2ecf20Sopenharmony_ci
22748c2ecf20Sopenharmony_ci}
22758c2ecf20Sopenharmony_ci
22768c2ecf20Sopenharmony_civoid rtl88ee_set_key(struct ieee80211_hw *hw, u32 key_index,
22778c2ecf20Sopenharmony_ci		     u8 *p_macaddr, bool is_group, u8 enc_algo,
22788c2ecf20Sopenharmony_ci		     bool is_wepkey, bool clear_all)
22798c2ecf20Sopenharmony_ci{
22808c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
22818c2ecf20Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
22828c2ecf20Sopenharmony_ci	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
22838c2ecf20Sopenharmony_ci	u8 *macaddr = p_macaddr;
22848c2ecf20Sopenharmony_ci	u32 entry_id = 0;
22858c2ecf20Sopenharmony_ci	bool is_pairwise = false;
22868c2ecf20Sopenharmony_ci	static u8 cam_const_addr[4][6] = {
22878c2ecf20Sopenharmony_ci		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
22888c2ecf20Sopenharmony_ci		{0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
22898c2ecf20Sopenharmony_ci		{0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
22908c2ecf20Sopenharmony_ci		{0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
22918c2ecf20Sopenharmony_ci	};
22928c2ecf20Sopenharmony_ci	static u8 cam_const_broad[] = {
22938c2ecf20Sopenharmony_ci		0xff, 0xff, 0xff, 0xff, 0xff, 0xff
22948c2ecf20Sopenharmony_ci	};
22958c2ecf20Sopenharmony_ci
22968c2ecf20Sopenharmony_ci	if (clear_all) {
22978c2ecf20Sopenharmony_ci		u8 idx = 0;
22988c2ecf20Sopenharmony_ci		u8 cam_offset = 0;
22998c2ecf20Sopenharmony_ci		u8 clear_number = 5;
23008c2ecf20Sopenharmony_ci
23018c2ecf20Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
23028c2ecf20Sopenharmony_ci
23038c2ecf20Sopenharmony_ci		for (idx = 0; idx < clear_number; idx++) {
23048c2ecf20Sopenharmony_ci			rtl_cam_mark_invalid(hw, cam_offset + idx);
23058c2ecf20Sopenharmony_ci			rtl_cam_empty_entry(hw, cam_offset + idx);
23068c2ecf20Sopenharmony_ci
23078c2ecf20Sopenharmony_ci			if (idx < 5) {
23088c2ecf20Sopenharmony_ci				memset(rtlpriv->sec.key_buf[idx], 0,
23098c2ecf20Sopenharmony_ci				       MAX_KEY_LEN);
23108c2ecf20Sopenharmony_ci				rtlpriv->sec.key_len[idx] = 0;
23118c2ecf20Sopenharmony_ci			}
23128c2ecf20Sopenharmony_ci		}
23138c2ecf20Sopenharmony_ci
23148c2ecf20Sopenharmony_ci	} else {
23158c2ecf20Sopenharmony_ci		switch (enc_algo) {
23168c2ecf20Sopenharmony_ci		case WEP40_ENCRYPTION:
23178c2ecf20Sopenharmony_ci			enc_algo = CAM_WEP40;
23188c2ecf20Sopenharmony_ci			break;
23198c2ecf20Sopenharmony_ci		case WEP104_ENCRYPTION:
23208c2ecf20Sopenharmony_ci			enc_algo = CAM_WEP104;
23218c2ecf20Sopenharmony_ci			break;
23228c2ecf20Sopenharmony_ci		case TKIP_ENCRYPTION:
23238c2ecf20Sopenharmony_ci			enc_algo = CAM_TKIP;
23248c2ecf20Sopenharmony_ci			break;
23258c2ecf20Sopenharmony_ci		case AESCCMP_ENCRYPTION:
23268c2ecf20Sopenharmony_ci			enc_algo = CAM_AES;
23278c2ecf20Sopenharmony_ci			break;
23288c2ecf20Sopenharmony_ci		default:
23298c2ecf20Sopenharmony_ci			pr_err("switch case %#x not processed\n",
23308c2ecf20Sopenharmony_ci			       enc_algo);
23318c2ecf20Sopenharmony_ci			enc_algo = CAM_TKIP;
23328c2ecf20Sopenharmony_ci			break;
23338c2ecf20Sopenharmony_ci		}
23348c2ecf20Sopenharmony_ci
23358c2ecf20Sopenharmony_ci		if (is_wepkey || rtlpriv->sec.use_defaultkey) {
23368c2ecf20Sopenharmony_ci			macaddr = cam_const_addr[key_index];
23378c2ecf20Sopenharmony_ci			entry_id = key_index;
23388c2ecf20Sopenharmony_ci		} else {
23398c2ecf20Sopenharmony_ci			if (is_group) {
23408c2ecf20Sopenharmony_ci				macaddr = cam_const_broad;
23418c2ecf20Sopenharmony_ci				entry_id = key_index;
23428c2ecf20Sopenharmony_ci			} else {
23438c2ecf20Sopenharmony_ci				if (mac->opmode == NL80211_IFTYPE_AP ||
23448c2ecf20Sopenharmony_ci				    mac->opmode == NL80211_IFTYPE_MESH_POINT) {
23458c2ecf20Sopenharmony_ci					entry_id =
23468c2ecf20Sopenharmony_ci					  rtl_cam_get_free_entry(hw, p_macaddr);
23478c2ecf20Sopenharmony_ci					if (entry_id >=  TOTAL_CAM_ENTRY) {
23488c2ecf20Sopenharmony_ci						pr_err("Can not find free hw security cam entry\n");
23498c2ecf20Sopenharmony_ci						return;
23508c2ecf20Sopenharmony_ci					}
23518c2ecf20Sopenharmony_ci				} else {
23528c2ecf20Sopenharmony_ci					entry_id = CAM_PAIRWISE_KEY_POSITION;
23538c2ecf20Sopenharmony_ci				}
23548c2ecf20Sopenharmony_ci				key_index = PAIRWISE_KEYIDX;
23558c2ecf20Sopenharmony_ci				is_pairwise = true;
23568c2ecf20Sopenharmony_ci			}
23578c2ecf20Sopenharmony_ci		}
23588c2ecf20Sopenharmony_ci
23598c2ecf20Sopenharmony_ci		if (rtlpriv->sec.key_len[key_index] == 0) {
23608c2ecf20Sopenharmony_ci			rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
23618c2ecf20Sopenharmony_ci				"delete one entry, entry_id is %d\n",
23628c2ecf20Sopenharmony_ci				entry_id);
23638c2ecf20Sopenharmony_ci			if (mac->opmode == NL80211_IFTYPE_AP ||
23648c2ecf20Sopenharmony_ci				mac->opmode == NL80211_IFTYPE_MESH_POINT)
23658c2ecf20Sopenharmony_ci				rtl_cam_del_entry(hw, p_macaddr);
23668c2ecf20Sopenharmony_ci			rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
23678c2ecf20Sopenharmony_ci		} else {
23688c2ecf20Sopenharmony_ci			rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
23698c2ecf20Sopenharmony_ci				"add one entry\n");
23708c2ecf20Sopenharmony_ci			if (is_pairwise) {
23718c2ecf20Sopenharmony_ci				rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
23728c2ecf20Sopenharmony_ci					"set Pairwise key\n");
23738c2ecf20Sopenharmony_ci
23748c2ecf20Sopenharmony_ci				rtl_cam_add_one_entry(hw, macaddr, key_index,
23758c2ecf20Sopenharmony_ci						      entry_id, enc_algo,
23768c2ecf20Sopenharmony_ci						      CAM_CONFIG_NO_USEDK,
23778c2ecf20Sopenharmony_ci						      rtlpriv->sec.key_buf[key_index]);
23788c2ecf20Sopenharmony_ci			} else {
23798c2ecf20Sopenharmony_ci				rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
23808c2ecf20Sopenharmony_ci					"set group key\n");
23818c2ecf20Sopenharmony_ci
23828c2ecf20Sopenharmony_ci				if (mac->opmode == NL80211_IFTYPE_ADHOC) {
23838c2ecf20Sopenharmony_ci					rtl_cam_add_one_entry(hw,
23848c2ecf20Sopenharmony_ci							rtlefuse->dev_addr,
23858c2ecf20Sopenharmony_ci							PAIRWISE_KEYIDX,
23868c2ecf20Sopenharmony_ci							CAM_PAIRWISE_KEY_POSITION,
23878c2ecf20Sopenharmony_ci							enc_algo,
23888c2ecf20Sopenharmony_ci							CAM_CONFIG_NO_USEDK,
23898c2ecf20Sopenharmony_ci							rtlpriv->sec.key_buf
23908c2ecf20Sopenharmony_ci							[entry_id]);
23918c2ecf20Sopenharmony_ci				}
23928c2ecf20Sopenharmony_ci
23938c2ecf20Sopenharmony_ci				rtl_cam_add_one_entry(hw, macaddr, key_index,
23948c2ecf20Sopenharmony_ci						      entry_id, enc_algo,
23958c2ecf20Sopenharmony_ci						      CAM_CONFIG_NO_USEDK,
23968c2ecf20Sopenharmony_ci						      rtlpriv->sec.key_buf[entry_id]);
23978c2ecf20Sopenharmony_ci			}
23988c2ecf20Sopenharmony_ci
23998c2ecf20Sopenharmony_ci		}
24008c2ecf20Sopenharmony_ci	}
24018c2ecf20Sopenharmony_ci}
24028c2ecf20Sopenharmony_ci
24038c2ecf20Sopenharmony_cistatic void rtl8188ee_bt_var_init(struct ieee80211_hw *hw)
24048c2ecf20Sopenharmony_ci{
24058c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
24068c2ecf20Sopenharmony_ci
24078c2ecf20Sopenharmony_ci	rtlpriv->btcoexist.bt_coexistence =
24088c2ecf20Sopenharmony_ci		rtlpriv->btcoexist.eeprom_bt_coexist;
24098c2ecf20Sopenharmony_ci	rtlpriv->btcoexist.bt_ant_num = rtlpriv->btcoexist.eeprom_bt_ant_num;
24108c2ecf20Sopenharmony_ci	rtlpriv->btcoexist.bt_coexist_type = rtlpriv->btcoexist.eeprom_bt_type;
24118c2ecf20Sopenharmony_ci
24128c2ecf20Sopenharmony_ci	if (rtlpriv->btcoexist.reg_bt_iso == 2)
24138c2ecf20Sopenharmony_ci		rtlpriv->btcoexist.bt_ant_isolation =
24148c2ecf20Sopenharmony_ci				rtlpriv->btcoexist.eeprom_bt_ant_isol;
24158c2ecf20Sopenharmony_ci	else
24168c2ecf20Sopenharmony_ci		rtlpriv->btcoexist.bt_ant_isolation =
24178c2ecf20Sopenharmony_ci				rtlpriv->btcoexist.reg_bt_iso;
24188c2ecf20Sopenharmony_ci
24198c2ecf20Sopenharmony_ci	rtlpriv->btcoexist.bt_radio_shared_type =
24208c2ecf20Sopenharmony_ci		rtlpriv->btcoexist.eeprom_bt_radio_shared;
24218c2ecf20Sopenharmony_ci
24228c2ecf20Sopenharmony_ci	if (rtlpriv->btcoexist.bt_coexistence) {
24238c2ecf20Sopenharmony_ci		if (rtlpriv->btcoexist.reg_bt_sco == 1)
24248c2ecf20Sopenharmony_ci			rtlpriv->btcoexist.bt_service = BT_OTHER_ACTION;
24258c2ecf20Sopenharmony_ci		else if (rtlpriv->btcoexist.reg_bt_sco == 2)
24268c2ecf20Sopenharmony_ci			rtlpriv->btcoexist.bt_service = BT_SCO;
24278c2ecf20Sopenharmony_ci		else if (rtlpriv->btcoexist.reg_bt_sco == 4)
24288c2ecf20Sopenharmony_ci			rtlpriv->btcoexist.bt_service = BT_BUSY;
24298c2ecf20Sopenharmony_ci		else if (rtlpriv->btcoexist.reg_bt_sco == 5)
24308c2ecf20Sopenharmony_ci			rtlpriv->btcoexist.bt_service = BT_OTHERBUSY;
24318c2ecf20Sopenharmony_ci		else
24328c2ecf20Sopenharmony_ci			rtlpriv->btcoexist.bt_service = BT_IDLE;
24338c2ecf20Sopenharmony_ci
24348c2ecf20Sopenharmony_ci		rtlpriv->btcoexist.bt_edca_ul = 0;
24358c2ecf20Sopenharmony_ci		rtlpriv->btcoexist.bt_edca_dl = 0;
24368c2ecf20Sopenharmony_ci		rtlpriv->btcoexist.bt_rssi_state = 0xff;
24378c2ecf20Sopenharmony_ci	}
24388c2ecf20Sopenharmony_ci}
24398c2ecf20Sopenharmony_ci
24408c2ecf20Sopenharmony_civoid rtl8188ee_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
24418c2ecf20Sopenharmony_ci					      bool auto_load_fail, u8 *hwinfo)
24428c2ecf20Sopenharmony_ci{
24438c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
24448c2ecf20Sopenharmony_ci	u8 value;
24458c2ecf20Sopenharmony_ci
24468c2ecf20Sopenharmony_ci	if (!auto_load_fail) {
24478c2ecf20Sopenharmony_ci		rtlpriv->btcoexist.eeprom_bt_coexist =
24488c2ecf20Sopenharmony_ci			((hwinfo[EEPROM_RF_FEATURE_OPTION_88E] & 0xe0) >> 5);
24498c2ecf20Sopenharmony_ci		if (hwinfo[EEPROM_RF_FEATURE_OPTION_88E] == 0xFF)
24508c2ecf20Sopenharmony_ci			rtlpriv->btcoexist.eeprom_bt_coexist  = 0;
24518c2ecf20Sopenharmony_ci		value = hwinfo[EEPROM_RF_BT_SETTING_88E];
24528c2ecf20Sopenharmony_ci		rtlpriv->btcoexist.eeprom_bt_type = ((value & 0xe) >> 1);
24538c2ecf20Sopenharmony_ci		rtlpriv->btcoexist.eeprom_bt_ant_num = (value & 0x1);
24548c2ecf20Sopenharmony_ci		rtlpriv->btcoexist.eeprom_bt_ant_isol = ((value & 0x10) >> 4);
24558c2ecf20Sopenharmony_ci		rtlpriv->btcoexist.eeprom_bt_radio_shared =
24568c2ecf20Sopenharmony_ci				 ((value & 0x20) >> 5);
24578c2ecf20Sopenharmony_ci	} else {
24588c2ecf20Sopenharmony_ci		rtlpriv->btcoexist.eeprom_bt_coexist = 0;
24598c2ecf20Sopenharmony_ci		rtlpriv->btcoexist.eeprom_bt_type = BT_2WIRE;
24608c2ecf20Sopenharmony_ci		rtlpriv->btcoexist.eeprom_bt_ant_num = ANT_X2;
24618c2ecf20Sopenharmony_ci		rtlpriv->btcoexist.eeprom_bt_ant_isol = 0;
24628c2ecf20Sopenharmony_ci		rtlpriv->btcoexist.eeprom_bt_radio_shared = BT_RADIO_SHARED;
24638c2ecf20Sopenharmony_ci	}
24648c2ecf20Sopenharmony_ci
24658c2ecf20Sopenharmony_ci	rtl8188ee_bt_var_init(hw);
24668c2ecf20Sopenharmony_ci}
24678c2ecf20Sopenharmony_ci
24688c2ecf20Sopenharmony_civoid rtl8188ee_bt_reg_init(struct ieee80211_hw *hw)
24698c2ecf20Sopenharmony_ci{
24708c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
24718c2ecf20Sopenharmony_ci
24728c2ecf20Sopenharmony_ci	/* 0:Low, 1:High, 2:From Efuse. */
24738c2ecf20Sopenharmony_ci	rtlpriv->btcoexist.reg_bt_iso = 2;
24748c2ecf20Sopenharmony_ci	/* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */
24758c2ecf20Sopenharmony_ci	rtlpriv->btcoexist.reg_bt_sco = 3;
24768c2ecf20Sopenharmony_ci	/* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
24778c2ecf20Sopenharmony_ci	rtlpriv->btcoexist.reg_bt_sco = 0;
24788c2ecf20Sopenharmony_ci}
24798c2ecf20Sopenharmony_ci
24808c2ecf20Sopenharmony_civoid rtl8188ee_bt_hw_init(struct ieee80211_hw *hw)
24818c2ecf20Sopenharmony_ci{
24828c2ecf20Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
24838c2ecf20Sopenharmony_ci	struct rtl_phy *rtlphy = &rtlpriv->phy;
24848c2ecf20Sopenharmony_ci	u8 u1_tmp;
24858c2ecf20Sopenharmony_ci
24868c2ecf20Sopenharmony_ci	if (rtlpriv->btcoexist.bt_coexistence &&
24878c2ecf20Sopenharmony_ci	    ((rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC4) ||
24888c2ecf20Sopenharmony_ci	      rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC8)) {
24898c2ecf20Sopenharmony_ci		if (rtlpriv->btcoexist.bt_ant_isolation)
24908c2ecf20Sopenharmony_ci			rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0);
24918c2ecf20Sopenharmony_ci
24928c2ecf20Sopenharmony_ci		u1_tmp = rtl_read_byte(rtlpriv, 0x4fd) & BIT(0);
24938c2ecf20Sopenharmony_ci		u1_tmp = u1_tmp |
24948c2ecf20Sopenharmony_ci			 ((rtlpriv->btcoexist.bt_ant_isolation == 1) ?
24958c2ecf20Sopenharmony_ci			 0 : BIT((1)) |
24968c2ecf20Sopenharmony_ci			 ((rtlpriv->btcoexist.bt_service == BT_SCO) ?
24978c2ecf20Sopenharmony_ci			 0 : BIT(2)));
24988c2ecf20Sopenharmony_ci		rtl_write_byte(rtlpriv, 0x4fd, u1_tmp);
24998c2ecf20Sopenharmony_ci
25008c2ecf20Sopenharmony_ci		rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+4, 0xaaaa9aaa);
25018c2ecf20Sopenharmony_ci		rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+8, 0xffbd0040);
25028c2ecf20Sopenharmony_ci		rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+0xc, 0x40000010);
25038c2ecf20Sopenharmony_ci
25048c2ecf20Sopenharmony_ci		/* Config to 1T1R. */
25058c2ecf20Sopenharmony_ci		if (rtlphy->rf_type == RF_1T1R) {
25068c2ecf20Sopenharmony_ci			u1_tmp = rtl_read_byte(rtlpriv, ROFDM0_TRXPATHENABLE);
25078c2ecf20Sopenharmony_ci			u1_tmp &= ~(BIT(1));
25088c2ecf20Sopenharmony_ci			rtl_write_byte(rtlpriv, ROFDM0_TRXPATHENABLE, u1_tmp);
25098c2ecf20Sopenharmony_ci
25108c2ecf20Sopenharmony_ci			u1_tmp = rtl_read_byte(rtlpriv, ROFDM1_TRXPATHENABLE);
25118c2ecf20Sopenharmony_ci			u1_tmp &= ~(BIT(1));
25128c2ecf20Sopenharmony_ci			rtl_write_byte(rtlpriv, ROFDM1_TRXPATHENABLE, u1_tmp);
25138c2ecf20Sopenharmony_ci		}
25148c2ecf20Sopenharmony_ci	}
25158c2ecf20Sopenharmony_ci}
25168c2ecf20Sopenharmony_ci
25178c2ecf20Sopenharmony_civoid rtl88ee_suspend(struct ieee80211_hw *hw)
25188c2ecf20Sopenharmony_ci{
25198c2ecf20Sopenharmony_ci}
25208c2ecf20Sopenharmony_ci
25218c2ecf20Sopenharmony_civoid rtl88ee_resume(struct ieee80211_hw *hw)
25228c2ecf20Sopenharmony_ci{
25238c2ecf20Sopenharmony_ci}
2524