162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/* Copyright(c) 2009-2014  Realtek Corporation.*/
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci#include "../wifi.h"
562306a36Sopenharmony_ci#include "../efuse.h"
662306a36Sopenharmony_ci#include "../base.h"
762306a36Sopenharmony_ci#include "../regd.h"
862306a36Sopenharmony_ci#include "../cam.h"
962306a36Sopenharmony_ci#include "../ps.h"
1062306a36Sopenharmony_ci#include "../pci.h"
1162306a36Sopenharmony_ci#include "reg.h"
1262306a36Sopenharmony_ci#include "def.h"
1362306a36Sopenharmony_ci#include "phy.h"
1462306a36Sopenharmony_ci#include "dm.h"
1562306a36Sopenharmony_ci#include "fw.h"
1662306a36Sopenharmony_ci#include "led.h"
1762306a36Sopenharmony_ci#include "hw.h"
1862306a36Sopenharmony_ci#include "../pwrseqcmd.h"
1962306a36Sopenharmony_ci#include "pwrseq.h"
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#define LLT_CONFIG	5
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_cistatic void _rtl92ee_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
2462306a36Sopenharmony_ci				      u8 set_bits, u8 clear_bits)
2562306a36Sopenharmony_ci{
2662306a36Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
2762306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci	rtlpci->reg_bcn_ctrl_val |= set_bits;
3062306a36Sopenharmony_ci	rtlpci->reg_bcn_ctrl_val &= ~clear_bits;
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlpci->reg_bcn_ctrl_val);
3362306a36Sopenharmony_ci}
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_cistatic void _rtl92ee_stop_tx_beacon(struct ieee80211_hw *hw)
3662306a36Sopenharmony_ci{
3762306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
3862306a36Sopenharmony_ci	u8 tmp;
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci	tmp = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
4162306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp & (~BIT(6)));
4262306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64);
4362306a36Sopenharmony_ci	tmp = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
4462306a36Sopenharmony_ci	tmp &= ~(BIT(0));
4562306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp);
4662306a36Sopenharmony_ci}
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_cistatic void _rtl92ee_resume_tx_beacon(struct ieee80211_hw *hw)
4962306a36Sopenharmony_ci{
5062306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
5162306a36Sopenharmony_ci	u8 tmp;
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci	tmp = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
5462306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp | BIT(6));
5562306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
5662306a36Sopenharmony_ci	tmp = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
5762306a36Sopenharmony_ci	tmp |= BIT(0);
5862306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp);
5962306a36Sopenharmony_ci}
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_cistatic void _rtl92ee_enable_bcn_sub_func(struct ieee80211_hw *hw)
6262306a36Sopenharmony_ci{
6362306a36Sopenharmony_ci	_rtl92ee_set_bcn_ctrl_reg(hw, 0, BIT(1));
6462306a36Sopenharmony_ci}
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_cistatic void _rtl92ee_disable_bcn_sub_func(struct ieee80211_hw *hw)
6762306a36Sopenharmony_ci{
6862306a36Sopenharmony_ci	_rtl92ee_set_bcn_ctrl_reg(hw, BIT(1), 0);
6962306a36Sopenharmony_ci}
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_cistatic void _rtl92ee_set_fw_clock_on(struct ieee80211_hw *hw,
7262306a36Sopenharmony_ci				     u8 rpwm_val, bool b_need_turn_off_ckk)
7362306a36Sopenharmony_ci{
7462306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
7562306a36Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
7662306a36Sopenharmony_ci	bool b_support_remote_wake_up;
7762306a36Sopenharmony_ci	u32 count = 0, isr_regaddr, content;
7862306a36Sopenharmony_ci	bool b_schedule_timer = b_need_turn_off_ckk;
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci	rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN,
8162306a36Sopenharmony_ci				      (u8 *)(&b_support_remote_wake_up));
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci	if (!rtlhal->fw_ready)
8462306a36Sopenharmony_ci		return;
8562306a36Sopenharmony_ci	if (!rtlpriv->psc.fw_current_inpsmode)
8662306a36Sopenharmony_ci		return;
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	while (1) {
8962306a36Sopenharmony_ci		spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
9062306a36Sopenharmony_ci		if (rtlhal->fw_clk_change_in_progress) {
9162306a36Sopenharmony_ci			while (rtlhal->fw_clk_change_in_progress) {
9262306a36Sopenharmony_ci				spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
9362306a36Sopenharmony_ci				count++;
9462306a36Sopenharmony_ci				udelay(100);
9562306a36Sopenharmony_ci				if (count > 1000)
9662306a36Sopenharmony_ci					return;
9762306a36Sopenharmony_ci				spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
9862306a36Sopenharmony_ci			}
9962306a36Sopenharmony_ci			spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
10062306a36Sopenharmony_ci		} else {
10162306a36Sopenharmony_ci			rtlhal->fw_clk_change_in_progress = false;
10262306a36Sopenharmony_ci			spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
10362306a36Sopenharmony_ci			break;
10462306a36Sopenharmony_ci		}
10562306a36Sopenharmony_ci	}
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	if (IS_IN_LOW_POWER_STATE_92E(rtlhal->fw_ps_state)) {
10862306a36Sopenharmony_ci		rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM,
10962306a36Sopenharmony_ci					      (u8 *)(&rpwm_val));
11062306a36Sopenharmony_ci		if (FW_PS_IS_ACK(rpwm_val)) {
11162306a36Sopenharmony_ci			isr_regaddr = REG_HISR;
11262306a36Sopenharmony_ci			content = rtl_read_dword(rtlpriv, isr_regaddr);
11362306a36Sopenharmony_ci			while (!(content & IMR_CPWM) && (count < 500)) {
11462306a36Sopenharmony_ci				udelay(50);
11562306a36Sopenharmony_ci				count++;
11662306a36Sopenharmony_ci				content = rtl_read_dword(rtlpriv, isr_regaddr);
11762306a36Sopenharmony_ci			}
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci			if (content & IMR_CPWM) {
12062306a36Sopenharmony_ci				rtl_write_word(rtlpriv, isr_regaddr, 0x0100);
12162306a36Sopenharmony_ci				rtlhal->fw_ps_state = FW_PS_STATE_RF_ON_92E;
12262306a36Sopenharmony_ci				rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
12362306a36Sopenharmony_ci					"Receive CPWM INT!!! PSState = %X\n",
12462306a36Sopenharmony_ci					rtlhal->fw_ps_state);
12562306a36Sopenharmony_ci			}
12662306a36Sopenharmony_ci		}
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci		spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
12962306a36Sopenharmony_ci		rtlhal->fw_clk_change_in_progress = false;
13062306a36Sopenharmony_ci		spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
13162306a36Sopenharmony_ci		if (b_schedule_timer) {
13262306a36Sopenharmony_ci			mod_timer(&rtlpriv->works.fw_clockoff_timer,
13362306a36Sopenharmony_ci				  jiffies + MSECS(10));
13462306a36Sopenharmony_ci		}
13562306a36Sopenharmony_ci	} else  {
13662306a36Sopenharmony_ci		spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
13762306a36Sopenharmony_ci		rtlhal->fw_clk_change_in_progress = false;
13862306a36Sopenharmony_ci		spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
13962306a36Sopenharmony_ci	}
14062306a36Sopenharmony_ci}
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_cistatic void _rtl92ee_set_fw_clock_off(struct ieee80211_hw *hw, u8 rpwm_val)
14362306a36Sopenharmony_ci{
14462306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
14562306a36Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
14662306a36Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
14762306a36Sopenharmony_ci	struct rtl8192_tx_ring *ring;
14862306a36Sopenharmony_ci	enum rf_pwrstate rtstate;
14962306a36Sopenharmony_ci	bool b_schedule_timer = false;
15062306a36Sopenharmony_ci	u8 queue;
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci	if (!rtlhal->fw_ready)
15362306a36Sopenharmony_ci		return;
15462306a36Sopenharmony_ci	if (!rtlpriv->psc.fw_current_inpsmode)
15562306a36Sopenharmony_ci		return;
15662306a36Sopenharmony_ci	if (!rtlhal->allow_sw_to_change_hwclc)
15762306a36Sopenharmony_ci		return;
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, (u8 *)(&rtstate));
16062306a36Sopenharmony_ci	if (rtstate == ERFOFF || rtlpriv->psc.inactive_pwrstate == ERFOFF)
16162306a36Sopenharmony_ci		return;
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci	for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) {
16462306a36Sopenharmony_ci		ring = &rtlpci->tx_ring[queue];
16562306a36Sopenharmony_ci		if (skb_queue_len(&ring->queue)) {
16662306a36Sopenharmony_ci			b_schedule_timer = true;
16762306a36Sopenharmony_ci			break;
16862306a36Sopenharmony_ci		}
16962306a36Sopenharmony_ci	}
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	if (b_schedule_timer) {
17262306a36Sopenharmony_ci		mod_timer(&rtlpriv->works.fw_clockoff_timer,
17362306a36Sopenharmony_ci			  jiffies + MSECS(10));
17462306a36Sopenharmony_ci		return;
17562306a36Sopenharmony_ci	}
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci	if (FW_PS_STATE(rtlhal->fw_ps_state) != FW_PS_STATE_RF_OFF_LOW_PWR) {
17862306a36Sopenharmony_ci		spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
17962306a36Sopenharmony_ci		if (!rtlhal->fw_clk_change_in_progress) {
18062306a36Sopenharmony_ci			rtlhal->fw_clk_change_in_progress = true;
18162306a36Sopenharmony_ci			spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
18262306a36Sopenharmony_ci			rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val);
18362306a36Sopenharmony_ci			rtl_write_word(rtlpriv, REG_HISR, 0x0100);
18462306a36Sopenharmony_ci			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
18562306a36Sopenharmony_ci						      (u8 *)(&rpwm_val));
18662306a36Sopenharmony_ci			spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
18762306a36Sopenharmony_ci			rtlhal->fw_clk_change_in_progress = false;
18862306a36Sopenharmony_ci			spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
18962306a36Sopenharmony_ci		} else {
19062306a36Sopenharmony_ci			spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
19162306a36Sopenharmony_ci			mod_timer(&rtlpriv->works.fw_clockoff_timer,
19262306a36Sopenharmony_ci				  jiffies + MSECS(10));
19362306a36Sopenharmony_ci		}
19462306a36Sopenharmony_ci	}
19562306a36Sopenharmony_ci}
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_cistatic void _rtl92ee_set_fw_ps_rf_on(struct ieee80211_hw *hw)
19862306a36Sopenharmony_ci{
19962306a36Sopenharmony_ci	u8 rpwm_val = 0;
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci	rpwm_val |= (FW_PS_STATE_RF_OFF_92E | FW_PS_ACK);
20262306a36Sopenharmony_ci	_rtl92ee_set_fw_clock_on(hw, rpwm_val, true);
20362306a36Sopenharmony_ci}
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_cistatic void _rtl92ee_set_fw_ps_rf_off_low_power(struct ieee80211_hw *hw)
20662306a36Sopenharmony_ci{
20762306a36Sopenharmony_ci	u8 rpwm_val = 0;
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci	rpwm_val |= FW_PS_STATE_RF_OFF_LOW_PWR;
21062306a36Sopenharmony_ci	_rtl92ee_set_fw_clock_off(hw, rpwm_val);
21162306a36Sopenharmony_ci}
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_civoid rtl92ee_fw_clk_off_timer_callback(unsigned long data)
21462306a36Sopenharmony_ci{
21562306a36Sopenharmony_ci	struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci	_rtl92ee_set_fw_ps_rf_off_low_power(hw);
21862306a36Sopenharmony_ci}
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_cistatic void _rtl92ee_fwlps_leave(struct ieee80211_hw *hw)
22162306a36Sopenharmony_ci{
22262306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
22362306a36Sopenharmony_ci	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
22462306a36Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
22562306a36Sopenharmony_ci	bool fw_current_inps = false;
22662306a36Sopenharmony_ci	u8 rpwm_val = 0, fw_pwrmode = FW_PS_ACTIVE_MODE;
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci	if (ppsc->low_power_enable) {
22962306a36Sopenharmony_ci		rpwm_val = (FW_PS_STATE_ALL_ON_92E | FW_PS_ACK);/* RF on */
23062306a36Sopenharmony_ci		_rtl92ee_set_fw_clock_on(hw, rpwm_val, false);
23162306a36Sopenharmony_ci		rtlhal->allow_sw_to_change_hwclc = false;
23262306a36Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
23362306a36Sopenharmony_ci					      (u8 *)(&fw_pwrmode));
23462306a36Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
23562306a36Sopenharmony_ci					      (u8 *)(&fw_current_inps));
23662306a36Sopenharmony_ci	} else {
23762306a36Sopenharmony_ci		rpwm_val = FW_PS_STATE_ALL_ON_92E;	/* RF on */
23862306a36Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
23962306a36Sopenharmony_ci					      (u8 *)(&rpwm_val));
24062306a36Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
24162306a36Sopenharmony_ci					      (u8 *)(&fw_pwrmode));
24262306a36Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
24362306a36Sopenharmony_ci					      (u8 *)(&fw_current_inps));
24462306a36Sopenharmony_ci	}
24562306a36Sopenharmony_ci}
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_cistatic void _rtl92ee_fwlps_enter(struct ieee80211_hw *hw)
24862306a36Sopenharmony_ci{
24962306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
25062306a36Sopenharmony_ci	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
25162306a36Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
25262306a36Sopenharmony_ci	bool fw_current_inps = true;
25362306a36Sopenharmony_ci	u8 rpwm_val;
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci	if (ppsc->low_power_enable) {
25662306a36Sopenharmony_ci		rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR;	/* RF off */
25762306a36Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
25862306a36Sopenharmony_ci					      (u8 *)(&fw_current_inps));
25962306a36Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
26062306a36Sopenharmony_ci					      (u8 *)(&ppsc->fwctrl_psmode));
26162306a36Sopenharmony_ci		rtlhal->allow_sw_to_change_hwclc = true;
26262306a36Sopenharmony_ci		_rtl92ee_set_fw_clock_off(hw, rpwm_val);
26362306a36Sopenharmony_ci	} else {
26462306a36Sopenharmony_ci		rpwm_val = FW_PS_STATE_RF_OFF_92E;	/* RF off */
26562306a36Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
26662306a36Sopenharmony_ci					      (u8 *)(&fw_current_inps));
26762306a36Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
26862306a36Sopenharmony_ci					      (u8 *)(&ppsc->fwctrl_psmode));
26962306a36Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
27062306a36Sopenharmony_ci					      (u8 *)(&rpwm_val));
27162306a36Sopenharmony_ci	}
27262306a36Sopenharmony_ci}
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_civoid rtl92ee_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
27562306a36Sopenharmony_ci{
27662306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
27762306a36Sopenharmony_ci	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
27862306a36Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci	switch (variable) {
28162306a36Sopenharmony_ci	case HW_VAR_RCR:
28262306a36Sopenharmony_ci		*((u32 *)(val)) = rtlpci->receive_config;
28362306a36Sopenharmony_ci		break;
28462306a36Sopenharmony_ci	case HW_VAR_RF_STATE:
28562306a36Sopenharmony_ci		*((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
28662306a36Sopenharmony_ci		break;
28762306a36Sopenharmony_ci	case HW_VAR_FWLPS_RF_ON:{
28862306a36Sopenharmony_ci			enum rf_pwrstate rfstate;
28962306a36Sopenharmony_ci			u32 val_rcr;
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci			rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE,
29262306a36Sopenharmony_ci						      (u8 *)(&rfstate));
29362306a36Sopenharmony_ci			if (rfstate == ERFOFF) {
29462306a36Sopenharmony_ci				*((bool *)(val)) = true;
29562306a36Sopenharmony_ci			} else {
29662306a36Sopenharmony_ci				val_rcr = rtl_read_dword(rtlpriv, REG_RCR);
29762306a36Sopenharmony_ci				val_rcr &= 0x00070000;
29862306a36Sopenharmony_ci				if (val_rcr)
29962306a36Sopenharmony_ci					*((bool *)(val)) = false;
30062306a36Sopenharmony_ci				else
30162306a36Sopenharmony_ci					*((bool *)(val)) = true;
30262306a36Sopenharmony_ci			}
30362306a36Sopenharmony_ci		}
30462306a36Sopenharmony_ci		break;
30562306a36Sopenharmony_ci	case HW_VAR_FW_PSMODE_STATUS:
30662306a36Sopenharmony_ci		*((bool *)(val)) = ppsc->fw_current_inpsmode;
30762306a36Sopenharmony_ci		break;
30862306a36Sopenharmony_ci	case HW_VAR_CORRECT_TSF:{
30962306a36Sopenharmony_ci		u64 tsf;
31062306a36Sopenharmony_ci		u32 *ptsf_low = (u32 *)&tsf;
31162306a36Sopenharmony_ci		u32 *ptsf_high = ((u32 *)&tsf) + 1;
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci		*ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4));
31462306a36Sopenharmony_ci		*ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ci		*((u64 *)(val)) = tsf;
31762306a36Sopenharmony_ci		}
31862306a36Sopenharmony_ci		break;
31962306a36Sopenharmony_ci	case HAL_DEF_WOWLAN:
32062306a36Sopenharmony_ci		break;
32162306a36Sopenharmony_ci	default:
32262306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG,
32362306a36Sopenharmony_ci			"switch case %#x not processed\n", variable);
32462306a36Sopenharmony_ci		break;
32562306a36Sopenharmony_ci	}
32662306a36Sopenharmony_ci}
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_cistatic void _rtl92ee_download_rsvd_page(struct ieee80211_hw *hw)
32962306a36Sopenharmony_ci{
33062306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
33162306a36Sopenharmony_ci	u8 tmp_regcr, tmp_reg422;
33262306a36Sopenharmony_ci	u8 bcnvalid_reg, txbc_reg;
33362306a36Sopenharmony_ci	u8 count = 0, dlbcn_count = 0;
33462306a36Sopenharmony_ci	bool b_recover = false;
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci	/*Set REG_CR bit 8. DMA beacon by SW.*/
33762306a36Sopenharmony_ci	tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
33862306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_CR + 1, tmp_regcr | BIT(0));
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci	/* Disable Hw protection for a time which revserd for Hw sending beacon.
34162306a36Sopenharmony_ci	 * Fix download reserved page packet fail
34262306a36Sopenharmony_ci	 * that access collision with the protection time.
34362306a36Sopenharmony_ci	 * 2010.05.11. Added by tynli.
34462306a36Sopenharmony_ci	 */
34562306a36Sopenharmony_ci	_rtl92ee_set_bcn_ctrl_reg(hw, 0, BIT(3));
34662306a36Sopenharmony_ci	_rtl92ee_set_bcn_ctrl_reg(hw, BIT(4), 0);
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci	/* Set FWHW_TXQ_CTRL 0x422[6]=0 to
34962306a36Sopenharmony_ci	 * tell Hw the packet is not a real beacon frame.
35062306a36Sopenharmony_ci	 */
35162306a36Sopenharmony_ci	tmp_reg422 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
35262306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422 & (~BIT(6)));
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci	if (tmp_reg422 & BIT(6))
35562306a36Sopenharmony_ci		b_recover = true;
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_ci	do {
35862306a36Sopenharmony_ci		/* Clear beacon valid check bit */
35962306a36Sopenharmony_ci		bcnvalid_reg = rtl_read_byte(rtlpriv, REG_DWBCN0_CTRL + 2);
36062306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_DWBCN0_CTRL + 2,
36162306a36Sopenharmony_ci			       bcnvalid_reg | BIT(0));
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci		/* download rsvd page */
36462306a36Sopenharmony_ci		rtl92ee_set_fw_rsvdpagepkt(hw, false);
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci		txbc_reg = rtl_read_byte(rtlpriv, REG_MGQ_TXBD_NUM + 3);
36762306a36Sopenharmony_ci		count = 0;
36862306a36Sopenharmony_ci		while ((txbc_reg & BIT(4)) && count < 20) {
36962306a36Sopenharmony_ci			count++;
37062306a36Sopenharmony_ci			udelay(10);
37162306a36Sopenharmony_ci			txbc_reg = rtl_read_byte(rtlpriv, REG_MGQ_TXBD_NUM + 3);
37262306a36Sopenharmony_ci		}
37362306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_MGQ_TXBD_NUM + 3,
37462306a36Sopenharmony_ci			       txbc_reg | BIT(4));
37562306a36Sopenharmony_ci
37662306a36Sopenharmony_ci		/* check rsvd page download OK. */
37762306a36Sopenharmony_ci		bcnvalid_reg = rtl_read_byte(rtlpriv, REG_DWBCN0_CTRL + 2);
37862306a36Sopenharmony_ci		count = 0;
37962306a36Sopenharmony_ci		while (!(bcnvalid_reg & BIT(0)) && count < 20) {
38062306a36Sopenharmony_ci			count++;
38162306a36Sopenharmony_ci			udelay(50);
38262306a36Sopenharmony_ci			bcnvalid_reg = rtl_read_byte(rtlpriv,
38362306a36Sopenharmony_ci						     REG_DWBCN0_CTRL + 2);
38462306a36Sopenharmony_ci		}
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_ci		if (bcnvalid_reg & BIT(0))
38762306a36Sopenharmony_ci			rtl_write_byte(rtlpriv, REG_DWBCN0_CTRL + 2, BIT(0));
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_ci		dlbcn_count++;
39062306a36Sopenharmony_ci	} while (!(bcnvalid_reg & BIT(0)) && dlbcn_count < 5);
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ci	if (!(bcnvalid_reg & BIT(0)))
39362306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
39462306a36Sopenharmony_ci			"Download RSVD page failed!\n");
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ci	/* Enable Bcn */
39762306a36Sopenharmony_ci	_rtl92ee_set_bcn_ctrl_reg(hw, BIT(3), 0);
39862306a36Sopenharmony_ci	_rtl92ee_set_bcn_ctrl_reg(hw, 0, BIT(4));
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ci	if (b_recover)
40162306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422);
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_ci	tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
40462306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_CR + 1, tmp_regcr & (~BIT(0)));
40562306a36Sopenharmony_ci}
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_civoid rtl92ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
40862306a36Sopenharmony_ci{
40962306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
41062306a36Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
41162306a36Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
41262306a36Sopenharmony_ci	struct rtl_efuse *efuse = rtl_efuse(rtl_priv(hw));
41362306a36Sopenharmony_ci	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
41462306a36Sopenharmony_ci	u8 idx;
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_ci	switch (variable) {
41762306a36Sopenharmony_ci	case HW_VAR_ETHER_ADDR:
41862306a36Sopenharmony_ci		for (idx = 0; idx < ETH_ALEN; idx++)
41962306a36Sopenharmony_ci			rtl_write_byte(rtlpriv, (REG_MACID + idx), val[idx]);
42062306a36Sopenharmony_ci		break;
42162306a36Sopenharmony_ci	case HW_VAR_BASIC_RATE:{
42262306a36Sopenharmony_ci		u16 b_rate_cfg = ((u16 *)val)[0];
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci		b_rate_cfg = b_rate_cfg & 0x15f;
42562306a36Sopenharmony_ci		b_rate_cfg |= 0x01;
42662306a36Sopenharmony_ci		b_rate_cfg = (b_rate_cfg | 0xd) & (~BIT(1));
42762306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff);
42862306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_RRSR + 1, (b_rate_cfg >> 8) & 0xff);
42962306a36Sopenharmony_ci		break; }
43062306a36Sopenharmony_ci	case HW_VAR_BSSID:
43162306a36Sopenharmony_ci		for (idx = 0; idx < ETH_ALEN; idx++)
43262306a36Sopenharmony_ci			rtl_write_byte(rtlpriv, (REG_BSSID + idx), val[idx]);
43362306a36Sopenharmony_ci		break;
43462306a36Sopenharmony_ci	case HW_VAR_SIFS:
43562306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]);
43662306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]);
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]);
43962306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_ci		if (!mac->ht_enable)
44262306a36Sopenharmony_ci			rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, 0x0e0e);
44362306a36Sopenharmony_ci		else
44462306a36Sopenharmony_ci			rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
44562306a36Sopenharmony_ci				       *((u16 *)val));
44662306a36Sopenharmony_ci		break;
44762306a36Sopenharmony_ci	case HW_VAR_SLOT_TIME:{
44862306a36Sopenharmony_ci		u8 e_aci;
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_MLME, DBG_TRACE,
45162306a36Sopenharmony_ci			"HW_VAR_SLOT_TIME %x\n", val[0]);
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci		for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
45662306a36Sopenharmony_ci			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
45762306a36Sopenharmony_ci						      (u8 *)(&e_aci));
45862306a36Sopenharmony_ci		}
45962306a36Sopenharmony_ci		break; }
46062306a36Sopenharmony_ci	case HW_VAR_ACK_PREAMBLE:{
46162306a36Sopenharmony_ci		u8 reg_tmp;
46262306a36Sopenharmony_ci		u8 short_preamble = (bool)(*(u8 *)val);
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_ci		reg_tmp = (rtlpriv->mac80211.cur_40_prime_sc) << 5;
46562306a36Sopenharmony_ci		if (short_preamble)
46662306a36Sopenharmony_ci			reg_tmp |= 0x80;
46762306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp);
46862306a36Sopenharmony_ci		rtlpriv->mac80211.short_preamble = short_preamble;
46962306a36Sopenharmony_ci		}
47062306a36Sopenharmony_ci		break;
47162306a36Sopenharmony_ci	case HW_VAR_WPA_CONFIG:
47262306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val));
47362306a36Sopenharmony_ci		break;
47462306a36Sopenharmony_ci	case HW_VAR_AMPDU_FACTOR:{
47562306a36Sopenharmony_ci		u8 regtoset_normal[4] = { 0x41, 0xa8, 0x72, 0xb9 };
47662306a36Sopenharmony_ci		u8 fac;
47762306a36Sopenharmony_ci		u8 *reg = NULL;
47862306a36Sopenharmony_ci		u8 i = 0;
47962306a36Sopenharmony_ci
48062306a36Sopenharmony_ci		reg = regtoset_normal;
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ci		fac = *((u8 *)val);
48362306a36Sopenharmony_ci		if (fac <= 3) {
48462306a36Sopenharmony_ci			fac = (1 << (fac + 2));
48562306a36Sopenharmony_ci			if (fac > 0xf)
48662306a36Sopenharmony_ci				fac = 0xf;
48762306a36Sopenharmony_ci			for (i = 0; i < 4; i++) {
48862306a36Sopenharmony_ci				if ((reg[i] & 0xf0) > (fac << 4))
48962306a36Sopenharmony_ci					reg[i] = (reg[i] & 0x0f) |
49062306a36Sopenharmony_ci						(fac << 4);
49162306a36Sopenharmony_ci				if ((reg[i] & 0x0f) > fac)
49262306a36Sopenharmony_ci					reg[i] = (reg[i] & 0xf0) | fac;
49362306a36Sopenharmony_ci				rtl_write_byte(rtlpriv,
49462306a36Sopenharmony_ci					       (REG_AGGLEN_LMT + i),
49562306a36Sopenharmony_ci					       reg[i]);
49662306a36Sopenharmony_ci			}
49762306a36Sopenharmony_ci			rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD,
49862306a36Sopenharmony_ci				"Set HW_VAR_AMPDU_FACTOR:%#x\n", fac);
49962306a36Sopenharmony_ci		}
50062306a36Sopenharmony_ci		}
50162306a36Sopenharmony_ci		break;
50262306a36Sopenharmony_ci	case HW_VAR_AC_PARAM:{
50362306a36Sopenharmony_ci		u8 e_aci = *((u8 *)val);
50462306a36Sopenharmony_ci
50562306a36Sopenharmony_ci		if (rtlpci->acm_method != EACMWAY2_SW)
50662306a36Sopenharmony_ci			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
50762306a36Sopenharmony_ci						      (u8 *)(&e_aci));
50862306a36Sopenharmony_ci		}
50962306a36Sopenharmony_ci		break;
51062306a36Sopenharmony_ci	case HW_VAR_ACM_CTRL:{
51162306a36Sopenharmony_ci		u8 e_aci = *((u8 *)val);
51262306a36Sopenharmony_ci		union aci_aifsn *aifs = (union aci_aifsn *)(&mac->ac[0].aifs);
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_ci		u8 acm = aifs->f.acm;
51562306a36Sopenharmony_ci		u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ci		acm_ctrl = acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1);
51862306a36Sopenharmony_ci
51962306a36Sopenharmony_ci		if (acm) {
52062306a36Sopenharmony_ci			switch (e_aci) {
52162306a36Sopenharmony_ci			case AC0_BE:
52262306a36Sopenharmony_ci				acm_ctrl |= ACMHW_BEQEN;
52362306a36Sopenharmony_ci				break;
52462306a36Sopenharmony_ci			case AC2_VI:
52562306a36Sopenharmony_ci				acm_ctrl |= ACMHW_VIQEN;
52662306a36Sopenharmony_ci				break;
52762306a36Sopenharmony_ci			case AC3_VO:
52862306a36Sopenharmony_ci				acm_ctrl |= ACMHW_VOQEN;
52962306a36Sopenharmony_ci				break;
53062306a36Sopenharmony_ci			default:
53162306a36Sopenharmony_ci				rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
53262306a36Sopenharmony_ci					"HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
53362306a36Sopenharmony_ci					acm);
53462306a36Sopenharmony_ci				break;
53562306a36Sopenharmony_ci			}
53662306a36Sopenharmony_ci		} else {
53762306a36Sopenharmony_ci			switch (e_aci) {
53862306a36Sopenharmony_ci			case AC0_BE:
53962306a36Sopenharmony_ci				acm_ctrl &= (~ACMHW_BEQEN);
54062306a36Sopenharmony_ci				break;
54162306a36Sopenharmony_ci			case AC2_VI:
54262306a36Sopenharmony_ci				acm_ctrl &= (~ACMHW_VIQEN);
54362306a36Sopenharmony_ci				break;
54462306a36Sopenharmony_ci			case AC3_VO:
54562306a36Sopenharmony_ci				acm_ctrl &= (~ACMHW_VOQEN);
54662306a36Sopenharmony_ci				break;
54762306a36Sopenharmony_ci			default:
54862306a36Sopenharmony_ci				rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG,
54962306a36Sopenharmony_ci					"switch case %#x not processed\n",
55062306a36Sopenharmony_ci					e_aci);
55162306a36Sopenharmony_ci				break;
55262306a36Sopenharmony_ci			}
55362306a36Sopenharmony_ci		}
55462306a36Sopenharmony_ci
55562306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_QOS, DBG_TRACE,
55662306a36Sopenharmony_ci			"SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
55762306a36Sopenharmony_ci			acm_ctrl);
55862306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
55962306a36Sopenharmony_ci		}
56062306a36Sopenharmony_ci		break;
56162306a36Sopenharmony_ci	case HW_VAR_RCR:{
56262306a36Sopenharmony_ci		rtl_write_dword(rtlpriv, REG_RCR, ((u32 *)(val))[0]);
56362306a36Sopenharmony_ci		rtlpci->receive_config = ((u32 *)(val))[0];
56462306a36Sopenharmony_ci		}
56562306a36Sopenharmony_ci		break;
56662306a36Sopenharmony_ci	case HW_VAR_RETRY_LIMIT:{
56762306a36Sopenharmony_ci		u8 retry_limit = ((u8 *)(val))[0];
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_ci		rtl_write_word(rtlpriv, REG_RETRY_LIMIT,
57062306a36Sopenharmony_ci			       retry_limit << RETRY_LIMIT_SHORT_SHIFT |
57162306a36Sopenharmony_ci			       retry_limit << RETRY_LIMIT_LONG_SHIFT);
57262306a36Sopenharmony_ci		}
57362306a36Sopenharmony_ci		break;
57462306a36Sopenharmony_ci	case HW_VAR_DUAL_TSF_RST:
57562306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
57662306a36Sopenharmony_ci		break;
57762306a36Sopenharmony_ci	case HW_VAR_EFUSE_BYTES:
57862306a36Sopenharmony_ci		efuse->efuse_usedbytes = *((u16 *)val);
57962306a36Sopenharmony_ci		break;
58062306a36Sopenharmony_ci	case HW_VAR_EFUSE_USAGE:
58162306a36Sopenharmony_ci		efuse->efuse_usedpercentage = *((u8 *)val);
58262306a36Sopenharmony_ci		break;
58362306a36Sopenharmony_ci	case HW_VAR_IO_CMD:
58462306a36Sopenharmony_ci		rtl92ee_phy_set_io_cmd(hw, (*(enum io_type *)val));
58562306a36Sopenharmony_ci		break;
58662306a36Sopenharmony_ci	case HW_VAR_SET_RPWM:{
58762306a36Sopenharmony_ci		u8 rpwm_val;
58862306a36Sopenharmony_ci
58962306a36Sopenharmony_ci		rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM);
59062306a36Sopenharmony_ci		udelay(1);
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci		if (rpwm_val & BIT(7)) {
59362306a36Sopenharmony_ci			rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, (*(u8 *)val));
59462306a36Sopenharmony_ci		} else {
59562306a36Sopenharmony_ci			rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
59662306a36Sopenharmony_ci				       ((*(u8 *)val) | BIT(7)));
59762306a36Sopenharmony_ci		}
59862306a36Sopenharmony_ci		}
59962306a36Sopenharmony_ci		break;
60062306a36Sopenharmony_ci	case HW_VAR_H2C_FW_PWRMODE:
60162306a36Sopenharmony_ci		rtl92ee_set_fw_pwrmode_cmd(hw, (*(u8 *)val));
60262306a36Sopenharmony_ci		break;
60362306a36Sopenharmony_ci	case HW_VAR_FW_PSMODE_STATUS:
60462306a36Sopenharmony_ci		ppsc->fw_current_inpsmode = *((bool *)val);
60562306a36Sopenharmony_ci		break;
60662306a36Sopenharmony_ci	case HW_VAR_RESUME_CLK_ON:
60762306a36Sopenharmony_ci		_rtl92ee_set_fw_ps_rf_on(hw);
60862306a36Sopenharmony_ci		break;
60962306a36Sopenharmony_ci	case HW_VAR_FW_LPS_ACTION:{
61062306a36Sopenharmony_ci		bool b_enter_fwlps = *((bool *)val);
61162306a36Sopenharmony_ci
61262306a36Sopenharmony_ci		if (b_enter_fwlps)
61362306a36Sopenharmony_ci			_rtl92ee_fwlps_enter(hw);
61462306a36Sopenharmony_ci		else
61562306a36Sopenharmony_ci			_rtl92ee_fwlps_leave(hw);
61662306a36Sopenharmony_ci		}
61762306a36Sopenharmony_ci		break;
61862306a36Sopenharmony_ci	case HW_VAR_H2C_FW_JOINBSSRPT:{
61962306a36Sopenharmony_ci		u8 mstatus = (*(u8 *)val);
62062306a36Sopenharmony_ci
62162306a36Sopenharmony_ci		if (mstatus == RT_MEDIA_CONNECT) {
62262306a36Sopenharmony_ci			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL);
62362306a36Sopenharmony_ci			_rtl92ee_download_rsvd_page(hw);
62462306a36Sopenharmony_ci		}
62562306a36Sopenharmony_ci		rtl92ee_set_fw_media_status_rpt_cmd(hw, mstatus);
62662306a36Sopenharmony_ci		}
62762306a36Sopenharmony_ci		break;
62862306a36Sopenharmony_ci	case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
62962306a36Sopenharmony_ci		rtl92ee_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
63062306a36Sopenharmony_ci		break;
63162306a36Sopenharmony_ci	case HW_VAR_AID:{
63262306a36Sopenharmony_ci		u16 u2btmp;
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_ci		u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
63562306a36Sopenharmony_ci		u2btmp &= 0xC000;
63662306a36Sopenharmony_ci		rtl_write_word(rtlpriv, REG_BCN_PSR_RPT,
63762306a36Sopenharmony_ci			       (u2btmp | mac->assoc_id));
63862306a36Sopenharmony_ci		}
63962306a36Sopenharmony_ci		break;
64062306a36Sopenharmony_ci	case HW_VAR_CORRECT_TSF:{
64162306a36Sopenharmony_ci		u8 btype_ibss = ((u8 *)(val))[0];
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_ci		if (btype_ibss)
64462306a36Sopenharmony_ci			_rtl92ee_stop_tx_beacon(hw);
64562306a36Sopenharmony_ci
64662306a36Sopenharmony_ci		_rtl92ee_set_bcn_ctrl_reg(hw, 0, BIT(3));
64762306a36Sopenharmony_ci
64862306a36Sopenharmony_ci		rtl_write_dword(rtlpriv, REG_TSFTR,
64962306a36Sopenharmony_ci				(u32)(mac->tsf & 0xffffffff));
65062306a36Sopenharmony_ci		rtl_write_dword(rtlpriv, REG_TSFTR + 4,
65162306a36Sopenharmony_ci				(u32)((mac->tsf >> 32) & 0xffffffff));
65262306a36Sopenharmony_ci
65362306a36Sopenharmony_ci		_rtl92ee_set_bcn_ctrl_reg(hw, BIT(3), 0);
65462306a36Sopenharmony_ci
65562306a36Sopenharmony_ci		if (btype_ibss)
65662306a36Sopenharmony_ci			_rtl92ee_resume_tx_beacon(hw);
65762306a36Sopenharmony_ci		}
65862306a36Sopenharmony_ci		break;
65962306a36Sopenharmony_ci	case HW_VAR_KEEP_ALIVE: {
66062306a36Sopenharmony_ci		u8 array[2];
66162306a36Sopenharmony_ci
66262306a36Sopenharmony_ci		array[0] = 0xff;
66362306a36Sopenharmony_ci		array[1] = *((u8 *)val);
66462306a36Sopenharmony_ci		rtl92ee_fill_h2c_cmd(hw, H2C_92E_KEEP_ALIVE_CTRL, 2, array);
66562306a36Sopenharmony_ci		}
66662306a36Sopenharmony_ci		break;
66762306a36Sopenharmony_ci	default:
66862306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG,
66962306a36Sopenharmony_ci			"switch case %#x not processed\n", variable);
67062306a36Sopenharmony_ci		break;
67162306a36Sopenharmony_ci	}
67262306a36Sopenharmony_ci}
67362306a36Sopenharmony_ci
67462306a36Sopenharmony_cistatic bool _rtl92ee_llt_table_init(struct ieee80211_hw *hw)
67562306a36Sopenharmony_ci{
67662306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
67762306a36Sopenharmony_ci	u8 txpktbuf_bndy;
67862306a36Sopenharmony_ci	u8 u8tmp, testcnt = 0;
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_ci	txpktbuf_bndy = 0xF7;
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_RQPN, 0x80E60808);
68362306a36Sopenharmony_ci
68462306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_TRXFF_BNDY, txpktbuf_bndy);
68562306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x3d00 - 1);
68662306a36Sopenharmony_ci
68762306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_DWBCN0_CTRL + 1, txpktbuf_bndy);
68862306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_DWBCN1_CTRL + 1, txpktbuf_bndy);
68962306a36Sopenharmony_ci
69062306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_BCNQ_BDNY, txpktbuf_bndy);
69162306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_BCNQ1_BDNY, txpktbuf_bndy);
69262306a36Sopenharmony_ci
69362306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_MGQ_BDNY, txpktbuf_bndy);
69462306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy);
69562306a36Sopenharmony_ci
69662306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_PBP, 0x31);
69762306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);
69862306a36Sopenharmony_ci
69962306a36Sopenharmony_ci	u8tmp = rtl_read_byte(rtlpriv, REG_AUTO_LLT + 2);
70062306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_AUTO_LLT + 2, u8tmp | BIT(0));
70162306a36Sopenharmony_ci
70262306a36Sopenharmony_ci	while (u8tmp & BIT(0)) {
70362306a36Sopenharmony_ci		u8tmp = rtl_read_byte(rtlpriv, REG_AUTO_LLT + 2);
70462306a36Sopenharmony_ci		udelay(10);
70562306a36Sopenharmony_ci		testcnt++;
70662306a36Sopenharmony_ci		if (testcnt > 10)
70762306a36Sopenharmony_ci			break;
70862306a36Sopenharmony_ci	}
70962306a36Sopenharmony_ci
71062306a36Sopenharmony_ci	return true;
71162306a36Sopenharmony_ci}
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_cistatic void _rtl92ee_gen_refresh_led_state(struct ieee80211_hw *hw)
71462306a36Sopenharmony_ci{
71562306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
71662306a36Sopenharmony_ci	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
71762306a36Sopenharmony_ci	enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0;
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_ci	if (rtlpriv->rtlhal.up_first_time)
72062306a36Sopenharmony_ci		return;
72162306a36Sopenharmony_ci
72262306a36Sopenharmony_ci	if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
72362306a36Sopenharmony_ci		rtl92ee_sw_led_on(hw, pin0);
72462306a36Sopenharmony_ci	else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT)
72562306a36Sopenharmony_ci		rtl92ee_sw_led_on(hw, pin0);
72662306a36Sopenharmony_ci	else
72762306a36Sopenharmony_ci		rtl92ee_sw_led_off(hw, pin0);
72862306a36Sopenharmony_ci}
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_cistatic bool _rtl92ee_init_mac(struct ieee80211_hw *hw)
73162306a36Sopenharmony_ci{
73262306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
73362306a36Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
73462306a36Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
73562306a36Sopenharmony_ci
73662306a36Sopenharmony_ci	u8 bytetmp;
73762306a36Sopenharmony_ci	u16 wordtmp;
73862306a36Sopenharmony_ci	u32 dwordtmp;
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0);
74162306a36Sopenharmony_ci
74262306a36Sopenharmony_ci	dwordtmp = rtl_read_dword(rtlpriv, REG_SYS_CFG1);
74362306a36Sopenharmony_ci	if (dwordtmp & BIT(24)) {
74462306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, 0x7c, 0xc3);
74562306a36Sopenharmony_ci	} else {
74662306a36Sopenharmony_ci		bytetmp = rtl_read_byte(rtlpriv, 0x16);
74762306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, 0x16, bytetmp | BIT(4) | BIT(6));
74862306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, 0x7c, 0x83);
74962306a36Sopenharmony_ci	}
75062306a36Sopenharmony_ci	/* 1. 40Mhz crystal source*/
75162306a36Sopenharmony_ci	bytetmp = rtl_read_byte(rtlpriv, REG_AFE_CTRL2);
75262306a36Sopenharmony_ci	bytetmp &= 0xfb;
75362306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_AFE_CTRL2, bytetmp);
75462306a36Sopenharmony_ci
75562306a36Sopenharmony_ci	dwordtmp = rtl_read_dword(rtlpriv, REG_AFE_CTRL4);
75662306a36Sopenharmony_ci	dwordtmp &= 0xfffffc7f;
75762306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_AFE_CTRL4, dwordtmp);
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_ci	/* 2. 92E AFE parameter
76062306a36Sopenharmony_ci	 * MP chip then check version
76162306a36Sopenharmony_ci	 */
76262306a36Sopenharmony_ci	bytetmp = rtl_read_byte(rtlpriv, REG_AFE_CTRL2);
76362306a36Sopenharmony_ci	bytetmp &= 0xbf;
76462306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_AFE_CTRL2, bytetmp);
76562306a36Sopenharmony_ci
76662306a36Sopenharmony_ci	dwordtmp = rtl_read_dword(rtlpriv, REG_AFE_CTRL4);
76762306a36Sopenharmony_ci	dwordtmp &= 0xffdfffff;
76862306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_AFE_CTRL4, dwordtmp);
76962306a36Sopenharmony_ci
77062306a36Sopenharmony_ci	/* HW Power on sequence */
77162306a36Sopenharmony_ci	if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
77262306a36Sopenharmony_ci				      PWR_INTF_PCI_MSK,
77362306a36Sopenharmony_ci				      RTL8192E_NIC_ENABLE_FLOW)) {
77462306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
77562306a36Sopenharmony_ci			"init MAC Fail as rtl_hal_pwrseqcmdparsing\n");
77662306a36Sopenharmony_ci		return false;
77762306a36Sopenharmony_ci	}
77862306a36Sopenharmony_ci
77962306a36Sopenharmony_ci	/* Release MAC IO register reset */
78062306a36Sopenharmony_ci	bytetmp = rtl_read_byte(rtlpriv, REG_CR);
78162306a36Sopenharmony_ci	bytetmp = 0xff;
78262306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_CR, bytetmp);
78362306a36Sopenharmony_ci	mdelay(2);
78462306a36Sopenharmony_ci	bytetmp = 0x7f;
78562306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, bytetmp);
78662306a36Sopenharmony_ci	mdelay(2);
78762306a36Sopenharmony_ci
78862306a36Sopenharmony_ci	/* Add for wakeup online */
78962306a36Sopenharmony_ci	bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CLKR);
79062306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_SYS_CLKR, bytetmp | BIT(3));
79162306a36Sopenharmony_ci	bytetmp = rtl_read_byte(rtlpriv, REG_GPIO_MUXCFG + 1);
79262306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG + 1, bytetmp & (~BIT(4)));
79362306a36Sopenharmony_ci	/* Release MAC IO register reset */
79462306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_CR, 0x2ff);
79562306a36Sopenharmony_ci
79662306a36Sopenharmony_ci	if (!rtlhal->mac_func_enable) {
79762306a36Sopenharmony_ci		if (!_rtl92ee_llt_table_init(hw)) {
79862306a36Sopenharmony_ci			rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
79962306a36Sopenharmony_ci				"LLT table init fail\n");
80062306a36Sopenharmony_ci			return false;
80162306a36Sopenharmony_ci		}
80262306a36Sopenharmony_ci	}
80362306a36Sopenharmony_ci
80462306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
80562306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_HISRE, 0xffffffff);
80662306a36Sopenharmony_ci
80762306a36Sopenharmony_ci	wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL);
80862306a36Sopenharmony_ci	wordtmp &= 0xf;
80962306a36Sopenharmony_ci	wordtmp |= 0xF5B1;
81062306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp);
81162306a36Sopenharmony_ci	/* Reported Tx status from HW for rate adaptive.*/
81262306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F);
81362306a36Sopenharmony_ci
81462306a36Sopenharmony_ci	/* Set RCR register */
81562306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
81662306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xffff);
81762306a36Sopenharmony_ci
81862306a36Sopenharmony_ci	/* Set TCR register */
81962306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config);
82062306a36Sopenharmony_ci
82162306a36Sopenharmony_ci	/* Set TX/RX descriptor physical address -- HI part */
82262306a36Sopenharmony_ci	if (!rtlpriv->cfg->mod_params->dma64)
82362306a36Sopenharmony_ci		goto dma64_end;
82462306a36Sopenharmony_ci
82562306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_BCNQ_DESA + 4,
82662306a36Sopenharmony_ci			((u64)rtlpci->tx_ring[BEACON_QUEUE].buffer_desc_dma) >>
82762306a36Sopenharmony_ci				32);
82862306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_MGQ_DESA + 4,
82962306a36Sopenharmony_ci			(u64)rtlpci->tx_ring[MGNT_QUEUE].buffer_desc_dma >> 32);
83062306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_VOQ_DESA + 4,
83162306a36Sopenharmony_ci			(u64)rtlpci->tx_ring[VO_QUEUE].buffer_desc_dma >> 32);
83262306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_VIQ_DESA + 4,
83362306a36Sopenharmony_ci			(u64)rtlpci->tx_ring[VI_QUEUE].buffer_desc_dma >> 32);
83462306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_BEQ_DESA + 4,
83562306a36Sopenharmony_ci			(u64)rtlpci->tx_ring[BE_QUEUE].buffer_desc_dma >> 32);
83662306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_BKQ_DESA + 4,
83762306a36Sopenharmony_ci			(u64)rtlpci->tx_ring[BK_QUEUE].buffer_desc_dma >> 32);
83862306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_HQ0_DESA + 4,
83962306a36Sopenharmony_ci			(u64)rtlpci->tx_ring[HIGH_QUEUE].buffer_desc_dma >> 32);
84062306a36Sopenharmony_ci
84162306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_RX_DESA + 4,
84262306a36Sopenharmony_ci			(u64)rtlpci->rx_ring[RX_MPDU_QUEUE].dma >> 32);
84362306a36Sopenharmony_ci
84462306a36Sopenharmony_cidma64_end:
84562306a36Sopenharmony_ci
84662306a36Sopenharmony_ci	/* Set TX/RX descriptor physical address(from OS API). */
84762306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_BCNQ_DESA,
84862306a36Sopenharmony_ci			((u64)rtlpci->tx_ring[BEACON_QUEUE].buffer_desc_dma) &
84962306a36Sopenharmony_ci			DMA_BIT_MASK(32));
85062306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_MGQ_DESA,
85162306a36Sopenharmony_ci			(u64)rtlpci->tx_ring[MGNT_QUEUE].buffer_desc_dma &
85262306a36Sopenharmony_ci			DMA_BIT_MASK(32));
85362306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_VOQ_DESA,
85462306a36Sopenharmony_ci			(u64)rtlpci->tx_ring[VO_QUEUE].buffer_desc_dma &
85562306a36Sopenharmony_ci			DMA_BIT_MASK(32));
85662306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_VIQ_DESA,
85762306a36Sopenharmony_ci			(u64)rtlpci->tx_ring[VI_QUEUE].buffer_desc_dma &
85862306a36Sopenharmony_ci			DMA_BIT_MASK(32));
85962306a36Sopenharmony_ci
86062306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_BEQ_DESA,
86162306a36Sopenharmony_ci			(u64)rtlpci->tx_ring[BE_QUEUE].buffer_desc_dma &
86262306a36Sopenharmony_ci			DMA_BIT_MASK(32));
86362306a36Sopenharmony_ci
86462306a36Sopenharmony_ci	dwordtmp = rtl_read_dword(rtlpriv, REG_BEQ_DESA);
86562306a36Sopenharmony_ci
86662306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_BKQ_DESA,
86762306a36Sopenharmony_ci			(u64)rtlpci->tx_ring[BK_QUEUE].buffer_desc_dma &
86862306a36Sopenharmony_ci			DMA_BIT_MASK(32));
86962306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_HQ0_DESA,
87062306a36Sopenharmony_ci			(u64)rtlpci->tx_ring[HIGH_QUEUE].buffer_desc_dma &
87162306a36Sopenharmony_ci			DMA_BIT_MASK(32));
87262306a36Sopenharmony_ci
87362306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_RX_DESA,
87462306a36Sopenharmony_ci			(u64)rtlpci->rx_ring[RX_MPDU_QUEUE].dma &
87562306a36Sopenharmony_ci			DMA_BIT_MASK(32));
87662306a36Sopenharmony_ci
87762306a36Sopenharmony_ci	/* if we want to support 64 bit DMA, we should set it here,
87862306a36Sopenharmony_ci	 * but now we do not support 64 bit DMA
87962306a36Sopenharmony_ci	 */
88062306a36Sopenharmony_ci
88162306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_TSFTIMER_HCI, 0x3fffffff);
88262306a36Sopenharmony_ci
88362306a36Sopenharmony_ci	bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 3);
88462306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, bytetmp | 0xF7);
88562306a36Sopenharmony_ci
88662306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_INT_MIG, 0);
88762306a36Sopenharmony_ci
88862306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0);
88962306a36Sopenharmony_ci
89062306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_MGQ_TXBD_NUM,
89162306a36Sopenharmony_ci		       TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000));
89262306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_VOQ_TXBD_NUM,
89362306a36Sopenharmony_ci		       TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000));
89462306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_VIQ_TXBD_NUM,
89562306a36Sopenharmony_ci		       TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000));
89662306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_BEQ_TXBD_NUM,
89762306a36Sopenharmony_ci		       TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000));
89862306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_VOQ_TXBD_NUM,
89962306a36Sopenharmony_ci		       TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000));
90062306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_BKQ_TXBD_NUM,
90162306a36Sopenharmony_ci		       TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000));
90262306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_HI0Q_TXBD_NUM,
90362306a36Sopenharmony_ci		       TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000));
90462306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_HI1Q_TXBD_NUM,
90562306a36Sopenharmony_ci		       TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000));
90662306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_HI2Q_TXBD_NUM,
90762306a36Sopenharmony_ci		       TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000));
90862306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_HI3Q_TXBD_NUM,
90962306a36Sopenharmony_ci		       TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000));
91062306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_HI4Q_TXBD_NUM,
91162306a36Sopenharmony_ci		       TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000));
91262306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_HI5Q_TXBD_NUM,
91362306a36Sopenharmony_ci		       TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000));
91462306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_HI6Q_TXBD_NUM,
91562306a36Sopenharmony_ci		       TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000));
91662306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_HI7Q_TXBD_NUM,
91762306a36Sopenharmony_ci		       TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000));
91862306a36Sopenharmony_ci	/*Rx*/
91962306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_RX_RXBD_NUM,
92062306a36Sopenharmony_ci		       RX_DESC_NUM_92E |
92162306a36Sopenharmony_ci		       ((RTL8192EE_SEG_NUM << 13) & 0x6000) | 0x8000);
92262306a36Sopenharmony_ci
92362306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_TSFTIMER_HCI, 0XFFFFFFFF);
92462306a36Sopenharmony_ci
92562306a36Sopenharmony_ci	_rtl92ee_gen_refresh_led_state(hw);
92662306a36Sopenharmony_ci	return true;
92762306a36Sopenharmony_ci}
92862306a36Sopenharmony_ci
92962306a36Sopenharmony_cistatic void _rtl92ee_hw_configure(struct ieee80211_hw *hw)
93062306a36Sopenharmony_ci{
93162306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
93262306a36Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
93362306a36Sopenharmony_ci	u32 reg_rrsr;
93462306a36Sopenharmony_ci
93562306a36Sopenharmony_ci	reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
93662306a36Sopenharmony_ci	/* Init value for RRSR. */
93762306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_RRSR, reg_rrsr);
93862306a36Sopenharmony_ci
93962306a36Sopenharmony_ci	/* ARFB table 9 for 11ac 5G 2SS */
94062306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_ARFR0, 0x00000010);
94162306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_ARFR0 + 4, 0x3e0ff000);
94262306a36Sopenharmony_ci
94362306a36Sopenharmony_ci	/* ARFB table 10 for 11ac 5G 1SS */
94462306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_ARFR1, 0x00000010);
94562306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_ARFR1 + 4, 0x000ff000);
94662306a36Sopenharmony_ci
94762306a36Sopenharmony_ci	/* Set SLOT time */
94862306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_SLOT, 0x09);
94962306a36Sopenharmony_ci
95062306a36Sopenharmony_ci	/* CF-End setting. */
95162306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F80);
95262306a36Sopenharmony_ci
95362306a36Sopenharmony_ci	/* Set retry limit */
95462306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_RETRY_LIMIT, 0x0707);
95562306a36Sopenharmony_ci
95662306a36Sopenharmony_ci	/* BAR settings */
95762306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x0201ffff);
95862306a36Sopenharmony_ci
95962306a36Sopenharmony_ci	/* Set Data / Response auto rate fallack retry count */
96062306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000);
96162306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504);
96262306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000);
96362306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504);
96462306a36Sopenharmony_ci
96562306a36Sopenharmony_ci	/* Beacon related, for rate adaptive */
96662306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2);
96762306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff);
96862306a36Sopenharmony_ci
96962306a36Sopenharmony_ci	rtlpci->reg_bcn_ctrl_val = 0x1d;
97062306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val);
97162306a36Sopenharmony_ci
97262306a36Sopenharmony_ci	/* Marked out by Bruce, 2010-09-09.
97362306a36Sopenharmony_ci	 * This register is configured for the 2nd Beacon (multiple BSSID).
97462306a36Sopenharmony_ci	 * We shall disable this register if we only support 1 BSSID.
97562306a36Sopenharmony_ci	 * vivi guess 92d also need this, also 92d now doesnot set this reg
97662306a36Sopenharmony_ci	 */
97762306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_BCN_CTRL_1, 0);
97862306a36Sopenharmony_ci
97962306a36Sopenharmony_ci	/* TBTT prohibit hold time. Suggested by designer TimChen. */
98062306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); /* 8 ms */
98162306a36Sopenharmony_ci
98262306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_PIFS, 0);
98362306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16);
98462306a36Sopenharmony_ci
98562306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040);
98662306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x08ff);
98762306a36Sopenharmony_ci
98862306a36Sopenharmony_ci	/* For Rx TP. Suggested by SD1 Richard. Added by tynli. 2010.04.12.*/
98962306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666);
99062306a36Sopenharmony_ci
99162306a36Sopenharmony_ci	/* ACKTO for IOT issue. */
99262306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_ACKTO, 0x40);
99362306a36Sopenharmony_ci
99462306a36Sopenharmony_ci	/* Set Spec SIFS (used in NAV) */
99562306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x100a);
99662306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_MAC_SPEC_SIFS, 0x100a);
99762306a36Sopenharmony_ci
99862306a36Sopenharmony_ci	/* Set SIFS for CCK */
99962306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x100a);
100062306a36Sopenharmony_ci
100162306a36Sopenharmony_ci	/* Set SIFS for OFDM */
100262306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x100a);
100362306a36Sopenharmony_ci
100462306a36Sopenharmony_ci	/* Note Data sheet don't define */
100562306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, 0x4C7, 0x80);
100662306a36Sopenharmony_ci
100762306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x20);
100862306a36Sopenharmony_ci
100962306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_MAX_AGGR_NUM, 0x1717);
101062306a36Sopenharmony_ci
101162306a36Sopenharmony_ci	/* Set Multicast Address. 2009.01.07. by tynli. */
101262306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff);
101362306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff);
101462306a36Sopenharmony_ci}
101562306a36Sopenharmony_ci
101662306a36Sopenharmony_cistatic void _rtl92ee_enable_aspm_back_door(struct ieee80211_hw *hw)
101762306a36Sopenharmony_ci{
101862306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
101962306a36Sopenharmony_ci	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
102062306a36Sopenharmony_ci	u32 tmp32 = 0, count = 0;
102162306a36Sopenharmony_ci	u8 tmp8 = 0;
102262306a36Sopenharmony_ci
102362306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_BACKDOOR_DBI_DATA, 0x78);
102462306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2, 0x2);
102562306a36Sopenharmony_ci	tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2);
102662306a36Sopenharmony_ci	count = 0;
102762306a36Sopenharmony_ci	while (tmp8 && count < 20) {
102862306a36Sopenharmony_ci		udelay(10);
102962306a36Sopenharmony_ci		tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2);
103062306a36Sopenharmony_ci		count++;
103162306a36Sopenharmony_ci	}
103262306a36Sopenharmony_ci
103362306a36Sopenharmony_ci	if (0 == tmp8) {
103462306a36Sopenharmony_ci		tmp32 = rtl_read_dword(rtlpriv, REG_BACKDOOR_DBI_RDATA);
103562306a36Sopenharmony_ci		if ((tmp32 & 0xff00) != 0x2000) {
103662306a36Sopenharmony_ci			tmp32 &= 0xffff00ff;
103762306a36Sopenharmony_ci			rtl_write_dword(rtlpriv, REG_BACKDOOR_DBI_WDATA,
103862306a36Sopenharmony_ci					tmp32 | BIT(13));
103962306a36Sopenharmony_ci			rtl_write_word(rtlpriv, REG_BACKDOOR_DBI_DATA, 0xf078);
104062306a36Sopenharmony_ci			rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2, 0x1);
104162306a36Sopenharmony_ci
104262306a36Sopenharmony_ci			tmp8 = rtl_read_byte(rtlpriv,
104362306a36Sopenharmony_ci					     REG_BACKDOOR_DBI_DATA + 2);
104462306a36Sopenharmony_ci			count = 0;
104562306a36Sopenharmony_ci			while (tmp8 && count < 20) {
104662306a36Sopenharmony_ci				udelay(10);
104762306a36Sopenharmony_ci				tmp8 = rtl_read_byte(rtlpriv,
104862306a36Sopenharmony_ci						     REG_BACKDOOR_DBI_DATA + 2);
104962306a36Sopenharmony_ci				count++;
105062306a36Sopenharmony_ci			}
105162306a36Sopenharmony_ci		}
105262306a36Sopenharmony_ci	}
105362306a36Sopenharmony_ci
105462306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_BACKDOOR_DBI_DATA, 0x70c);
105562306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2, 0x2);
105662306a36Sopenharmony_ci	tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2);
105762306a36Sopenharmony_ci	count = 0;
105862306a36Sopenharmony_ci	while (tmp8 && count < 20) {
105962306a36Sopenharmony_ci		udelay(10);
106062306a36Sopenharmony_ci		tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2);
106162306a36Sopenharmony_ci		count++;
106262306a36Sopenharmony_ci	}
106362306a36Sopenharmony_ci	if (0 == tmp8) {
106462306a36Sopenharmony_ci		tmp32 = rtl_read_dword(rtlpriv, REG_BACKDOOR_DBI_RDATA);
106562306a36Sopenharmony_ci		rtl_write_dword(rtlpriv, REG_BACKDOOR_DBI_WDATA,
106662306a36Sopenharmony_ci				tmp32 | BIT(31));
106762306a36Sopenharmony_ci		rtl_write_word(rtlpriv, REG_BACKDOOR_DBI_DATA, 0xf70c);
106862306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2, 0x1);
106962306a36Sopenharmony_ci	}
107062306a36Sopenharmony_ci
107162306a36Sopenharmony_ci	tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2);
107262306a36Sopenharmony_ci	count = 0;
107362306a36Sopenharmony_ci	while (tmp8 && count < 20) {
107462306a36Sopenharmony_ci		udelay(10);
107562306a36Sopenharmony_ci		tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2);
107662306a36Sopenharmony_ci		count++;
107762306a36Sopenharmony_ci	}
107862306a36Sopenharmony_ci
107962306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_BACKDOOR_DBI_DATA, 0x718);
108062306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2, 0x2);
108162306a36Sopenharmony_ci	tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2);
108262306a36Sopenharmony_ci	count = 0;
108362306a36Sopenharmony_ci	while (tmp8 && count < 20) {
108462306a36Sopenharmony_ci		udelay(10);
108562306a36Sopenharmony_ci		tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2);
108662306a36Sopenharmony_ci		count++;
108762306a36Sopenharmony_ci	}
108862306a36Sopenharmony_ci	if (ppsc->support_backdoor || (0 == tmp8)) {
108962306a36Sopenharmony_ci		tmp32 = rtl_read_dword(rtlpriv, REG_BACKDOOR_DBI_RDATA);
109062306a36Sopenharmony_ci		rtl_write_dword(rtlpriv, REG_BACKDOOR_DBI_WDATA,
109162306a36Sopenharmony_ci				tmp32 | BIT(11) | BIT(12));
109262306a36Sopenharmony_ci		rtl_write_word(rtlpriv, REG_BACKDOOR_DBI_DATA, 0xf718);
109362306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2, 0x1);
109462306a36Sopenharmony_ci	}
109562306a36Sopenharmony_ci	tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2);
109662306a36Sopenharmony_ci	count = 0;
109762306a36Sopenharmony_ci	while (tmp8 && count < 20) {
109862306a36Sopenharmony_ci		udelay(10);
109962306a36Sopenharmony_ci		tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2);
110062306a36Sopenharmony_ci		count++;
110162306a36Sopenharmony_ci	}
110262306a36Sopenharmony_ci}
110362306a36Sopenharmony_ci
110462306a36Sopenharmony_civoid rtl92ee_enable_hw_security_config(struct ieee80211_hw *hw)
110562306a36Sopenharmony_ci{
110662306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
110762306a36Sopenharmony_ci	u8 sec_reg_value;
110862306a36Sopenharmony_ci	u8 tmp;
110962306a36Sopenharmony_ci
111062306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG,
111162306a36Sopenharmony_ci		"PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
111262306a36Sopenharmony_ci		rtlpriv->sec.pairwise_enc_algorithm,
111362306a36Sopenharmony_ci		rtlpriv->sec.group_enc_algorithm);
111462306a36Sopenharmony_ci
111562306a36Sopenharmony_ci	if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
111662306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
111762306a36Sopenharmony_ci			"not open hw encryption\n");
111862306a36Sopenharmony_ci		return;
111962306a36Sopenharmony_ci	}
112062306a36Sopenharmony_ci
112162306a36Sopenharmony_ci	sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE;
112262306a36Sopenharmony_ci
112362306a36Sopenharmony_ci	if (rtlpriv->sec.use_defaultkey) {
112462306a36Sopenharmony_ci		sec_reg_value |= SCR_TXUSEDK;
112562306a36Sopenharmony_ci		sec_reg_value |= SCR_RXUSEDK;
112662306a36Sopenharmony_ci	}
112762306a36Sopenharmony_ci
112862306a36Sopenharmony_ci	sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
112962306a36Sopenharmony_ci
113062306a36Sopenharmony_ci	tmp = rtl_read_byte(rtlpriv, REG_CR + 1);
113162306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_CR + 1, tmp | BIT(1));
113262306a36Sopenharmony_ci
113362306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
113462306a36Sopenharmony_ci		"The SECR-value %x\n", sec_reg_value);
113562306a36Sopenharmony_ci
113662306a36Sopenharmony_ci	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
113762306a36Sopenharmony_ci}
113862306a36Sopenharmony_ci
113962306a36Sopenharmony_cistatic bool _rtl8192ee_check_pcie_dma_hang(struct rtl_priv *rtlpriv)
114062306a36Sopenharmony_ci{
114162306a36Sopenharmony_ci	u8 tmp;
114262306a36Sopenharmony_ci
114362306a36Sopenharmony_ci	/* write reg 0x350 Bit[26]=1. Enable debug port. */
114462306a36Sopenharmony_ci	tmp = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 3);
114562306a36Sopenharmony_ci	if (!(tmp & BIT(2))) {
114662306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 3,
114762306a36Sopenharmony_ci			       tmp | BIT(2));
114862306a36Sopenharmony_ci		mdelay(100); /* Suggested by DD Justin_tsai. */
114962306a36Sopenharmony_ci	}
115062306a36Sopenharmony_ci
115162306a36Sopenharmony_ci	/* read reg 0x350 Bit[25] if 1 : RX hang
115262306a36Sopenharmony_ci	 * read reg 0x350 Bit[24] if 1 : TX hang
115362306a36Sopenharmony_ci	 */
115462306a36Sopenharmony_ci	tmp = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 3);
115562306a36Sopenharmony_ci	if ((tmp & BIT(0)) || (tmp & BIT(1))) {
115662306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
115762306a36Sopenharmony_ci			"CheckPcieDMAHang8192EE(): true!!\n");
115862306a36Sopenharmony_ci		return true;
115962306a36Sopenharmony_ci	}
116062306a36Sopenharmony_ci	return false;
116162306a36Sopenharmony_ci}
116262306a36Sopenharmony_ci
116362306a36Sopenharmony_cistatic void _rtl8192ee_reset_pcie_interface_dma(struct rtl_priv *rtlpriv,
116462306a36Sopenharmony_ci						bool mac_power_on)
116562306a36Sopenharmony_ci{
116662306a36Sopenharmony_ci	u8 tmp;
116762306a36Sopenharmony_ci	bool release_mac_rx_pause;
116862306a36Sopenharmony_ci	u8 backup_pcie_dma_pause;
116962306a36Sopenharmony_ci
117062306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
117162306a36Sopenharmony_ci		"ResetPcieInterfaceDMA8192EE()\n");
117262306a36Sopenharmony_ci
117362306a36Sopenharmony_ci	/* Revise Note: Follow the document "PCIe RX DMA Hang Reset Flow_v03"
117462306a36Sopenharmony_ci	 * released by SD1 Alan.
117562306a36Sopenharmony_ci	 */
117662306a36Sopenharmony_ci
117762306a36Sopenharmony_ci	/* 1. disable register write lock
117862306a36Sopenharmony_ci	 *	write 0x1C bit[1:0] = 2'h0
117962306a36Sopenharmony_ci	 *	write 0xCC bit[2] = 1'b1
118062306a36Sopenharmony_ci	 */
118162306a36Sopenharmony_ci	tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL);
118262306a36Sopenharmony_ci	tmp &= ~(BIT(1) | BIT(0));
118362306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_RSV_CTRL, tmp);
118462306a36Sopenharmony_ci	tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2);
118562306a36Sopenharmony_ci	tmp |= BIT(2);
118662306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp);
118762306a36Sopenharmony_ci
118862306a36Sopenharmony_ci	/* 2. Check and pause TRX DMA
118962306a36Sopenharmony_ci	 *	write 0x284 bit[18] = 1'b1
119062306a36Sopenharmony_ci	 *	write 0x301 = 0xFF
119162306a36Sopenharmony_ci	 */
119262306a36Sopenharmony_ci	tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
119362306a36Sopenharmony_ci	if (tmp & BIT(2)) {
119462306a36Sopenharmony_ci		/* Already pause before the function for another reason. */
119562306a36Sopenharmony_ci		release_mac_rx_pause = false;
119662306a36Sopenharmony_ci	} else {
119762306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, (tmp | BIT(2)));
119862306a36Sopenharmony_ci		release_mac_rx_pause = true;
119962306a36Sopenharmony_ci	}
120062306a36Sopenharmony_ci
120162306a36Sopenharmony_ci	backup_pcie_dma_pause = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 1);
120262306a36Sopenharmony_ci	if (backup_pcie_dma_pause != 0xFF)
120362306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xFF);
120462306a36Sopenharmony_ci
120562306a36Sopenharmony_ci	if (mac_power_on) {
120662306a36Sopenharmony_ci		/* 3. reset TRX function
120762306a36Sopenharmony_ci		 *	write 0x100 = 0x00
120862306a36Sopenharmony_ci		 */
120962306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_CR, 0);
121062306a36Sopenharmony_ci	}
121162306a36Sopenharmony_ci
121262306a36Sopenharmony_ci	/* 4. Reset PCIe DMA
121362306a36Sopenharmony_ci	 *	write 0x003 bit[0] = 0
121462306a36Sopenharmony_ci	 */
121562306a36Sopenharmony_ci	tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
121662306a36Sopenharmony_ci	tmp &= ~(BIT(0));
121762306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp);
121862306a36Sopenharmony_ci
121962306a36Sopenharmony_ci	/* 5. Enable PCIe DMA
122062306a36Sopenharmony_ci	 *	write 0x003 bit[0] = 1
122162306a36Sopenharmony_ci	 */
122262306a36Sopenharmony_ci	tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
122362306a36Sopenharmony_ci	tmp |= BIT(0);
122462306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp);
122562306a36Sopenharmony_ci
122662306a36Sopenharmony_ci	if (mac_power_on) {
122762306a36Sopenharmony_ci		/* 6. enable TRX function
122862306a36Sopenharmony_ci		 *	write 0x100 = 0xFF
122962306a36Sopenharmony_ci		 */
123062306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_CR, 0xFF);
123162306a36Sopenharmony_ci
123262306a36Sopenharmony_ci		/* We should init LLT & RQPN and
123362306a36Sopenharmony_ci		 * prepare Tx/Rx descrptor address later
123462306a36Sopenharmony_ci		 * because MAC function is reset.
123562306a36Sopenharmony_ci		 */
123662306a36Sopenharmony_ci	}
123762306a36Sopenharmony_ci
123862306a36Sopenharmony_ci	/* 7. Restore PCIe autoload down bit
123962306a36Sopenharmony_ci	 *	write 0xF8 bit[17] = 1'b1
124062306a36Sopenharmony_ci	 */
124162306a36Sopenharmony_ci	tmp = rtl_read_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2);
124262306a36Sopenharmony_ci	tmp |= BIT(1);
124362306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2, tmp);
124462306a36Sopenharmony_ci
124562306a36Sopenharmony_ci	/* In MAC power on state, BB and RF maybe in ON state,
124662306a36Sopenharmony_ci	 * if we release TRx DMA here
124762306a36Sopenharmony_ci	 * it will cause packets to be started to Tx/Rx,
124862306a36Sopenharmony_ci	 * so we release Tx/Rx DMA later.
124962306a36Sopenharmony_ci	 */
125062306a36Sopenharmony_ci	if (!mac_power_on) {
125162306a36Sopenharmony_ci		/* 8. release TRX DMA
125262306a36Sopenharmony_ci		 *	write 0x284 bit[18] = 1'b0
125362306a36Sopenharmony_ci		 *	write 0x301 = 0x00
125462306a36Sopenharmony_ci		 */
125562306a36Sopenharmony_ci		if (release_mac_rx_pause) {
125662306a36Sopenharmony_ci			tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
125762306a36Sopenharmony_ci			rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL,
125862306a36Sopenharmony_ci				       (tmp & (~BIT(2))));
125962306a36Sopenharmony_ci		}
126062306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1,
126162306a36Sopenharmony_ci			       backup_pcie_dma_pause);
126262306a36Sopenharmony_ci	}
126362306a36Sopenharmony_ci
126462306a36Sopenharmony_ci	/* 9. lock system register
126562306a36Sopenharmony_ci	 *	write 0xCC bit[2] = 1'b0
126662306a36Sopenharmony_ci	 */
126762306a36Sopenharmony_ci	tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2);
126862306a36Sopenharmony_ci	tmp &= ~(BIT(2));
126962306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp);
127062306a36Sopenharmony_ci}
127162306a36Sopenharmony_ci
127262306a36Sopenharmony_ciint rtl92ee_hw_init(struct ieee80211_hw *hw)
127362306a36Sopenharmony_ci{
127462306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
127562306a36Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
127662306a36Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
127762306a36Sopenharmony_ci	struct rtl_phy *rtlphy = &rtlpriv->phy;
127862306a36Sopenharmony_ci	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
127962306a36Sopenharmony_ci	bool rtstatus = true;
128062306a36Sopenharmony_ci	int err = 0;
128162306a36Sopenharmony_ci	u8 tmp_u1b, u1byte;
128262306a36Sopenharmony_ci	u32 tmp_u4b;
128362306a36Sopenharmony_ci
128462306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, " Rtl8192EE hw init\n");
128562306a36Sopenharmony_ci	rtlpriv->rtlhal.being_init_adapter = true;
128662306a36Sopenharmony_ci	rtlpriv->intf_ops->disable_aspm(hw);
128762306a36Sopenharmony_ci
128862306a36Sopenharmony_ci	tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CLKR+1);
128962306a36Sopenharmony_ci	u1byte = rtl_read_byte(rtlpriv, REG_CR);
129062306a36Sopenharmony_ci	if ((tmp_u1b & BIT(3)) && (u1byte != 0 && u1byte != 0xEA)) {
129162306a36Sopenharmony_ci		rtlhal->mac_func_enable = true;
129262306a36Sopenharmony_ci	} else {
129362306a36Sopenharmony_ci		rtlhal->mac_func_enable = false;
129462306a36Sopenharmony_ci		rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_92E;
129562306a36Sopenharmony_ci	}
129662306a36Sopenharmony_ci
129762306a36Sopenharmony_ci	if (_rtl8192ee_check_pcie_dma_hang(rtlpriv)) {
129862306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "92ee dma hang!\n");
129962306a36Sopenharmony_ci		_rtl8192ee_reset_pcie_interface_dma(rtlpriv,
130062306a36Sopenharmony_ci						    rtlhal->mac_func_enable);
130162306a36Sopenharmony_ci		rtlhal->mac_func_enable = false;
130262306a36Sopenharmony_ci	}
130362306a36Sopenharmony_ci
130462306a36Sopenharmony_ci	rtstatus = _rtl92ee_init_mac(hw);
130562306a36Sopenharmony_ci
130662306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, 0x577, 0x03);
130762306a36Sopenharmony_ci
130862306a36Sopenharmony_ci	/*for Crystal 40 Mhz setting */
130962306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_AFE_CTRL4, 0x2A);
131062306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_AFE_CTRL4 + 1, 0x00);
131162306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_AFE_CTRL2, 0x83);
131262306a36Sopenharmony_ci
131362306a36Sopenharmony_ci	/*Forced the antenna b to wifi */
131462306a36Sopenharmony_ci	if (rtlpriv->btcoexist.btc_info.btcoexist == 1) {
131562306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, 0x64, 0);
131662306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, 0x65, 1);
131762306a36Sopenharmony_ci	}
131862306a36Sopenharmony_ci	if (!rtstatus) {
131962306a36Sopenharmony_ci		pr_err("Init MAC failed\n");
132062306a36Sopenharmony_ci		err = 1;
132162306a36Sopenharmony_ci		return err;
132262306a36Sopenharmony_ci	}
132362306a36Sopenharmony_ci	rtlhal->rx_tag = 0;
132462306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, 0x8000);
132562306a36Sopenharmony_ci	err = rtl92ee_download_fw(hw, false);
132662306a36Sopenharmony_ci	if (err) {
132762306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
132862306a36Sopenharmony_ci			"Failed to download FW. Init HW without FW now..\n");
132962306a36Sopenharmony_ci		err = 1;
133062306a36Sopenharmony_ci		rtlhal->fw_ready = false;
133162306a36Sopenharmony_ci		return err;
133262306a36Sopenharmony_ci	}
133362306a36Sopenharmony_ci	rtlhal->fw_ready = true;
133462306a36Sopenharmony_ci	/*fw related variable initialize */
133562306a36Sopenharmony_ci	ppsc->fw_current_inpsmode = false;
133662306a36Sopenharmony_ci	rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_92E;
133762306a36Sopenharmony_ci	rtlhal->fw_clk_change_in_progress = false;
133862306a36Sopenharmony_ci	rtlhal->allow_sw_to_change_hwclc = false;
133962306a36Sopenharmony_ci	rtlhal->last_hmeboxnum = 0;
134062306a36Sopenharmony_ci
134162306a36Sopenharmony_ci	rtl92ee_phy_mac_config(hw);
134262306a36Sopenharmony_ci
134362306a36Sopenharmony_ci	rtl92ee_phy_bb_config(hw);
134462306a36Sopenharmony_ci
134562306a36Sopenharmony_ci	rtl92ee_phy_rf_config(hw);
134662306a36Sopenharmony_ci
134762306a36Sopenharmony_ci	rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, RF90_PATH_A,
134862306a36Sopenharmony_ci						 RF_CHNLBW, RFREG_OFFSET_MASK);
134962306a36Sopenharmony_ci	rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, RF90_PATH_B,
135062306a36Sopenharmony_ci						 RF_CHNLBW, RFREG_OFFSET_MASK);
135162306a36Sopenharmony_ci	rtlphy->backup_rf_0x1a = (u32)rtl_get_rfreg(hw, RF90_PATH_A, RF_RX_G1,
135262306a36Sopenharmony_ci						    RFREG_OFFSET_MASK);
135362306a36Sopenharmony_ci	rtlphy->rfreg_chnlval[0] = (rtlphy->rfreg_chnlval[0] & 0xfffff3ff) |
135462306a36Sopenharmony_ci				   BIT(10) | BIT(11);
135562306a36Sopenharmony_ci
135662306a36Sopenharmony_ci	rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
135762306a36Sopenharmony_ci		      rtlphy->rfreg_chnlval[0]);
135862306a36Sopenharmony_ci	rtl_set_rfreg(hw, RF90_PATH_B, RF_CHNLBW, RFREG_OFFSET_MASK,
135962306a36Sopenharmony_ci		      rtlphy->rfreg_chnlval[0]);
136062306a36Sopenharmony_ci
136162306a36Sopenharmony_ci	/*---- Set CCK and OFDM Block "ON"----*/
136262306a36Sopenharmony_ci	rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
136362306a36Sopenharmony_ci	rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
136462306a36Sopenharmony_ci
136562306a36Sopenharmony_ci	/* Must set this,
136662306a36Sopenharmony_ci	 * otherwise the rx sensitivity will be very pool. Maddest
136762306a36Sopenharmony_ci	 */
136862306a36Sopenharmony_ci	rtl_set_rfreg(hw, RF90_PATH_A, 0xB1, RFREG_OFFSET_MASK, 0x54418);
136962306a36Sopenharmony_ci
137062306a36Sopenharmony_ci	/*Set Hardware(MAC default setting.)*/
137162306a36Sopenharmony_ci	_rtl92ee_hw_configure(hw);
137262306a36Sopenharmony_ci
137362306a36Sopenharmony_ci	rtlhal->mac_func_enable = true;
137462306a36Sopenharmony_ci
137562306a36Sopenharmony_ci	rtl_cam_reset_all_entry(hw);
137662306a36Sopenharmony_ci	rtl92ee_enable_hw_security_config(hw);
137762306a36Sopenharmony_ci
137862306a36Sopenharmony_ci	ppsc->rfpwr_state = ERFON;
137962306a36Sopenharmony_ci
138062306a36Sopenharmony_ci	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
138162306a36Sopenharmony_ci	_rtl92ee_enable_aspm_back_door(hw);
138262306a36Sopenharmony_ci	rtlpriv->intf_ops->enable_aspm(hw);
138362306a36Sopenharmony_ci
138462306a36Sopenharmony_ci	rtl92ee_bt_hw_init(hw);
138562306a36Sopenharmony_ci
138662306a36Sopenharmony_ci	rtlpriv->rtlhal.being_init_adapter = false;
138762306a36Sopenharmony_ci
138862306a36Sopenharmony_ci	if (ppsc->rfpwr_state == ERFON) {
138962306a36Sopenharmony_ci		if (rtlphy->iqk_initialized) {
139062306a36Sopenharmony_ci			rtl92ee_phy_iq_calibrate(hw, true);
139162306a36Sopenharmony_ci		} else {
139262306a36Sopenharmony_ci			rtl92ee_phy_iq_calibrate(hw, false);
139362306a36Sopenharmony_ci			rtlphy->iqk_initialized = true;
139462306a36Sopenharmony_ci		}
139562306a36Sopenharmony_ci	}
139662306a36Sopenharmony_ci
139762306a36Sopenharmony_ci	rtlphy->rfpath_rx_enable[0] = true;
139862306a36Sopenharmony_ci	if (rtlphy->rf_type == RF_2T2R)
139962306a36Sopenharmony_ci		rtlphy->rfpath_rx_enable[1] = true;
140062306a36Sopenharmony_ci
140162306a36Sopenharmony_ci	efuse_one_byte_read(hw, 0x1FA, &tmp_u1b);
140262306a36Sopenharmony_ci	if (!(tmp_u1b & BIT(0))) {
140362306a36Sopenharmony_ci		rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05);
140462306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "PA BIAS path A\n");
140562306a36Sopenharmony_ci	}
140662306a36Sopenharmony_ci
140762306a36Sopenharmony_ci	if ((!(tmp_u1b & BIT(1))) && (rtlphy->rf_type == RF_2T2R)) {
140862306a36Sopenharmony_ci		rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0F, 0x05);
140962306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "PA BIAS path B\n");
141062306a36Sopenharmony_ci	}
141162306a36Sopenharmony_ci
141262306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_NAV_UPPER, ((30000 + 127) / 128));
141362306a36Sopenharmony_ci
141462306a36Sopenharmony_ci	/*Fixed LDPC rx hang issue. */
141562306a36Sopenharmony_ci	tmp_u4b = rtl_read_dword(rtlpriv, REG_SYS_SWR_CTRL1);
141662306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_SYS_SWR_CTRL2, 0x75);
141762306a36Sopenharmony_ci	tmp_u4b =  (tmp_u4b & 0xfff00fff) | (0x7E << 12);
141862306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_SYS_SWR_CTRL1, tmp_u4b);
141962306a36Sopenharmony_ci
142062306a36Sopenharmony_ci	rtl92ee_dm_init(hw);
142162306a36Sopenharmony_ci
142262306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, 0x4fc, 0);
142362306a36Sopenharmony_ci
142462306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
142562306a36Sopenharmony_ci		"end of Rtl8192EE hw init %x\n", err);
142662306a36Sopenharmony_ci	return 0;
142762306a36Sopenharmony_ci}
142862306a36Sopenharmony_ci
142962306a36Sopenharmony_cistatic enum version_8192e _rtl92ee_read_chip_version(struct ieee80211_hw *hw)
143062306a36Sopenharmony_ci{
143162306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
143262306a36Sopenharmony_ci	struct rtl_phy *rtlphy = &rtlpriv->phy;
143362306a36Sopenharmony_ci	enum version_8192e version;
143462306a36Sopenharmony_ci	u32 value32;
143562306a36Sopenharmony_ci
143662306a36Sopenharmony_ci	rtlphy->rf_type = RF_2T2R;
143762306a36Sopenharmony_ci
143862306a36Sopenharmony_ci	value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG1);
143962306a36Sopenharmony_ci	if (value32 & TRP_VAUX_EN)
144062306a36Sopenharmony_ci		version = (enum version_8192e)VERSION_TEST_CHIP_2T2R_8192E;
144162306a36Sopenharmony_ci	else
144262306a36Sopenharmony_ci		version = (enum version_8192e)VERSION_NORMAL_CHIP_2T2R_8192E;
144362306a36Sopenharmony_ci
144462306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
144562306a36Sopenharmony_ci		"Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
144662306a36Sopenharmony_ci		"RF_2T2R" : "RF_1T1R");
144762306a36Sopenharmony_ci
144862306a36Sopenharmony_ci	return version;
144962306a36Sopenharmony_ci}
145062306a36Sopenharmony_ci
145162306a36Sopenharmony_cistatic int _rtl92ee_set_media_status(struct ieee80211_hw *hw,
145262306a36Sopenharmony_ci				     enum nl80211_iftype type)
145362306a36Sopenharmony_ci{
145462306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
145562306a36Sopenharmony_ci	u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc;
145662306a36Sopenharmony_ci	enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
145762306a36Sopenharmony_ci	u8 mode = MSR_NOLINK;
145862306a36Sopenharmony_ci
145962306a36Sopenharmony_ci	switch (type) {
146062306a36Sopenharmony_ci	case NL80211_IFTYPE_UNSPECIFIED:
146162306a36Sopenharmony_ci		mode = MSR_NOLINK;
146262306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
146362306a36Sopenharmony_ci			"Set Network type to NO LINK!\n");
146462306a36Sopenharmony_ci		break;
146562306a36Sopenharmony_ci	case NL80211_IFTYPE_ADHOC:
146662306a36Sopenharmony_ci	case NL80211_IFTYPE_MESH_POINT:
146762306a36Sopenharmony_ci		mode = MSR_ADHOC;
146862306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
146962306a36Sopenharmony_ci			"Set Network type to Ad Hoc!\n");
147062306a36Sopenharmony_ci		break;
147162306a36Sopenharmony_ci	case NL80211_IFTYPE_STATION:
147262306a36Sopenharmony_ci		mode = MSR_INFRA;
147362306a36Sopenharmony_ci		ledaction = LED_CTL_LINK;
147462306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
147562306a36Sopenharmony_ci			"Set Network type to STA!\n");
147662306a36Sopenharmony_ci		break;
147762306a36Sopenharmony_ci	case NL80211_IFTYPE_AP:
147862306a36Sopenharmony_ci		mode = MSR_AP;
147962306a36Sopenharmony_ci		ledaction = LED_CTL_LINK;
148062306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
148162306a36Sopenharmony_ci			"Set Network type to AP!\n");
148262306a36Sopenharmony_ci		break;
148362306a36Sopenharmony_ci	default:
148462306a36Sopenharmony_ci		pr_err("Network type %d not support!\n", type);
148562306a36Sopenharmony_ci		return 1;
148662306a36Sopenharmony_ci	}
148762306a36Sopenharmony_ci
148862306a36Sopenharmony_ci	/* MSR_INFRA == Link in infrastructure network;
148962306a36Sopenharmony_ci	 * MSR_ADHOC == Link in ad hoc network;
149062306a36Sopenharmony_ci	 * Therefore, check link state is necessary.
149162306a36Sopenharmony_ci	 *
149262306a36Sopenharmony_ci	 * MSR_AP == AP mode; link state is not cared here.
149362306a36Sopenharmony_ci	 */
149462306a36Sopenharmony_ci	if (mode != MSR_AP && rtlpriv->mac80211.link_state < MAC80211_LINKED) {
149562306a36Sopenharmony_ci		mode = MSR_NOLINK;
149662306a36Sopenharmony_ci		ledaction = LED_CTL_NO_LINK;
149762306a36Sopenharmony_ci	}
149862306a36Sopenharmony_ci
149962306a36Sopenharmony_ci	if (mode == MSR_NOLINK || mode == MSR_INFRA) {
150062306a36Sopenharmony_ci		_rtl92ee_stop_tx_beacon(hw);
150162306a36Sopenharmony_ci		_rtl92ee_enable_bcn_sub_func(hw);
150262306a36Sopenharmony_ci	} else if (mode == MSR_ADHOC || mode == MSR_AP) {
150362306a36Sopenharmony_ci		_rtl92ee_resume_tx_beacon(hw);
150462306a36Sopenharmony_ci		_rtl92ee_disable_bcn_sub_func(hw);
150562306a36Sopenharmony_ci	} else {
150662306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
150762306a36Sopenharmony_ci			"Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n",
150862306a36Sopenharmony_ci			mode);
150962306a36Sopenharmony_ci	}
151062306a36Sopenharmony_ci
151162306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, MSR, bt_msr | mode);
151262306a36Sopenharmony_ci	rtlpriv->cfg->ops->led_control(hw, ledaction);
151362306a36Sopenharmony_ci	if (mode == MSR_AP)
151462306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
151562306a36Sopenharmony_ci	else
151662306a36Sopenharmony_ci		rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
151762306a36Sopenharmony_ci	return 0;
151862306a36Sopenharmony_ci}
151962306a36Sopenharmony_ci
152062306a36Sopenharmony_civoid rtl92ee_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
152162306a36Sopenharmony_ci{
152262306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
152362306a36Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
152462306a36Sopenharmony_ci	u32 reg_rcr = rtlpci->receive_config;
152562306a36Sopenharmony_ci
152662306a36Sopenharmony_ci	if (rtlpriv->psc.rfpwr_state != ERFON)
152762306a36Sopenharmony_ci		return;
152862306a36Sopenharmony_ci
152962306a36Sopenharmony_ci	if (check_bssid) {
153062306a36Sopenharmony_ci		reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
153162306a36Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
153262306a36Sopenharmony_ci					      (u8 *)(&reg_rcr));
153362306a36Sopenharmony_ci		_rtl92ee_set_bcn_ctrl_reg(hw, 0, BIT(4));
153462306a36Sopenharmony_ci	} else {
153562306a36Sopenharmony_ci		reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
153662306a36Sopenharmony_ci		_rtl92ee_set_bcn_ctrl_reg(hw, BIT(4), 0);
153762306a36Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
153862306a36Sopenharmony_ci					      (u8 *)(&reg_rcr));
153962306a36Sopenharmony_ci	}
154062306a36Sopenharmony_ci}
154162306a36Sopenharmony_ci
154262306a36Sopenharmony_ciint rtl92ee_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
154362306a36Sopenharmony_ci{
154462306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
154562306a36Sopenharmony_ci
154662306a36Sopenharmony_ci	if (_rtl92ee_set_media_status(hw, type))
154762306a36Sopenharmony_ci		return -EOPNOTSUPP;
154862306a36Sopenharmony_ci
154962306a36Sopenharmony_ci	if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
155062306a36Sopenharmony_ci		if (type != NL80211_IFTYPE_AP &&
155162306a36Sopenharmony_ci		    type != NL80211_IFTYPE_MESH_POINT)
155262306a36Sopenharmony_ci			rtl92ee_set_check_bssid(hw, true);
155362306a36Sopenharmony_ci	} else {
155462306a36Sopenharmony_ci		rtl92ee_set_check_bssid(hw, false);
155562306a36Sopenharmony_ci	}
155662306a36Sopenharmony_ci
155762306a36Sopenharmony_ci	return 0;
155862306a36Sopenharmony_ci}
155962306a36Sopenharmony_ci
156062306a36Sopenharmony_ci/* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */
156162306a36Sopenharmony_civoid rtl92ee_set_qos(struct ieee80211_hw *hw, int aci)
156262306a36Sopenharmony_ci{
156362306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
156462306a36Sopenharmony_ci
156562306a36Sopenharmony_ci	rtl92ee_dm_init_edca_turbo(hw);
156662306a36Sopenharmony_ci	switch (aci) {
156762306a36Sopenharmony_ci	case AC1_BK:
156862306a36Sopenharmony_ci		rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f);
156962306a36Sopenharmony_ci		break;
157062306a36Sopenharmony_ci	case AC0_BE:
157162306a36Sopenharmony_ci		/* rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param); */
157262306a36Sopenharmony_ci		break;
157362306a36Sopenharmony_ci	case AC2_VI:
157462306a36Sopenharmony_ci		rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322);
157562306a36Sopenharmony_ci		break;
157662306a36Sopenharmony_ci	case AC3_VO:
157762306a36Sopenharmony_ci		rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
157862306a36Sopenharmony_ci		break;
157962306a36Sopenharmony_ci	default:
158062306a36Sopenharmony_ci		WARN_ONCE(true, "rtl8192ee: invalid aci: %d !\n", aci);
158162306a36Sopenharmony_ci		break;
158262306a36Sopenharmony_ci	}
158362306a36Sopenharmony_ci}
158462306a36Sopenharmony_ci
158562306a36Sopenharmony_civoid rtl92ee_enable_interrupt(struct ieee80211_hw *hw)
158662306a36Sopenharmony_ci{
158762306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
158862306a36Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
158962306a36Sopenharmony_ci
159062306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
159162306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
159262306a36Sopenharmony_ci	rtlpci->irq_enabled = true;
159362306a36Sopenharmony_ci}
159462306a36Sopenharmony_ci
159562306a36Sopenharmony_civoid rtl92ee_disable_interrupt(struct ieee80211_hw *hw)
159662306a36Sopenharmony_ci{
159762306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
159862306a36Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
159962306a36Sopenharmony_ci
160062306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_HIMR, IMR_DISABLED);
160162306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_HIMRE, IMR_DISABLED);
160262306a36Sopenharmony_ci	rtlpci->irq_enabled = false;
160362306a36Sopenharmony_ci	/*synchronize_irq(rtlpci->pdev->irq);*/
160462306a36Sopenharmony_ci}
160562306a36Sopenharmony_ci
160662306a36Sopenharmony_cistatic void _rtl92ee_poweroff_adapter(struct ieee80211_hw *hw)
160762306a36Sopenharmony_ci{
160862306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
160962306a36Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
161062306a36Sopenharmony_ci	u8 u1b_tmp;
161162306a36Sopenharmony_ci
161262306a36Sopenharmony_ci	rtlhal->mac_func_enable = false;
161362306a36Sopenharmony_ci
161462306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "POWER OFF adapter\n");
161562306a36Sopenharmony_ci
161662306a36Sopenharmony_ci	/* Run LPS WL RFOFF flow */
161762306a36Sopenharmony_ci	rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
161862306a36Sopenharmony_ci				 PWR_INTF_PCI_MSK, RTL8192E_NIC_LPS_ENTER_FLOW);
161962306a36Sopenharmony_ci	/* turn off RF */
162062306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00);
162162306a36Sopenharmony_ci
162262306a36Sopenharmony_ci	/* ==== Reset digital sequence   ======  */
162362306a36Sopenharmony_ci	if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->fw_ready)
162462306a36Sopenharmony_ci		rtl92ee_firmware_selfreset(hw);
162562306a36Sopenharmony_ci
162662306a36Sopenharmony_ci	/* Reset MCU  */
162762306a36Sopenharmony_ci	u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
162862306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2))));
162962306a36Sopenharmony_ci
163062306a36Sopenharmony_ci	/* reset MCU ready status */
163162306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
163262306a36Sopenharmony_ci
163362306a36Sopenharmony_ci	/* HW card disable configuration. */
163462306a36Sopenharmony_ci	rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
163562306a36Sopenharmony_ci				 PWR_INTF_PCI_MSK, RTL8192E_NIC_DISABLE_FLOW);
163662306a36Sopenharmony_ci
163762306a36Sopenharmony_ci	/* Reset MCU IO Wrapper */
163862306a36Sopenharmony_ci	u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
163962306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0))));
164062306a36Sopenharmony_ci	u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
164162306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp | BIT(0)));
164262306a36Sopenharmony_ci
164362306a36Sopenharmony_ci	/* lock ISO/CLK/Power control register */
164462306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0E);
164562306a36Sopenharmony_ci}
164662306a36Sopenharmony_ci
164762306a36Sopenharmony_civoid rtl92ee_card_disable(struct ieee80211_hw *hw)
164862306a36Sopenharmony_ci{
164962306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
165062306a36Sopenharmony_ci	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
165162306a36Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
165262306a36Sopenharmony_ci	enum nl80211_iftype opmode;
165362306a36Sopenharmony_ci
165462306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "RTL8192ee card disable\n");
165562306a36Sopenharmony_ci
165662306a36Sopenharmony_ci	RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
165762306a36Sopenharmony_ci
165862306a36Sopenharmony_ci	mac->link_state = MAC80211_NOLINK;
165962306a36Sopenharmony_ci	opmode = NL80211_IFTYPE_UNSPECIFIED;
166062306a36Sopenharmony_ci
166162306a36Sopenharmony_ci	_rtl92ee_set_media_status(hw, opmode);
166262306a36Sopenharmony_ci
166362306a36Sopenharmony_ci	if (rtlpriv->rtlhal.driver_is_goingto_unload ||
166462306a36Sopenharmony_ci	    ppsc->rfoff_reason > RF_CHANGE_BY_PS)
166562306a36Sopenharmony_ci		rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
166662306a36Sopenharmony_ci
166762306a36Sopenharmony_ci	_rtl92ee_poweroff_adapter(hw);
166862306a36Sopenharmony_ci
166962306a36Sopenharmony_ci	/* after power off we should do iqk again */
167062306a36Sopenharmony_ci	if (!rtlpriv->cfg->ops->get_btc_status())
167162306a36Sopenharmony_ci		rtlpriv->phy.iqk_initialized = false;
167262306a36Sopenharmony_ci}
167362306a36Sopenharmony_ci
167462306a36Sopenharmony_civoid rtl92ee_interrupt_recognized(struct ieee80211_hw *hw,
167562306a36Sopenharmony_ci				  struct rtl_int *intvec)
167662306a36Sopenharmony_ci{
167762306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
167862306a36Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
167962306a36Sopenharmony_ci
168062306a36Sopenharmony_ci	intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0];
168162306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, ISR, intvec->inta);
168262306a36Sopenharmony_ci
168362306a36Sopenharmony_ci	intvec->intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1];
168462306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, REG_HISRE, intvec->intb);
168562306a36Sopenharmony_ci}
168662306a36Sopenharmony_ci
168762306a36Sopenharmony_civoid rtl92ee_set_beacon_related_registers(struct ieee80211_hw *hw)
168862306a36Sopenharmony_ci{
168962306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
169062306a36Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
169162306a36Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
169262306a36Sopenharmony_ci	u16 bcn_interval, atim_window;
169362306a36Sopenharmony_ci
169462306a36Sopenharmony_ci	bcn_interval = mac->beacon_interval;
169562306a36Sopenharmony_ci	atim_window = 2;	/*FIX MERGE */
169662306a36Sopenharmony_ci	rtl92ee_disable_interrupt(hw);
169762306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
169862306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
169962306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
170062306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18);
170162306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18);
170262306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, 0x606, 0x30);
170362306a36Sopenharmony_ci	rtlpci->reg_bcn_ctrl_val |= BIT(3);
170462306a36Sopenharmony_ci	rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlpci->reg_bcn_ctrl_val);
170562306a36Sopenharmony_ci}
170662306a36Sopenharmony_ci
170762306a36Sopenharmony_civoid rtl92ee_set_beacon_interval(struct ieee80211_hw *hw)
170862306a36Sopenharmony_ci{
170962306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
171062306a36Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
171162306a36Sopenharmony_ci	u16 bcn_interval = mac->beacon_interval;
171262306a36Sopenharmony_ci
171362306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_BEACON, DBG_DMESG,
171462306a36Sopenharmony_ci		"beacon_interval:%d\n", bcn_interval);
171562306a36Sopenharmony_ci	rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
171662306a36Sopenharmony_ci}
171762306a36Sopenharmony_ci
171862306a36Sopenharmony_civoid rtl92ee_update_interrupt_mask(struct ieee80211_hw *hw,
171962306a36Sopenharmony_ci				   u32 add_msr, u32 rm_msr)
172062306a36Sopenharmony_ci{
172162306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
172262306a36Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
172362306a36Sopenharmony_ci
172462306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD,
172562306a36Sopenharmony_ci		"add_msr:%x, rm_msr:%x\n", add_msr, rm_msr);
172662306a36Sopenharmony_ci
172762306a36Sopenharmony_ci	if (add_msr)
172862306a36Sopenharmony_ci		rtlpci->irq_mask[0] |= add_msr;
172962306a36Sopenharmony_ci	if (rm_msr)
173062306a36Sopenharmony_ci		rtlpci->irq_mask[0] &= (~rm_msr);
173162306a36Sopenharmony_ci	rtl92ee_disable_interrupt(hw);
173262306a36Sopenharmony_ci	rtl92ee_enable_interrupt(hw);
173362306a36Sopenharmony_ci}
173462306a36Sopenharmony_ci
173562306a36Sopenharmony_cistatic u8 _rtl92ee_get_chnl_group(u8 chnl)
173662306a36Sopenharmony_ci{
173762306a36Sopenharmony_ci	u8 group = 0;
173862306a36Sopenharmony_ci
173962306a36Sopenharmony_ci	if (chnl <= 14) {
174062306a36Sopenharmony_ci		if (1 <= chnl && chnl <= 2)
174162306a36Sopenharmony_ci			group = 0;
174262306a36Sopenharmony_ci		else if (3 <= chnl && chnl <= 5)
174362306a36Sopenharmony_ci			group = 1;
174462306a36Sopenharmony_ci		else if (6 <= chnl && chnl <= 8)
174562306a36Sopenharmony_ci			group = 2;
174662306a36Sopenharmony_ci		else if (9 <= chnl && chnl <= 11)
174762306a36Sopenharmony_ci			group = 3;
174862306a36Sopenharmony_ci		else if (12 <= chnl && chnl <= 14)
174962306a36Sopenharmony_ci			group = 4;
175062306a36Sopenharmony_ci	} else {
175162306a36Sopenharmony_ci		if (36 <= chnl && chnl <= 42)
175262306a36Sopenharmony_ci			group = 0;
175362306a36Sopenharmony_ci		else if (44 <= chnl && chnl <= 48)
175462306a36Sopenharmony_ci			group = 1;
175562306a36Sopenharmony_ci		else if (50 <= chnl && chnl <= 58)
175662306a36Sopenharmony_ci			group = 2;
175762306a36Sopenharmony_ci		else if (60 <= chnl && chnl <= 64)
175862306a36Sopenharmony_ci			group = 3;
175962306a36Sopenharmony_ci		else if (100 <= chnl && chnl <= 106)
176062306a36Sopenharmony_ci			group = 4;
176162306a36Sopenharmony_ci		else if (108 <= chnl && chnl <= 114)
176262306a36Sopenharmony_ci			group = 5;
176362306a36Sopenharmony_ci		else if (116 <= chnl && chnl <= 122)
176462306a36Sopenharmony_ci			group = 6;
176562306a36Sopenharmony_ci		else if (124 <= chnl && chnl <= 130)
176662306a36Sopenharmony_ci			group = 7;
176762306a36Sopenharmony_ci		else if (132 <= chnl && chnl <= 138)
176862306a36Sopenharmony_ci			group = 8;
176962306a36Sopenharmony_ci		else if (140 <= chnl && chnl <= 144)
177062306a36Sopenharmony_ci			group = 9;
177162306a36Sopenharmony_ci		else if (149 <= chnl && chnl <= 155)
177262306a36Sopenharmony_ci			group = 10;
177362306a36Sopenharmony_ci		else if (157 <= chnl && chnl <= 161)
177462306a36Sopenharmony_ci			group = 11;
177562306a36Sopenharmony_ci		else if (165 <= chnl && chnl <= 171)
177662306a36Sopenharmony_ci			group = 12;
177762306a36Sopenharmony_ci		else if (173 <= chnl && chnl <= 177)
177862306a36Sopenharmony_ci			group = 13;
177962306a36Sopenharmony_ci	}
178062306a36Sopenharmony_ci	return group;
178162306a36Sopenharmony_ci}
178262306a36Sopenharmony_ci
178362306a36Sopenharmony_cistatic void _rtl8192ee_read_power_value_fromprom(struct ieee80211_hw *hw,
178462306a36Sopenharmony_ci						 struct txpower_info_2g *pwr2g,
178562306a36Sopenharmony_ci						 struct txpower_info_5g *pwr5g,
178662306a36Sopenharmony_ci						 bool autoload_fail, u8 *hwinfo)
178762306a36Sopenharmony_ci{
178862306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
178962306a36Sopenharmony_ci	u32 rf, addr = EEPROM_TX_PWR_INX, group, i = 0;
179062306a36Sopenharmony_ci
179162306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
179262306a36Sopenharmony_ci		"hal_ReadPowerValueFromPROM92E(): PROMContent[0x%x]=0x%x\n",
179362306a36Sopenharmony_ci		(addr + 1), hwinfo[addr + 1]);
179462306a36Sopenharmony_ci	if (0xFF == hwinfo[addr+1])  /*YJ,add,120316*/
179562306a36Sopenharmony_ci		autoload_fail = true;
179662306a36Sopenharmony_ci
179762306a36Sopenharmony_ci	if (autoload_fail) {
179862306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
179962306a36Sopenharmony_ci			"auto load fail : Use Default value!\n");
180062306a36Sopenharmony_ci		for (rf = 0 ; rf < MAX_RF_PATH ; rf++) {
180162306a36Sopenharmony_ci			/* 2.4G default value */
180262306a36Sopenharmony_ci			for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) {
180362306a36Sopenharmony_ci				pwr2g->index_cck_base[rf][group] = 0x2D;
180462306a36Sopenharmony_ci				pwr2g->index_bw40_base[rf][group] = 0x2D;
180562306a36Sopenharmony_ci			}
180662306a36Sopenharmony_ci			for (i = 0; i < MAX_TX_COUNT; i++) {
180762306a36Sopenharmony_ci				if (i == 0) {
180862306a36Sopenharmony_ci					pwr2g->bw20_diff[rf][0] = 0x02;
180962306a36Sopenharmony_ci					pwr2g->ofdm_diff[rf][0] = 0x04;
181062306a36Sopenharmony_ci				} else {
181162306a36Sopenharmony_ci					pwr2g->bw20_diff[rf][i] = 0xFE;
181262306a36Sopenharmony_ci					pwr2g->bw40_diff[rf][i] = 0xFE;
181362306a36Sopenharmony_ci					pwr2g->cck_diff[rf][i] = 0xFE;
181462306a36Sopenharmony_ci					pwr2g->ofdm_diff[rf][i] = 0xFE;
181562306a36Sopenharmony_ci				}
181662306a36Sopenharmony_ci			}
181762306a36Sopenharmony_ci
181862306a36Sopenharmony_ci			/*5G default value*/
181962306a36Sopenharmony_ci			for (group = 0 ; group < MAX_CHNL_GROUP_5G; group++)
182062306a36Sopenharmony_ci				pwr5g->index_bw40_base[rf][group] = 0x2A;
182162306a36Sopenharmony_ci
182262306a36Sopenharmony_ci			for (i = 0; i < MAX_TX_COUNT; i++) {
182362306a36Sopenharmony_ci				if (i == 0) {
182462306a36Sopenharmony_ci					pwr5g->ofdm_diff[rf][0] = 0x04;
182562306a36Sopenharmony_ci					pwr5g->bw20_diff[rf][0] = 0x00;
182662306a36Sopenharmony_ci					pwr5g->bw80_diff[rf][0] = 0xFE;
182762306a36Sopenharmony_ci					pwr5g->bw160_diff[rf][0] = 0xFE;
182862306a36Sopenharmony_ci				} else {
182962306a36Sopenharmony_ci					pwr5g->ofdm_diff[rf][0] = 0xFE;
183062306a36Sopenharmony_ci					pwr5g->bw20_diff[rf][0] = 0xFE;
183162306a36Sopenharmony_ci					pwr5g->bw40_diff[rf][0] = 0xFE;
183262306a36Sopenharmony_ci					pwr5g->bw80_diff[rf][0] = 0xFE;
183362306a36Sopenharmony_ci					pwr5g->bw160_diff[rf][0] = 0xFE;
183462306a36Sopenharmony_ci				}
183562306a36Sopenharmony_ci			}
183662306a36Sopenharmony_ci		}
183762306a36Sopenharmony_ci		return;
183862306a36Sopenharmony_ci	}
183962306a36Sopenharmony_ci
184062306a36Sopenharmony_ci	rtl_priv(hw)->efuse.txpwr_fromeprom = true;
184162306a36Sopenharmony_ci
184262306a36Sopenharmony_ci	for (rf = 0 ; rf < MAX_RF_PATH ; rf++) {
184362306a36Sopenharmony_ci		/*2.4G default value*/
184462306a36Sopenharmony_ci		for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) {
184562306a36Sopenharmony_ci			pwr2g->index_cck_base[rf][group] = hwinfo[addr++];
184662306a36Sopenharmony_ci			if (pwr2g->index_cck_base[rf][group] == 0xFF)
184762306a36Sopenharmony_ci				pwr2g->index_cck_base[rf][group] = 0x2D;
184862306a36Sopenharmony_ci		}
184962306a36Sopenharmony_ci		for (group = 0 ; group < MAX_CHNL_GROUP_24G - 1; group++) {
185062306a36Sopenharmony_ci			pwr2g->index_bw40_base[rf][group] = hwinfo[addr++];
185162306a36Sopenharmony_ci			if (pwr2g->index_bw40_base[rf][group] == 0xFF)
185262306a36Sopenharmony_ci				pwr2g->index_bw40_base[rf][group] = 0x2D;
185362306a36Sopenharmony_ci		}
185462306a36Sopenharmony_ci		for (i = 0; i < MAX_TX_COUNT; i++) {
185562306a36Sopenharmony_ci			if (i == 0) {
185662306a36Sopenharmony_ci				pwr2g->bw40_diff[rf][i] = 0;
185762306a36Sopenharmony_ci				if (hwinfo[addr] == 0xFF) {
185862306a36Sopenharmony_ci					pwr2g->bw20_diff[rf][i] = 0x02;
185962306a36Sopenharmony_ci				} else {
186062306a36Sopenharmony_ci					pwr2g->bw20_diff[rf][i] = (hwinfo[addr]
186162306a36Sopenharmony_ci								   & 0xf0) >> 4;
186262306a36Sopenharmony_ci					if (pwr2g->bw20_diff[rf][i] & BIT(3))
186362306a36Sopenharmony_ci						pwr2g->bw20_diff[rf][i] |= 0xF0;
186462306a36Sopenharmony_ci				}
186562306a36Sopenharmony_ci
186662306a36Sopenharmony_ci				if (hwinfo[addr] == 0xFF) {
186762306a36Sopenharmony_ci					pwr2g->ofdm_diff[rf][i] = 0x04;
186862306a36Sopenharmony_ci				} else {
186962306a36Sopenharmony_ci					pwr2g->ofdm_diff[rf][i] = (hwinfo[addr]
187062306a36Sopenharmony_ci								   & 0x0f);
187162306a36Sopenharmony_ci					if (pwr2g->ofdm_diff[rf][i] & BIT(3))
187262306a36Sopenharmony_ci						pwr2g->ofdm_diff[rf][i] |= 0xF0;
187362306a36Sopenharmony_ci				}
187462306a36Sopenharmony_ci				pwr2g->cck_diff[rf][i] = 0;
187562306a36Sopenharmony_ci				addr++;
187662306a36Sopenharmony_ci			} else {
187762306a36Sopenharmony_ci				if (hwinfo[addr] == 0xFF) {
187862306a36Sopenharmony_ci					pwr2g->bw40_diff[rf][i] = 0xFE;
187962306a36Sopenharmony_ci				} else {
188062306a36Sopenharmony_ci					pwr2g->bw40_diff[rf][i] = (hwinfo[addr]
188162306a36Sopenharmony_ci								   & 0xf0) >> 4;
188262306a36Sopenharmony_ci					if (pwr2g->bw40_diff[rf][i] & BIT(3))
188362306a36Sopenharmony_ci						pwr2g->bw40_diff[rf][i] |= 0xF0;
188462306a36Sopenharmony_ci				}
188562306a36Sopenharmony_ci
188662306a36Sopenharmony_ci				if (hwinfo[addr] == 0xFF) {
188762306a36Sopenharmony_ci					pwr2g->bw20_diff[rf][i] = 0xFE;
188862306a36Sopenharmony_ci				} else {
188962306a36Sopenharmony_ci					pwr2g->bw20_diff[rf][i] = (hwinfo[addr]
189062306a36Sopenharmony_ci								   & 0x0f);
189162306a36Sopenharmony_ci					if (pwr2g->bw20_diff[rf][i] & BIT(3))
189262306a36Sopenharmony_ci						pwr2g->bw20_diff[rf][i] |= 0xF0;
189362306a36Sopenharmony_ci				}
189462306a36Sopenharmony_ci				addr++;
189562306a36Sopenharmony_ci
189662306a36Sopenharmony_ci				if (hwinfo[addr] == 0xFF) {
189762306a36Sopenharmony_ci					pwr2g->ofdm_diff[rf][i] = 0xFE;
189862306a36Sopenharmony_ci				} else {
189962306a36Sopenharmony_ci					pwr2g->ofdm_diff[rf][i] = (hwinfo[addr]
190062306a36Sopenharmony_ci								   & 0xf0) >> 4;
190162306a36Sopenharmony_ci					if (pwr2g->ofdm_diff[rf][i] & BIT(3))
190262306a36Sopenharmony_ci						pwr2g->ofdm_diff[rf][i] |= 0xF0;
190362306a36Sopenharmony_ci				}
190462306a36Sopenharmony_ci
190562306a36Sopenharmony_ci				if (hwinfo[addr] == 0xFF) {
190662306a36Sopenharmony_ci					pwr2g->cck_diff[rf][i] = 0xFE;
190762306a36Sopenharmony_ci				} else {
190862306a36Sopenharmony_ci					pwr2g->cck_diff[rf][i] = (hwinfo[addr]
190962306a36Sopenharmony_ci								  & 0x0f);
191062306a36Sopenharmony_ci					if (pwr2g->cck_diff[rf][i] & BIT(3))
191162306a36Sopenharmony_ci						pwr2g->cck_diff[rf][i] |= 0xF0;
191262306a36Sopenharmony_ci				}
191362306a36Sopenharmony_ci				addr++;
191462306a36Sopenharmony_ci			}
191562306a36Sopenharmony_ci		}
191662306a36Sopenharmony_ci
191762306a36Sopenharmony_ci		/*5G default value*/
191862306a36Sopenharmony_ci		for (group = 0 ; group < MAX_CHNL_GROUP_5G; group++) {
191962306a36Sopenharmony_ci			pwr5g->index_bw40_base[rf][group] = hwinfo[addr++];
192062306a36Sopenharmony_ci			if (pwr5g->index_bw40_base[rf][group] == 0xFF)
192162306a36Sopenharmony_ci				pwr5g->index_bw40_base[rf][group] = 0xFE;
192262306a36Sopenharmony_ci		}
192362306a36Sopenharmony_ci
192462306a36Sopenharmony_ci		for (i = 0; i < MAX_TX_COUNT; i++) {
192562306a36Sopenharmony_ci			if (i == 0) {
192662306a36Sopenharmony_ci				pwr5g->bw40_diff[rf][i] = 0;
192762306a36Sopenharmony_ci
192862306a36Sopenharmony_ci				if (hwinfo[addr] == 0xFF) {
192962306a36Sopenharmony_ci					pwr5g->bw20_diff[rf][i] = 0;
193062306a36Sopenharmony_ci				} else {
193162306a36Sopenharmony_ci					pwr5g->bw20_diff[rf][0] = (hwinfo[addr]
193262306a36Sopenharmony_ci								   & 0xf0) >> 4;
193362306a36Sopenharmony_ci					if (pwr5g->bw20_diff[rf][i] & BIT(3))
193462306a36Sopenharmony_ci						pwr5g->bw20_diff[rf][i] |= 0xF0;
193562306a36Sopenharmony_ci				}
193662306a36Sopenharmony_ci
193762306a36Sopenharmony_ci				if (hwinfo[addr] == 0xFF) {
193862306a36Sopenharmony_ci					pwr5g->ofdm_diff[rf][i] = 0x04;
193962306a36Sopenharmony_ci				} else {
194062306a36Sopenharmony_ci					pwr5g->ofdm_diff[rf][0] = (hwinfo[addr]
194162306a36Sopenharmony_ci								   & 0x0f);
194262306a36Sopenharmony_ci					if (pwr5g->ofdm_diff[rf][i] & BIT(3))
194362306a36Sopenharmony_ci						pwr5g->ofdm_diff[rf][i] |= 0xF0;
194462306a36Sopenharmony_ci				}
194562306a36Sopenharmony_ci				addr++;
194662306a36Sopenharmony_ci			} else {
194762306a36Sopenharmony_ci				if (hwinfo[addr] == 0xFF) {
194862306a36Sopenharmony_ci					pwr5g->bw40_diff[rf][i] = 0xFE;
194962306a36Sopenharmony_ci				} else {
195062306a36Sopenharmony_ci					pwr5g->bw40_diff[rf][i] = (hwinfo[addr]
195162306a36Sopenharmony_ci								  & 0xf0) >> 4;
195262306a36Sopenharmony_ci					if (pwr5g->bw40_diff[rf][i] & BIT(3))
195362306a36Sopenharmony_ci						pwr5g->bw40_diff[rf][i] |= 0xF0;
195462306a36Sopenharmony_ci				}
195562306a36Sopenharmony_ci
195662306a36Sopenharmony_ci				if (hwinfo[addr] == 0xFF) {
195762306a36Sopenharmony_ci					pwr5g->bw20_diff[rf][i] = 0xFE;
195862306a36Sopenharmony_ci				} else {
195962306a36Sopenharmony_ci					pwr5g->bw20_diff[rf][i] = (hwinfo[addr]
196062306a36Sopenharmony_ci								   & 0x0f);
196162306a36Sopenharmony_ci					if (pwr5g->bw20_diff[rf][i] & BIT(3))
196262306a36Sopenharmony_ci						pwr5g->bw20_diff[rf][i] |= 0xF0;
196362306a36Sopenharmony_ci				}
196462306a36Sopenharmony_ci				addr++;
196562306a36Sopenharmony_ci			}
196662306a36Sopenharmony_ci		}
196762306a36Sopenharmony_ci
196862306a36Sopenharmony_ci		if (hwinfo[addr] == 0xFF) {
196962306a36Sopenharmony_ci			pwr5g->ofdm_diff[rf][1] = 0xFE;
197062306a36Sopenharmony_ci			pwr5g->ofdm_diff[rf][2] = 0xFE;
197162306a36Sopenharmony_ci		} else {
197262306a36Sopenharmony_ci			pwr5g->ofdm_diff[rf][1] = (hwinfo[addr] & 0xf0) >> 4;
197362306a36Sopenharmony_ci			pwr5g->ofdm_diff[rf][2] = (hwinfo[addr] & 0x0f);
197462306a36Sopenharmony_ci		}
197562306a36Sopenharmony_ci		addr++;
197662306a36Sopenharmony_ci
197762306a36Sopenharmony_ci		if (hwinfo[addr] == 0xFF)
197862306a36Sopenharmony_ci			pwr5g->ofdm_diff[rf][3] = 0xFE;
197962306a36Sopenharmony_ci		else
198062306a36Sopenharmony_ci			pwr5g->ofdm_diff[rf][3] = (hwinfo[addr] & 0x0f);
198162306a36Sopenharmony_ci		addr++;
198262306a36Sopenharmony_ci
198362306a36Sopenharmony_ci		for (i = 1; i < MAX_TX_COUNT; i++) {
198462306a36Sopenharmony_ci			if (pwr5g->ofdm_diff[rf][i] == 0xFF)
198562306a36Sopenharmony_ci				pwr5g->ofdm_diff[rf][i] = 0xFE;
198662306a36Sopenharmony_ci			else if (pwr5g->ofdm_diff[rf][i] & BIT(3))
198762306a36Sopenharmony_ci				pwr5g->ofdm_diff[rf][i] |= 0xF0;
198862306a36Sopenharmony_ci		}
198962306a36Sopenharmony_ci
199062306a36Sopenharmony_ci		for (i = 0; i < MAX_TX_COUNT; i++) {
199162306a36Sopenharmony_ci			if (hwinfo[addr] == 0xFF) {
199262306a36Sopenharmony_ci				pwr5g->bw80_diff[rf][i] = 0xFE;
199362306a36Sopenharmony_ci			} else {
199462306a36Sopenharmony_ci				pwr5g->bw80_diff[rf][i] = (hwinfo[addr] & 0xf0)
199562306a36Sopenharmony_ci							  >> 4;
199662306a36Sopenharmony_ci				if (pwr5g->bw80_diff[rf][i] & BIT(3))
199762306a36Sopenharmony_ci					pwr5g->bw80_diff[rf][i] |= 0xF0;
199862306a36Sopenharmony_ci			}
199962306a36Sopenharmony_ci
200062306a36Sopenharmony_ci			if (hwinfo[addr] == 0xFF) {
200162306a36Sopenharmony_ci				pwr5g->bw160_diff[rf][i] = 0xFE;
200262306a36Sopenharmony_ci			} else {
200362306a36Sopenharmony_ci				pwr5g->bw160_diff[rf][i] =
200462306a36Sopenharmony_ci				  (hwinfo[addr] & 0x0f);
200562306a36Sopenharmony_ci				if (pwr5g->bw160_diff[rf][i] & BIT(3))
200662306a36Sopenharmony_ci					pwr5g->bw160_diff[rf][i] |= 0xF0;
200762306a36Sopenharmony_ci			}
200862306a36Sopenharmony_ci			addr++;
200962306a36Sopenharmony_ci		}
201062306a36Sopenharmony_ci	}
201162306a36Sopenharmony_ci}
201262306a36Sopenharmony_ci
201362306a36Sopenharmony_cistatic void _rtl92ee_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
201462306a36Sopenharmony_ci						 bool autoload_fail, u8 *hwinfo)
201562306a36Sopenharmony_ci{
201662306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
201762306a36Sopenharmony_ci	struct rtl_efuse *efu = rtl_efuse(rtl_priv(hw));
201862306a36Sopenharmony_ci	struct txpower_info_2g pwr2g;
201962306a36Sopenharmony_ci	struct txpower_info_5g pwr5g;
202062306a36Sopenharmony_ci	u8 rf, idx;
202162306a36Sopenharmony_ci	u8 i;
202262306a36Sopenharmony_ci
202362306a36Sopenharmony_ci	_rtl8192ee_read_power_value_fromprom(hw, &pwr2g, &pwr5g,
202462306a36Sopenharmony_ci					     autoload_fail, hwinfo);
202562306a36Sopenharmony_ci
202662306a36Sopenharmony_ci	for (rf = 0; rf < MAX_RF_PATH; rf++) {
202762306a36Sopenharmony_ci		for (i = 0; i < 14; i++) {
202862306a36Sopenharmony_ci			idx = _rtl92ee_get_chnl_group(i + 1);
202962306a36Sopenharmony_ci
203062306a36Sopenharmony_ci			if (i == CHANNEL_MAX_NUMBER_2G - 1) {
203162306a36Sopenharmony_ci				efu->txpwrlevel_cck[rf][i] =
203262306a36Sopenharmony_ci						pwr2g.index_cck_base[rf][5];
203362306a36Sopenharmony_ci				efu->txpwrlevel_ht40_1s[rf][i] =
203462306a36Sopenharmony_ci						pwr2g.index_bw40_base[rf][idx];
203562306a36Sopenharmony_ci			} else {
203662306a36Sopenharmony_ci				efu->txpwrlevel_cck[rf][i] =
203762306a36Sopenharmony_ci						pwr2g.index_cck_base[rf][idx];
203862306a36Sopenharmony_ci				efu->txpwrlevel_ht40_1s[rf][i] =
203962306a36Sopenharmony_ci						pwr2g.index_bw40_base[rf][idx];
204062306a36Sopenharmony_ci			}
204162306a36Sopenharmony_ci		}
204262306a36Sopenharmony_ci		for (i = 0; i < CHANNEL_MAX_NUMBER_5G; i++) {
204362306a36Sopenharmony_ci			idx = _rtl92ee_get_chnl_group(channel5g[i]);
204462306a36Sopenharmony_ci			efu->txpwr_5g_bw40base[rf][i] =
204562306a36Sopenharmony_ci					pwr5g.index_bw40_base[rf][idx];
204662306a36Sopenharmony_ci		}
204762306a36Sopenharmony_ci		for (i = 0; i < CHANNEL_MAX_NUMBER_5G_80M; i++) {
204862306a36Sopenharmony_ci			u8 upper, lower;
204962306a36Sopenharmony_ci
205062306a36Sopenharmony_ci			idx = _rtl92ee_get_chnl_group(channel5g_80m[i]);
205162306a36Sopenharmony_ci			upper = pwr5g.index_bw40_base[rf][idx];
205262306a36Sopenharmony_ci			lower = pwr5g.index_bw40_base[rf][idx + 1];
205362306a36Sopenharmony_ci
205462306a36Sopenharmony_ci			efu->txpwr_5g_bw80base[rf][i] = (upper + lower) / 2;
205562306a36Sopenharmony_ci		}
205662306a36Sopenharmony_ci		for (i = 0; i < MAX_TX_COUNT; i++) {
205762306a36Sopenharmony_ci			efu->txpwr_cckdiff[rf][i] = pwr2g.cck_diff[rf][i];
205862306a36Sopenharmony_ci			efu->txpwr_legacyhtdiff[rf][i] = pwr2g.ofdm_diff[rf][i];
205962306a36Sopenharmony_ci			efu->txpwr_ht20diff[rf][i] = pwr2g.bw20_diff[rf][i];
206062306a36Sopenharmony_ci			efu->txpwr_ht40diff[rf][i] = pwr2g.bw40_diff[rf][i];
206162306a36Sopenharmony_ci
206262306a36Sopenharmony_ci			efu->txpwr_5g_ofdmdiff[rf][i] = pwr5g.ofdm_diff[rf][i];
206362306a36Sopenharmony_ci			efu->txpwr_5g_bw20diff[rf][i] = pwr5g.bw20_diff[rf][i];
206462306a36Sopenharmony_ci			efu->txpwr_5g_bw40diff[rf][i] = pwr5g.bw40_diff[rf][i];
206562306a36Sopenharmony_ci			efu->txpwr_5g_bw80diff[rf][i] = pwr5g.bw80_diff[rf][i];
206662306a36Sopenharmony_ci		}
206762306a36Sopenharmony_ci	}
206862306a36Sopenharmony_ci
206962306a36Sopenharmony_ci	if (!autoload_fail)
207062306a36Sopenharmony_ci		efu->eeprom_thermalmeter = hwinfo[EEPROM_THERMAL_METER_92E];
207162306a36Sopenharmony_ci	else
207262306a36Sopenharmony_ci		efu->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
207362306a36Sopenharmony_ci
207462306a36Sopenharmony_ci	if (efu->eeprom_thermalmeter == 0xff || autoload_fail) {
207562306a36Sopenharmony_ci		efu->apk_thermalmeterignore = true;
207662306a36Sopenharmony_ci		efu->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
207762306a36Sopenharmony_ci	}
207862306a36Sopenharmony_ci
207962306a36Sopenharmony_ci	efu->thermalmeter[0] = efu->eeprom_thermalmeter;
208062306a36Sopenharmony_ci	RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
208162306a36Sopenharmony_ci		"thermalmeter = 0x%x\n", efu->eeprom_thermalmeter);
208262306a36Sopenharmony_ci
208362306a36Sopenharmony_ci	if (!autoload_fail) {
208462306a36Sopenharmony_ci		efu->eeprom_regulatory = hwinfo[EEPROM_RF_BOARD_OPTION_92E]
208562306a36Sopenharmony_ci					 & 0x07;
208662306a36Sopenharmony_ci		if (hwinfo[EEPROM_RF_BOARD_OPTION_92E] == 0xFF)
208762306a36Sopenharmony_ci			efu->eeprom_regulatory = 0;
208862306a36Sopenharmony_ci	} else {
208962306a36Sopenharmony_ci		efu->eeprom_regulatory = 0;
209062306a36Sopenharmony_ci	}
209162306a36Sopenharmony_ci	RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
209262306a36Sopenharmony_ci		"eeprom_regulatory = 0x%x\n", efu->eeprom_regulatory);
209362306a36Sopenharmony_ci}
209462306a36Sopenharmony_ci
209562306a36Sopenharmony_cistatic void _rtl92ee_read_adapter_info(struct ieee80211_hw *hw)
209662306a36Sopenharmony_ci{
209762306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
209862306a36Sopenharmony_ci	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
209962306a36Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
210062306a36Sopenharmony_ci	int params[] = {RTL8192E_EEPROM_ID, EEPROM_VID, EEPROM_DID,
210162306a36Sopenharmony_ci			EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR,
210262306a36Sopenharmony_ci			EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID,
210362306a36Sopenharmony_ci			COUNTRY_CODE_WORLD_WIDE_13};
210462306a36Sopenharmony_ci	u8 *hwinfo;
210562306a36Sopenharmony_ci
210662306a36Sopenharmony_ci	hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL);
210762306a36Sopenharmony_ci	if (!hwinfo)
210862306a36Sopenharmony_ci		return;
210962306a36Sopenharmony_ci
211062306a36Sopenharmony_ci	if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params))
211162306a36Sopenharmony_ci		goto exit;
211262306a36Sopenharmony_ci
211362306a36Sopenharmony_ci	if (rtlefuse->eeprom_oemid == 0xFF)
211462306a36Sopenharmony_ci		rtlefuse->eeprom_oemid = 0;
211562306a36Sopenharmony_ci
211662306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
211762306a36Sopenharmony_ci		"EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid);
211862306a36Sopenharmony_ci	/* set channel plan from efuse */
211962306a36Sopenharmony_ci	rtlefuse->channel_plan = rtlefuse->eeprom_channelplan;
212062306a36Sopenharmony_ci	/*tx power*/
212162306a36Sopenharmony_ci	_rtl92ee_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag,
212262306a36Sopenharmony_ci					     hwinfo);
212362306a36Sopenharmony_ci
212462306a36Sopenharmony_ci	rtl92ee_read_bt_coexist_info_from_hwpg(hw, rtlefuse->autoload_failflag,
212562306a36Sopenharmony_ci					       hwinfo);
212662306a36Sopenharmony_ci
212762306a36Sopenharmony_ci	/*board type*/
212862306a36Sopenharmony_ci	rtlefuse->board_type = (((*(u8 *)&hwinfo[EEPROM_RF_BOARD_OPTION_92E])
212962306a36Sopenharmony_ci				& 0xE0) >> 5);
213062306a36Sopenharmony_ci	if ((*(u8 *)&hwinfo[EEPROM_RF_BOARD_OPTION_92E]) == 0xFF)
213162306a36Sopenharmony_ci		rtlefuse->board_type = 0;
213262306a36Sopenharmony_ci
213362306a36Sopenharmony_ci	if (rtlpriv->btcoexist.btc_info.btcoexist == 1)
213462306a36Sopenharmony_ci		rtlefuse->board_type |= BIT(2); /* ODM_BOARD_BT */
213562306a36Sopenharmony_ci
213662306a36Sopenharmony_ci	rtlhal->board_type = rtlefuse->board_type;
213762306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
213862306a36Sopenharmony_ci		"board_type = 0x%x\n", rtlefuse->board_type);
213962306a36Sopenharmony_ci	/*parse xtal*/
214062306a36Sopenharmony_ci	rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_92E];
214162306a36Sopenharmony_ci	if (hwinfo[EEPROM_XTAL_92E] == 0xFF)
214262306a36Sopenharmony_ci		rtlefuse->crystalcap = 0x20;
214362306a36Sopenharmony_ci
214462306a36Sopenharmony_ci	/*antenna diversity*/
214562306a36Sopenharmony_ci	rtlefuse->antenna_div_type = NO_ANTDIV;
214662306a36Sopenharmony_ci	rtlefuse->antenna_div_cfg = 0;
214762306a36Sopenharmony_ci
214862306a36Sopenharmony_ci	if (rtlhal->oem_id == RT_CID_DEFAULT) {
214962306a36Sopenharmony_ci		switch (rtlefuse->eeprom_oemid) {
215062306a36Sopenharmony_ci		case EEPROM_CID_DEFAULT:
215162306a36Sopenharmony_ci			if (rtlefuse->eeprom_did == 0x818B) {
215262306a36Sopenharmony_ci				if ((rtlefuse->eeprom_svid == 0x10EC) &&
215362306a36Sopenharmony_ci				    (rtlefuse->eeprom_smid == 0x001B))
215462306a36Sopenharmony_ci					rtlhal->oem_id = RT_CID_819X_LENOVO;
215562306a36Sopenharmony_ci			} else {
215662306a36Sopenharmony_ci				rtlhal->oem_id = RT_CID_DEFAULT;
215762306a36Sopenharmony_ci			}
215862306a36Sopenharmony_ci			break;
215962306a36Sopenharmony_ci		default:
216062306a36Sopenharmony_ci			rtlhal->oem_id = RT_CID_DEFAULT;
216162306a36Sopenharmony_ci			break;
216262306a36Sopenharmony_ci		}
216362306a36Sopenharmony_ci	}
216462306a36Sopenharmony_ciexit:
216562306a36Sopenharmony_ci	kfree(hwinfo);
216662306a36Sopenharmony_ci}
216762306a36Sopenharmony_ci
216862306a36Sopenharmony_cistatic void _rtl92ee_hal_customized_behavior(struct ieee80211_hw *hw)
216962306a36Sopenharmony_ci{
217062306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
217162306a36Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
217262306a36Sopenharmony_ci
217362306a36Sopenharmony_ci	rtlpriv->ledctl.led_opendrain = true;
217462306a36Sopenharmony_ci
217562306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG,
217662306a36Sopenharmony_ci		"RT Customized ID: 0x%02X\n", rtlhal->oem_id);
217762306a36Sopenharmony_ci}
217862306a36Sopenharmony_ci
217962306a36Sopenharmony_civoid rtl92ee_read_eeprom_info(struct ieee80211_hw *hw)
218062306a36Sopenharmony_ci{
218162306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
218262306a36Sopenharmony_ci	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
218362306a36Sopenharmony_ci	struct rtl_phy *rtlphy = &rtlpriv->phy;
218462306a36Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
218562306a36Sopenharmony_ci	u8 tmp_u1b;
218662306a36Sopenharmony_ci
218762306a36Sopenharmony_ci	rtlhal->version = _rtl92ee_read_chip_version(hw);
218862306a36Sopenharmony_ci	if (get_rf_type(rtlphy) == RF_1T1R) {
218962306a36Sopenharmony_ci		rtlpriv->dm.rfpath_rxenable[0] = true;
219062306a36Sopenharmony_ci	} else {
219162306a36Sopenharmony_ci		rtlpriv->dm.rfpath_rxenable[0] = true;
219262306a36Sopenharmony_ci		rtlpriv->dm.rfpath_rxenable[1] = true;
219362306a36Sopenharmony_ci	}
219462306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
219562306a36Sopenharmony_ci		rtlhal->version);
219662306a36Sopenharmony_ci	tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
219762306a36Sopenharmony_ci	if (tmp_u1b & BIT(4)) {
219862306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
219962306a36Sopenharmony_ci		rtlefuse->epromtype = EEPROM_93C46;
220062306a36Sopenharmony_ci	} else {
220162306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
220262306a36Sopenharmony_ci		rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
220362306a36Sopenharmony_ci	}
220462306a36Sopenharmony_ci	if (tmp_u1b & BIT(5)) {
220562306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
220662306a36Sopenharmony_ci		rtlefuse->autoload_failflag = false;
220762306a36Sopenharmony_ci		_rtl92ee_read_adapter_info(hw);
220862306a36Sopenharmony_ci	} else {
220962306a36Sopenharmony_ci		pr_err("Autoload ERR!!\n");
221062306a36Sopenharmony_ci	}
221162306a36Sopenharmony_ci	_rtl92ee_hal_customized_behavior(hw);
221262306a36Sopenharmony_ci
221362306a36Sopenharmony_ci	rtlphy->rfpath_rx_enable[0] = true;
221462306a36Sopenharmony_ci	if (rtlphy->rf_type == RF_2T2R)
221562306a36Sopenharmony_ci		rtlphy->rfpath_rx_enable[1] = true;
221662306a36Sopenharmony_ci}
221762306a36Sopenharmony_ci
221862306a36Sopenharmony_cistatic u8 _rtl92ee_mrate_idx_to_arfr_id(struct ieee80211_hw *hw, u8 rate_index)
221962306a36Sopenharmony_ci{
222062306a36Sopenharmony_ci	u8 ret = 0;
222162306a36Sopenharmony_ci
222262306a36Sopenharmony_ci	switch (rate_index) {
222362306a36Sopenharmony_ci	case RATR_INX_WIRELESS_NGB:
222462306a36Sopenharmony_ci		ret = 0;
222562306a36Sopenharmony_ci		break;
222662306a36Sopenharmony_ci	case RATR_INX_WIRELESS_N:
222762306a36Sopenharmony_ci	case RATR_INX_WIRELESS_NG:
222862306a36Sopenharmony_ci		ret = 4;
222962306a36Sopenharmony_ci		break;
223062306a36Sopenharmony_ci	case RATR_INX_WIRELESS_NB:
223162306a36Sopenharmony_ci		ret = 2;
223262306a36Sopenharmony_ci		break;
223362306a36Sopenharmony_ci	case RATR_INX_WIRELESS_GB:
223462306a36Sopenharmony_ci		ret = 6;
223562306a36Sopenharmony_ci		break;
223662306a36Sopenharmony_ci	case RATR_INX_WIRELESS_G:
223762306a36Sopenharmony_ci		ret = 7;
223862306a36Sopenharmony_ci		break;
223962306a36Sopenharmony_ci	case RATR_INX_WIRELESS_B:
224062306a36Sopenharmony_ci		ret = 8;
224162306a36Sopenharmony_ci		break;
224262306a36Sopenharmony_ci	default:
224362306a36Sopenharmony_ci		ret = 0;
224462306a36Sopenharmony_ci		break;
224562306a36Sopenharmony_ci	}
224662306a36Sopenharmony_ci	return ret;
224762306a36Sopenharmony_ci}
224862306a36Sopenharmony_ci
224962306a36Sopenharmony_cistatic void rtl92ee_update_hal_rate_mask(struct ieee80211_hw *hw,
225062306a36Sopenharmony_ci					 struct ieee80211_sta *sta,
225162306a36Sopenharmony_ci					 u8 rssi_level, bool update_bw)
225262306a36Sopenharmony_ci{
225362306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
225462306a36Sopenharmony_ci	struct rtl_phy *rtlphy = &rtlpriv->phy;
225562306a36Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
225662306a36Sopenharmony_ci	struct rtl_sta_info *sta_entry = NULL;
225762306a36Sopenharmony_ci	u32 ratr_bitmap;
225862306a36Sopenharmony_ci	u8 ratr_index;
225962306a36Sopenharmony_ci	u8 curtxbw_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
226062306a36Sopenharmony_ci			     ? 1 : 0;
226162306a36Sopenharmony_ci	u8 b_curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
226262306a36Sopenharmony_ci				1 : 0;
226362306a36Sopenharmony_ci	u8 b_curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
226462306a36Sopenharmony_ci				1 : 0;
226562306a36Sopenharmony_ci	enum wireless_mode wirelessmode = 0;
226662306a36Sopenharmony_ci	bool b_shortgi = false;
226762306a36Sopenharmony_ci	u8 rate_mask[7] = {0};
226862306a36Sopenharmony_ci	u8 macid = 0;
226962306a36Sopenharmony_ci	/*u8 mimo_ps = IEEE80211_SMPS_OFF;*/
227062306a36Sopenharmony_ci	sta_entry = (struct rtl_sta_info *)sta->drv_priv;
227162306a36Sopenharmony_ci	wirelessmode = sta_entry->wireless_mode;
227262306a36Sopenharmony_ci	if (mac->opmode == NL80211_IFTYPE_STATION ||
227362306a36Sopenharmony_ci	    mac->opmode == NL80211_IFTYPE_MESH_POINT)
227462306a36Sopenharmony_ci		curtxbw_40mhz = mac->bw_40;
227562306a36Sopenharmony_ci	else if (mac->opmode == NL80211_IFTYPE_AP ||
227662306a36Sopenharmony_ci		 mac->opmode == NL80211_IFTYPE_ADHOC)
227762306a36Sopenharmony_ci		macid = sta->aid + 1;
227862306a36Sopenharmony_ci
227962306a36Sopenharmony_ci	ratr_bitmap = sta->deflink.supp_rates[0];
228062306a36Sopenharmony_ci	if (mac->opmode == NL80211_IFTYPE_ADHOC)
228162306a36Sopenharmony_ci		ratr_bitmap = 0xfff;
228262306a36Sopenharmony_ci
228362306a36Sopenharmony_ci	ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 |
228462306a36Sopenharmony_ci			sta->deflink.ht_cap.mcs.rx_mask[0] << 12);
228562306a36Sopenharmony_ci
228662306a36Sopenharmony_ci	switch (wirelessmode) {
228762306a36Sopenharmony_ci	case WIRELESS_MODE_B:
228862306a36Sopenharmony_ci		ratr_index = RATR_INX_WIRELESS_B;
228962306a36Sopenharmony_ci		if (ratr_bitmap & 0x0000000c)
229062306a36Sopenharmony_ci			ratr_bitmap &= 0x0000000d;
229162306a36Sopenharmony_ci		else
229262306a36Sopenharmony_ci			ratr_bitmap &= 0x0000000f;
229362306a36Sopenharmony_ci		break;
229462306a36Sopenharmony_ci	case WIRELESS_MODE_G:
229562306a36Sopenharmony_ci		ratr_index = RATR_INX_WIRELESS_GB;
229662306a36Sopenharmony_ci
229762306a36Sopenharmony_ci		if (rssi_level == 1)
229862306a36Sopenharmony_ci			ratr_bitmap &= 0x00000f00;
229962306a36Sopenharmony_ci		else if (rssi_level == 2)
230062306a36Sopenharmony_ci			ratr_bitmap &= 0x00000ff0;
230162306a36Sopenharmony_ci		else
230262306a36Sopenharmony_ci			ratr_bitmap &= 0x00000ff5;
230362306a36Sopenharmony_ci		break;
230462306a36Sopenharmony_ci	case WIRELESS_MODE_N_24G:
230562306a36Sopenharmony_ci		if (curtxbw_40mhz)
230662306a36Sopenharmony_ci			ratr_index = RATR_INX_WIRELESS_NGB;
230762306a36Sopenharmony_ci		else
230862306a36Sopenharmony_ci			ratr_index = RATR_INX_WIRELESS_NB;
230962306a36Sopenharmony_ci
231062306a36Sopenharmony_ci		if (rtlphy->rf_type == RF_1T1R) {
231162306a36Sopenharmony_ci			if (curtxbw_40mhz) {
231262306a36Sopenharmony_ci				if (rssi_level == 1)
231362306a36Sopenharmony_ci					ratr_bitmap &= 0x000f0000;
231462306a36Sopenharmony_ci				else if (rssi_level == 2)
231562306a36Sopenharmony_ci					ratr_bitmap &= 0x000ff000;
231662306a36Sopenharmony_ci				else
231762306a36Sopenharmony_ci					ratr_bitmap &= 0x000ff015;
231862306a36Sopenharmony_ci			} else {
231962306a36Sopenharmony_ci				if (rssi_level == 1)
232062306a36Sopenharmony_ci					ratr_bitmap &= 0x000f0000;
232162306a36Sopenharmony_ci				else if (rssi_level == 2)
232262306a36Sopenharmony_ci					ratr_bitmap &= 0x000ff000;
232362306a36Sopenharmony_ci				else
232462306a36Sopenharmony_ci					ratr_bitmap &= 0x000ff005;
232562306a36Sopenharmony_ci			}
232662306a36Sopenharmony_ci		} else {
232762306a36Sopenharmony_ci			if (curtxbw_40mhz) {
232862306a36Sopenharmony_ci				if (rssi_level == 1)
232962306a36Sopenharmony_ci					ratr_bitmap &= 0x0f8f0000;
233062306a36Sopenharmony_ci				else if (rssi_level == 2)
233162306a36Sopenharmony_ci					ratr_bitmap &= 0x0ffff000;
233262306a36Sopenharmony_ci				else
233362306a36Sopenharmony_ci					ratr_bitmap &= 0x0ffff015;
233462306a36Sopenharmony_ci			} else {
233562306a36Sopenharmony_ci				if (rssi_level == 1)
233662306a36Sopenharmony_ci					ratr_bitmap &= 0x0f8f0000;
233762306a36Sopenharmony_ci				else if (rssi_level == 2)
233862306a36Sopenharmony_ci					ratr_bitmap &= 0x0ffff000;
233962306a36Sopenharmony_ci				else
234062306a36Sopenharmony_ci					ratr_bitmap &= 0x0ffff005;
234162306a36Sopenharmony_ci			}
234262306a36Sopenharmony_ci		}
234362306a36Sopenharmony_ci
234462306a36Sopenharmony_ci		if ((curtxbw_40mhz && b_curshortgi_40mhz) ||
234562306a36Sopenharmony_ci		    (!curtxbw_40mhz && b_curshortgi_20mhz)) {
234662306a36Sopenharmony_ci			if (macid == 0)
234762306a36Sopenharmony_ci				b_shortgi = true;
234862306a36Sopenharmony_ci			else if (macid == 1)
234962306a36Sopenharmony_ci				b_shortgi = false;
235062306a36Sopenharmony_ci		}
235162306a36Sopenharmony_ci		break;
235262306a36Sopenharmony_ci	default:
235362306a36Sopenharmony_ci		ratr_index = RATR_INX_WIRELESS_NGB;
235462306a36Sopenharmony_ci
235562306a36Sopenharmony_ci		if (rtlphy->rf_type == RF_1T1R)
235662306a36Sopenharmony_ci			ratr_bitmap &= 0x000ff0ff;
235762306a36Sopenharmony_ci		else
235862306a36Sopenharmony_ci			ratr_bitmap &= 0x0f8ff0ff;
235962306a36Sopenharmony_ci		break;
236062306a36Sopenharmony_ci	}
236162306a36Sopenharmony_ci	ratr_index = _rtl92ee_mrate_idx_to_arfr_id(hw, ratr_index);
236262306a36Sopenharmony_ci	sta_entry->ratr_index = ratr_index;
236362306a36Sopenharmony_ci
236462306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG,
236562306a36Sopenharmony_ci		"ratr_bitmap :%x\n", ratr_bitmap);
236662306a36Sopenharmony_ci	*(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
236762306a36Sopenharmony_ci				       (ratr_index << 28);
236862306a36Sopenharmony_ci	rate_mask[0] = macid;
236962306a36Sopenharmony_ci	rate_mask[1] = ratr_index | (b_shortgi ? 0x80 : 0x00);
237062306a36Sopenharmony_ci	rate_mask[2] = curtxbw_40mhz | ((!update_bw) << 3);
237162306a36Sopenharmony_ci	rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff);
237262306a36Sopenharmony_ci	rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >> 8);
237362306a36Sopenharmony_ci	rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16);
237462306a36Sopenharmony_ci	rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24);
237562306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG,
237662306a36Sopenharmony_ci		"Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x:%x:%x\n",
237762306a36Sopenharmony_ci		ratr_index, ratr_bitmap, rate_mask[0], rate_mask[1],
237862306a36Sopenharmony_ci		rate_mask[2], rate_mask[3], rate_mask[4],
237962306a36Sopenharmony_ci		rate_mask[5], rate_mask[6]);
238062306a36Sopenharmony_ci	rtl92ee_fill_h2c_cmd(hw, H2C_92E_RA_MASK, 7, rate_mask);
238162306a36Sopenharmony_ci	_rtl92ee_set_bcn_ctrl_reg(hw, BIT(3), 0);
238262306a36Sopenharmony_ci}
238362306a36Sopenharmony_ci
238462306a36Sopenharmony_civoid rtl92ee_update_hal_rate_tbl(struct ieee80211_hw *hw,
238562306a36Sopenharmony_ci				 struct ieee80211_sta *sta, u8 rssi_level,
238662306a36Sopenharmony_ci				 bool update_bw)
238762306a36Sopenharmony_ci{
238862306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
238962306a36Sopenharmony_ci
239062306a36Sopenharmony_ci	if (rtlpriv->dm.useramask)
239162306a36Sopenharmony_ci		rtl92ee_update_hal_rate_mask(hw, sta, rssi_level, update_bw);
239262306a36Sopenharmony_ci}
239362306a36Sopenharmony_ci
239462306a36Sopenharmony_civoid rtl92ee_update_channel_access_setting(struct ieee80211_hw *hw)
239562306a36Sopenharmony_ci{
239662306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
239762306a36Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
239862306a36Sopenharmony_ci	u16 sifs_timer;
239962306a36Sopenharmony_ci
240062306a36Sopenharmony_ci	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
240162306a36Sopenharmony_ci				      (u8 *)&mac->slot_time);
240262306a36Sopenharmony_ci	if (!mac->ht_enable)
240362306a36Sopenharmony_ci		sifs_timer = 0x0a0a;
240462306a36Sopenharmony_ci	else
240562306a36Sopenharmony_ci		sifs_timer = 0x0e0e;
240662306a36Sopenharmony_ci	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
240762306a36Sopenharmony_ci}
240862306a36Sopenharmony_ci
240962306a36Sopenharmony_cibool rtl92ee_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
241062306a36Sopenharmony_ci{
241162306a36Sopenharmony_ci	*valid = 1;
241262306a36Sopenharmony_ci	return true;
241362306a36Sopenharmony_ci}
241462306a36Sopenharmony_ci
241562306a36Sopenharmony_civoid rtl92ee_set_key(struct ieee80211_hw *hw, u32 key_index,
241662306a36Sopenharmony_ci		     u8 *p_macaddr, bool is_group, u8 enc_algo,
241762306a36Sopenharmony_ci		     bool is_wepkey, bool clear_all)
241862306a36Sopenharmony_ci{
241962306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
242062306a36Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
242162306a36Sopenharmony_ci	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
242262306a36Sopenharmony_ci	u8 *macaddr = p_macaddr;
242362306a36Sopenharmony_ci	u32 entry_id = 0;
242462306a36Sopenharmony_ci	bool is_pairwise = false;
242562306a36Sopenharmony_ci
242662306a36Sopenharmony_ci	static u8 cam_const_addr[4][6] = {
242762306a36Sopenharmony_ci		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
242862306a36Sopenharmony_ci		{0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
242962306a36Sopenharmony_ci		{0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
243062306a36Sopenharmony_ci		{0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
243162306a36Sopenharmony_ci	};
243262306a36Sopenharmony_ci	static u8 cam_const_broad[] = {
243362306a36Sopenharmony_ci		0xff, 0xff, 0xff, 0xff, 0xff, 0xff
243462306a36Sopenharmony_ci	};
243562306a36Sopenharmony_ci
243662306a36Sopenharmony_ci	if (clear_all) {
243762306a36Sopenharmony_ci		u8 idx = 0;
243862306a36Sopenharmony_ci		u8 cam_offset = 0;
243962306a36Sopenharmony_ci		u8 clear_number = 5;
244062306a36Sopenharmony_ci
244162306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
244262306a36Sopenharmony_ci
244362306a36Sopenharmony_ci		for (idx = 0; idx < clear_number; idx++) {
244462306a36Sopenharmony_ci			rtl_cam_mark_invalid(hw, cam_offset + idx);
244562306a36Sopenharmony_ci			rtl_cam_empty_entry(hw, cam_offset + idx);
244662306a36Sopenharmony_ci
244762306a36Sopenharmony_ci			if (idx < 5) {
244862306a36Sopenharmony_ci				memset(rtlpriv->sec.key_buf[idx], 0,
244962306a36Sopenharmony_ci				       MAX_KEY_LEN);
245062306a36Sopenharmony_ci				rtlpriv->sec.key_len[idx] = 0;
245162306a36Sopenharmony_ci			}
245262306a36Sopenharmony_ci		}
245362306a36Sopenharmony_ci
245462306a36Sopenharmony_ci	} else {
245562306a36Sopenharmony_ci		switch (enc_algo) {
245662306a36Sopenharmony_ci		case WEP40_ENCRYPTION:
245762306a36Sopenharmony_ci			enc_algo = CAM_WEP40;
245862306a36Sopenharmony_ci			break;
245962306a36Sopenharmony_ci		case WEP104_ENCRYPTION:
246062306a36Sopenharmony_ci			enc_algo = CAM_WEP104;
246162306a36Sopenharmony_ci			break;
246262306a36Sopenharmony_ci		case TKIP_ENCRYPTION:
246362306a36Sopenharmony_ci			enc_algo = CAM_TKIP;
246462306a36Sopenharmony_ci			break;
246562306a36Sopenharmony_ci		case AESCCMP_ENCRYPTION:
246662306a36Sopenharmony_ci			enc_algo = CAM_AES;
246762306a36Sopenharmony_ci			break;
246862306a36Sopenharmony_ci		default:
246962306a36Sopenharmony_ci			rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG,
247062306a36Sopenharmony_ci				"switch case %#x not processed\n", enc_algo);
247162306a36Sopenharmony_ci			enc_algo = CAM_TKIP;
247262306a36Sopenharmony_ci			break;
247362306a36Sopenharmony_ci		}
247462306a36Sopenharmony_ci
247562306a36Sopenharmony_ci		if (is_wepkey || rtlpriv->sec.use_defaultkey) {
247662306a36Sopenharmony_ci			macaddr = cam_const_addr[key_index];
247762306a36Sopenharmony_ci			entry_id = key_index;
247862306a36Sopenharmony_ci		} else {
247962306a36Sopenharmony_ci			if (is_group) {
248062306a36Sopenharmony_ci				macaddr = cam_const_broad;
248162306a36Sopenharmony_ci				entry_id = key_index;
248262306a36Sopenharmony_ci			} else {
248362306a36Sopenharmony_ci				if (mac->opmode == NL80211_IFTYPE_AP ||
248462306a36Sopenharmony_ci				    mac->opmode == NL80211_IFTYPE_MESH_POINT) {
248562306a36Sopenharmony_ci					entry_id = rtl_cam_get_free_entry(hw,
248662306a36Sopenharmony_ci								     p_macaddr);
248762306a36Sopenharmony_ci					if (entry_id >=  TOTAL_CAM_ENTRY) {
248862306a36Sopenharmony_ci						pr_err("Can not find free hw security cam entry\n");
248962306a36Sopenharmony_ci						return;
249062306a36Sopenharmony_ci					}
249162306a36Sopenharmony_ci				} else {
249262306a36Sopenharmony_ci					entry_id = CAM_PAIRWISE_KEY_POSITION;
249362306a36Sopenharmony_ci				}
249462306a36Sopenharmony_ci
249562306a36Sopenharmony_ci				key_index = PAIRWISE_KEYIDX;
249662306a36Sopenharmony_ci				is_pairwise = true;
249762306a36Sopenharmony_ci			}
249862306a36Sopenharmony_ci		}
249962306a36Sopenharmony_ci
250062306a36Sopenharmony_ci		if (rtlpriv->sec.key_len[key_index] == 0) {
250162306a36Sopenharmony_ci			rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
250262306a36Sopenharmony_ci				"delete one entry, entry_id is %d\n",
250362306a36Sopenharmony_ci				entry_id);
250462306a36Sopenharmony_ci			if (mac->opmode == NL80211_IFTYPE_AP ||
250562306a36Sopenharmony_ci			    mac->opmode == NL80211_IFTYPE_MESH_POINT)
250662306a36Sopenharmony_ci				rtl_cam_del_entry(hw, p_macaddr);
250762306a36Sopenharmony_ci			rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
250862306a36Sopenharmony_ci		} else {
250962306a36Sopenharmony_ci			rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
251062306a36Sopenharmony_ci				"add one entry\n");
251162306a36Sopenharmony_ci			if (is_pairwise) {
251262306a36Sopenharmony_ci				rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
251362306a36Sopenharmony_ci					"set Pairwise key\n");
251462306a36Sopenharmony_ci
251562306a36Sopenharmony_ci				rtl_cam_add_one_entry(hw, macaddr, key_index,
251662306a36Sopenharmony_ci					       entry_id, enc_algo,
251762306a36Sopenharmony_ci					       CAM_CONFIG_NO_USEDK,
251862306a36Sopenharmony_ci					       rtlpriv->sec.key_buf[key_index]);
251962306a36Sopenharmony_ci			} else {
252062306a36Sopenharmony_ci				rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
252162306a36Sopenharmony_ci					"set group key\n");
252262306a36Sopenharmony_ci
252362306a36Sopenharmony_ci				if (mac->opmode == NL80211_IFTYPE_ADHOC) {
252462306a36Sopenharmony_ci					rtl_cam_add_one_entry(hw,
252562306a36Sopenharmony_ci						rtlefuse->dev_addr,
252662306a36Sopenharmony_ci						PAIRWISE_KEYIDX,
252762306a36Sopenharmony_ci						CAM_PAIRWISE_KEY_POSITION,
252862306a36Sopenharmony_ci						enc_algo, CAM_CONFIG_NO_USEDK,
252962306a36Sopenharmony_ci						rtlpriv->sec.key_buf[entry_id]);
253062306a36Sopenharmony_ci				}
253162306a36Sopenharmony_ci
253262306a36Sopenharmony_ci				rtl_cam_add_one_entry(hw, macaddr, key_index,
253362306a36Sopenharmony_ci						entry_id, enc_algo,
253462306a36Sopenharmony_ci						CAM_CONFIG_NO_USEDK,
253562306a36Sopenharmony_ci						rtlpriv->sec.key_buf[entry_id]);
253662306a36Sopenharmony_ci			}
253762306a36Sopenharmony_ci		}
253862306a36Sopenharmony_ci	}
253962306a36Sopenharmony_ci}
254062306a36Sopenharmony_ci
254162306a36Sopenharmony_civoid rtl92ee_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
254262306a36Sopenharmony_ci					    bool auto_load_fail, u8 *hwinfo)
254362306a36Sopenharmony_ci{
254462306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
254562306a36Sopenharmony_ci	u8 value;
254662306a36Sopenharmony_ci
254762306a36Sopenharmony_ci	if (!auto_load_fail) {
254862306a36Sopenharmony_ci		value = hwinfo[EEPROM_RF_BOARD_OPTION_92E];
254962306a36Sopenharmony_ci		if (((value & 0xe0) >> 5) == 0x1)
255062306a36Sopenharmony_ci			rtlpriv->btcoexist.btc_info.btcoexist = 1;
255162306a36Sopenharmony_ci		else
255262306a36Sopenharmony_ci			rtlpriv->btcoexist.btc_info.btcoexist = 0;
255362306a36Sopenharmony_ci
255462306a36Sopenharmony_ci		rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8192E;
255562306a36Sopenharmony_ci		rtlpriv->btcoexist.btc_info.ant_num = ANT_X2;
255662306a36Sopenharmony_ci	} else {
255762306a36Sopenharmony_ci		rtlpriv->btcoexist.btc_info.btcoexist = 1;
255862306a36Sopenharmony_ci		rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8192E;
255962306a36Sopenharmony_ci		rtlpriv->btcoexist.btc_info.ant_num = ANT_X1;
256062306a36Sopenharmony_ci	}
256162306a36Sopenharmony_ci}
256262306a36Sopenharmony_ci
256362306a36Sopenharmony_civoid rtl92ee_bt_reg_init(struct ieee80211_hw *hw)
256462306a36Sopenharmony_ci{
256562306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
256662306a36Sopenharmony_ci
256762306a36Sopenharmony_ci	/* 0:Low, 1:High, 2:From Efuse. */
256862306a36Sopenharmony_ci	rtlpriv->btcoexist.reg_bt_iso = 2;
256962306a36Sopenharmony_ci	/* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */
257062306a36Sopenharmony_ci	rtlpriv->btcoexist.reg_bt_sco = 3;
257162306a36Sopenharmony_ci	/* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
257262306a36Sopenharmony_ci	rtlpriv->btcoexist.reg_bt_sco = 0;
257362306a36Sopenharmony_ci}
257462306a36Sopenharmony_ci
257562306a36Sopenharmony_civoid rtl92ee_bt_hw_init(struct ieee80211_hw *hw)
257662306a36Sopenharmony_ci{
257762306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
257862306a36Sopenharmony_ci
257962306a36Sopenharmony_ci	if (rtlpriv->cfg->ops->get_btc_status())
258062306a36Sopenharmony_ci		rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv);
258162306a36Sopenharmony_ci}
258262306a36Sopenharmony_ci
258362306a36Sopenharmony_civoid rtl92ee_suspend(struct ieee80211_hw *hw)
258462306a36Sopenharmony_ci{
258562306a36Sopenharmony_ci}
258662306a36Sopenharmony_ci
258762306a36Sopenharmony_civoid rtl92ee_resume(struct ieee80211_hw *hw)
258862306a36Sopenharmony_ci{
258962306a36Sopenharmony_ci}
259062306a36Sopenharmony_ci
259162306a36Sopenharmony_ci/* Turn on AAP (RCR:bit 0) for promicuous mode. */
259262306a36Sopenharmony_civoid rtl92ee_allow_all_destaddr(struct ieee80211_hw *hw,
259362306a36Sopenharmony_ci				bool allow_all_da, bool write_into_reg)
259462306a36Sopenharmony_ci{
259562306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
259662306a36Sopenharmony_ci	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
259762306a36Sopenharmony_ci
259862306a36Sopenharmony_ci	if (allow_all_da)	/* Set BIT0 */
259962306a36Sopenharmony_ci		rtlpci->receive_config |= RCR_AAP;
260062306a36Sopenharmony_ci	else			/* Clear BIT0 */
260162306a36Sopenharmony_ci		rtlpci->receive_config &= ~RCR_AAP;
260262306a36Sopenharmony_ci
260362306a36Sopenharmony_ci	if (write_into_reg)
260462306a36Sopenharmony_ci		rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
260562306a36Sopenharmony_ci
260662306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_TURBO | COMP_INIT, DBG_LOUD,
260762306a36Sopenharmony_ci		"receive_config=0x%08X, write_into_reg=%d\n",
260862306a36Sopenharmony_ci		rtlpci->receive_config, write_into_reg);
260962306a36Sopenharmony_ci}
2610