193121c03SLarry Finger // SPDX-License-Identifier: GPL-2.0
293121c03SLarry Finger /* Copyright(c) 2009-2014 Realtek Corporation.*/
3f1d2b4d3SLarry Finger
4f1d2b4d3SLarry Finger #include "../wifi.h"
5f1d2b4d3SLarry Finger #include "../efuse.h"
6f1d2b4d3SLarry Finger #include "../base.h"
7f1d2b4d3SLarry Finger #include "../regd.h"
8f1d2b4d3SLarry Finger #include "../cam.h"
9f1d2b4d3SLarry Finger #include "../ps.h"
10f1d2b4d3SLarry Finger #include "../pci.h"
11f1d2b4d3SLarry Finger #include "reg.h"
12f1d2b4d3SLarry Finger #include "def.h"
13f1d2b4d3SLarry Finger #include "phy.h"
14f1d2b4d3SLarry Finger #include "../rtl8723com/phy_common.h"
15f1d2b4d3SLarry Finger #include "dm.h"
16f1d2b4d3SLarry Finger #include "../rtl8723com/dm_common.h"
17f1d2b4d3SLarry Finger #include "fw.h"
18f1d2b4d3SLarry Finger #include "../rtl8723com/fw_common.h"
19f1d2b4d3SLarry Finger #include "led.h"
20f1d2b4d3SLarry Finger #include "hw.h"
21f1d2b4d3SLarry Finger #include "../pwrseqcmd.h"
22f1d2b4d3SLarry Finger #include "pwrseq.h"
23f1d2b4d3SLarry Finger #include "../btcoexist/rtl_btc.h"
2453ac7935SJérémy Lefaure #include <linux/kernel.h>
25f1d2b4d3SLarry Finger
26f1d2b4d3SLarry Finger #define LLT_CONFIG 5
27f1d2b4d3SLarry Finger
_rtl8723be_return_beacon_queue_skb(struct ieee80211_hw * hw)28f1d2b4d3SLarry Finger static void _rtl8723be_return_beacon_queue_skb(struct ieee80211_hw *hw)
29f1d2b4d3SLarry Finger {
30f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
31f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
32f1d2b4d3SLarry Finger struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
33f1d2b4d3SLarry Finger struct sk_buff_head free_list;
34f1d2b4d3SLarry Finger unsigned long flags;
35f1d2b4d3SLarry Finger
36f1d2b4d3SLarry Finger skb_queue_head_init(&free_list);
37f1d2b4d3SLarry Finger spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
38f1d2b4d3SLarry Finger while (skb_queue_len(&ring->queue)) {
39f1d2b4d3SLarry Finger struct rtl_tx_desc *entry = &ring->desc[ring->idx];
400dc0b5c2SChristophe JAILLET struct sk_buff *skb = __skb_dequeue(&ring->queue);
410dc0b5c2SChristophe JAILLET
420dc0b5c2SChristophe JAILLET dma_unmap_single(&rtlpci->pdev->dev,
430dc0b5c2SChristophe JAILLET rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry,
44f1d2b4d3SLarry Finger true, HW_DESC_TXBUFF_ADDR),
45f1d2b4d3SLarry Finger skb->len, DMA_TO_DEVICE);
46f1d2b4d3SLarry Finger __skb_queue_tail(&free_list, skb);
47f1d2b4d3SLarry Finger ring->idx = (ring->idx + 1) % ring->entries;
48f1d2b4d3SLarry Finger }
49f1d2b4d3SLarry Finger spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
50f1d2b4d3SLarry Finger
51f1d2b4d3SLarry Finger __skb_queue_purge(&free_list);
52f1d2b4d3SLarry Finger }
53f1d2b4d3SLarry Finger
_rtl8723be_set_bcn_ctrl_reg(struct ieee80211_hw * hw,u8 set_bits,u8 clear_bits)54f1d2b4d3SLarry Finger static void _rtl8723be_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
55f1d2b4d3SLarry Finger u8 set_bits, u8 clear_bits)
56f1d2b4d3SLarry Finger {
57f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
58f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
59f1d2b4d3SLarry Finger
60f1d2b4d3SLarry Finger rtlpci->reg_bcn_ctrl_val |= set_bits;
61f1d2b4d3SLarry Finger rtlpci->reg_bcn_ctrl_val &= ~clear_bits;
62f1d2b4d3SLarry Finger
63f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlpci->reg_bcn_ctrl_val);
64f1d2b4d3SLarry Finger }
65f1d2b4d3SLarry Finger
_rtl8723be_stop_tx_beacon(struct ieee80211_hw * hw)66f1d2b4d3SLarry Finger static void _rtl8723be_stop_tx_beacon(struct ieee80211_hw *hw)
67f1d2b4d3SLarry Finger {
68f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
69f1d2b4d3SLarry Finger u8 tmp1byte;
70f1d2b4d3SLarry Finger
71f1d2b4d3SLarry Finger tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
72f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6)));
73f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64);
74f1d2b4d3SLarry Finger tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
75f1d2b4d3SLarry Finger tmp1byte &= ~(BIT(0));
76f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
77f1d2b4d3SLarry Finger }
78f1d2b4d3SLarry Finger
_rtl8723be_resume_tx_beacon(struct ieee80211_hw * hw)79f1d2b4d3SLarry Finger static void _rtl8723be_resume_tx_beacon(struct ieee80211_hw *hw)
80f1d2b4d3SLarry Finger {
81f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
82f1d2b4d3SLarry Finger u8 tmp1byte;
83f1d2b4d3SLarry Finger
84f1d2b4d3SLarry Finger tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
85f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6));
86f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
87f1d2b4d3SLarry Finger tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
88f1d2b4d3SLarry Finger tmp1byte |= BIT(1);
89f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
90f1d2b4d3SLarry Finger }
91f1d2b4d3SLarry Finger
_rtl8723be_enable_bcn_sub_func(struct ieee80211_hw * hw)92f1d2b4d3SLarry Finger static void _rtl8723be_enable_bcn_sub_func(struct ieee80211_hw *hw)
93f1d2b4d3SLarry Finger {
94f1d2b4d3SLarry Finger _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(1));
95f1d2b4d3SLarry Finger }
96f1d2b4d3SLarry Finger
_rtl8723be_disable_bcn_sub_func(struct ieee80211_hw * hw)97f1d2b4d3SLarry Finger static void _rtl8723be_disable_bcn_sub_func(struct ieee80211_hw *hw)
98f1d2b4d3SLarry Finger {
99f1d2b4d3SLarry Finger _rtl8723be_set_bcn_ctrl_reg(hw, BIT(1), 0);
100f1d2b4d3SLarry Finger }
101f1d2b4d3SLarry Finger
_rtl8723be_set_fw_clock_on(struct ieee80211_hw * hw,u8 rpwm_val,bool b_need_turn_off_ckk)102f1d2b4d3SLarry Finger static void _rtl8723be_set_fw_clock_on(struct ieee80211_hw *hw, u8 rpwm_val,
103f1d2b4d3SLarry Finger bool b_need_turn_off_ckk)
104f1d2b4d3SLarry Finger {
105f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
106f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
107f1d2b4d3SLarry Finger bool b_support_remote_wake_up;
108f1d2b4d3SLarry Finger u32 count = 0, isr_regaddr, content;
109f1d2b4d3SLarry Finger bool b_schedule_timer = b_need_turn_off_ckk;
110f1d2b4d3SLarry Finger rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN,
111f1d2b4d3SLarry Finger (u8 *)(&b_support_remote_wake_up));
112f1d2b4d3SLarry Finger
113f1d2b4d3SLarry Finger if (!rtlhal->fw_ready)
114f1d2b4d3SLarry Finger return;
115f1d2b4d3SLarry Finger if (!rtlpriv->psc.fw_current_inpsmode)
116f1d2b4d3SLarry Finger return;
117f1d2b4d3SLarry Finger
118f1d2b4d3SLarry Finger while (1) {
119f1d2b4d3SLarry Finger spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
120f1d2b4d3SLarry Finger if (rtlhal->fw_clk_change_in_progress) {
121f1d2b4d3SLarry Finger while (rtlhal->fw_clk_change_in_progress) {
122f1d2b4d3SLarry Finger spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
123f1d2b4d3SLarry Finger count++;
124f1d2b4d3SLarry Finger udelay(100);
125f1d2b4d3SLarry Finger if (count > 1000)
126f1d2b4d3SLarry Finger return;
127f1d2b4d3SLarry Finger spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
128f1d2b4d3SLarry Finger }
129f1d2b4d3SLarry Finger spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
130f1d2b4d3SLarry Finger } else {
131f1d2b4d3SLarry Finger rtlhal->fw_clk_change_in_progress = false;
132f1d2b4d3SLarry Finger spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
133f1d2b4d3SLarry Finger break;
134f1d2b4d3SLarry Finger }
135f1d2b4d3SLarry Finger }
136f1d2b4d3SLarry Finger
137f1d2b4d3SLarry Finger if (IS_IN_LOW_POWER_STATE(rtlhal->fw_ps_state)) {
138f1d2b4d3SLarry Finger rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM,
139f1d2b4d3SLarry Finger (u8 *)(&rpwm_val));
140f1d2b4d3SLarry Finger if (FW_PS_IS_ACK(rpwm_val)) {
141f1d2b4d3SLarry Finger isr_regaddr = REG_HISR;
142f1d2b4d3SLarry Finger content = rtl_read_dword(rtlpriv, isr_regaddr);
143f1d2b4d3SLarry Finger while (!(content & IMR_CPWM) && (count < 500)) {
144f1d2b4d3SLarry Finger udelay(50);
145f1d2b4d3SLarry Finger count++;
146f1d2b4d3SLarry Finger content = rtl_read_dword(rtlpriv, isr_regaddr);
147f1d2b4d3SLarry Finger }
148e6dd230aSLarry Finger
149f1d2b4d3SLarry Finger if (content & IMR_CPWM) {
150f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, isr_regaddr, 0x0100);
151f1d2b4d3SLarry Finger rtlhal->fw_ps_state = FW_PS_STATE_RF_ON;
152f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
153f1d2b4d3SLarry Finger "Receive CPWM INT!!! Set pHalData->FwPSState = %X\n",
154f1d2b4d3SLarry Finger rtlhal->fw_ps_state);
155f1d2b4d3SLarry Finger }
156f1d2b4d3SLarry Finger }
157f1d2b4d3SLarry Finger
158f1d2b4d3SLarry Finger spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
159f1d2b4d3SLarry Finger rtlhal->fw_clk_change_in_progress = false;
160f1d2b4d3SLarry Finger spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
161f1d2b4d3SLarry Finger if (b_schedule_timer)
162f1d2b4d3SLarry Finger mod_timer(&rtlpriv->works.fw_clockoff_timer,
163f1d2b4d3SLarry Finger jiffies + MSECS(10));
164f1d2b4d3SLarry Finger } else {
165f1d2b4d3SLarry Finger spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
166f1d2b4d3SLarry Finger rtlhal->fw_clk_change_in_progress = false;
167f1d2b4d3SLarry Finger spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
168f1d2b4d3SLarry Finger }
169f1d2b4d3SLarry Finger }
170f1d2b4d3SLarry Finger
_rtl8723be_set_fw_clock_off(struct ieee80211_hw * hw,u8 rpwm_val)171f1d2b4d3SLarry Finger static void _rtl8723be_set_fw_clock_off(struct ieee80211_hw *hw, u8 rpwm_val)
172f1d2b4d3SLarry Finger {
173f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
174f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
175f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
176f1d2b4d3SLarry Finger struct rtl8192_tx_ring *ring;
177f1d2b4d3SLarry Finger enum rf_pwrstate rtstate;
178f1d2b4d3SLarry Finger bool b_schedule_timer = false;
179f1d2b4d3SLarry Finger u8 queue;
180f1d2b4d3SLarry Finger
181f1d2b4d3SLarry Finger if (!rtlhal->fw_ready)
182f1d2b4d3SLarry Finger return;
183f1d2b4d3SLarry Finger if (!rtlpriv->psc.fw_current_inpsmode)
184f1d2b4d3SLarry Finger return;
185f1d2b4d3SLarry Finger if (!rtlhal->allow_sw_to_change_hwclc)
186f1d2b4d3SLarry Finger return;
187f1d2b4d3SLarry Finger rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, (u8 *)(&rtstate));
188f1d2b4d3SLarry Finger if (rtstate == ERFOFF || rtlpriv->psc.inactive_pwrstate == ERFOFF)
189f1d2b4d3SLarry Finger return;
190f1d2b4d3SLarry Finger
191f1d2b4d3SLarry Finger for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) {
192f1d2b4d3SLarry Finger ring = &rtlpci->tx_ring[queue];
193f1d2b4d3SLarry Finger if (skb_queue_len(&ring->queue)) {
194f1d2b4d3SLarry Finger b_schedule_timer = true;
195f1d2b4d3SLarry Finger break;
196f1d2b4d3SLarry Finger }
197f1d2b4d3SLarry Finger }
198f1d2b4d3SLarry Finger
199f1d2b4d3SLarry Finger if (b_schedule_timer) {
200f1d2b4d3SLarry Finger mod_timer(&rtlpriv->works.fw_clockoff_timer,
201f1d2b4d3SLarry Finger jiffies + MSECS(10));
202f1d2b4d3SLarry Finger return;
203f1d2b4d3SLarry Finger }
204f1d2b4d3SLarry Finger
205f1d2b4d3SLarry Finger if (FW_PS_STATE(rtlhal->fw_ps_state) != FW_PS_STATE_RF_OFF_LOW_PWR) {
206f1d2b4d3SLarry Finger spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
207f1d2b4d3SLarry Finger if (!rtlhal->fw_clk_change_in_progress) {
208f1d2b4d3SLarry Finger rtlhal->fw_clk_change_in_progress = true;
209f1d2b4d3SLarry Finger spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
210f1d2b4d3SLarry Finger rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val);
211f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_HISR, 0x0100);
212f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
213f1d2b4d3SLarry Finger (u8 *)(&rpwm_val));
214f1d2b4d3SLarry Finger spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
215f1d2b4d3SLarry Finger rtlhal->fw_clk_change_in_progress = false;
216f1d2b4d3SLarry Finger spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
217f1d2b4d3SLarry Finger } else {
218f1d2b4d3SLarry Finger spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
219f1d2b4d3SLarry Finger mod_timer(&rtlpriv->works.fw_clockoff_timer,
220f1d2b4d3SLarry Finger jiffies + MSECS(10));
221f1d2b4d3SLarry Finger }
222f1d2b4d3SLarry Finger }
223f1d2b4d3SLarry Finger
224f1d2b4d3SLarry Finger }
225f1d2b4d3SLarry Finger
_rtl8723be_set_fw_ps_rf_on(struct ieee80211_hw * hw)226f1d2b4d3SLarry Finger static void _rtl8723be_set_fw_ps_rf_on(struct ieee80211_hw *hw)
227f1d2b4d3SLarry Finger {
228f1d2b4d3SLarry Finger u8 rpwm_val = 0;
229f1d2b4d3SLarry Finger rpwm_val |= (FW_PS_STATE_RF_OFF | FW_PS_ACK);
230f1d2b4d3SLarry Finger _rtl8723be_set_fw_clock_on(hw, rpwm_val, true);
231f1d2b4d3SLarry Finger }
232f1d2b4d3SLarry Finger
_rtl8723be_fwlps_leave(struct ieee80211_hw * hw)233f1d2b4d3SLarry Finger static void _rtl8723be_fwlps_leave(struct ieee80211_hw *hw)
234f1d2b4d3SLarry Finger {
235f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
236f1d2b4d3SLarry Finger struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
237f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
238f1d2b4d3SLarry Finger bool fw_current_inps = false;
239f1d2b4d3SLarry Finger u8 rpwm_val = 0, fw_pwrmode = FW_PS_ACTIVE_MODE;
240f1d2b4d3SLarry Finger
241f1d2b4d3SLarry Finger if (ppsc->low_power_enable) {
242f1d2b4d3SLarry Finger rpwm_val = (FW_PS_STATE_ALL_ON | FW_PS_ACK);/* RF on */
243f1d2b4d3SLarry Finger _rtl8723be_set_fw_clock_on(hw, rpwm_val, false);
244f1d2b4d3SLarry Finger rtlhal->allow_sw_to_change_hwclc = false;
245f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
246f1d2b4d3SLarry Finger (u8 *)(&fw_pwrmode));
247f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
248f1d2b4d3SLarry Finger (u8 *)(&fw_current_inps));
249f1d2b4d3SLarry Finger } else {
250f1d2b4d3SLarry Finger rpwm_val = FW_PS_STATE_ALL_ON; /* RF on */
251f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
252f1d2b4d3SLarry Finger (u8 *)(&rpwm_val));
253f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
254f1d2b4d3SLarry Finger (u8 *)(&fw_pwrmode));
255f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
256f1d2b4d3SLarry Finger (u8 *)(&fw_current_inps));
257f1d2b4d3SLarry Finger }
258f1d2b4d3SLarry Finger
259f1d2b4d3SLarry Finger }
260f1d2b4d3SLarry Finger
_rtl8723be_fwlps_enter(struct ieee80211_hw * hw)261f1d2b4d3SLarry Finger static void _rtl8723be_fwlps_enter(struct ieee80211_hw *hw)
262f1d2b4d3SLarry Finger {
263f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
264f1d2b4d3SLarry Finger struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
265f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
266f1d2b4d3SLarry Finger bool fw_current_inps = true;
267f1d2b4d3SLarry Finger u8 rpwm_val;
268f1d2b4d3SLarry Finger
269f1d2b4d3SLarry Finger if (ppsc->low_power_enable) {
270f1d2b4d3SLarry Finger rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR; /* RF off */
271f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
272f1d2b4d3SLarry Finger (u8 *)(&fw_current_inps));
273f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
274f1d2b4d3SLarry Finger (u8 *)(&ppsc->fwctrl_psmode));
275f1d2b4d3SLarry Finger rtlhal->allow_sw_to_change_hwclc = true;
276f1d2b4d3SLarry Finger _rtl8723be_set_fw_clock_off(hw, rpwm_val);
277f1d2b4d3SLarry Finger } else {
278f1d2b4d3SLarry Finger rpwm_val = FW_PS_STATE_RF_OFF; /* RF off */
279f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
280f1d2b4d3SLarry Finger (u8 *)(&fw_current_inps));
281f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
282f1d2b4d3SLarry Finger (u8 *)(&ppsc->fwctrl_psmode));
283f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
284f1d2b4d3SLarry Finger (u8 *)(&rpwm_val));
285f1d2b4d3SLarry Finger }
286f1d2b4d3SLarry Finger
287f1d2b4d3SLarry Finger }
288f1d2b4d3SLarry Finger
rtl8723be_get_hw_reg(struct ieee80211_hw * hw,u8 variable,u8 * val)289f1d2b4d3SLarry Finger void rtl8723be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
290f1d2b4d3SLarry Finger {
291f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
292f1d2b4d3SLarry Finger struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
293f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
294f1d2b4d3SLarry Finger
295f1d2b4d3SLarry Finger switch (variable) {
296f1d2b4d3SLarry Finger case HW_VAR_RCR:
297f1d2b4d3SLarry Finger *((u32 *)(val)) = rtlpci->receive_config;
298f1d2b4d3SLarry Finger break;
29992a1aa25SLarry Finger case HW_VAR_RF_STATE:
300f1d2b4d3SLarry Finger *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
301f1d2b4d3SLarry Finger break;
302f1d2b4d3SLarry Finger case HW_VAR_FWLPS_RF_ON:{
30392a1aa25SLarry Finger enum rf_pwrstate rfstate;
30492a1aa25SLarry Finger u32 val_rcr;
305f1d2b4d3SLarry Finger
306f1d2b4d3SLarry Finger rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE,
307f1d2b4d3SLarry Finger (u8 *)(&rfstate));
308f1d2b4d3SLarry Finger if (rfstate == ERFOFF) {
309f1d2b4d3SLarry Finger *((bool *)(val)) = true;
310f1d2b4d3SLarry Finger } else {
311f1d2b4d3SLarry Finger val_rcr = rtl_read_dword(rtlpriv, REG_RCR);
312f1d2b4d3SLarry Finger val_rcr &= 0x00070000;
313f1d2b4d3SLarry Finger if (val_rcr)
314f1d2b4d3SLarry Finger *((bool *)(val)) = false;
315f1d2b4d3SLarry Finger else
316f1d2b4d3SLarry Finger *((bool *)(val)) = true;
317f1d2b4d3SLarry Finger }
318f1d2b4d3SLarry Finger }
319f1d2b4d3SLarry Finger break;
320f1d2b4d3SLarry Finger case HW_VAR_FW_PSMODE_STATUS:
321f1d2b4d3SLarry Finger *((bool *)(val)) = ppsc->fw_current_inpsmode;
322f1d2b4d3SLarry Finger break;
323f1d2b4d3SLarry Finger case HW_VAR_CORRECT_TSF:{
324f1d2b4d3SLarry Finger u64 tsf;
325f1d2b4d3SLarry Finger u32 *ptsf_low = (u32 *)&tsf;
326f1d2b4d3SLarry Finger u32 *ptsf_high = ((u32 *)&tsf) + 1;
327f1d2b4d3SLarry Finger
328f1d2b4d3SLarry Finger *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4));
329f1d2b4d3SLarry Finger *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
3301cc49a5bSLarry Finger
3311cc49a5bSLarry Finger *((u64 *)(val)) = tsf;
332f1d2b4d3SLarry Finger }
333e6dd230aSLarry Finger break;
334ad574889SJoe Perches case HAL_DEF_WOWLAN:
335f1d2b4d3SLarry Finger break;
336f1d2b4d3SLarry Finger default:
337f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
338f1d2b4d3SLarry Finger "switch case %#x not processed\n", variable);
339f1d2b4d3SLarry Finger break;
340f1d2b4d3SLarry Finger }
341f1d2b4d3SLarry Finger }
342f1d2b4d3SLarry Finger
_rtl8723be_download_rsvd_page(struct ieee80211_hw * hw)343f1d2b4d3SLarry Finger static void _rtl8723be_download_rsvd_page(struct ieee80211_hw *hw)
344f1d2b4d3SLarry Finger {
345f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
346f1d2b4d3SLarry Finger u8 tmp_regcr, tmp_reg422, bcnvalid_reg;
347f1d2b4d3SLarry Finger u8 count = 0, dlbcn_count = 0;
348f1d2b4d3SLarry Finger bool b_recover = false;
349f1d2b4d3SLarry Finger
350f1d2b4d3SLarry Finger tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
351f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_CR + 1,
352f1d2b4d3SLarry Finger (tmp_regcr | BIT(0)));
353f1d2b4d3SLarry Finger
354f1d2b4d3SLarry Finger _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3));
355f1d2b4d3SLarry Finger _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0);
356f1d2b4d3SLarry Finger
357f1d2b4d3SLarry Finger tmp_reg422 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
358f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422 & (~BIT(6)));
359f1d2b4d3SLarry Finger if (tmp_reg422 & BIT(6))
360f1d2b4d3SLarry Finger b_recover = true;
361f1d2b4d3SLarry Finger
362f1d2b4d3SLarry Finger do {
363f1d2b4d3SLarry Finger bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL + 2);
364f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_TDECTRL + 2,
365f1d2b4d3SLarry Finger (bcnvalid_reg | BIT(0)));
366f1d2b4d3SLarry Finger _rtl8723be_return_beacon_queue_skb(hw);
367f1d2b4d3SLarry Finger
368f1d2b4d3SLarry Finger rtl8723be_set_fw_rsvdpagepkt(hw, 0);
369f1d2b4d3SLarry Finger bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL + 2);
370f1d2b4d3SLarry Finger count = 0;
371f1d2b4d3SLarry Finger while (!(bcnvalid_reg & BIT(0)) && count < 20) {
372f1d2b4d3SLarry Finger count++;
373f1d2b4d3SLarry Finger udelay(10);
374f1d2b4d3SLarry Finger bcnvalid_reg = rtl_read_byte(rtlpriv,
375f1d2b4d3SLarry Finger REG_TDECTRL + 2);
376f1d2b4d3SLarry Finger }
377f1d2b4d3SLarry Finger dlbcn_count++;
378f1d2b4d3SLarry Finger } while (!(bcnvalid_reg & BIT(0)) && dlbcn_count < 5);
379f1d2b4d3SLarry Finger
380f1d2b4d3SLarry Finger if (bcnvalid_reg & BIT(0))
381f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_TDECTRL + 2, BIT(0));
382f1d2b4d3SLarry Finger
383f1d2b4d3SLarry Finger _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
384f1d2b4d3SLarry Finger _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4));
385f1d2b4d3SLarry Finger
386f1d2b4d3SLarry Finger if (b_recover)
387f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422);
388f1d2b4d3SLarry Finger
389f1d2b4d3SLarry Finger tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
390f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_CR + 1, (tmp_regcr & ~(BIT(0))));
391f1d2b4d3SLarry Finger }
392f1d2b4d3SLarry Finger
rtl8723be_set_hw_reg(struct ieee80211_hw * hw,u8 variable,u8 * val)393f1d2b4d3SLarry Finger void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
394f1d2b4d3SLarry Finger {
395f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
396f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
397f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
398f1d2b4d3SLarry Finger struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
399f1d2b4d3SLarry Finger struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
400f1d2b4d3SLarry Finger u8 idx;
401f1d2b4d3SLarry Finger
402f1d2b4d3SLarry Finger switch (variable) {
403f1d2b4d3SLarry Finger case HW_VAR_ETHER_ADDR:
404f1d2b4d3SLarry Finger for (idx = 0; idx < ETH_ALEN; idx++)
405f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, (REG_MACID + idx), val[idx]);
406f1d2b4d3SLarry Finger break;
407f1d2b4d3SLarry Finger case HW_VAR_BASIC_RATE:{
408f1d2b4d3SLarry Finger u16 b_rate_cfg = ((u16 *)val)[0];
409f1d2b4d3SLarry Finger u8 rate_index = 0;
410f1d2b4d3SLarry Finger b_rate_cfg = b_rate_cfg & 0x15f;
411f1d2b4d3SLarry Finger b_rate_cfg |= 0x01;
412f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff);
413f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_RRSR + 1, (b_rate_cfg >> 8) & 0xff);
414f1d2b4d3SLarry Finger while (b_rate_cfg > 0x1) {
415f1d2b4d3SLarry Finger b_rate_cfg = (b_rate_cfg >> 1);
416f1d2b4d3SLarry Finger rate_index++;
417f1d2b4d3SLarry Finger }
418f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, rate_index);
419f1d2b4d3SLarry Finger }
420f1d2b4d3SLarry Finger break;
421f1d2b4d3SLarry Finger case HW_VAR_BSSID:
422f1d2b4d3SLarry Finger for (idx = 0; idx < ETH_ALEN; idx++)
423f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, (REG_BSSID + idx), val[idx]);
424f1d2b4d3SLarry Finger
425f1d2b4d3SLarry Finger break;
426f1d2b4d3SLarry Finger case HW_VAR_SIFS:
427f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]);
428f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]);
429f1d2b4d3SLarry Finger
430f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]);
431f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
432f1d2b4d3SLarry Finger
433f1d2b4d3SLarry Finger if (!mac->ht_enable)
434f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, 0x0e0e);
435f1d2b4d3SLarry Finger else
436f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
437f1d2b4d3SLarry Finger *((u16 *)val));
438e6dd230aSLarry Finger break;
439f1d2b4d3SLarry Finger case HW_VAR_SLOT_TIME:{
440f1d2b4d3SLarry Finger u8 e_aci;
441f1d2b4d3SLarry Finger
442f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD,
443f1d2b4d3SLarry Finger "HW_VAR_SLOT_TIME %x\n", val[0]);
444f1d2b4d3SLarry Finger
445f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
446f1d2b4d3SLarry Finger
447f1d2b4d3SLarry Finger for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
448f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
449f1d2b4d3SLarry Finger (u8 *)(&e_aci));
450f1d2b4d3SLarry Finger }
451f1d2b4d3SLarry Finger }
452f1d2b4d3SLarry Finger break;
453f1d2b4d3SLarry Finger case HW_VAR_ACK_PREAMBLE:{
454f1d2b4d3SLarry Finger u8 reg_tmp;
455f1d2b4d3SLarry Finger u8 short_preamble = (bool)(*(u8 *)val);
456f1d2b4d3SLarry Finger reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL + 2);
457f1d2b4d3SLarry Finger if (short_preamble) {
458f1d2b4d3SLarry Finger reg_tmp |= 0x02;
459f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
460f1d2b4d3SLarry Finger } else {
461f1d2b4d3SLarry Finger reg_tmp &= 0xFD;
462f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
463f1d2b4d3SLarry Finger }
464f1d2b4d3SLarry Finger }
465f1d2b4d3SLarry Finger break;
466f1d2b4d3SLarry Finger case HW_VAR_WPA_CONFIG:
467f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val));
468f1d2b4d3SLarry Finger break;
469f1d2b4d3SLarry Finger case HW_VAR_AMPDU_MIN_SPACE:{
470f1d2b4d3SLarry Finger u8 min_spacing_to_set;
471f1d2b4d3SLarry Finger u8 sec_min_space;
472f1d2b4d3SLarry Finger
473f1d2b4d3SLarry Finger min_spacing_to_set = *((u8 *)val);
474f1d2b4d3SLarry Finger if (min_spacing_to_set <= 7) {
475f1d2b4d3SLarry Finger sec_min_space = 0;
476f1d2b4d3SLarry Finger
477f1d2b4d3SLarry Finger if (min_spacing_to_set < sec_min_space)
478f1d2b4d3SLarry Finger min_spacing_to_set = sec_min_space;
479f1d2b4d3SLarry Finger
480f1d2b4d3SLarry Finger mac->min_space_cfg = ((mac->min_space_cfg & 0xf8) |
481e6dd230aSLarry Finger min_spacing_to_set);
482f1d2b4d3SLarry Finger
483f1d2b4d3SLarry Finger *val = min_spacing_to_set;
484f1d2b4d3SLarry Finger
485f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD,
486f1d2b4d3SLarry Finger "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
487f1d2b4d3SLarry Finger mac->min_space_cfg);
488f1d2b4d3SLarry Finger
489f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
490f1d2b4d3SLarry Finger mac->min_space_cfg);
491f1d2b4d3SLarry Finger }
492f1d2b4d3SLarry Finger }
493f1d2b4d3SLarry Finger break;
494f1d2b4d3SLarry Finger case HW_VAR_SHORTGI_DENSITY:{
495f1d2b4d3SLarry Finger u8 density_to_set;
496e6dd230aSLarry Finger
497f1d2b4d3SLarry Finger density_to_set = *((u8 *)val);
498f1d2b4d3SLarry Finger mac->min_space_cfg |= (density_to_set << 3);
499f1d2b4d3SLarry Finger
500f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD,
501f1d2b4d3SLarry Finger "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
502f1d2b4d3SLarry Finger mac->min_space_cfg);
503f1d2b4d3SLarry Finger
504f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
505f1d2b4d3SLarry Finger mac->min_space_cfg);
506f1d2b4d3SLarry Finger }
507f1d2b4d3SLarry Finger break;
508f1d2b4d3SLarry Finger case HW_VAR_AMPDU_FACTOR:{
509f1d2b4d3SLarry Finger u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9};
510f1d2b4d3SLarry Finger u8 factor_toset;
511f1d2b4d3SLarry Finger u8 *p_regtoset = NULL;
512f1d2b4d3SLarry Finger u8 index = 0;
513f1d2b4d3SLarry Finger
514f1d2b4d3SLarry Finger p_regtoset = regtoset_normal;
515f1d2b4d3SLarry Finger
516f1d2b4d3SLarry Finger factor_toset = *((u8 *)val);
517f1d2b4d3SLarry Finger if (factor_toset <= 3) {
518f1d2b4d3SLarry Finger factor_toset = (1 << (factor_toset + 2));
519f1d2b4d3SLarry Finger if (factor_toset > 0xf)
520f1d2b4d3SLarry Finger factor_toset = 0xf;
521f1d2b4d3SLarry Finger
522f1d2b4d3SLarry Finger for (index = 0; index < 4; index++) {
523f1d2b4d3SLarry Finger if ((p_regtoset[index] & 0xf0) >
524f1d2b4d3SLarry Finger (factor_toset << 4))
525f1d2b4d3SLarry Finger p_regtoset[index] =
526f1d2b4d3SLarry Finger (p_regtoset[index] & 0x0f) |
527f1d2b4d3SLarry Finger (factor_toset << 4);
528f1d2b4d3SLarry Finger
529f1d2b4d3SLarry Finger if ((p_regtoset[index] & 0x0f) > factor_toset)
530f1d2b4d3SLarry Finger p_regtoset[index] =
531f1d2b4d3SLarry Finger (p_regtoset[index] & 0xf0) |
532f1d2b4d3SLarry Finger (factor_toset);
533f1d2b4d3SLarry Finger
534f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv,
535f1d2b4d3SLarry Finger (REG_AGGLEN_LMT + index),
536e6dd230aSLarry Finger p_regtoset[index]);
537f1d2b4d3SLarry Finger
538f1d2b4d3SLarry Finger }
539f1d2b4d3SLarry Finger
540f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD,
541f1d2b4d3SLarry Finger "Set HW_VAR_AMPDU_FACTOR: %#x\n",
542f1d2b4d3SLarry Finger factor_toset);
543f1d2b4d3SLarry Finger }
544f1d2b4d3SLarry Finger }
545f1d2b4d3SLarry Finger break;
546f1d2b4d3SLarry Finger case HW_VAR_AC_PARAM:{
547f1d2b4d3SLarry Finger u8 e_aci = *((u8 *)val);
548f1d2b4d3SLarry Finger rtl8723_dm_init_edca_turbo(hw);
549f1d2b4d3SLarry Finger
550f1d2b4d3SLarry Finger if (rtlpci->acm_method != EACMWAY2_SW)
551f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
552f1d2b4d3SLarry Finger (u8 *)(&e_aci));
553f1d2b4d3SLarry Finger }
554f1d2b4d3SLarry Finger break;
555f1d2b4d3SLarry Finger case HW_VAR_ACM_CTRL:{
556f1d2b4d3SLarry Finger u8 e_aci = *((u8 *)val);
557f1d2b4d3SLarry Finger union aci_aifsn *p_aci_aifsn =
558f1d2b4d3SLarry Finger (union aci_aifsn *)(&(mac->ac[0].aifs));
559f1d2b4d3SLarry Finger u8 acm = p_aci_aifsn->f.acm;
560f1d2b4d3SLarry Finger u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);
561f1d2b4d3SLarry Finger
562f1d2b4d3SLarry Finger acm_ctrl =
563f1d2b4d3SLarry Finger acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1);
564f1d2b4d3SLarry Finger
565f1d2b4d3SLarry Finger if (acm) {
566f1d2b4d3SLarry Finger switch (e_aci) {
567f1d2b4d3SLarry Finger case AC0_BE:
568f1d2b4d3SLarry Finger acm_ctrl |= ACMHW_BEQEN;
569f1d2b4d3SLarry Finger break;
570f1d2b4d3SLarry Finger case AC2_VI:
571f1d2b4d3SLarry Finger acm_ctrl |= ACMHW_VIQEN;
572f1d2b4d3SLarry Finger break;
573e6dd230aSLarry Finger case AC3_VO:
574f1d2b4d3SLarry Finger acm_ctrl |= ACMHW_VOQEN;
575f1d2b4d3SLarry Finger break;
576f1d2b4d3SLarry Finger default:
577f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
578f1d2b4d3SLarry Finger "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
579f1d2b4d3SLarry Finger acm);
580f1d2b4d3SLarry Finger break;
581f1d2b4d3SLarry Finger }
582f1d2b4d3SLarry Finger } else {
583f1d2b4d3SLarry Finger switch (e_aci) {
584f1d2b4d3SLarry Finger case AC0_BE:
585f1d2b4d3SLarry Finger acm_ctrl &= (~ACMHW_BEQEN);
586f1d2b4d3SLarry Finger break;
587f1d2b4d3SLarry Finger case AC2_VI:
588f1d2b4d3SLarry Finger acm_ctrl &= (~ACMHW_VIQEN);
589f1d2b4d3SLarry Finger break;
590e6dd230aSLarry Finger case AC3_VO:
591ad574889SJoe Perches acm_ctrl &= (~ACMHW_VOQEN);
592ad574889SJoe Perches break;
593f1d2b4d3SLarry Finger default:
594f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
595f1d2b4d3SLarry Finger "switch case %#x not processed\n",
596f1d2b4d3SLarry Finger e_aci);
597e6dd230aSLarry Finger break;
598f1d2b4d3SLarry Finger }
599f1d2b4d3SLarry Finger }
600f1d2b4d3SLarry Finger
601f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_QOS, DBG_TRACE,
602f1d2b4d3SLarry Finger "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
603f1d2b4d3SLarry Finger acm_ctrl);
604f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
605f1d2b4d3SLarry Finger }
606f1d2b4d3SLarry Finger break;
607f1d2b4d3SLarry Finger case HW_VAR_RCR:
608f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_RCR, ((u32 *)(val))[0]);
609f1d2b4d3SLarry Finger rtlpci->receive_config = ((u32 *)(val))[0];
610f1d2b4d3SLarry Finger break;
611f1d2b4d3SLarry Finger case HW_VAR_RETRY_LIMIT:{
612f1d2b4d3SLarry Finger u8 retry_limit = ((u8 *)(val))[0];
613f1d2b4d3SLarry Finger
614f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_RL,
615f1d2b4d3SLarry Finger retry_limit << RETRY_LIMIT_SHORT_SHIFT |
616f1d2b4d3SLarry Finger retry_limit << RETRY_LIMIT_LONG_SHIFT);
617f1d2b4d3SLarry Finger }
618f1d2b4d3SLarry Finger break;
619f1d2b4d3SLarry Finger case HW_VAR_DUAL_TSF_RST:
620f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
621f1d2b4d3SLarry Finger break;
622f1d2b4d3SLarry Finger case HW_VAR_EFUSE_BYTES:
623f1d2b4d3SLarry Finger rtlefuse->efuse_usedbytes = *((u16 *)val);
624f1d2b4d3SLarry Finger break;
625f1d2b4d3SLarry Finger case HW_VAR_EFUSE_USAGE:
626f1d2b4d3SLarry Finger rtlefuse->efuse_usedpercentage = *((u8 *)val);
627f1d2b4d3SLarry Finger break;
628f1d2b4d3SLarry Finger case HW_VAR_IO_CMD:
629f1d2b4d3SLarry Finger rtl8723be_phy_set_io_cmd(hw, (*(enum io_type *)val));
630f1d2b4d3SLarry Finger break;
631f1d2b4d3SLarry Finger case HW_VAR_SET_RPWM:{
632f1d2b4d3SLarry Finger u8 rpwm_val;
633f1d2b4d3SLarry Finger
634f1d2b4d3SLarry Finger rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM);
635f1d2b4d3SLarry Finger udelay(1);
636f1d2b4d3SLarry Finger
637f1d2b4d3SLarry Finger if (rpwm_val & BIT(7)) {
638f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, (*(u8 *)val));
639f1d2b4d3SLarry Finger } else {
640f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
641f1d2b4d3SLarry Finger ((*(u8 *)val) | BIT(7)));
642f1d2b4d3SLarry Finger }
643f1d2b4d3SLarry Finger }
644f1d2b4d3SLarry Finger break;
645f1d2b4d3SLarry Finger case HW_VAR_H2C_FW_PWRMODE:
646f1d2b4d3SLarry Finger rtl8723be_set_fw_pwrmode_cmd(hw, (*(u8 *)val));
647f1d2b4d3SLarry Finger break;
648f1d2b4d3SLarry Finger case HW_VAR_FW_PSMODE_STATUS:
649f1d2b4d3SLarry Finger ppsc->fw_current_inpsmode = *((bool *)val);
650f1d2b4d3SLarry Finger break;
651f1d2b4d3SLarry Finger case HW_VAR_RESUME_CLK_ON:
652f1d2b4d3SLarry Finger _rtl8723be_set_fw_ps_rf_on(hw);
653f1d2b4d3SLarry Finger break;
654f1d2b4d3SLarry Finger case HW_VAR_FW_LPS_ACTION:{
655f1d2b4d3SLarry Finger bool b_enter_fwlps = *((bool *)val);
656f1d2b4d3SLarry Finger
657f1d2b4d3SLarry Finger if (b_enter_fwlps)
658f1d2b4d3SLarry Finger _rtl8723be_fwlps_enter(hw);
659f1d2b4d3SLarry Finger else
660f1d2b4d3SLarry Finger _rtl8723be_fwlps_leave(hw);
661f1d2b4d3SLarry Finger }
662f1d2b4d3SLarry Finger break;
663f1d2b4d3SLarry Finger case HW_VAR_H2C_FW_JOINBSSRPT:{
664f1d2b4d3SLarry Finger u8 mstatus = (*(u8 *)val);
665f1d2b4d3SLarry Finger
666f1d2b4d3SLarry Finger if (mstatus == RT_MEDIA_CONNECT) {
667f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL);
668f1d2b4d3SLarry Finger _rtl8723be_download_rsvd_page(hw);
669f1d2b4d3SLarry Finger }
670f1d2b4d3SLarry Finger rtl8723be_set_fw_media_status_rpt_cmd(hw, mstatus);
671f1d2b4d3SLarry Finger }
672f1d2b4d3SLarry Finger break;
673f1d2b4d3SLarry Finger case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
674f1d2b4d3SLarry Finger rtl8723be_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
675f1d2b4d3SLarry Finger break;
676f1d2b4d3SLarry Finger case HW_VAR_AID:{
677f1d2b4d3SLarry Finger u16 u2btmp;
678f1d2b4d3SLarry Finger u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
679f1d2b4d3SLarry Finger u2btmp &= 0xC000;
680f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_BCN_PSR_RPT,
681f1d2b4d3SLarry Finger (u2btmp | mac->assoc_id));
682f1d2b4d3SLarry Finger }
683f1d2b4d3SLarry Finger break;
684f1d2b4d3SLarry Finger case HW_VAR_CORRECT_TSF:{
685f1d2b4d3SLarry Finger u8 btype_ibss = ((u8 *)(val))[0];
686f1d2b4d3SLarry Finger
687f1d2b4d3SLarry Finger if (btype_ibss)
688f1d2b4d3SLarry Finger _rtl8723be_stop_tx_beacon(hw);
689f1d2b4d3SLarry Finger
690f1d2b4d3SLarry Finger _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3));
691f1d2b4d3SLarry Finger
692f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_TSFTR,
693f1d2b4d3SLarry Finger (u32) (mac->tsf & 0xffffffff));
694f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_TSFTR + 4,
695f1d2b4d3SLarry Finger (u32) ((mac->tsf >> 32) & 0xffffffff));
696f1d2b4d3SLarry Finger
697f1d2b4d3SLarry Finger _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
698f1d2b4d3SLarry Finger
699f1d2b4d3SLarry Finger if (btype_ibss)
700f1d2b4d3SLarry Finger _rtl8723be_resume_tx_beacon(hw);
701f1d2b4d3SLarry Finger }
702f1d2b4d3SLarry Finger break;
703f1d2b4d3SLarry Finger case HW_VAR_KEEP_ALIVE:{
704f1d2b4d3SLarry Finger u8 array[2];
705f1d2b4d3SLarry Finger array[0] = 0xff;
706f1d2b4d3SLarry Finger array[1] = *((u8 *)val);
707e6dd230aSLarry Finger rtl8723be_fill_h2c_cmd(hw, H2C_8723B_KEEP_ALIVE_CTRL, 2, array);
708ad574889SJoe Perches }
709f1d2b4d3SLarry Finger break;
710f1d2b4d3SLarry Finger default:
711f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
712f1d2b4d3SLarry Finger "switch case %#x not processed\n", variable);
713f1d2b4d3SLarry Finger break;
714f1d2b4d3SLarry Finger }
715f1d2b4d3SLarry Finger }
716f1d2b4d3SLarry Finger
_rtl8723be_llt_write(struct ieee80211_hw * hw,u32 address,u32 data)717f1d2b4d3SLarry Finger static bool _rtl8723be_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
718f1d2b4d3SLarry Finger {
719f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
720f1d2b4d3SLarry Finger bool status = true;
721f1d2b4d3SLarry Finger long count = 0;
722f1d2b4d3SLarry Finger u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) |
723f1d2b4d3SLarry Finger _LLT_OP(_LLT_WRITE_ACCESS);
724f1d2b4d3SLarry Finger
725f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
726f1d2b4d3SLarry Finger
727f1d2b4d3SLarry Finger do {
728f1d2b4d3SLarry Finger value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
7294e2b4378SLarry Finger if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
730f1d2b4d3SLarry Finger break;
731f1d2b4d3SLarry Finger
732f1d2b4d3SLarry Finger if (count > POLLING_LLT_THRESHOLD) {
733f1d2b4d3SLarry Finger pr_err("Failed to polling write LLT done at address %d!\n",
734f1d2b4d3SLarry Finger address);
735f1d2b4d3SLarry Finger status = false;
736f1d2b4d3SLarry Finger break;
737f1d2b4d3SLarry Finger }
738f1d2b4d3SLarry Finger } while (++count);
739f1d2b4d3SLarry Finger
740f1d2b4d3SLarry Finger return status;
741f1d2b4d3SLarry Finger }
742f1d2b4d3SLarry Finger
_rtl8723be_llt_table_init(struct ieee80211_hw * hw)743f1d2b4d3SLarry Finger static bool _rtl8723be_llt_table_init(struct ieee80211_hw *hw)
74492a1aa25SLarry Finger {
745f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
746f1d2b4d3SLarry Finger unsigned short i;
74792a1aa25SLarry Finger u8 txpktbuf_bndy;
748f1d2b4d3SLarry Finger u8 maxpage;
749f1d2b4d3SLarry Finger bool status;
750f1d2b4d3SLarry Finger
751f1d2b4d3SLarry Finger maxpage = 255;
752f1d2b4d3SLarry Finger txpktbuf_bndy = 245;
753f1d2b4d3SLarry Finger
754f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_TRXFF_BNDY,
755f1d2b4d3SLarry Finger (0x27FF0000 | txpktbuf_bndy));
756f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy);
757f1d2b4d3SLarry Finger
758f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
759f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
760f1d2b4d3SLarry Finger
761f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy);
762f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_PBP, 0x31);
763f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);
764f1d2b4d3SLarry Finger
765f1d2b4d3SLarry Finger for (i = 0; i < (txpktbuf_bndy - 1); i++) {
766f1d2b4d3SLarry Finger status = _rtl8723be_llt_write(hw, i, i + 1);
767f1d2b4d3SLarry Finger if (!status)
768f1d2b4d3SLarry Finger return status;
769f1d2b4d3SLarry Finger }
770f1d2b4d3SLarry Finger
771f1d2b4d3SLarry Finger status = _rtl8723be_llt_write(hw, (txpktbuf_bndy - 1), 0xFF);
77292a1aa25SLarry Finger
773f1d2b4d3SLarry Finger if (!status)
774f1d2b4d3SLarry Finger return status;
775f1d2b4d3SLarry Finger
776f1d2b4d3SLarry Finger for (i = txpktbuf_bndy; i < maxpage; i++) {
777f1d2b4d3SLarry Finger status = _rtl8723be_llt_write(hw, i, (i + 1));
77892a1aa25SLarry Finger if (!status)
779f1d2b4d3SLarry Finger return status;
780f1d2b4d3SLarry Finger }
781f1d2b4d3SLarry Finger
782f1d2b4d3SLarry Finger status = _rtl8723be_llt_write(hw, maxpage, txpktbuf_bndy);
783f1d2b4d3SLarry Finger if (!status)
784f1d2b4d3SLarry Finger return status;
785f1d2b4d3SLarry Finger
786f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_RQPN, 0x80e40808);
787f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x00);
788f1d2b4d3SLarry Finger
789f1d2b4d3SLarry Finger return true;
790f1d2b4d3SLarry Finger }
791f1d2b4d3SLarry Finger
_rtl8723be_gen_refresh_led_state(struct ieee80211_hw * hw)792d5efe153SLarry Finger static void _rtl8723be_gen_refresh_led_state(struct ieee80211_hw *hw)
793f1d2b4d3SLarry Finger {
794f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
795f1d2b4d3SLarry Finger struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
796f1d2b4d3SLarry Finger enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0;
797f1d2b4d3SLarry Finger
798f1d2b4d3SLarry Finger if (rtlpriv->rtlhal.up_first_time)
799f1d2b4d3SLarry Finger return;
800f1d2b4d3SLarry Finger
801f1d2b4d3SLarry Finger if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
802f1d2b4d3SLarry Finger rtl8723be_sw_led_on(hw, pin0);
803f1d2b4d3SLarry Finger else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT)
804f1d2b4d3SLarry Finger rtl8723be_sw_led_on(hw, pin0);
805f1d2b4d3SLarry Finger else
806f1d2b4d3SLarry Finger rtl8723be_sw_led_off(hw, pin0);
807f1d2b4d3SLarry Finger }
808f1d2b4d3SLarry Finger
_rtl8723be_init_mac(struct ieee80211_hw * hw)809f1d2b4d3SLarry Finger static bool _rtl8723be_init_mac(struct ieee80211_hw *hw)
810f1d2b4d3SLarry Finger {
811f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
812f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
813f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
814f1d2b4d3SLarry Finger unsigned char bytetmp;
815f1d2b4d3SLarry Finger unsigned short wordtmp;
816f1d2b4d3SLarry Finger
817f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
818f1d2b4d3SLarry Finger
819f1d2b4d3SLarry Finger /*Auto Power Down to CHIP-off State*/
820f1d2b4d3SLarry Finger bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) & (~BIT(7));
821f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp);
822f1d2b4d3SLarry Finger
823e6dd230aSLarry Finger /* HW Power on sequence */
824f1d2b4d3SLarry Finger if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK,
825f1d2b4d3SLarry Finger PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,
826f1d2b4d3SLarry Finger RTL8723_NIC_ENABLE_FLOW)) {
827f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
828af8a41ccSPing-Ke Shih "init MAC Fail as power on failure\n");
829af8a41ccSPing-Ke Shih return false;
830af8a41ccSPing-Ke Shih }
831f1d2b4d3SLarry Finger
832f1d2b4d3SLarry Finger if (rtlpriv->cfg->ops->get_btc_status())
833f1d2b4d3SLarry Finger rtlpriv->btcoexist.btc_ops->btc_power_on_setting(rtlpriv);
834f1d2b4d3SLarry Finger
835f1d2b4d3SLarry Finger bytetmp = rtl_read_byte(rtlpriv, REG_MULTI_FUNC_CTRL);
836f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_MULTI_FUNC_CTRL, bytetmp | BIT(3));
837f1d2b4d3SLarry Finger
838f1d2b4d3SLarry Finger bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO) | BIT(4);
839f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_APS_FSMCO, bytetmp);
840f1d2b4d3SLarry Finger
841f1d2b4d3SLarry Finger bytetmp = rtl_read_byte(rtlpriv, REG_CR);
842f1d2b4d3SLarry Finger bytetmp = 0xff;
843f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_CR, bytetmp);
844f1d2b4d3SLarry Finger mdelay(2);
845f1d2b4d3SLarry Finger
846f1d2b4d3SLarry Finger bytetmp = rtl_read_byte(rtlpriv, REG_HWSEQ_CTRL);
847f1d2b4d3SLarry Finger bytetmp |= 0x7f;
848f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, bytetmp);
849f1d2b4d3SLarry Finger mdelay(2);
850f1d2b4d3SLarry Finger
851f1d2b4d3SLarry Finger bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CFG + 3);
852f1d2b4d3SLarry Finger if (bytetmp & BIT(0)) {
853f1d2b4d3SLarry Finger bytetmp = rtl_read_byte(rtlpriv, 0x7c);
854f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x7c, bytetmp | BIT(6));
855f1d2b4d3SLarry Finger }
856f1d2b4d3SLarry Finger
857f1d2b4d3SLarry Finger bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CLKR);
858f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_CLKR, bytetmp | BIT(3));
859f1d2b4d3SLarry Finger bytetmp = rtl_read_byte(rtlpriv, REG_GPIO_MUXCFG + 1);
860f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG + 1, bytetmp & (~BIT(4)));
86102686841SZheng Bin
862f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_CR, 0x2ff);
863f1d2b4d3SLarry Finger
864f1d2b4d3SLarry Finger if (!rtlhal->mac_func_enable) {
865f1d2b4d3SLarry Finger if (!_rtl8723be_llt_table_init(hw))
866f1d2b4d3SLarry Finger return false;
867f1d2b4d3SLarry Finger }
868f1d2b4d3SLarry Finger
869f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
870f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_HISRE, 0xffffffff);
871f1d2b4d3SLarry Finger
872f1d2b4d3SLarry Finger /* Enable FW Beamformer Interrupt */
873f1d2b4d3SLarry Finger bytetmp = rtl_read_byte(rtlpriv, REG_FWIMR + 3);
874f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_FWIMR + 3, bytetmp | BIT(6));
875f1d2b4d3SLarry Finger
876f1d2b4d3SLarry Finger wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL);
877f1d2b4d3SLarry Finger wordtmp &= 0xf;
878f1d2b4d3SLarry Finger wordtmp |= 0xF5B1;
879f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp);
880f1d2b4d3SLarry Finger
881f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F);
882f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
883f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xFFFF);
884f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config);
885f1d2b4d3SLarry Finger
886f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_BCNQ_DESA,
887f1d2b4d3SLarry Finger ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) &
888f1d2b4d3SLarry Finger DMA_BIT_MASK(32));
889f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_MGQ_DESA,
890f1d2b4d3SLarry Finger (u64) rtlpci->tx_ring[MGNT_QUEUE].dma &
891f1d2b4d3SLarry Finger DMA_BIT_MASK(32));
892f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_VOQ_DESA,
893f1d2b4d3SLarry Finger (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32));
894f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_VIQ_DESA,
895f1d2b4d3SLarry Finger (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32));
896f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_BEQ_DESA,
897f1d2b4d3SLarry Finger (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32));
898f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_BKQ_DESA,
899f1d2b4d3SLarry Finger (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32));
900f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_HQ_DESA,
901f1d2b4d3SLarry Finger (u64) rtlpci->tx_ring[HIGH_QUEUE].dma &
902f1d2b4d3SLarry Finger DMA_BIT_MASK(32));
903f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_RX_DESA,
904f1d2b4d3SLarry Finger (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma &
905f1d2b4d3SLarry Finger DMA_BIT_MASK(32));
906f1d2b4d3SLarry Finger
907f1d2b4d3SLarry Finger bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 3);
908f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, bytetmp | 0x77);
909f1d2b4d3SLarry Finger
910f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_INT_MIG, 0);
911f1d2b4d3SLarry Finger
912f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0);
913f1d2b4d3SLarry Finger
914f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SECONDARY_CCA_CTRL, 0x3);
915f1d2b4d3SLarry Finger
916f1d2b4d3SLarry Finger /* <20130114, Kordan> The following setting is
917f1d2b4d3SLarry Finger * only for DPDT and Fixed board type.
918f1d2b4d3SLarry Finger * TODO: A better solution is configure it
919f1d2b4d3SLarry Finger * according EFUSE during the run-time.
920f1d2b4d3SLarry Finger */
921f1d2b4d3SLarry Finger rtl_set_bbreg(hw, 0x64, BIT(20), 0x0);/* 0x66[4]=0 */
922f1d2b4d3SLarry Finger rtl_set_bbreg(hw, 0x64, BIT(24), 0x0);/* 0x66[8]=0 */
923f1d2b4d3SLarry Finger rtl_set_bbreg(hw, 0x40, BIT(4), 0x0)/* 0x40[4]=0 */;
924f1d2b4d3SLarry Finger rtl_set_bbreg(hw, 0x40, BIT(3), 0x1)/* 0x40[3]=1 */;
925f1d2b4d3SLarry Finger rtl_set_bbreg(hw, 0x4C, BIT(24) | BIT(23), 0x2)/* 0x4C[24:23]=10 */;
926f1d2b4d3SLarry Finger rtl_set_bbreg(hw, 0x944, BIT(1) | BIT(0), 0x3)/* 0x944[1:0]=11 */;
927f1d2b4d3SLarry Finger rtl_set_bbreg(hw, 0x930, MASKBYTE0, 0x77)/* 0x930[7:0]=77 */;
928f1d2b4d3SLarry Finger rtl_set_bbreg(hw, 0x38, BIT(11), 0x1)/* 0x38[11]=1 */;
929f1d2b4d3SLarry Finger
930f1d2b4d3SLarry Finger bytetmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
931f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, bytetmp & (~BIT(2)));
932f1d2b4d3SLarry Finger
933f1d2b4d3SLarry Finger _rtl8723be_gen_refresh_led_state(hw);
934f1d2b4d3SLarry Finger return true;
935f1d2b4d3SLarry Finger }
936f1d2b4d3SLarry Finger
_rtl8723be_hw_configure(struct ieee80211_hw * hw)937f1d2b4d3SLarry Finger static void _rtl8723be_hw_configure(struct ieee80211_hw *hw)
938f1d2b4d3SLarry Finger {
939f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
940f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
941f1d2b4d3SLarry Finger u32 reg_rrsr;
942f1d2b4d3SLarry Finger
943f1d2b4d3SLarry Finger reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
944f1d2b4d3SLarry Finger /* Init value for RRSR. */
945f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_RRSR, reg_rrsr);
946f1d2b4d3SLarry Finger
947f1d2b4d3SLarry Finger /* ARFB table 9 for 11ac 5G 2SS */
948f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_ARFR0 + 4, 0xfffff000);
949f1d2b4d3SLarry Finger
950f1d2b4d3SLarry Finger /* ARFB table 10 for 11ac 5G 1SS */
951f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_ARFR1 + 4, 0x003ff000);
952f1d2b4d3SLarry Finger
953f1d2b4d3SLarry Finger /* CF-End setting. */
954f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F00);
955f1d2b4d3SLarry Finger
956f1d2b4d3SLarry Finger /* 0x456 = 0x70, sugguested by Zhilin */
957f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_AMPDU_MAX_TIME, 0x70);
958f1d2b4d3SLarry Finger
959f1d2b4d3SLarry Finger /* Set retry limit */
960f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_RL, 0x0707);
961f1d2b4d3SLarry Finger
962f1d2b4d3SLarry Finger /* Set Data / Response auto rate fallack retry count */
963f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000);
964f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504);
965f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000);
966f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504);
967f1d2b4d3SLarry Finger
968f1d2b4d3SLarry Finger rtlpci->reg_bcn_ctrl_val = 0x1d;
969f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val);
970f1d2b4d3SLarry Finger
971f1d2b4d3SLarry Finger /* TBTT prohibit hold time. Suggested by designer TimChen. */
972f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); /* 8 ms */
973f1d2b4d3SLarry Finger
974f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040);
975f1d2b4d3SLarry Finger
976f1d2b4d3SLarry Finger /*For Rx TP. Suggested by SD1 Richard. Added by tynli. 2010.04.12.*/
977f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666);
978f1d2b4d3SLarry Finger
979f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_HT_SINGLE_AMPDU, 0x80);
980f1d2b4d3SLarry Finger
981f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x20);
982f1d2b4d3SLarry Finger
983f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_MAX_AGGR_NUM, 0x1F);
984f1d2b4d3SLarry Finger }
985f1d2b4d3SLarry Finger
_rtl8723be_dbi_read(struct rtl_priv * rtlpriv,u16 addr)986f1d2b4d3SLarry Finger static u8 _rtl8723be_dbi_read(struct rtl_priv *rtlpriv, u16 addr)
987f1d2b4d3SLarry Finger {
988f1d2b4d3SLarry Finger u16 read_addr = addr & 0xfffc;
989f1d2b4d3SLarry Finger u8 ret = 0, tmp = 0, count = 0;
990f1d2b4d3SLarry Finger
991f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_DBI_ADDR, read_addr);
992f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_DBI_FLAG, 0x2);
993f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
994f1d2b4d3SLarry Finger count = 0;
995f1d2b4d3SLarry Finger while (tmp && count < 20) {
996f1d2b4d3SLarry Finger udelay(10);
997f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
998f1d2b4d3SLarry Finger count++;
999f1d2b4d3SLarry Finger }
1000f1d2b4d3SLarry Finger if (0 == tmp) {
1001f1d2b4d3SLarry Finger read_addr = REG_DBI_RDATA + addr % 4;
1002f1d2b4d3SLarry Finger ret = rtl_read_byte(rtlpriv, read_addr);
1003f1d2b4d3SLarry Finger }
1004f1d2b4d3SLarry Finger
1005f1d2b4d3SLarry Finger return ret;
1006f1d2b4d3SLarry Finger }
1007f1d2b4d3SLarry Finger
_rtl8723be_dbi_write(struct rtl_priv * rtlpriv,u16 addr,u8 data)1008f1d2b4d3SLarry Finger static void _rtl8723be_dbi_write(struct rtl_priv *rtlpriv, u16 addr, u8 data)
1009f1d2b4d3SLarry Finger {
1010f1d2b4d3SLarry Finger u8 tmp = 0, count = 0;
1011f1d2b4d3SLarry Finger u16 write_addr = 0, remainder = addr % 4;
1012f1d2b4d3SLarry Finger
1013f1d2b4d3SLarry Finger /* Write DBI 1Byte Data */
1014f1d2b4d3SLarry Finger write_addr = REG_DBI_WDATA + remainder;
1015f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, write_addr, data);
1016f1d2b4d3SLarry Finger
1017f1d2b4d3SLarry Finger /* Write DBI 2Byte Address & Write Enable */
1018f1d2b4d3SLarry Finger write_addr = (addr & 0xfffc) | (BIT(0) << (remainder + 12));
1019f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_DBI_ADDR, write_addr);
1020f1d2b4d3SLarry Finger
1021f1d2b4d3SLarry Finger /* Write DBI Write Flag */
1022f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_DBI_FLAG, 0x1);
1023f1d2b4d3SLarry Finger
1024f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1025f1d2b4d3SLarry Finger count = 0;
1026f1d2b4d3SLarry Finger while (tmp && count < 20) {
1027f1d2b4d3SLarry Finger udelay(10);
1028f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1029f1d2b4d3SLarry Finger count++;
1030f1d2b4d3SLarry Finger }
1031f1d2b4d3SLarry Finger }
1032f1d2b4d3SLarry Finger
_rtl8723be_mdio_read(struct rtl_priv * rtlpriv,u8 addr)1033f1d2b4d3SLarry Finger static u16 _rtl8723be_mdio_read(struct rtl_priv *rtlpriv, u8 addr)
1034f1d2b4d3SLarry Finger {
1035f1d2b4d3SLarry Finger u16 ret = 0;
1036f1d2b4d3SLarry Finger u8 tmp = 0, count = 0;
1037f1d2b4d3SLarry Finger
1038f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_MDIO_CTL, addr | BIT(6));
1039f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(6);
1040f1d2b4d3SLarry Finger count = 0;
1041f1d2b4d3SLarry Finger while (tmp && count < 20) {
1042f1d2b4d3SLarry Finger udelay(10);
1043f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(6);
1044f1d2b4d3SLarry Finger count++;
1045f1d2b4d3SLarry Finger }
1046f1d2b4d3SLarry Finger
1047f1d2b4d3SLarry Finger if (0 == tmp)
1048f1d2b4d3SLarry Finger ret = rtl_read_word(rtlpriv, REG_MDIO_RDATA);
1049f1d2b4d3SLarry Finger
1050f1d2b4d3SLarry Finger return ret;
1051f1d2b4d3SLarry Finger }
1052f1d2b4d3SLarry Finger
_rtl8723be_mdio_write(struct rtl_priv * rtlpriv,u8 addr,u16 data)1053f1d2b4d3SLarry Finger static void _rtl8723be_mdio_write(struct rtl_priv *rtlpriv, u8 addr, u16 data)
1054f1d2b4d3SLarry Finger {
1055f1d2b4d3SLarry Finger u8 tmp = 0, count = 0;
1056f1d2b4d3SLarry Finger
1057f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_MDIO_WDATA, data);
1058f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_MDIO_CTL, addr | BIT(5));
1059f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(5);
1060f1d2b4d3SLarry Finger count = 0;
1061f1d2b4d3SLarry Finger while (tmp && count < 20) {
1062f1d2b4d3SLarry Finger udelay(10);
1063f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(5);
1064f1d2b4d3SLarry Finger count++;
1065f1d2b4d3SLarry Finger }
1066f1d2b4d3SLarry Finger }
1067f1d2b4d3SLarry Finger
_rtl8723be_enable_aspm_back_door(struct ieee80211_hw * hw)1068f1d2b4d3SLarry Finger static void _rtl8723be_enable_aspm_back_door(struct ieee80211_hw *hw)
1069f1d2b4d3SLarry Finger {
1070f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1071f1d2b4d3SLarry Finger u8 tmp8 = 0;
1072f1d2b4d3SLarry Finger u16 tmp16 = 0;
1073f1d2b4d3SLarry Finger
1074f1d2b4d3SLarry Finger /* <Roger_Notes> Overwrite following ePHY parameter for
1075f1d2b4d3SLarry Finger * some platform compatibility issue,
1076f1d2b4d3SLarry Finger * especially when CLKReq is enabled, 2012.11.09.
1077f1d2b4d3SLarry Finger */
1078f1d2b4d3SLarry Finger tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x01);
1079f1d2b4d3SLarry Finger if (tmp16 != 0x0663)
1080f1d2b4d3SLarry Finger _rtl8723be_mdio_write(rtlpriv, 0x01, 0x0663);
1081f1d2b4d3SLarry Finger
1082f1d2b4d3SLarry Finger tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x04);
1083f1d2b4d3SLarry Finger if (tmp16 != 0x7544)
1084f1d2b4d3SLarry Finger _rtl8723be_mdio_write(rtlpriv, 0x04, 0x7544);
1085f1d2b4d3SLarry Finger
1086f1d2b4d3SLarry Finger tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x06);
1087f1d2b4d3SLarry Finger if (tmp16 != 0xB880)
1088f1d2b4d3SLarry Finger _rtl8723be_mdio_write(rtlpriv, 0x06, 0xB880);
1089f1d2b4d3SLarry Finger
1090f1d2b4d3SLarry Finger tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x07);
1091f1d2b4d3SLarry Finger if (tmp16 != 0x4000)
1092f1d2b4d3SLarry Finger _rtl8723be_mdio_write(rtlpriv, 0x07, 0x4000);
1093f1d2b4d3SLarry Finger
1094f1d2b4d3SLarry Finger tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x08);
1095f1d2b4d3SLarry Finger if (tmp16 != 0x9003)
1096f1d2b4d3SLarry Finger _rtl8723be_mdio_write(rtlpriv, 0x08, 0x9003);
1097f1d2b4d3SLarry Finger
1098f1d2b4d3SLarry Finger tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x09);
1099f1d2b4d3SLarry Finger if (tmp16 != 0x0D03)
1100f1d2b4d3SLarry Finger _rtl8723be_mdio_write(rtlpriv, 0x09, 0x0D03);
1101f1d2b4d3SLarry Finger
1102f1d2b4d3SLarry Finger tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x0A);
1103f1d2b4d3SLarry Finger if (tmp16 != 0x4037)
1104f1d2b4d3SLarry Finger _rtl8723be_mdio_write(rtlpriv, 0x0A, 0x4037);
1105f1d2b4d3SLarry Finger
1106f1d2b4d3SLarry Finger tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x0B);
1107f1d2b4d3SLarry Finger if (tmp16 != 0x0070)
110878dc897bSLarry Finger _rtl8723be_mdio_write(rtlpriv, 0x0B, 0x0070);
110978dc897bSLarry Finger
1110f1d2b4d3SLarry Finger /* Configuration Space offset 0x70f BIT7 is used to control L0S */
1111f1d2b4d3SLarry Finger tmp8 = _rtl8723be_dbi_read(rtlpriv, 0x70f);
1112f1d2b4d3SLarry Finger _rtl8723be_dbi_write(rtlpriv, 0x70f, tmp8 | BIT(7) |
1113f1d2b4d3SLarry Finger ASPM_L1_LATENCY << 3);
1114f1d2b4d3SLarry Finger
1115f1d2b4d3SLarry Finger /* Configuration Space offset 0x719 Bit3 is for L1
1116f1d2b4d3SLarry Finger * BIT4 is for clock request
1117f1d2b4d3SLarry Finger */
1118f1d2b4d3SLarry Finger tmp8 = _rtl8723be_dbi_read(rtlpriv, 0x719);
1119f1d2b4d3SLarry Finger _rtl8723be_dbi_write(rtlpriv, 0x719, tmp8 | BIT(3) | BIT(4));
1120f1d2b4d3SLarry Finger }
1121f1d2b4d3SLarry Finger
rtl8723be_enable_hw_security_config(struct ieee80211_hw * hw)1122f1d2b4d3SLarry Finger void rtl8723be_enable_hw_security_config(struct ieee80211_hw *hw)
1123e6dd230aSLarry Finger {
1124f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1125f1d2b4d3SLarry Finger u8 sec_reg_value;
1126f1d2b4d3SLarry Finger
1127f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG,
1128f1d2b4d3SLarry Finger "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
1129e6dd230aSLarry Finger rtlpriv->sec.pairwise_enc_algorithm,
1130f1d2b4d3SLarry Finger rtlpriv->sec.group_enc_algorithm);
1131f1d2b4d3SLarry Finger
1132f1d2b4d3SLarry Finger if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
1133f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
1134f1d2b4d3SLarry Finger "not open hw encryption\n");
1135f1d2b4d3SLarry Finger return;
1136f1d2b4d3SLarry Finger }
1137f1d2b4d3SLarry Finger
1138f1d2b4d3SLarry Finger sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE;
1139f1d2b4d3SLarry Finger
1140f1d2b4d3SLarry Finger if (rtlpriv->sec.use_defaultkey) {
1141f1d2b4d3SLarry Finger sec_reg_value |= SCR_TXUSEDK;
1142f1d2b4d3SLarry Finger sec_reg_value |= SCR_RXUSEDK;
1143f1d2b4d3SLarry Finger }
1144f1d2b4d3SLarry Finger
1145e6dd230aSLarry Finger sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
1146f1d2b4d3SLarry Finger
1147f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
1148f1d2b4d3SLarry Finger
1149f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
1150f1d2b4d3SLarry Finger "The SECR-value %x\n", sec_reg_value);
1151f1d2b4d3SLarry Finger
1152f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
1153f1d2b4d3SLarry Finger }
1154f1d2b4d3SLarry Finger
_rtl8723be_poweroff_adapter(struct ieee80211_hw * hw)1155f1d2b4d3SLarry Finger static void _rtl8723be_poweroff_adapter(struct ieee80211_hw *hw)
1156f1d2b4d3SLarry Finger {
1157f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1158f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1159f1d2b4d3SLarry Finger u8 u1b_tmp;
1160f1d2b4d3SLarry Finger
1161f1d2b4d3SLarry Finger rtlhal->mac_func_enable = false;
1162f1d2b4d3SLarry Finger /* Combo (PCIe + USB) Card and PCIe-MF Card */
1163f1d2b4d3SLarry Finger /* 1. Run LPS WL RFOFF flow */
1164f1d2b4d3SLarry Finger rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1165f1d2b4d3SLarry Finger PWR_INTF_PCI_MSK, RTL8723_NIC_LPS_ENTER_FLOW);
1166f1d2b4d3SLarry Finger
1167f1d2b4d3SLarry Finger /* 2. 0x1F[7:0] = 0 */
1168f1d2b4d3SLarry Finger /* turn off RF */
1169f1d2b4d3SLarry Finger /* rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); */
1170f1d2b4d3SLarry Finger if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) &&
1171f1d2b4d3SLarry Finger rtlhal->fw_ready) {
1172f1d2b4d3SLarry Finger rtl8723be_firmware_selfreset(hw);
1173f1d2b4d3SLarry Finger }
1174f1d2b4d3SLarry Finger
1175f1d2b4d3SLarry Finger /* Reset MCU. Suggested by Filen. */
1176f1d2b4d3SLarry Finger u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1177f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2))));
1178f1d2b4d3SLarry Finger
1179f1d2b4d3SLarry Finger /* g. MCUFWDL 0x80[1:0]=0 */
1180f1d2b4d3SLarry Finger /* reset MCU ready status */
1181f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
1182f1d2b4d3SLarry Finger
1183f1d2b4d3SLarry Finger /* HW card disable configuration. */
1184f1d2b4d3SLarry Finger rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1185f1d2b4d3SLarry Finger PWR_INTF_PCI_MSK, RTL8723_NIC_DISABLE_FLOW);
1186f1d2b4d3SLarry Finger
1187f1d2b4d3SLarry Finger /* Reset MCU IO Wrapper */
1188f1d2b4d3SLarry Finger u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1189f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0))));
1190f1d2b4d3SLarry Finger u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1191f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1b_tmp | BIT(0));
1192f1d2b4d3SLarry Finger
1193f1d2b4d3SLarry Finger /* 7. RSV_CTRL 0x1C[7:0] = 0x0E */
1194f1d2b4d3SLarry Finger /* lock ISO/CLK/Power control register */
1195f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e);
1196f1d2b4d3SLarry Finger }
1197f1d2b4d3SLarry Finger
_rtl8723be_check_pcie_dma_hang(struct rtl_priv * rtlpriv)1198f1d2b4d3SLarry Finger static bool _rtl8723be_check_pcie_dma_hang(struct rtl_priv *rtlpriv)
1199f1d2b4d3SLarry Finger {
1200f1d2b4d3SLarry Finger u8 tmp;
1201f1d2b4d3SLarry Finger
1202f1d2b4d3SLarry Finger /* write reg 0x350 Bit[26]=1. Enable debug port. */
1203f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_DBI_CTRL + 3);
1204f1d2b4d3SLarry Finger if (!(tmp & BIT(2))) {
1205f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_DBI_CTRL + 3, (tmp | BIT(2)));
1206f1d2b4d3SLarry Finger mdelay(100); /* Suggested by DD Justin_tsai. */
1207f1d2b4d3SLarry Finger }
1208f1d2b4d3SLarry Finger
1209f1d2b4d3SLarry Finger /* read reg 0x350 Bit[25] if 1 : RX hang
1210e6dd230aSLarry Finger * read reg 0x350 Bit[24] if 1 : TX hang
1211f1d2b4d3SLarry Finger */
1212f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_DBI_CTRL + 3);
1213f1d2b4d3SLarry Finger if ((tmp & BIT(0)) || (tmp & BIT(1))) {
1214f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1215f1d2b4d3SLarry Finger "CheckPcieDMAHang8723BE(): true!!\n");
1216f1d2b4d3SLarry Finger return true;
1217f1d2b4d3SLarry Finger }
1218f1d2b4d3SLarry Finger return false;
1219f1d2b4d3SLarry Finger }
1220f1d2b4d3SLarry Finger
_rtl8723be_reset_pcie_interface_dma(struct rtl_priv * rtlpriv,bool mac_power_on)1221f1d2b4d3SLarry Finger static void _rtl8723be_reset_pcie_interface_dma(struct rtl_priv *rtlpriv,
1222f1d2b4d3SLarry Finger bool mac_power_on)
1223f1d2b4d3SLarry Finger {
1224e6dd230aSLarry Finger u8 tmp;
1225f1d2b4d3SLarry Finger bool release_mac_rx_pause;
1226f1d2b4d3SLarry Finger u8 backup_pcie_dma_pause;
1227f1d2b4d3SLarry Finger
1228f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1229f1d2b4d3SLarry Finger "ResetPcieInterfaceDMA8723BE()\n");
1230f1d2b4d3SLarry Finger
1231f1d2b4d3SLarry Finger /* Revise Note: Follow the document "PCIe RX DMA Hang Reset Flow_v03"
1232f1d2b4d3SLarry Finger * released by SD1 Alan.
1233f1d2b4d3SLarry Finger * 2013.05.07, by tynli.
1234f1d2b4d3SLarry Finger */
1235f1d2b4d3SLarry Finger
1236f1d2b4d3SLarry Finger /* 1. disable register write lock
1237f1d2b4d3SLarry Finger * write 0x1C bit[1:0] = 2'h0
1238f1d2b4d3SLarry Finger * write 0xCC bit[2] = 1'b1
1239f1d2b4d3SLarry Finger */
1240f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL);
1241f1d2b4d3SLarry Finger tmp &= ~(BIT(1) | BIT(0));
1242f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_RSV_CTRL, tmp);
1243f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2);
1244f1d2b4d3SLarry Finger tmp |= BIT(2);
1245f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp);
1246f1d2b4d3SLarry Finger
1247f1d2b4d3SLarry Finger /* 2. Check and pause TRX DMA
1248f1d2b4d3SLarry Finger * write 0x284 bit[18] = 1'b1
1249f1d2b4d3SLarry Finger * write 0x301 = 0xFF
1250f1d2b4d3SLarry Finger */
1251f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1252f1d2b4d3SLarry Finger if (tmp & BIT(2)) {
1253f1d2b4d3SLarry Finger /* Already pause before the function for another purpose. */
1254f1d2b4d3SLarry Finger release_mac_rx_pause = false;
1255f1d2b4d3SLarry Finger } else {
1256f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, (tmp | BIT(2)));
1257f1d2b4d3SLarry Finger release_mac_rx_pause = true;
1258f1d2b4d3SLarry Finger }
1259f1d2b4d3SLarry Finger
1260f1d2b4d3SLarry Finger backup_pcie_dma_pause = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 1);
1261f1d2b4d3SLarry Finger if (backup_pcie_dma_pause != 0xFF)
1262f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xFF);
1263f1d2b4d3SLarry Finger
1264f1d2b4d3SLarry Finger if (mac_power_on) {
1265f1d2b4d3SLarry Finger /* 3. reset TRX function
1266f1d2b4d3SLarry Finger * write 0x100 = 0x00
1267f1d2b4d3SLarry Finger */
1268f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_CR, 0);
1269f1d2b4d3SLarry Finger }
1270f1d2b4d3SLarry Finger
1271f1d2b4d3SLarry Finger /* 4. Reset PCIe DMA
1272f1d2b4d3SLarry Finger * write 0x003 bit[0] = 0
1273f1d2b4d3SLarry Finger */
1274f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1275f1d2b4d3SLarry Finger tmp &= ~(BIT(0));
1276f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp);
1277f1d2b4d3SLarry Finger
1278f1d2b4d3SLarry Finger /* 5. Enable PCIe DMA
1279f1d2b4d3SLarry Finger * write 0x003 bit[0] = 1
1280f1d2b4d3SLarry Finger */
1281f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1282f1d2b4d3SLarry Finger tmp |= BIT(0);
1283f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp);
1284f1d2b4d3SLarry Finger
1285f1d2b4d3SLarry Finger if (mac_power_on) {
1286f1d2b4d3SLarry Finger /* 6. enable TRX function
1287f1d2b4d3SLarry Finger * write 0x100 = 0xFF
1288f1d2b4d3SLarry Finger */
1289f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_CR, 0xFF);
1290f1d2b4d3SLarry Finger
1291f1d2b4d3SLarry Finger /* We should init LLT & RQPN and
1292f1d2b4d3SLarry Finger * prepare Tx/Rx descrptor address later
1293f1d2b4d3SLarry Finger * because MAC function is reset.
1294f1d2b4d3SLarry Finger */
1295f1d2b4d3SLarry Finger }
1296f1d2b4d3SLarry Finger
1297f1d2b4d3SLarry Finger /* 7. Restore PCIe autoload down bit
1298f1d2b4d3SLarry Finger * write 0xF8 bit[17] = 1'b1
1299f1d2b4d3SLarry Finger */
1300f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2);
1301f1d2b4d3SLarry Finger tmp |= BIT(1);
1302f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2, tmp);
1303f1d2b4d3SLarry Finger
1304f1d2b4d3SLarry Finger /* In MAC power on state, BB and RF maybe in ON state,
1305f1d2b4d3SLarry Finger * if we release TRx DMA here
1306f1d2b4d3SLarry Finger * it will cause packets to be started to Tx/Rx,
1307f1d2b4d3SLarry Finger * so we release Tx/Rx DMA later.
1308f1d2b4d3SLarry Finger */
1309f1d2b4d3SLarry Finger if (!mac_power_on) {
1310f1d2b4d3SLarry Finger /* 8. release TRX DMA
1311f1d2b4d3SLarry Finger * write 0x284 bit[18] = 1'b0
1312f1d2b4d3SLarry Finger * write 0x301 = 0x00
1313f1d2b4d3SLarry Finger */
1314f1d2b4d3SLarry Finger if (release_mac_rx_pause) {
1315f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1316f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL,
1317f1d2b4d3SLarry Finger (tmp & (~BIT(2))));
1318f1d2b4d3SLarry Finger }
1319f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1,
1320f1d2b4d3SLarry Finger backup_pcie_dma_pause);
1321f1d2b4d3SLarry Finger }
1322f1d2b4d3SLarry Finger
1323f1d2b4d3SLarry Finger /* 9. lock system register
1324f1d2b4d3SLarry Finger * write 0xCC bit[2] = 1'b0
1325f1d2b4d3SLarry Finger */
1326f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2);
1327f1d2b4d3SLarry Finger tmp &= ~(BIT(2));
1328f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp);
1329f1d2b4d3SLarry Finger }
1330f1d2b4d3SLarry Finger
rtl8723be_hw_init(struct ieee80211_hw * hw)1331f1d2b4d3SLarry Finger int rtl8723be_hw_init(struct ieee80211_hw *hw)
1332f1d2b4d3SLarry Finger {
1333f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1334f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1335f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1336f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
1337f1d2b4d3SLarry Finger struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1338f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1339f1d2b4d3SLarry Finger bool rtstatus = true;
1340f1d2b4d3SLarry Finger int err;
1341f1d2b4d3SLarry Finger u8 tmp_u1b;
1342f1d2b4d3SLarry Finger unsigned long flags;
1343f1d2b4d3SLarry Finger
1344f1d2b4d3SLarry Finger /* reenable interrupts to not interfere with other devices */
1345f1d2b4d3SLarry Finger local_save_flags(flags);
1346f1d2b4d3SLarry Finger local_irq_enable();
1347f1d2b4d3SLarry Finger
1348f1d2b4d3SLarry Finger rtlhal->fw_ready = false;
1349f1d2b4d3SLarry Finger rtlpriv->rtlhal.being_init_adapter = true;
1350f1d2b4d3SLarry Finger rtlpriv->intf_ops->disable_aspm(hw);
1351f1d2b4d3SLarry Finger
1352f1d2b4d3SLarry Finger tmp_u1b = rtl_read_byte(rtlpriv, REG_CR);
1353f1d2b4d3SLarry Finger if (tmp_u1b != 0 && tmp_u1b != 0xea) {
1354f1d2b4d3SLarry Finger rtlhal->mac_func_enable = true;
1355f1d2b4d3SLarry Finger } else {
1356f1d2b4d3SLarry Finger rtlhal->mac_func_enable = false;
1357f1d2b4d3SLarry Finger rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON;
1358f1d2b4d3SLarry Finger }
1359f1d2b4d3SLarry Finger
1360f1d2b4d3SLarry Finger if (_rtl8723be_check_pcie_dma_hang(rtlpriv)) {
1361f1d2b4d3SLarry Finger _rtl8723be_reset_pcie_interface_dma(rtlpriv,
1362f1d2b4d3SLarry Finger rtlhal->mac_func_enable);
1363f1d2b4d3SLarry Finger rtlhal->mac_func_enable = false;
1364f1d2b4d3SLarry Finger }
1365f1d2b4d3SLarry Finger if (rtlhal->mac_func_enable) {
1366f1d2b4d3SLarry Finger _rtl8723be_poweroff_adapter(hw);
13674e2b4378SLarry Finger rtlhal->mac_func_enable = false;
1368f1d2b4d3SLarry Finger }
1369f1d2b4d3SLarry Finger rtstatus = _rtl8723be_init_mac(hw);
1370f1d2b4d3SLarry Finger if (!rtstatus) {
1371f1d2b4d3SLarry Finger pr_err("Init MAC failed\n");
1372f1d2b4d3SLarry Finger err = 1;
1373f1d2b4d3SLarry Finger goto exit;
1374f1d2b4d3SLarry Finger }
1375f1d2b4d3SLarry Finger
1376f1d2b4d3SLarry Finger tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CFG);
1377e6dd230aSLarry Finger rtl_write_byte(rtlpriv, REG_SYS_CFG, tmp_u1b & 0x7F);
1378f1d2b4d3SLarry Finger
1379f1d2b4d3SLarry Finger err = rtl8723_download_fw(hw, true, FW_8723B_POLLING_TIMEOUT_COUNT);
1380f1d2b4d3SLarry Finger if (err) {
1381f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
1382f1d2b4d3SLarry Finger "Failed to download FW. Init HW without FW now..\n");
1383f1d2b4d3SLarry Finger err = 1;
1384f1d2b4d3SLarry Finger goto exit;
1385f1d2b4d3SLarry Finger }
1386f1d2b4d3SLarry Finger rtlhal->fw_ready = true;
1387f1d2b4d3SLarry Finger
1388f1d2b4d3SLarry Finger rtlhal->last_hmeboxnum = 0;
1389f1d2b4d3SLarry Finger rtl8723be_phy_mac_config(hw);
1390f1d2b4d3SLarry Finger /* because last function modify RCR, so we update
1391f1d2b4d3SLarry Finger * rcr var here, or TP will unstable for receive_config
1392f1d2b4d3SLarry Finger * is wrong, RX RCR_ACRC32 will cause TP unstable & Rx
1393f1d2b4d3SLarry Finger * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252
1394f1d2b4d3SLarry Finger */
1395f1d2b4d3SLarry Finger rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR);
1396f1d2b4d3SLarry Finger rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
1397f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
1398f1d2b4d3SLarry Finger
1399f1d2b4d3SLarry Finger rtl8723be_phy_bb_config(hw);
1400f1d2b4d3SLarry Finger rtl8723be_phy_rf_config(hw);
1401f1d2b4d3SLarry Finger
1402f1d2b4d3SLarry Finger rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
1403f1d2b4d3SLarry Finger RF_CHNLBW, RFREG_OFFSET_MASK);
1404f1d2b4d3SLarry Finger rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1,
1405f1d2b4d3SLarry Finger RF_CHNLBW, RFREG_OFFSET_MASK);
1406f1d2b4d3SLarry Finger rtlphy->rfreg_chnlval[0] &= 0xFFF03FF;
1407f1d2b4d3SLarry Finger rtlphy->rfreg_chnlval[0] |= (BIT(10) | BIT(11));
1408f1d2b4d3SLarry Finger
1409f1d2b4d3SLarry Finger _rtl8723be_hw_configure(hw);
1410f1d2b4d3SLarry Finger rtlhal->mac_func_enable = true;
1411f1d2b4d3SLarry Finger rtl_cam_reset_all_entry(hw);
1412f1d2b4d3SLarry Finger rtl8723be_enable_hw_security_config(hw);
1413f1d2b4d3SLarry Finger
1414f1d2b4d3SLarry Finger ppsc->rfpwr_state = ERFON;
1415f1d2b4d3SLarry Finger
1416f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
1417f1d2b4d3SLarry Finger _rtl8723be_enable_aspm_back_door(hw);
1418f1d2b4d3SLarry Finger rtlpriv->intf_ops->enable_aspm(hw);
1419f1d2b4d3SLarry Finger
1420f1d2b4d3SLarry Finger rtl8723be_bt_hw_init(hw);
1421f1d2b4d3SLarry Finger
1422f1d2b4d3SLarry Finger if (ppsc->rfpwr_state == ERFON) {
1423f1d2b4d3SLarry Finger rtl8723be_phy_set_rfpath_switch(hw, 1);
1424f1d2b4d3SLarry Finger /* when use 1ant NIC, iqk will disturb BT music
1425f1d2b4d3SLarry Finger * root cause is not clear now, is something
1426a7088392SPing-Ke Shih * related with 'mdelay' and Reg[0x948]
1427a7088392SPing-Ke Shih */
1428a7088392SPing-Ke Shih if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2 ||
1429f1d2b4d3SLarry Finger !rtlpriv->cfg->ops->get_btc_status()) {
1430f1d2b4d3SLarry Finger rtl8723be_phy_iq_calibrate(hw,
1431f1d2b4d3SLarry Finger (rtlphy->iqk_initialized ?
1432f1d2b4d3SLarry Finger true : false));
1433f1d2b4d3SLarry Finger rtlphy->iqk_initialized = true;
1434f1d2b4d3SLarry Finger }
1435f1d2b4d3SLarry Finger rtl8723be_dm_check_txpower_tracking(hw);
1436f1d2b4d3SLarry Finger rtl8723be_phy_lc_calibrate(hw);
1437f1d2b4d3SLarry Finger }
1438f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_NAV_UPPER, ((30000 + 127) / 128));
1439f1d2b4d3SLarry Finger
1440f1d2b4d3SLarry Finger /* Release Rx DMA. */
1441f1d2b4d3SLarry Finger tmp_u1b = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1442f1d2b4d3SLarry Finger if (tmp_u1b & BIT(2)) {
1443f1d2b4d3SLarry Finger /* Release Rx DMA if needed */
1444f1d2b4d3SLarry Finger tmp_u1b &= (~BIT(2));
1445f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, tmp_u1b);
1446f1d2b4d3SLarry Finger }
1447f1d2b4d3SLarry Finger /* Release Tx/Rx PCIE DMA. */
1448f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0);
1449f1d2b4d3SLarry Finger
1450f1d2b4d3SLarry Finger rtl8723be_dm_init(hw);
1451f1d2b4d3SLarry Finger exit:
1452f1d2b4d3SLarry Finger local_irq_restore(flags);
1453f1d2b4d3SLarry Finger rtlpriv->rtlhal.being_init_adapter = false;
1454f1d2b4d3SLarry Finger return err;
1455f1d2b4d3SLarry Finger }
1456f1d2b4d3SLarry Finger
_rtl8723be_read_chip_version(struct ieee80211_hw * hw)1457f1d2b4d3SLarry Finger static enum version_8723e _rtl8723be_read_chip_version(struct ieee80211_hw *hw)
1458f1d2b4d3SLarry Finger {
1459f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1460f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
1461f1d2b4d3SLarry Finger enum version_8723e version = VERSION_UNKNOWN;
1462e6dd230aSLarry Finger u32 value32;
1463f1d2b4d3SLarry Finger
1464f1d2b4d3SLarry Finger value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG1);
1465f1d2b4d3SLarry Finger if ((value32 & (CHIP_8723B)) != CHIP_8723B)
1466f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "unknown chip version\n");
1467f1d2b4d3SLarry Finger else
1468f1d2b4d3SLarry Finger version = (enum version_8723e)CHIP_8723B;
1469f1d2b4d3SLarry Finger
1470f1d2b4d3SLarry Finger rtlphy->rf_type = RF_1T1R;
1471f1d2b4d3SLarry Finger
1472f1d2b4d3SLarry Finger /* treat rtl8723be chip as MP version in default */
1473f1d2b4d3SLarry Finger version = (enum version_8723e)(version | NORMAL_CHIP);
1474f1d2b4d3SLarry Finger
1475f1d2b4d3SLarry Finger value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
1476f1d2b4d3SLarry Finger /* cut version */
1477f1d2b4d3SLarry Finger version |= (enum version_8723e)(value32 & CHIP_VER_RTL_MASK);
1478e6dd230aSLarry Finger /* Manufacture */
1479f1d2b4d3SLarry Finger if (((value32 & EXT_VENDOR_ID) >> 18) == 0x01)
1480f1d2b4d3SLarry Finger version = (enum version_8723e)(version | CHIP_VENDOR_SMIC);
1481f1d2b4d3SLarry Finger
1482f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1483f1d2b4d3SLarry Finger "Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
1484f1d2b4d3SLarry Finger "RF_2T2R" : "RF_1T1R");
1485f1d2b4d3SLarry Finger
1486f1d2b4d3SLarry Finger return version;
1487f1d2b4d3SLarry Finger }
1488f1d2b4d3SLarry Finger
_rtl8723be_set_media_status(struct ieee80211_hw * hw,enum nl80211_iftype type)1489f1d2b4d3SLarry Finger static int _rtl8723be_set_media_status(struct ieee80211_hw *hw,
1490f1d2b4d3SLarry Finger enum nl80211_iftype type)
1491f1d2b4d3SLarry Finger {
1492f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1493f1d2b4d3SLarry Finger u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc;
1494f1d2b4d3SLarry Finger enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
1495f1d2b4d3SLarry Finger u8 mode = MSR_NOLINK;
1496e6dd230aSLarry Finger
1497f1d2b4d3SLarry Finger switch (type) {
1498f1d2b4d3SLarry Finger case NL80211_IFTYPE_UNSPECIFIED:
1499f1d2b4d3SLarry Finger mode = MSR_NOLINK;
1500f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
1501f1d2b4d3SLarry Finger "Set Network type to NO LINK!\n");
1502e6dd230aSLarry Finger break;
1503f1d2b4d3SLarry Finger case NL80211_IFTYPE_ADHOC:
1504f1d2b4d3SLarry Finger case NL80211_IFTYPE_MESH_POINT:
1505f1d2b4d3SLarry Finger mode = MSR_ADHOC;
1506f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
1507f1d2b4d3SLarry Finger "Set Network type to Ad Hoc!\n");
1508e6dd230aSLarry Finger break;
1509f1d2b4d3SLarry Finger case NL80211_IFTYPE_STATION:
1510f1d2b4d3SLarry Finger mode = MSR_INFRA;
1511f1d2b4d3SLarry Finger ledaction = LED_CTL_LINK;
1512f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
1513f1d2b4d3SLarry Finger "Set Network type to STA!\n");
1514e6dd230aSLarry Finger break;
1515f1d2b4d3SLarry Finger case NL80211_IFTYPE_AP:
1516f1d2b4d3SLarry Finger mode = MSR_AP;
1517f1d2b4d3SLarry Finger ledaction = LED_CTL_LINK;
15184e2b4378SLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
1519f1d2b4d3SLarry Finger "Set Network type to AP!\n");
1520f1d2b4d3SLarry Finger break;
1521f1d2b4d3SLarry Finger default:
1522f1d2b4d3SLarry Finger pr_err("Network type %d not support!\n", type);
1523f1d2b4d3SLarry Finger return 1;
1524f1d2b4d3SLarry Finger }
1525f1d2b4d3SLarry Finger
1526f1d2b4d3SLarry Finger /* MSR_INFRA == Link in infrastructure network;
1527f1d2b4d3SLarry Finger * MSR_ADHOC == Link in ad hoc network;
1528f1d2b4d3SLarry Finger * Therefore, check link state is necessary.
1529f1d2b4d3SLarry Finger *
1530f1d2b4d3SLarry Finger * MSR_AP == AP mode; link state is not cared here.
1531f1d2b4d3SLarry Finger */
1532f1d2b4d3SLarry Finger if (mode != MSR_AP && rtlpriv->mac80211.link_state < MAC80211_LINKED) {
1533f1d2b4d3SLarry Finger mode = MSR_NOLINK;
1534f1d2b4d3SLarry Finger ledaction = LED_CTL_NO_LINK;
1535f1d2b4d3SLarry Finger }
1536f1d2b4d3SLarry Finger
1537f1d2b4d3SLarry Finger if (mode == MSR_NOLINK || mode == MSR_INFRA) {
1538f1d2b4d3SLarry Finger _rtl8723be_stop_tx_beacon(hw);
1539f1d2b4d3SLarry Finger _rtl8723be_enable_bcn_sub_func(hw);
1540e6dd230aSLarry Finger } else if (mode == MSR_ADHOC || mode == MSR_AP) {
1541f1d2b4d3SLarry Finger _rtl8723be_resume_tx_beacon(hw);
1542f1d2b4d3SLarry Finger _rtl8723be_disable_bcn_sub_func(hw);
1543f1d2b4d3SLarry Finger } else {
1544f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
1545f1d2b4d3SLarry Finger "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n",
1546f1d2b4d3SLarry Finger mode);
1547f1d2b4d3SLarry Finger }
1548f1d2b4d3SLarry Finger
1549f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, MSR, bt_msr | mode);
1550f1d2b4d3SLarry Finger rtlpriv->cfg->ops->led_control(hw, ledaction);
1551f1d2b4d3SLarry Finger if (mode == MSR_AP)
1552f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1553f1d2b4d3SLarry Finger else
1554f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
1555f1d2b4d3SLarry Finger return 0;
1556f1d2b4d3SLarry Finger }
1557f1d2b4d3SLarry Finger
rtl8723be_set_check_bssid(struct ieee80211_hw * hw,bool check_bssid)1558f1d2b4d3SLarry Finger void rtl8723be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1559f1d2b4d3SLarry Finger {
1560f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1561f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1562f1d2b4d3SLarry Finger u32 reg_rcr = rtlpci->receive_config;
1563f1d2b4d3SLarry Finger
1564f1d2b4d3SLarry Finger if (rtlpriv->psc.rfpwr_state != ERFON)
1565f1d2b4d3SLarry Finger return;
1566f1d2b4d3SLarry Finger
1567f1d2b4d3SLarry Finger if (check_bssid) {
1568f1d2b4d3SLarry Finger reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1569f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1570f1d2b4d3SLarry Finger (u8 *)(®_rcr));
1571f1d2b4d3SLarry Finger _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4));
1572f1d2b4d3SLarry Finger } else if (!check_bssid) {
1573f1d2b4d3SLarry Finger reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
1574f1d2b4d3SLarry Finger _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0);
1575f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1576f1d2b4d3SLarry Finger (u8 *)(®_rcr));
1577f1d2b4d3SLarry Finger }
1578f1d2b4d3SLarry Finger
1579f1d2b4d3SLarry Finger }
1580f1d2b4d3SLarry Finger
rtl8723be_set_network_type(struct ieee80211_hw * hw,enum nl80211_iftype type)1581f1d2b4d3SLarry Finger int rtl8723be_set_network_type(struct ieee80211_hw *hw,
1582f1d2b4d3SLarry Finger enum nl80211_iftype type)
1583f1d2b4d3SLarry Finger {
1584f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1585f1d2b4d3SLarry Finger
1586f1d2b4d3SLarry Finger if (_rtl8723be_set_media_status(hw, type))
1587f1d2b4d3SLarry Finger return -EOPNOTSUPP;
1588f1d2b4d3SLarry Finger
1589f1d2b4d3SLarry Finger if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
1590f1d2b4d3SLarry Finger if (type != NL80211_IFTYPE_AP)
1591f1d2b4d3SLarry Finger rtl8723be_set_check_bssid(hw, true);
1592f1d2b4d3SLarry Finger } else {
1593f1d2b4d3SLarry Finger rtl8723be_set_check_bssid(hw, false);
1594f1d2b4d3SLarry Finger }
1595f1d2b4d3SLarry Finger
1596f1d2b4d3SLarry Finger return 0;
1597f1d2b4d3SLarry Finger }
1598f1d2b4d3SLarry Finger
1599f1d2b4d3SLarry Finger /* don't set REG_EDCA_BE_PARAM here
1600f1d2b4d3SLarry Finger * because mac80211 will send pkt when scan
1601f1d2b4d3SLarry Finger */
rtl8723be_set_qos(struct ieee80211_hw * hw,int aci)1602f1d2b4d3SLarry Finger void rtl8723be_set_qos(struct ieee80211_hw *hw, int aci)
1603f1d2b4d3SLarry Finger {
1604f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1605f1d2b4d3SLarry Finger
1606f1d2b4d3SLarry Finger rtl8723_dm_init_edca_turbo(hw);
1607f1d2b4d3SLarry Finger switch (aci) {
1608f1d2b4d3SLarry Finger case AC1_BK:
1609f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f);
1610f1d2b4d3SLarry Finger break;
1611f1d2b4d3SLarry Finger case AC0_BE:
1612f1d2b4d3SLarry Finger break;
1613f1d2b4d3SLarry Finger case AC2_VI:
1614f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322);
1615f1d2b4d3SLarry Finger break;
1616531940f9SLarry Finger case AC3_VO:
1617f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
1618f1d2b4d3SLarry Finger break;
1619f1d2b4d3SLarry Finger default:
1620f1d2b4d3SLarry Finger WARN_ONCE(true, "rtl8723be: invalid aci: %d !\n", aci);
1621f1d2b4d3SLarry Finger break;
1622f1d2b4d3SLarry Finger }
1623f1d2b4d3SLarry Finger }
1624f1d2b4d3SLarry Finger
rtl8723be_enable_interrupt(struct ieee80211_hw * hw)1625f1d2b4d3SLarry Finger void rtl8723be_enable_interrupt(struct ieee80211_hw *hw)
1626f1d2b4d3SLarry Finger {
1627f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1628f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1629f1d2b4d3SLarry Finger
1630f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
1631f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
1632f1d2b4d3SLarry Finger rtlpci->irq_enabled = true;
1633f1d2b4d3SLarry Finger
1634f1d2b4d3SLarry Finger /*enable system interrupt*/
1635f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_HSIMR, rtlpci->sys_irq_mask & 0xFFFFFFFF);
1636f1d2b4d3SLarry Finger }
1637f1d2b4d3SLarry Finger
rtl8723be_disable_interrupt(struct ieee80211_hw * hw)1638f1d2b4d3SLarry Finger void rtl8723be_disable_interrupt(struct ieee80211_hw *hw)
1639f1d2b4d3SLarry Finger {
1640f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1641f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1642f1d2b4d3SLarry Finger
1643f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_HIMR, IMR_DISABLED);
1644f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_HIMRE, IMR_DISABLED);
1645f1d2b4d3SLarry Finger rtlpci->irq_enabled = false;
1646f1d2b4d3SLarry Finger /*synchronize_irq(rtlpci->pdev->irq);*/
1647f1d2b4d3SLarry Finger }
1648f1d2b4d3SLarry Finger
rtl8723be_card_disable(struct ieee80211_hw * hw)1649f1d2b4d3SLarry Finger void rtl8723be_card_disable(struct ieee80211_hw *hw)
1650f1d2b4d3SLarry Finger {
1651f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1652f1d2b4d3SLarry Finger struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1653f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1654f1d2b4d3SLarry Finger enum nl80211_iftype opmode;
1655f1d2b4d3SLarry Finger
1656f1d2b4d3SLarry Finger mac->link_state = MAC80211_NOLINK;
1657f1d2b4d3SLarry Finger opmode = NL80211_IFTYPE_UNSPECIFIED;
1658f1d2b4d3SLarry Finger _rtl8723be_set_media_status(hw, opmode);
1659f1d2b4d3SLarry Finger if (rtlpriv->rtlhal.driver_is_goingto_unload ||
1660f1d2b4d3SLarry Finger ppsc->rfoff_reason > RF_CHANGE_BY_PS)
1661f1d2b4d3SLarry Finger rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
1662a7088392SPing-Ke Shih RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1663f1d2b4d3SLarry Finger _rtl8723be_poweroff_adapter(hw);
1664f1d2b4d3SLarry Finger
1665f1d2b4d3SLarry Finger /* after power off we should do iqk again */
1666f1d2b4d3SLarry Finger if (!rtlpriv->cfg->ops->get_btc_status())
166778aa6012SLarry Finger rtlpriv->phy.iqk_initialized = false;
1668f1d2b4d3SLarry Finger }
1669f1d2b4d3SLarry Finger
rtl8723be_interrupt_recognized(struct ieee80211_hw * hw,struct rtl_int * intvec)1670f1d2b4d3SLarry Finger void rtl8723be_interrupt_recognized(struct ieee80211_hw *hw,
1671f1d2b4d3SLarry Finger struct rtl_int *intvec)
167278aa6012SLarry Finger {
167378aa6012SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1674f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
167578aa6012SLarry Finger
1676f1d2b4d3SLarry Finger intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0];
167778aa6012SLarry Finger rtl_write_dword(rtlpriv, ISR, intvec->inta);
1678f1d2b4d3SLarry Finger
1679f1d2b4d3SLarry Finger intvec->intb = rtl_read_dword(rtlpriv, REG_HISRE) &
1680f1d2b4d3SLarry Finger rtlpci->irq_mask[1];
1681f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, REG_HISRE, intvec->intb);
1682f1d2b4d3SLarry Finger }
1683f1d2b4d3SLarry Finger
rtl8723be_set_beacon_related_registers(struct ieee80211_hw * hw)1684f1d2b4d3SLarry Finger void rtl8723be_set_beacon_related_registers(struct ieee80211_hw *hw)
1685f1d2b4d3SLarry Finger {
1686f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1687f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1688f1d2b4d3SLarry Finger u16 bcn_interval, atim_window;
1689f1d2b4d3SLarry Finger
1690f1d2b4d3SLarry Finger bcn_interval = mac->beacon_interval;
1691f1d2b4d3SLarry Finger atim_window = 2; /*FIX MERGE */
1692f1d2b4d3SLarry Finger rtl8723be_disable_interrupt(hw);
1693f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
1694f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1695f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
1696f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18);
1697f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18);
1698f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x606, 0x30);
1699f1d2b4d3SLarry Finger rtl8723be_enable_interrupt(hw);
1700f1d2b4d3SLarry Finger }
1701f1d2b4d3SLarry Finger
rtl8723be_set_beacon_interval(struct ieee80211_hw * hw)1702f1d2b4d3SLarry Finger void rtl8723be_set_beacon_interval(struct ieee80211_hw *hw)
1703f1d2b4d3SLarry Finger {
1704e6dd230aSLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1705f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1706f1d2b4d3SLarry Finger u16 bcn_interval = mac->beacon_interval;
1707f1d2b4d3SLarry Finger
1708f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_BEACON, DBG_DMESG,
1709f1d2b4d3SLarry Finger "beacon_interval:%d\n", bcn_interval);
1710f1d2b4d3SLarry Finger rtl8723be_disable_interrupt(hw);
1711f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1712f1d2b4d3SLarry Finger rtl8723be_enable_interrupt(hw);
1713f1d2b4d3SLarry Finger }
1714f1d2b4d3SLarry Finger
rtl8723be_update_interrupt_mask(struct ieee80211_hw * hw,u32 add_msr,u32 rm_msr)1715f1d2b4d3SLarry Finger void rtl8723be_update_interrupt_mask(struct ieee80211_hw *hw,
1716f1d2b4d3SLarry Finger u32 add_msr, u32 rm_msr)
1717e6dd230aSLarry Finger {
1718f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1719f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1720f1d2b4d3SLarry Finger
1721f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD,
1722f1d2b4d3SLarry Finger "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr);
1723f1d2b4d3SLarry Finger
1724f1d2b4d3SLarry Finger if (add_msr)
1725f1d2b4d3SLarry Finger rtlpci->irq_mask[0] |= add_msr;
1726f1d2b4d3SLarry Finger if (rm_msr)
1727f1d2b4d3SLarry Finger rtlpci->irq_mask[0] &= (~rm_msr);
1728f1d2b4d3SLarry Finger rtl8723be_disable_interrupt(hw);
1729f1d2b4d3SLarry Finger rtl8723be_enable_interrupt(hw);
1730f1d2b4d3SLarry Finger }
1731f1d2b4d3SLarry Finger
_rtl8723be_get_chnl_group(u8 chnl)1732f1d2b4d3SLarry Finger static u8 _rtl8723be_get_chnl_group(u8 chnl)
1733f1d2b4d3SLarry Finger {
1734f1d2b4d3SLarry Finger u8 group;
1735f1d2b4d3SLarry Finger
1736f1d2b4d3SLarry Finger if (chnl < 3)
1737f1d2b4d3SLarry Finger group = 0;
1738f1d2b4d3SLarry Finger else if (chnl < 9)
1739f1d2b4d3SLarry Finger group = 1;
1740f1d2b4d3SLarry Finger else
1741f1d2b4d3SLarry Finger group = 2;
1742f1d2b4d3SLarry Finger return group;
1743f1d2b4d3SLarry Finger }
1744f1d2b4d3SLarry Finger
_rtl8723be_read_power_value_fromprom(struct ieee80211_hw * hw,struct txpower_info_2g * pw2g,struct txpower_info_5g * pw5g,bool autoload_fail,u8 * hwinfo)1745f1d2b4d3SLarry Finger static void _rtl8723be_read_power_value_fromprom(struct ieee80211_hw *hw,
1746f1d2b4d3SLarry Finger struct txpower_info_2g *pw2g,
1747f1d2b4d3SLarry Finger struct txpower_info_5g *pw5g,
1748f1d2b4d3SLarry Finger bool autoload_fail, u8 *hwinfo)
1749e6dd230aSLarry Finger {
1750f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1751f1d2b4d3SLarry Finger u32 path, addr = EEPROM_TX_PWR_INX, group, cnt = 0;
1752f1d2b4d3SLarry Finger
1753f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1754f1d2b4d3SLarry Finger "hal_ReadPowerValueFromPROM8723BE(): PROMContent[0x%x]=0x%x\n",
1755f1d2b4d3SLarry Finger (addr + 1), hwinfo[addr + 1]);
1756e6dd230aSLarry Finger if (0xFF == hwinfo[addr + 1]) /*YJ,add,120316*/
1757f1d2b4d3SLarry Finger autoload_fail = true;
1758f1d2b4d3SLarry Finger
1759f1d2b4d3SLarry Finger if (autoload_fail) {
1760f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1761f1d2b4d3SLarry Finger "auto load fail : Use Default value!\n");
1762f1d2b4d3SLarry Finger for (path = 0; path < MAX_RF_PATH; path++) {
1763f1d2b4d3SLarry Finger /* 2.4G default value */
1764f1d2b4d3SLarry Finger for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) {
1765f1d2b4d3SLarry Finger pw2g->index_cck_base[path][group] = 0x2D;
1766f1d2b4d3SLarry Finger pw2g->index_bw40_base[path][group] = 0x2D;
1767f1d2b4d3SLarry Finger }
1768f1d2b4d3SLarry Finger for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1769f1d2b4d3SLarry Finger if (cnt == 0) {
1770f1d2b4d3SLarry Finger pw2g->bw20_diff[path][0] = 0x02;
1771f1d2b4d3SLarry Finger pw2g->ofdm_diff[path][0] = 0x04;
1772f1d2b4d3SLarry Finger } else {
1773f1d2b4d3SLarry Finger pw2g->bw20_diff[path][cnt] = 0xFE;
1774f1d2b4d3SLarry Finger pw2g->bw40_diff[path][cnt] = 0xFE;
1775f1d2b4d3SLarry Finger pw2g->cck_diff[path][cnt] = 0xFE;
1776f1d2b4d3SLarry Finger pw2g->ofdm_diff[path][cnt] = 0xFE;
1777f1d2b4d3SLarry Finger }
1778f1d2b4d3SLarry Finger }
1779f1d2b4d3SLarry Finger }
1780f1d2b4d3SLarry Finger return;
1781f1d2b4d3SLarry Finger }
1782f1d2b4d3SLarry Finger
1783f1d2b4d3SLarry Finger for (path = 0; path < MAX_RF_PATH; path++) {
1784f1d2b4d3SLarry Finger /*2.4G default value*/
1785f1d2b4d3SLarry Finger for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
1786f1d2b4d3SLarry Finger pw2g->index_cck_base[path][group] = hwinfo[addr++];
1787f1d2b4d3SLarry Finger if (pw2g->index_cck_base[path][group] == 0xFF)
1788f1d2b4d3SLarry Finger pw2g->index_cck_base[path][group] = 0x2D;
1789f1d2b4d3SLarry Finger
1790f1d2b4d3SLarry Finger }
1791f1d2b4d3SLarry Finger for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) {
1792f1d2b4d3SLarry Finger pw2g->index_bw40_base[path][group] = hwinfo[addr++];
1793f1d2b4d3SLarry Finger if (pw2g->index_bw40_base[path][group] == 0xFF)
1794f1d2b4d3SLarry Finger pw2g->index_bw40_base[path][group] = 0x2D;
1795f1d2b4d3SLarry Finger }
1796f1d2b4d3SLarry Finger for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1797f1d2b4d3SLarry Finger if (cnt == 0) {
1798f1d2b4d3SLarry Finger pw2g->bw40_diff[path][cnt] = 0;
1799f1d2b4d3SLarry Finger if (hwinfo[addr] == 0xFF) {
1800f1d2b4d3SLarry Finger pw2g->bw20_diff[path][cnt] = 0x02;
1801f1d2b4d3SLarry Finger } else {
1802f1d2b4d3SLarry Finger pw2g->bw20_diff[path][cnt] =
1803f1d2b4d3SLarry Finger (hwinfo[addr] & 0xf0) >> 4;
1804f1d2b4d3SLarry Finger /*bit sign number to 8 bit sign number*/
1805f1d2b4d3SLarry Finger if (pw2g->bw20_diff[path][cnt] & BIT(3))
1806f1d2b4d3SLarry Finger pw2g->bw20_diff[path][cnt] |=
1807f1d2b4d3SLarry Finger 0xF0;
1808f1d2b4d3SLarry Finger }
1809f1d2b4d3SLarry Finger
1810f1d2b4d3SLarry Finger if (hwinfo[addr] == 0xFF) {
1811f1d2b4d3SLarry Finger pw2g->ofdm_diff[path][cnt] = 0x04;
1812f1d2b4d3SLarry Finger } else {
1813f1d2b4d3SLarry Finger pw2g->ofdm_diff[path][cnt] =
1814f1d2b4d3SLarry Finger (hwinfo[addr] & 0x0f);
1815f1d2b4d3SLarry Finger /*bit sign number to 8 bit sign number*/
1816f1d2b4d3SLarry Finger if (pw2g->ofdm_diff[path][cnt] & BIT(3))
1817f1d2b4d3SLarry Finger pw2g->ofdm_diff[path][cnt] |=
1818f1d2b4d3SLarry Finger 0xF0;
1819f1d2b4d3SLarry Finger }
1820f1d2b4d3SLarry Finger pw2g->cck_diff[path][cnt] = 0;
1821f1d2b4d3SLarry Finger addr++;
1822f1d2b4d3SLarry Finger } else {
1823f1d2b4d3SLarry Finger if (hwinfo[addr] == 0xFF) {
1824f1d2b4d3SLarry Finger pw2g->bw40_diff[path][cnt] = 0xFE;
1825f1d2b4d3SLarry Finger } else {
1826f1d2b4d3SLarry Finger pw2g->bw40_diff[path][cnt] =
1827f1d2b4d3SLarry Finger (hwinfo[addr] & 0xf0) >> 4;
1828f1d2b4d3SLarry Finger if (pw2g->bw40_diff[path][cnt] & BIT(3))
1829f1d2b4d3SLarry Finger pw2g->bw40_diff[path][cnt] |=
1830f1d2b4d3SLarry Finger 0xF0;
1831f1d2b4d3SLarry Finger }
1832f1d2b4d3SLarry Finger
1833f1d2b4d3SLarry Finger if (hwinfo[addr] == 0xFF) {
1834f1d2b4d3SLarry Finger pw2g->bw20_diff[path][cnt] = 0xFE;
1835f1d2b4d3SLarry Finger } else {
1836f1d2b4d3SLarry Finger pw2g->bw20_diff[path][cnt] =
1837f1d2b4d3SLarry Finger (hwinfo[addr] & 0x0f);
1838f1d2b4d3SLarry Finger if (pw2g->bw20_diff[path][cnt] & BIT(3))
1839f1d2b4d3SLarry Finger pw2g->bw20_diff[path][cnt] |=
1840f1d2b4d3SLarry Finger 0xF0;
1841f1d2b4d3SLarry Finger }
1842f1d2b4d3SLarry Finger addr++;
1843f1d2b4d3SLarry Finger
1844f1d2b4d3SLarry Finger if (hwinfo[addr] == 0xFF) {
1845f1d2b4d3SLarry Finger pw2g->ofdm_diff[path][cnt] = 0xFE;
1846f1d2b4d3SLarry Finger } else {
1847f1d2b4d3SLarry Finger pw2g->ofdm_diff[path][cnt] =
1848f1d2b4d3SLarry Finger (hwinfo[addr] & 0xf0) >> 4;
1849f1d2b4d3SLarry Finger if (pw2g->ofdm_diff[path][cnt] & BIT(3))
1850f1d2b4d3SLarry Finger pw2g->ofdm_diff[path][cnt] |=
1851f1d2b4d3SLarry Finger 0xF0;
1852f1d2b4d3SLarry Finger }
1853f1d2b4d3SLarry Finger
1854f1d2b4d3SLarry Finger if (hwinfo[addr] == 0xFF)
1855f1d2b4d3SLarry Finger pw2g->cck_diff[path][cnt] = 0xFE;
1856f1d2b4d3SLarry Finger else {
1857f1d2b4d3SLarry Finger pw2g->cck_diff[path][cnt] =
1858f1d2b4d3SLarry Finger (hwinfo[addr] & 0x0f);
1859f1d2b4d3SLarry Finger if (pw2g->cck_diff[path][cnt] & BIT(3))
1860f1d2b4d3SLarry Finger pw2g->cck_diff[path][cnt] |=
1861f1d2b4d3SLarry Finger 0xF0;
1862f1d2b4d3SLarry Finger }
1863f1d2b4d3SLarry Finger addr++;
1864f1d2b4d3SLarry Finger }
1865f1d2b4d3SLarry Finger }
1866f1d2b4d3SLarry Finger
1867f1d2b4d3SLarry Finger /*5G default value*/
1868f1d2b4d3SLarry Finger for (group = 0; group < MAX_CHNL_GROUP_5G; group++) {
1869f1d2b4d3SLarry Finger pw5g->index_bw40_base[path][group] = hwinfo[addr++];
1870f1d2b4d3SLarry Finger if (pw5g->index_bw40_base[path][group] == 0xFF)
1871f1d2b4d3SLarry Finger pw5g->index_bw40_base[path][group] = 0xFE;
1872f1d2b4d3SLarry Finger }
1873f1d2b4d3SLarry Finger
1874f1d2b4d3SLarry Finger for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1875f1d2b4d3SLarry Finger if (cnt == 0) {
1876f1d2b4d3SLarry Finger pw5g->bw40_diff[path][cnt] = 0;
1877f1d2b4d3SLarry Finger
1878f1d2b4d3SLarry Finger if (hwinfo[addr] == 0xFF) {
1879f1d2b4d3SLarry Finger pw5g->bw20_diff[path][cnt] = 0;
1880f1d2b4d3SLarry Finger } else {
1881f1d2b4d3SLarry Finger pw5g->bw20_diff[path][0] =
1882f1d2b4d3SLarry Finger (hwinfo[addr] & 0xf0) >> 4;
1883f1d2b4d3SLarry Finger if (pw5g->bw20_diff[path][cnt] & BIT(3))
1884f1d2b4d3SLarry Finger pw5g->bw20_diff[path][cnt] |=
1885f1d2b4d3SLarry Finger 0xF0;
1886f1d2b4d3SLarry Finger }
1887f1d2b4d3SLarry Finger
1888f1d2b4d3SLarry Finger if (hwinfo[addr] == 0xFF)
1889f1d2b4d3SLarry Finger pw5g->ofdm_diff[path][cnt] = 0x04;
1890f1d2b4d3SLarry Finger else {
1891f1d2b4d3SLarry Finger pw5g->ofdm_diff[path][0] =
1892f1d2b4d3SLarry Finger (hwinfo[addr] & 0x0f);
1893f1d2b4d3SLarry Finger if (pw5g->ofdm_diff[path][cnt] & BIT(3))
1894f1d2b4d3SLarry Finger pw5g->ofdm_diff[path][cnt] |=
1895f1d2b4d3SLarry Finger 0xF0;
1896f1d2b4d3SLarry Finger }
1897f1d2b4d3SLarry Finger addr++;
1898f1d2b4d3SLarry Finger } else {
1899f1d2b4d3SLarry Finger if (hwinfo[addr] == 0xFF) {
1900f1d2b4d3SLarry Finger pw5g->bw40_diff[path][cnt] = 0xFE;
1901f1d2b4d3SLarry Finger } else {
1902f1d2b4d3SLarry Finger pw5g->bw40_diff[path][cnt] =
1903f1d2b4d3SLarry Finger (hwinfo[addr] & 0xf0) >> 4;
1904f1d2b4d3SLarry Finger if (pw5g->bw40_diff[path][cnt] & BIT(3))
1905f1d2b4d3SLarry Finger pw5g->bw40_diff[path][cnt] |= 0xF0;
1906f1d2b4d3SLarry Finger }
1907f1d2b4d3SLarry Finger
1908f1d2b4d3SLarry Finger if (hwinfo[addr] == 0xFF) {
1909f1d2b4d3SLarry Finger pw5g->bw20_diff[path][cnt] = 0xFE;
1910f1d2b4d3SLarry Finger } else {
1911f1d2b4d3SLarry Finger pw5g->bw20_diff[path][cnt] =
1912f1d2b4d3SLarry Finger (hwinfo[addr] & 0x0f);
1913f1d2b4d3SLarry Finger if (pw5g->bw20_diff[path][cnt] & BIT(3))
1914f1d2b4d3SLarry Finger pw5g->bw20_diff[path][cnt] |= 0xF0;
1915f1d2b4d3SLarry Finger }
1916f1d2b4d3SLarry Finger addr++;
1917f1d2b4d3SLarry Finger }
1918f1d2b4d3SLarry Finger }
1919f1d2b4d3SLarry Finger
1920f1d2b4d3SLarry Finger if (hwinfo[addr] == 0xFF) {
1921f1d2b4d3SLarry Finger pw5g->ofdm_diff[path][1] = 0xFE;
1922f1d2b4d3SLarry Finger pw5g->ofdm_diff[path][2] = 0xFE;
1923f1d2b4d3SLarry Finger } else {
1924f1d2b4d3SLarry Finger pw5g->ofdm_diff[path][1] = (hwinfo[addr] & 0xf0) >> 4;
1925f1d2b4d3SLarry Finger pw5g->ofdm_diff[path][2] = (hwinfo[addr] & 0x0f);
1926f1d2b4d3SLarry Finger }
1927f1d2b4d3SLarry Finger addr++;
1928f1d2b4d3SLarry Finger
1929f1d2b4d3SLarry Finger if (hwinfo[addr] == 0xFF)
1930f1d2b4d3SLarry Finger pw5g->ofdm_diff[path][3] = 0xFE;
1931f1d2b4d3SLarry Finger else
1932f1d2b4d3SLarry Finger pw5g->ofdm_diff[path][3] = (hwinfo[addr] & 0x0f);
1933f1d2b4d3SLarry Finger addr++;
1934f1d2b4d3SLarry Finger
1935f1d2b4d3SLarry Finger for (cnt = 1; cnt < MAX_TX_COUNT; cnt++) {
1936f1d2b4d3SLarry Finger if (pw5g->ofdm_diff[path][cnt] == 0xFF)
1937f1d2b4d3SLarry Finger pw5g->ofdm_diff[path][cnt] = 0xFE;
1938f1d2b4d3SLarry Finger else if (pw5g->ofdm_diff[path][cnt] & BIT(3))
1939f1d2b4d3SLarry Finger pw5g->ofdm_diff[path][cnt] |= 0xF0;
1940f1d2b4d3SLarry Finger }
1941f1d2b4d3SLarry Finger }
1942f1d2b4d3SLarry Finger }
1943f1d2b4d3SLarry Finger
_rtl8723be_read_txpower_info_from_hwpg(struct ieee80211_hw * hw,bool autoload_fail,u8 * hwinfo)1944f1d2b4d3SLarry Finger static void _rtl8723be_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1945f1d2b4d3SLarry Finger bool autoload_fail,
1946f1d2b4d3SLarry Finger u8 *hwinfo)
1947f1d2b4d3SLarry Finger {
1948f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1949f1d2b4d3SLarry Finger struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1950f1d2b4d3SLarry Finger struct txpower_info_2g pw2g;
1951f1d2b4d3SLarry Finger struct txpower_info_5g pw5g;
1952f1d2b4d3SLarry Finger u8 rf_path, index;
1953f1d2b4d3SLarry Finger u8 i;
1954f1d2b4d3SLarry Finger
1955f1d2b4d3SLarry Finger _rtl8723be_read_power_value_fromprom(hw, &pw2g, &pw5g, autoload_fail,
1956f1d2b4d3SLarry Finger hwinfo);
1957f1d2b4d3SLarry Finger
1958f1d2b4d3SLarry Finger for (rf_path = 0; rf_path < 2; rf_path++) {
1959f1d2b4d3SLarry Finger for (i = 0; i < 14; i++) {
1960f1d2b4d3SLarry Finger index = _rtl8723be_get_chnl_group(i+1);
1961f1d2b4d3SLarry Finger
1962f1d2b4d3SLarry Finger rtlefuse->txpwrlevel_cck[rf_path][i] =
1963f1d2b4d3SLarry Finger pw2g.index_cck_base[rf_path][index];
1964f1d2b4d3SLarry Finger rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
1965f1d2b4d3SLarry Finger pw2g.index_bw40_base[rf_path][index];
1966f1d2b4d3SLarry Finger }
1967f1d2b4d3SLarry Finger for (i = 0; i < MAX_TX_COUNT; i++) {
1968f1d2b4d3SLarry Finger rtlefuse->txpwr_ht20diff[rf_path][i] =
1969f1d2b4d3SLarry Finger pw2g.bw20_diff[rf_path][i];
1970f1d2b4d3SLarry Finger rtlefuse->txpwr_ht40diff[rf_path][i] =
1971f1d2b4d3SLarry Finger pw2g.bw40_diff[rf_path][i];
1972f1d2b4d3SLarry Finger rtlefuse->txpwr_legacyhtdiff[rf_path][i] =
1973f1d2b4d3SLarry Finger pw2g.ofdm_diff[rf_path][i];
1974f1d2b4d3SLarry Finger }
1975f1d2b4d3SLarry Finger
1976f1d2b4d3SLarry Finger for (i = 0; i < 14; i++) {
1977f1d2b4d3SLarry Finger RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1978f1d2b4d3SLarry Finger "RF(%d)-Ch(%d) [CCK / HT40_1S ] = [0x%x / 0x%x ]\n",
1979f1d2b4d3SLarry Finger rf_path, i,
1980f1d2b4d3SLarry Finger rtlefuse->txpwrlevel_cck[rf_path][i],
1981f1d2b4d3SLarry Finger rtlefuse->txpwrlevel_ht40_1s[rf_path][i]);
1982f1d2b4d3SLarry Finger }
1983f1d2b4d3SLarry Finger }
1984f1d2b4d3SLarry Finger
1985f1d2b4d3SLarry Finger if (!autoload_fail)
1986f1d2b4d3SLarry Finger rtlefuse->eeprom_thermalmeter =
1987f1d2b4d3SLarry Finger hwinfo[EEPROM_THERMAL_METER_88E];
1988f1d2b4d3SLarry Finger else
1989f1d2b4d3SLarry Finger rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
1990f1d2b4d3SLarry Finger
1991f1d2b4d3SLarry Finger if (rtlefuse->eeprom_thermalmeter == 0xff || autoload_fail) {
1992f1d2b4d3SLarry Finger rtlefuse->apk_thermalmeterignore = true;
1993f1d2b4d3SLarry Finger rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
1994f1d2b4d3SLarry Finger }
1995f1d2b4d3SLarry Finger
1996f1d2b4d3SLarry Finger rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
1997f1d2b4d3SLarry Finger RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1998f1d2b4d3SLarry Finger "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
1999f1d2b4d3SLarry Finger
2000f1d2b4d3SLarry Finger if (!autoload_fail) {
2001f1d2b4d3SLarry Finger rtlefuse->eeprom_regulatory =
2002f1d2b4d3SLarry Finger hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0x07;/*bit0~2*/
2003f1d2b4d3SLarry Finger if (hwinfo[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
2004f1d2b4d3SLarry Finger rtlefuse->eeprom_regulatory = 0;
2005f1d2b4d3SLarry Finger } else {
2006f1d2b4d3SLarry Finger rtlefuse->eeprom_regulatory = 0;
2007f1d2b4d3SLarry Finger }
20087fe1fe75SPing-Ke Shih RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
20097fe1fe75SPing-Ke Shih "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
20107fe1fe75SPing-Ke Shih }
20117fe1fe75SPing-Ke Shih
_rtl8723be_read_package_type(struct ieee80211_hw * hw)20127fe1fe75SPing-Ke Shih static u8 _rtl8723be_read_package_type(struct ieee80211_hw *hw)
20137fe1fe75SPing-Ke Shih {
20147fe1fe75SPing-Ke Shih u8 package_type;
20157fe1fe75SPing-Ke Shih u8 value;
20167fe1fe75SPing-Ke Shih
20177fe1fe75SPing-Ke Shih efuse_power_switch(hw, false, true);
20187fe1fe75SPing-Ke Shih if (!efuse_one_byte_read(hw, 0x1FB, &value))
20197fe1fe75SPing-Ke Shih value = 0;
20207fe1fe75SPing-Ke Shih efuse_power_switch(hw, false, false);
20217fe1fe75SPing-Ke Shih
20227fe1fe75SPing-Ke Shih switch (value & 0x7) {
20237fe1fe75SPing-Ke Shih case 0x4:
20247fe1fe75SPing-Ke Shih package_type = PACKAGE_TFBGA79;
20257fe1fe75SPing-Ke Shih break;
20267fe1fe75SPing-Ke Shih case 0x5:
20277fe1fe75SPing-Ke Shih package_type = PACKAGE_TFBGA90;
20287fe1fe75SPing-Ke Shih break;
20297fe1fe75SPing-Ke Shih case 0x6:
20307fe1fe75SPing-Ke Shih package_type = PACKAGE_QFN68;
20317fe1fe75SPing-Ke Shih break;
20327fe1fe75SPing-Ke Shih case 0x7:
20337fe1fe75SPing-Ke Shih package_type = PACKAGE_TFBGA80;
20347fe1fe75SPing-Ke Shih break;
20357fe1fe75SPing-Ke Shih default:
20367fe1fe75SPing-Ke Shih package_type = PACKAGE_DEFAULT;
20377fe1fe75SPing-Ke Shih break;
20387fe1fe75SPing-Ke Shih }
2039f1d2b4d3SLarry Finger
2040f1d2b4d3SLarry Finger return package_type;
2041f1d2b4d3SLarry Finger }
2042f1d2b4d3SLarry Finger
_rtl8723be_read_adapter_info(struct ieee80211_hw * hw,bool pseudo_test)2043f1d2b4d3SLarry Finger static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw,
2044f1d2b4d3SLarry Finger bool pseudo_test)
20459e9c9c24SLarry Finger {
20469e9c9c24SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
20479e9c9c24SLarry Finger struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
20489e9c9c24SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
20499e9c9c24SLarry Finger int params[] = {RTL8723BE_EEPROM_ID, EEPROM_VID, EEPROM_DID,
20509e9c9c24SLarry Finger EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR,
2051f1d2b4d3SLarry Finger EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID,
2052f1d2b4d3SLarry Finger COUNTRY_CODE_WORLD_WIDE_13};
2053f1d2b4d3SLarry Finger u8 *hwinfo;
2054f1d2b4d3SLarry Finger int i;
2055f1d2b4d3SLarry Finger bool is_toshiba_smid1 = false;
2056f1d2b4d3SLarry Finger bool is_toshiba_smid2 = false;
2057f1d2b4d3SLarry Finger bool is_samsung_smid = false;
2058f1d2b4d3SLarry Finger bool is_lenovo_smid = false;
2059f1d2b4d3SLarry Finger u16 toshiba_smid1[] = {
2060f1d2b4d3SLarry Finger 0x6151, 0x6152, 0x6154, 0x6155, 0x6177, 0x6178, 0x6179, 0x6180,
2061f1d2b4d3SLarry Finger 0x7151, 0x7152, 0x7154, 0x7155, 0x7177, 0x7178, 0x7179, 0x7180,
2062f1d2b4d3SLarry Finger 0x8151, 0x8152, 0x8154, 0x8155, 0x8181, 0x8182, 0x8184, 0x8185,
2063f1d2b4d3SLarry Finger 0x9151, 0x9152, 0x9154, 0x9155, 0x9181, 0x9182, 0x9184, 0x9185
2064f1d2b4d3SLarry Finger };
2065f1d2b4d3SLarry Finger u16 toshiba_smid2[] = {
2066f1d2b4d3SLarry Finger 0x6181, 0x6184, 0x6185, 0x7181, 0x7182, 0x7184, 0x7185, 0x8181,
2067f1d2b4d3SLarry Finger 0x8182, 0x8184, 0x8185, 0x9181, 0x9182, 0x9184, 0x9185
2068f1d2b4d3SLarry Finger };
2069f1d2b4d3SLarry Finger u16 samsung_smid[] = {
2070f1d2b4d3SLarry Finger 0x6191, 0x6192, 0x6193, 0x7191, 0x7192, 0x7193, 0x8191, 0x8192,
2071f1d2b4d3SLarry Finger 0x8193, 0x9191, 0x9192, 0x9193
2072f1d2b4d3SLarry Finger };
2073f1d2b4d3SLarry Finger u16 lenovo_smid[] = {
2074f1d2b4d3SLarry Finger 0x8195, 0x9195, 0x7194, 0x8200, 0x8201, 0x8202, 0x9199, 0x9200
2075f1d2b4d3SLarry Finger };
2076f1d2b4d3SLarry Finger
2077f1d2b4d3SLarry Finger if (pseudo_test) {
20789e9c9c24SLarry Finger /* needs to be added */
20799e9c9c24SLarry Finger return;
20805345ea6aSArnd Bergmann }
20815345ea6aSArnd Bergmann
20829e9c9c24SLarry Finger hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL);
20839e9c9c24SLarry Finger if (!hwinfo)
2084f1d2b4d3SLarry Finger return;
2085f1d2b4d3SLarry Finger
2086f1d2b4d3SLarry Finger if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params))
2087f1d2b4d3SLarry Finger goto exit;
2088f1d2b4d3SLarry Finger
2089f1d2b4d3SLarry Finger /*parse xtal*/
2090f1d2b4d3SLarry Finger rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_8723BE];
2091f1d2b4d3SLarry Finger if (rtlefuse->crystalcap == 0xFF)
2092f1d2b4d3SLarry Finger rtlefuse->crystalcap = 0x20;
2093f1d2b4d3SLarry Finger
2094f1d2b4d3SLarry Finger _rtl8723be_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag,
2095f1d2b4d3SLarry Finger hwinfo);
2096f1d2b4d3SLarry Finger
2097881d53abSPing-Ke Shih rtl8723be_read_bt_coexist_info_from_hwpg(hw,
2098881d53abSPing-Ke Shih rtlefuse->autoload_failflag,
2099881d53abSPing-Ke Shih hwinfo);
2100881d53abSPing-Ke Shih
2101e6dd230aSLarry Finger if (rtlpriv->btcoexist.btc_info.btcoexist == 1)
2102881d53abSPing-Ke Shih rtlefuse->board_type |= BIT(2); /* ODM_BOARD_BT */
2103881d53abSPing-Ke Shih
21047fe1fe75SPing-Ke Shih rtlhal->board_type = rtlefuse->board_type;
21057fe1fe75SPing-Ke Shih rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
2106f1d2b4d3SLarry Finger "board_type = 0x%x\n", rtlefuse->board_type);
2107f1d2b4d3SLarry Finger
2108f1d2b4d3SLarry Finger rtlhal->package_type = _rtl8723be_read_package_type(hw);
2109f1d2b4d3SLarry Finger
2110f1d2b4d3SLarry Finger /* set channel plan from efuse */
211153ac7935SJérémy Lefaure rtlefuse->channel_plan = rtlefuse->eeprom_channelplan;
2112f1d2b4d3SLarry Finger
2113f1d2b4d3SLarry Finger if (rtlhal->oem_id == RT_CID_DEFAULT) {
2114f1d2b4d3SLarry Finger /* Does this one have a Toshiba SMID from group 1? */
2115f1d2b4d3SLarry Finger for (i = 0; i < ARRAY_SIZE(toshiba_smid1); i++) {
2116f1d2b4d3SLarry Finger if (rtlefuse->eeprom_smid == toshiba_smid1[i]) {
2117f1d2b4d3SLarry Finger is_toshiba_smid1 = true;
211853ac7935SJérémy Lefaure break;
2119f1d2b4d3SLarry Finger }
2120f1d2b4d3SLarry Finger }
2121f1d2b4d3SLarry Finger /* Does this one have a Toshiba SMID from group 2? */
2122f1d2b4d3SLarry Finger for (i = 0; i < ARRAY_SIZE(toshiba_smid2); i++) {
2123f1d2b4d3SLarry Finger if (rtlefuse->eeprom_smid == toshiba_smid2[i]) {
2124f1d2b4d3SLarry Finger is_toshiba_smid2 = true;
212553ac7935SJérémy Lefaure break;
2126f1d2b4d3SLarry Finger }
2127f1d2b4d3SLarry Finger }
2128f1d2b4d3SLarry Finger /* Does this one have a Samsung SMID? */
2129f1d2b4d3SLarry Finger for (i = 0; i < ARRAY_SIZE(samsung_smid); i++) {
2130f1d2b4d3SLarry Finger if (rtlefuse->eeprom_smid == samsung_smid[i]) {
2131f1d2b4d3SLarry Finger is_samsung_smid = true;
213253ac7935SJérémy Lefaure break;
2133f1d2b4d3SLarry Finger }
2134f1d2b4d3SLarry Finger }
2135f1d2b4d3SLarry Finger /* Does this one have a Lenovo SMID? */
2136f1d2b4d3SLarry Finger for (i = 0; i < ARRAY_SIZE(lenovo_smid); i++) {
2137f1d2b4d3SLarry Finger if (rtlefuse->eeprom_smid == lenovo_smid[i]) {
2138f1d2b4d3SLarry Finger is_lenovo_smid = true;
2139f1d2b4d3SLarry Finger break;
2140f1d2b4d3SLarry Finger }
2141f1d2b4d3SLarry Finger }
2142f1d2b4d3SLarry Finger switch (rtlefuse->eeprom_oemid) {
2143f1d2b4d3SLarry Finger case EEPROM_CID_DEFAULT:
2144f1d2b4d3SLarry Finger if (rtlefuse->eeprom_did == 0x8176) {
2145f1d2b4d3SLarry Finger if (rtlefuse->eeprom_svid == 0x10EC &&
2146f1d2b4d3SLarry Finger is_toshiba_smid1) {
2147f1d2b4d3SLarry Finger rtlhal->oem_id = RT_CID_TOSHIBA;
2148f1d2b4d3SLarry Finger } else if (rtlefuse->eeprom_svid == 0x1025) {
2149f1d2b4d3SLarry Finger rtlhal->oem_id = RT_CID_819X_ACER;
2150f1d2b4d3SLarry Finger } else if (rtlefuse->eeprom_svid == 0x10EC &&
2151f1d2b4d3SLarry Finger is_samsung_smid) {
2152f1d2b4d3SLarry Finger rtlhal->oem_id = RT_CID_819X_SAMSUNG;
2153f1d2b4d3SLarry Finger } else if (rtlefuse->eeprom_svid == 0x10EC &&
2154f1d2b4d3SLarry Finger is_lenovo_smid) {
2155f1d2b4d3SLarry Finger rtlhal->oem_id = RT_CID_819X_LENOVO;
2156f1d2b4d3SLarry Finger } else if ((rtlefuse->eeprom_svid == 0x10EC &&
2157f1d2b4d3SLarry Finger rtlefuse->eeprom_smid == 0x8197) ||
2158f1d2b4d3SLarry Finger (rtlefuse->eeprom_svid == 0x10EC &&
2159f1d2b4d3SLarry Finger rtlefuse->eeprom_smid == 0x9196)) {
2160f1d2b4d3SLarry Finger rtlhal->oem_id = RT_CID_819X_CLEVO;
2161f1d2b4d3SLarry Finger } else if ((rtlefuse->eeprom_svid == 0x1028 &&
2162f1d2b4d3SLarry Finger rtlefuse->eeprom_smid == 0x8194) ||
2163f1d2b4d3SLarry Finger (rtlefuse->eeprom_svid == 0x1028 &&
2164f1d2b4d3SLarry Finger rtlefuse->eeprom_smid == 0x8198) ||
2165f1d2b4d3SLarry Finger (rtlefuse->eeprom_svid == 0x1028 &&
2166f1d2b4d3SLarry Finger rtlefuse->eeprom_smid == 0x9197) ||
2167f1d2b4d3SLarry Finger (rtlefuse->eeprom_svid == 0x1028 &&
2168f1d2b4d3SLarry Finger rtlefuse->eeprom_smid == 0x9198)) {
2169f1d2b4d3SLarry Finger rtlhal->oem_id = RT_CID_819X_DELL;
2170f1d2b4d3SLarry Finger } else if ((rtlefuse->eeprom_svid == 0x103C &&
2171f1d2b4d3SLarry Finger rtlefuse->eeprom_smid == 0x1629)) {
2172f1d2b4d3SLarry Finger rtlhal->oem_id = RT_CID_819X_HP;
2173f1d2b4d3SLarry Finger } else if ((rtlefuse->eeprom_svid == 0x1A32 &&
2174f1d2b4d3SLarry Finger rtlefuse->eeprom_smid == 0x2315)) {
2175f1d2b4d3SLarry Finger rtlhal->oem_id = RT_CID_819X_QMI;
2176f1d2b4d3SLarry Finger } else if ((rtlefuse->eeprom_svid == 0x10EC &&
2177f1d2b4d3SLarry Finger rtlefuse->eeprom_smid == 0x8203)) {
2178f1d2b4d3SLarry Finger rtlhal->oem_id = RT_CID_819X_PRONETS;
2179f1d2b4d3SLarry Finger } else if ((rtlefuse->eeprom_svid == 0x1043 &&
2180f1d2b4d3SLarry Finger rtlefuse->eeprom_smid == 0x84B5)) {
2181f1d2b4d3SLarry Finger rtlhal->oem_id = RT_CID_819X_EDIMAX_ASUS;
2182f1d2b4d3SLarry Finger } else {
2183f1d2b4d3SLarry Finger rtlhal->oem_id = RT_CID_DEFAULT;
2184f1d2b4d3SLarry Finger }
2185f1d2b4d3SLarry Finger } else if (rtlefuse->eeprom_did == 0x8178) {
2186f1d2b4d3SLarry Finger if (rtlefuse->eeprom_svid == 0x10EC &&
2187f1d2b4d3SLarry Finger is_toshiba_smid2)
2188f1d2b4d3SLarry Finger rtlhal->oem_id = RT_CID_TOSHIBA;
2189f1d2b4d3SLarry Finger else if (rtlefuse->eeprom_svid == 0x1025)
2190f1d2b4d3SLarry Finger rtlhal->oem_id = RT_CID_819X_ACER;
2191f1d2b4d3SLarry Finger else if ((rtlefuse->eeprom_svid == 0x10EC &&
2192f1d2b4d3SLarry Finger rtlefuse->eeprom_smid == 0x8186))
2193f1d2b4d3SLarry Finger rtlhal->oem_id = RT_CID_819X_PRONETS;
2194f1d2b4d3SLarry Finger else if ((rtlefuse->eeprom_svid == 0x1043 &&
2195f1d2b4d3SLarry Finger rtlefuse->eeprom_smid == 0x84B6))
2196f1d2b4d3SLarry Finger rtlhal->oem_id =
2197f1d2b4d3SLarry Finger RT_CID_819X_EDIMAX_ASUS;
2198f1d2b4d3SLarry Finger else
2199f1d2b4d3SLarry Finger rtlhal->oem_id = RT_CID_DEFAULT;
2200f1d2b4d3SLarry Finger } else {
2201f1d2b4d3SLarry Finger rtlhal->oem_id = RT_CID_DEFAULT;
2202f1d2b4d3SLarry Finger }
2203f1d2b4d3SLarry Finger break;
2204f1d2b4d3SLarry Finger case EEPROM_CID_TOSHIBA:
2205f1d2b4d3SLarry Finger rtlhal->oem_id = RT_CID_TOSHIBA;
2206f1d2b4d3SLarry Finger break;
2207f1d2b4d3SLarry Finger case EEPROM_CID_CCX:
2208f1d2b4d3SLarry Finger rtlhal->oem_id = RT_CID_CCX;
2209f1d2b4d3SLarry Finger break;
2210f1d2b4d3SLarry Finger case EEPROM_CID_QMI:
2211f1d2b4d3SLarry Finger rtlhal->oem_id = RT_CID_819X_QMI;
2212f1d2b4d3SLarry Finger break;
2213f1d2b4d3SLarry Finger case EEPROM_CID_WHQL:
2214f1d2b4d3SLarry Finger break;
2215f1d2b4d3SLarry Finger default:
22169e9c9c24SLarry Finger rtlhal->oem_id = RT_CID_DEFAULT;
22179e9c9c24SLarry Finger break;
2218f1d2b4d3SLarry Finger }
2219f1d2b4d3SLarry Finger }
2220f1d2b4d3SLarry Finger exit:
2221f1d2b4d3SLarry Finger kfree(hwinfo);
2222f1d2b4d3SLarry Finger }
2223f1d2b4d3SLarry Finger
_rtl8723be_hal_customized_behavior(struct ieee80211_hw * hw)2224f1d2b4d3SLarry Finger static void _rtl8723be_hal_customized_behavior(struct ieee80211_hw *hw)
2225d5efe153SLarry Finger {
2226f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
2227f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2228d5efe153SLarry Finger
2229f1d2b4d3SLarry Finger rtlpriv->ledctl.led_opendrain = true;
2230f1d2b4d3SLarry Finger switch (rtlhal->oem_id) {
2231f1d2b4d3SLarry Finger case RT_CID_819X_HP:
2232f1d2b4d3SLarry Finger rtlpriv->ledctl.led_opendrain = true;
2233f1d2b4d3SLarry Finger break;
2234f1d2b4d3SLarry Finger case RT_CID_819X_LENOVO:
2235f1d2b4d3SLarry Finger case RT_CID_DEFAULT:
2236f1d2b4d3SLarry Finger case RT_CID_TOSHIBA:
2237f1d2b4d3SLarry Finger case RT_CID_CCX:
2238f1d2b4d3SLarry Finger case RT_CID_819X_ACER:
2239e6dd230aSLarry Finger case RT_CID_WHQL:
2240f1d2b4d3SLarry Finger default:
2241f1d2b4d3SLarry Finger break;
2242f1d2b4d3SLarry Finger }
2243f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG,
2244f1d2b4d3SLarry Finger "RT Customized ID: 0x%02X\n", rtlhal->oem_id);
2245f1d2b4d3SLarry Finger }
2246f1d2b4d3SLarry Finger
rtl8723be_read_eeprom_info(struct ieee80211_hw * hw)2247f1d2b4d3SLarry Finger void rtl8723be_read_eeprom_info(struct ieee80211_hw *hw)
2248f1d2b4d3SLarry Finger {
2249f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
2250f1d2b4d3SLarry Finger struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2251f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
2252f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2253f1d2b4d3SLarry Finger u8 tmp_u1b;
2254f1d2b4d3SLarry Finger
2255f1d2b4d3SLarry Finger rtlhal->version = _rtl8723be_read_chip_version(hw);
2256f1d2b4d3SLarry Finger if (get_rf_type(rtlphy) == RF_1T1R)
2257e6dd230aSLarry Finger rtlpriv->dm.rfpath_rxenable[0] = true;
2258f1d2b4d3SLarry Finger else
2259f1d2b4d3SLarry Finger rtlpriv->dm.rfpath_rxenable[0] =
2260f1d2b4d3SLarry Finger rtlpriv->dm.rfpath_rxenable[1] = true;
2261e6dd230aSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
2262f1d2b4d3SLarry Finger rtlhal->version);
2263f1d2b4d3SLarry Finger tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
2264e6dd230aSLarry Finger if (tmp_u1b & BIT(4)) {
2265f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
2266f1d2b4d3SLarry Finger rtlefuse->epromtype = EEPROM_93C46;
2267f1d2b4d3SLarry Finger } else {
2268e6dd230aSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
2269f1d2b4d3SLarry Finger rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
2270f1d2b4d3SLarry Finger }
2271f1d2b4d3SLarry Finger if (tmp_u1b & BIT(5)) {
22724e2b4378SLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
2273f1d2b4d3SLarry Finger rtlefuse->autoload_failflag = false;
2274f1d2b4d3SLarry Finger _rtl8723be_read_adapter_info(hw, false);
2275f1d2b4d3SLarry Finger } else {
2276f1d2b4d3SLarry Finger pr_err("Autoload ERR!!\n");
2277f1d2b4d3SLarry Finger }
2278f1d2b4d3SLarry Finger _rtl8723be_hal_customized_behavior(hw);
2279f1d2b4d3SLarry Finger }
2280f1d2b4d3SLarry Finger
_rtl8723be_mrate_idx_to_arfr_id(struct ieee80211_hw * hw,u8 rate_index)2281f1d2b4d3SLarry Finger static u8 _rtl8723be_mrate_idx_to_arfr_id(struct ieee80211_hw *hw,
2282f1d2b4d3SLarry Finger u8 rate_index)
2283f1d2b4d3SLarry Finger {
2284f1d2b4d3SLarry Finger u8 ret = 0;
2285f1d2b4d3SLarry Finger switch (rate_index) {
2286f1d2b4d3SLarry Finger case RATR_INX_WIRELESS_NGB:
2287f1d2b4d3SLarry Finger ret = 1;
2288f1d2b4d3SLarry Finger break;
2289f1d2b4d3SLarry Finger case RATR_INX_WIRELESS_N:
2290f1d2b4d3SLarry Finger case RATR_INX_WIRELESS_NG:
2291f1d2b4d3SLarry Finger ret = 5;
2292f1d2b4d3SLarry Finger break;
2293f1d2b4d3SLarry Finger case RATR_INX_WIRELESS_NB:
2294f1d2b4d3SLarry Finger ret = 3;
2295f1d2b4d3SLarry Finger break;
2296f1d2b4d3SLarry Finger case RATR_INX_WIRELESS_GB:
2297f1d2b4d3SLarry Finger ret = 6;
2298f1d2b4d3SLarry Finger break;
2299f1d2b4d3SLarry Finger case RATR_INX_WIRELESS_G:
2300f1d2b4d3SLarry Finger ret = 7;
2301f1d2b4d3SLarry Finger break;
2302f1d2b4d3SLarry Finger case RATR_INX_WIRELESS_B:
2303f1d2b4d3SLarry Finger ret = 8;
2304f1d2b4d3SLarry Finger break;
2305f1d2b4d3SLarry Finger default:
2306f1d2b4d3SLarry Finger ret = 0;
2307f1d2b4d3SLarry Finger break;
2308f1d2b4d3SLarry Finger }
2309f1d2b4d3SLarry Finger return ret;
23101d22b177SPing-Ke Shih }
2311f1d2b4d3SLarry Finger
rtl8723be_update_hal_rate_mask(struct ieee80211_hw * hw,struct ieee80211_sta * sta,u8 rssi_level,bool update_bw)2312f1d2b4d3SLarry Finger static void rtl8723be_update_hal_rate_mask(struct ieee80211_hw *hw,
2313f1d2b4d3SLarry Finger struct ieee80211_sta *sta,
2314f1d2b4d3SLarry Finger u8 rssi_level, bool update_bw)
2315f1d2b4d3SLarry Finger {
2316f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
2317f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
2318*046d2e7cSSriram R struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2319f1d2b4d3SLarry Finger struct rtl_sta_info *sta_entry = NULL;
2320*046d2e7cSSriram R u32 ratr_bitmap;
2321f1d2b4d3SLarry Finger u8 ratr_index;
2322*046d2e7cSSriram R u8 curtxbw_40mhz = (sta->deflink.ht_cap.cap &
2323f1d2b4d3SLarry Finger IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0;
2324f1d2b4d3SLarry Finger u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
2325f1d2b4d3SLarry Finger 1 : 0;
2326f1d2b4d3SLarry Finger u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
2327f1d2b4d3SLarry Finger 1 : 0;
2328f1d2b4d3SLarry Finger enum wireless_mode wirelessmode = 0;
2329f1d2b4d3SLarry Finger bool shortgi = false;
2330f1d2b4d3SLarry Finger u8 rate_mask[7];
2331f1d2b4d3SLarry Finger u8 macid = 0;
2332f1d2b4d3SLarry Finger
2333f1d2b4d3SLarry Finger sta_entry = (struct rtl_sta_info *)sta->drv_priv;
2334f1d2b4d3SLarry Finger wirelessmode = sta_entry->wireless_mode;
2335f1d2b4d3SLarry Finger if (mac->opmode == NL80211_IFTYPE_STATION ||
2336f1d2b4d3SLarry Finger mac->opmode == NL80211_IFTYPE_MESH_POINT)
2337f1d2b4d3SLarry Finger curtxbw_40mhz = mac->bw_40;
2338*046d2e7cSSriram R else if (mac->opmode == NL80211_IFTYPE_AP ||
2339f1d2b4d3SLarry Finger mac->opmode == NL80211_IFTYPE_ADHOC)
2340f1d2b4d3SLarry Finger macid = sta->aid + 1;
2341f1d2b4d3SLarry Finger
2342f1d2b4d3SLarry Finger ratr_bitmap = sta->deflink.supp_rates[0];
2343*046d2e7cSSriram R
2344*046d2e7cSSriram R if (mac->opmode == NL80211_IFTYPE_ADHOC)
2345f1d2b4d3SLarry Finger ratr_bitmap = 0xfff;
2346f1d2b4d3SLarry Finger
2347f1d2b4d3SLarry Finger ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 |
2348f1d2b4d3SLarry Finger sta->deflink.ht_cap.mcs.rx_mask[0] << 12);
2349f1d2b4d3SLarry Finger switch (wirelessmode) {
2350f1d2b4d3SLarry Finger case WIRELESS_MODE_B:
2351f1d2b4d3SLarry Finger ratr_index = RATR_INX_WIRELESS_B;
2352f1d2b4d3SLarry Finger if (ratr_bitmap & 0x0000000c)
2353f1d2b4d3SLarry Finger ratr_bitmap &= 0x0000000d;
2354f1d2b4d3SLarry Finger else
2355f1d2b4d3SLarry Finger ratr_bitmap &= 0x0000000f;
2356f1d2b4d3SLarry Finger break;
2357f1d2b4d3SLarry Finger case WIRELESS_MODE_G:
2358f1d2b4d3SLarry Finger ratr_index = RATR_INX_WIRELESS_GB;
2359f1d2b4d3SLarry Finger
2360f1d2b4d3SLarry Finger if (rssi_level == 1)
2361f1d2b4d3SLarry Finger ratr_bitmap &= 0x00000f00;
2362f1d2b4d3SLarry Finger else if (rssi_level == 2)
2363f1d2b4d3SLarry Finger ratr_bitmap &= 0x00000ff0;
2364f1d2b4d3SLarry Finger else
2365f1d2b4d3SLarry Finger ratr_bitmap &= 0x00000ff5;
2366f1d2b4d3SLarry Finger break;
2367f1d2b4d3SLarry Finger case WIRELESS_MODE_N_24G:
2368f1d2b4d3SLarry Finger case WIRELESS_MODE_N_5G:
2369f1d2b4d3SLarry Finger ratr_index = RATR_INX_WIRELESS_NGB;
2370f1d2b4d3SLarry Finger if (rtlphy->rf_type == RF_1T1R) {
2371f1d2b4d3SLarry Finger if (curtxbw_40mhz) {
2372f1d2b4d3SLarry Finger if (rssi_level == 1)
2373f1d2b4d3SLarry Finger ratr_bitmap &= 0x000f0000;
2374f1d2b4d3SLarry Finger else if (rssi_level == 2)
2375f1d2b4d3SLarry Finger ratr_bitmap &= 0x000ff000;
2376f1d2b4d3SLarry Finger else
2377f1d2b4d3SLarry Finger ratr_bitmap &= 0x000ff015;
2378f1d2b4d3SLarry Finger } else {
2379f1d2b4d3SLarry Finger if (rssi_level == 1)
2380f1d2b4d3SLarry Finger ratr_bitmap &= 0x000f0000;
2381f1d2b4d3SLarry Finger else if (rssi_level == 2)
2382f1d2b4d3SLarry Finger ratr_bitmap &= 0x000ff000;
2383f1d2b4d3SLarry Finger else
2384f1d2b4d3SLarry Finger ratr_bitmap &= 0x000ff005;
2385f1d2b4d3SLarry Finger }
2386f1d2b4d3SLarry Finger } else {
2387f1d2b4d3SLarry Finger if (curtxbw_40mhz) {
2388f1d2b4d3SLarry Finger if (rssi_level == 1)
2389f1d2b4d3SLarry Finger ratr_bitmap &= 0x0f8f0000;
2390f1d2b4d3SLarry Finger else if (rssi_level == 2)
2391f1d2b4d3SLarry Finger ratr_bitmap &= 0x0f8ff000;
2392f1d2b4d3SLarry Finger else
2393f1d2b4d3SLarry Finger ratr_bitmap &= 0x0f8ff015;
2394f1d2b4d3SLarry Finger } else {
2395f1d2b4d3SLarry Finger if (rssi_level == 1)
2396f1d2b4d3SLarry Finger ratr_bitmap &= 0x0f8f0000;
2397f1d2b4d3SLarry Finger else if (rssi_level == 2)
2398f1d2b4d3SLarry Finger ratr_bitmap &= 0x0f8ff000;
2399f1d2b4d3SLarry Finger else
2400f1d2b4d3SLarry Finger ratr_bitmap &= 0x0f8ff005;
2401f1d2b4d3SLarry Finger }
2402f1d2b4d3SLarry Finger }
2403f1d2b4d3SLarry Finger if ((curtxbw_40mhz && curshortgi_40mhz) ||
2404f1d2b4d3SLarry Finger (!curtxbw_40mhz && curshortgi_20mhz)) {
2405f1d2b4d3SLarry Finger if (macid == 0)
2406f1d2b4d3SLarry Finger shortgi = true;
2407f1d2b4d3SLarry Finger else if (macid == 1)
2408f1d2b4d3SLarry Finger shortgi = false;
2409f1d2b4d3SLarry Finger }
2410f1d2b4d3SLarry Finger break;
2411f1d2b4d3SLarry Finger default:
2412f1d2b4d3SLarry Finger ratr_index = RATR_INX_WIRELESS_NGB;
2413f1d2b4d3SLarry Finger
2414f1d2b4d3SLarry Finger if (rtlphy->rf_type == RF_1T2R)
2415f1d2b4d3SLarry Finger ratr_bitmap &= 0x000ff0ff;
2416f1d2b4d3SLarry Finger else
2417f1d2b4d3SLarry Finger ratr_bitmap &= 0x0f0ff0ff;
2418f1d2b4d3SLarry Finger break;
2419e6dd230aSLarry Finger }
2420f1d2b4d3SLarry Finger
2421f1d2b4d3SLarry Finger sta_entry->ratr_index = ratr_index;
2422f1d2b4d3SLarry Finger
2423f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG,
2424f1d2b4d3SLarry Finger "ratr_bitmap :%x\n", ratr_bitmap);
2425f1d2b4d3SLarry Finger *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
24261d22b177SPing-Ke Shih (ratr_index << 28);
2427f1d2b4d3SLarry Finger rate_mask[0] = macid;
2428f1d2b4d3SLarry Finger rate_mask[1] = _rtl8723be_mrate_idx_to_arfr_id(hw, ratr_index) |
2429f1d2b4d3SLarry Finger (shortgi ? 0x80 : 0x00);
2430f1d2b4d3SLarry Finger rate_mask[2] = curtxbw_40mhz | ((!update_bw) << 3);
2431f1d2b4d3SLarry Finger
2432f1d2b4d3SLarry Finger rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff);
2433e6dd230aSLarry Finger rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >> 8);
2434f1d2b4d3SLarry Finger rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16);
2435f1d2b4d3SLarry Finger rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24);
2436f1d2b4d3SLarry Finger
2437f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG,
2438f1d2b4d3SLarry Finger "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x:%x:%x\n",
2439f1d2b4d3SLarry Finger ratr_index, ratr_bitmap,
2440f1d2b4d3SLarry Finger rate_mask[0], rate_mask[1],
2441f1d2b4d3SLarry Finger rate_mask[2], rate_mask[3],
2442f1d2b4d3SLarry Finger rate_mask[4], rate_mask[5],
2443f1d2b4d3SLarry Finger rate_mask[6]);
2444f1d2b4d3SLarry Finger rtl8723be_fill_h2c_cmd(hw, H2C_8723B_RA_MASK, 7, rate_mask);
2445f1d2b4d3SLarry Finger _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
24461d22b177SPing-Ke Shih }
2447f1d2b4d3SLarry Finger
rtl8723be_update_hal_rate_tbl(struct ieee80211_hw * hw,struct ieee80211_sta * sta,u8 rssi_level,bool update_bw)2448f1d2b4d3SLarry Finger void rtl8723be_update_hal_rate_tbl(struct ieee80211_hw *hw,
2449f1d2b4d3SLarry Finger struct ieee80211_sta *sta,
24501d22b177SPing-Ke Shih u8 rssi_level, bool update_bw)
2451f1d2b4d3SLarry Finger {
2452f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
2453f1d2b4d3SLarry Finger if (rtlpriv->dm.useramask)
2454f1d2b4d3SLarry Finger rtl8723be_update_hal_rate_mask(hw, sta, rssi_level, update_bw);
2455f1d2b4d3SLarry Finger }
2456f1d2b4d3SLarry Finger
rtl8723be_update_channel_access_setting(struct ieee80211_hw * hw)2457f1d2b4d3SLarry Finger void rtl8723be_update_channel_access_setting(struct ieee80211_hw *hw)
2458f1d2b4d3SLarry Finger {
2459f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
2460f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2461f1d2b4d3SLarry Finger u16 sifs_timer;
2462f1d2b4d3SLarry Finger
2463f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);
2464f1d2b4d3SLarry Finger if (!mac->ht_enable)
2465f1d2b4d3SLarry Finger sifs_timer = 0x0a0a;
2466f1d2b4d3SLarry Finger else
2467f1d2b4d3SLarry Finger sifs_timer = 0x0e0e;
2468f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
2469f1d2b4d3SLarry Finger }
2470f1d2b4d3SLarry Finger
rtl8723be_gpio_radio_on_off_checking(struct ieee80211_hw * hw,u8 * valid)2471f1d2b4d3SLarry Finger bool rtl8723be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
247276d7b12cSChristos Gkekas {
2473f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
2474f1d2b4d3SLarry Finger struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2475f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
2476f1d2b4d3SLarry Finger enum rf_pwrstate e_rfpowerstate_toset;
2477f1d2b4d3SLarry Finger u8 u1tmp;
2478f1d2b4d3SLarry Finger bool b_actuallyset = false;
2479f1d2b4d3SLarry Finger
2480f1d2b4d3SLarry Finger if (rtlpriv->rtlhal.being_init_adapter)
2481f1d2b4d3SLarry Finger return false;
2482f1d2b4d3SLarry Finger
2483f1d2b4d3SLarry Finger if (ppsc->swrf_processing)
2484f1d2b4d3SLarry Finger return false;
2485f1d2b4d3SLarry Finger
2486f1d2b4d3SLarry Finger spin_lock(&rtlpriv->locks.rf_ps_lock);
2487f1d2b4d3SLarry Finger if (ppsc->rfchange_inprogress) {
2488f1d2b4d3SLarry Finger spin_unlock(&rtlpriv->locks.rf_ps_lock);
2489f1d2b4d3SLarry Finger return false;
2490f1d2b4d3SLarry Finger } else {
2491f1d2b4d3SLarry Finger ppsc->rfchange_inprogress = true;
2492f1d2b4d3SLarry Finger spin_unlock(&rtlpriv->locks.rf_ps_lock);
2493f1d2b4d3SLarry Finger }
2494f1d2b4d3SLarry Finger
2495f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2,
2496f1d2b4d3SLarry Finger rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2) & ~(BIT(1)));
2497f1d2b4d3SLarry Finger
2498f1d2b4d3SLarry Finger u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2);
2499f1d2b4d3SLarry Finger
2500f1d2b4d3SLarry Finger if (rtlphy->polarity_ctl)
2501f1d2b4d3SLarry Finger e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON;
2502e6dd230aSLarry Finger else
2503f1d2b4d3SLarry Finger e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF;
2504f1d2b4d3SLarry Finger
2505f1d2b4d3SLarry Finger if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) {
2506f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
2507f1d2b4d3SLarry Finger "GPIOChangeRF - HW Radio ON, RF ON\n");
2508f1d2b4d3SLarry Finger
2509e6dd230aSLarry Finger e_rfpowerstate_toset = ERFON;
2510f1d2b4d3SLarry Finger ppsc->hwradiooff = false;
2511f1d2b4d3SLarry Finger b_actuallyset = true;
2512f1d2b4d3SLarry Finger } else if (!ppsc->hwradiooff && (e_rfpowerstate_toset == ERFOFF)) {
2513f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
2514f1d2b4d3SLarry Finger "GPIOChangeRF - HW Radio OFF, RF OFF\n");
2515f1d2b4d3SLarry Finger
2516f1d2b4d3SLarry Finger e_rfpowerstate_toset = ERFOFF;
2517f1d2b4d3SLarry Finger ppsc->hwradiooff = true;
2518f1d2b4d3SLarry Finger b_actuallyset = true;
2519f1d2b4d3SLarry Finger }
2520f1d2b4d3SLarry Finger
2521f1d2b4d3SLarry Finger if (b_actuallyset) {
2522f1d2b4d3SLarry Finger spin_lock(&rtlpriv->locks.rf_ps_lock);
2523f1d2b4d3SLarry Finger ppsc->rfchange_inprogress = false;
2524f1d2b4d3SLarry Finger spin_unlock(&rtlpriv->locks.rf_ps_lock);
2525f1d2b4d3SLarry Finger } else {
2526f1d2b4d3SLarry Finger if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
2527f1d2b4d3SLarry Finger RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2528f1d2b4d3SLarry Finger
2529f1d2b4d3SLarry Finger spin_lock(&rtlpriv->locks.rf_ps_lock);
2530f1d2b4d3SLarry Finger ppsc->rfchange_inprogress = false;
2531f1d2b4d3SLarry Finger spin_unlock(&rtlpriv->locks.rf_ps_lock);
2532f1d2b4d3SLarry Finger }
2533f1d2b4d3SLarry Finger
2534f1d2b4d3SLarry Finger *valid = 1;
2535f1d2b4d3SLarry Finger return !ppsc->hwradiooff;
2536f1d2b4d3SLarry Finger
2537f1d2b4d3SLarry Finger }
2538f1d2b4d3SLarry Finger
rtl8723be_set_key(struct ieee80211_hw * hw,u32 key_index,u8 * p_macaddr,bool is_group,u8 enc_algo,bool is_wepkey,bool clear_all)2539f1d2b4d3SLarry Finger void rtl8723be_set_key(struct ieee80211_hw *hw, u32 key_index,
2540f1d2b4d3SLarry Finger u8 *p_macaddr, bool is_group, u8 enc_algo,
2541f1d2b4d3SLarry Finger bool is_wepkey, bool clear_all)
2542f1d2b4d3SLarry Finger {
2543f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
2544f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2545f1d2b4d3SLarry Finger struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2546f1d2b4d3SLarry Finger u8 *macaddr = p_macaddr;
2547f1d2b4d3SLarry Finger u32 entry_id = 0;
2548f1d2b4d3SLarry Finger bool is_pairwise = false;
2549f1d2b4d3SLarry Finger
2550f1d2b4d3SLarry Finger static u8 cam_const_addr[4][6] = {
2551f1d2b4d3SLarry Finger {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
2552f1d2b4d3SLarry Finger {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
2553f1d2b4d3SLarry Finger {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
2554f1d2b4d3SLarry Finger {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
2555f1d2b4d3SLarry Finger };
2556f1d2b4d3SLarry Finger static u8 cam_const_broad[] = {
2557f1d2b4d3SLarry Finger 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2558f1d2b4d3SLarry Finger };
2559f1d2b4d3SLarry Finger
2560f1d2b4d3SLarry Finger if (clear_all) {
2561e6dd230aSLarry Finger u8 idx = 0;
2562f1d2b4d3SLarry Finger u8 cam_offset = 0;
2563f1d2b4d3SLarry Finger u8 clear_number = 5;
2564f1d2b4d3SLarry Finger
2565f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
2566f1d2b4d3SLarry Finger
2567f1d2b4d3SLarry Finger for (idx = 0; idx < clear_number; idx++) {
2568f1d2b4d3SLarry Finger rtl_cam_mark_invalid(hw, cam_offset + idx);
2569f1d2b4d3SLarry Finger rtl_cam_empty_entry(hw, cam_offset + idx);
2570f1d2b4d3SLarry Finger
2571f1d2b4d3SLarry Finger if (idx < 5) {
2572f1d2b4d3SLarry Finger memset(rtlpriv->sec.key_buf[idx], 0,
2573f1d2b4d3SLarry Finger MAX_KEY_LEN);
2574f1d2b4d3SLarry Finger rtlpriv->sec.key_len[idx] = 0;
2575f1d2b4d3SLarry Finger }
2576f1d2b4d3SLarry Finger }
2577f1d2b4d3SLarry Finger
2578f1d2b4d3SLarry Finger } else {
2579f1d2b4d3SLarry Finger switch (enc_algo) {
2580f1d2b4d3SLarry Finger case WEP40_ENCRYPTION:
2581f1d2b4d3SLarry Finger enc_algo = CAM_WEP40;
2582f1d2b4d3SLarry Finger break;
2583f1d2b4d3SLarry Finger case WEP104_ENCRYPTION:
2584f1d2b4d3SLarry Finger enc_algo = CAM_WEP104;
2585f1d2b4d3SLarry Finger break;
2586f1d2b4d3SLarry Finger case TKIP_ENCRYPTION:
2587f1d2b4d3SLarry Finger enc_algo = CAM_TKIP;
2588f1d2b4d3SLarry Finger break;
2589e6dd230aSLarry Finger case AESCCMP_ENCRYPTION:
2590ad574889SJoe Perches enc_algo = CAM_AES;
2591f1d2b4d3SLarry Finger break;
2592f1d2b4d3SLarry Finger default:
2593f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
2594f1d2b4d3SLarry Finger "switch case %#x not processed\n", enc_algo);
2595f1d2b4d3SLarry Finger enc_algo = CAM_TKIP;
2596f1d2b4d3SLarry Finger break;
2597f1d2b4d3SLarry Finger }
2598f1d2b4d3SLarry Finger
2599f1d2b4d3SLarry Finger if (is_wepkey || rtlpriv->sec.use_defaultkey) {
2600f1d2b4d3SLarry Finger macaddr = cam_const_addr[key_index];
2601f1d2b4d3SLarry Finger entry_id = key_index;
2602f1d2b4d3SLarry Finger } else {
2603f1d2b4d3SLarry Finger if (is_group) {
2604f1d2b4d3SLarry Finger macaddr = cam_const_broad;
2605f1d2b4d3SLarry Finger entry_id = key_index;
2606f1d2b4d3SLarry Finger } else {
26074e2b4378SLarry Finger if (mac->opmode == NL80211_IFTYPE_AP) {
2608f1d2b4d3SLarry Finger entry_id = rtl_cam_get_free_entry(hw,
2609f1d2b4d3SLarry Finger p_macaddr);
2610f1d2b4d3SLarry Finger if (entry_id >= TOTAL_CAM_ENTRY) {
2611f1d2b4d3SLarry Finger pr_err("Can not find free hw security cam entry\n");
2612f1d2b4d3SLarry Finger return;
2613f1d2b4d3SLarry Finger }
2614f1d2b4d3SLarry Finger } else {
2615f1d2b4d3SLarry Finger entry_id = CAM_PAIRWISE_KEY_POSITION;
2616f1d2b4d3SLarry Finger }
2617f1d2b4d3SLarry Finger
2618f1d2b4d3SLarry Finger key_index = PAIRWISE_KEYIDX;
2619f1d2b4d3SLarry Finger is_pairwise = true;
2620e6dd230aSLarry Finger }
2621f1d2b4d3SLarry Finger }
2622f1d2b4d3SLarry Finger
2623f1d2b4d3SLarry Finger if (rtlpriv->sec.key_len[key_index] == 0) {
2624f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
2625f1d2b4d3SLarry Finger "delete one entry, entry_id is %d\n",
2626f1d2b4d3SLarry Finger entry_id);
2627e6dd230aSLarry Finger if (mac->opmode == NL80211_IFTYPE_AP)
2628f1d2b4d3SLarry Finger rtl_cam_del_entry(hw, p_macaddr);
2629f1d2b4d3SLarry Finger rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
2630e6dd230aSLarry Finger } else {
26316b9e6f62SColin Ian King rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
2632f1d2b4d3SLarry Finger "add one entry\n");
2633f1d2b4d3SLarry Finger if (is_pairwise) {
2634f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
2635f1d2b4d3SLarry Finger "set Pairwise key\n");
2636f1d2b4d3SLarry Finger
2637f1d2b4d3SLarry Finger rtl_cam_add_one_entry(hw, macaddr, key_index,
2638e6dd230aSLarry Finger entry_id, enc_algo,
2639f1d2b4d3SLarry Finger CAM_CONFIG_NO_USEDK,
2640f1d2b4d3SLarry Finger rtlpriv->sec.key_buf[key_index]);
2641f1d2b4d3SLarry Finger } else {
2642f1d2b4d3SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
2643f1d2b4d3SLarry Finger "set group key\n");
2644f1d2b4d3SLarry Finger
2645f1d2b4d3SLarry Finger if (mac->opmode == NL80211_IFTYPE_ADHOC) {
2646f1d2b4d3SLarry Finger rtl_cam_add_one_entry(hw,
2647f1d2b4d3SLarry Finger rtlefuse->dev_addr,
2648f1d2b4d3SLarry Finger PAIRWISE_KEYIDX,
2649f1d2b4d3SLarry Finger CAM_PAIRWISE_KEY_POSITION,
2650f1d2b4d3SLarry Finger enc_algo,
2651f1d2b4d3SLarry Finger CAM_CONFIG_NO_USEDK,
2652f1d2b4d3SLarry Finger rtlpriv->sec.key_buf
2653f1d2b4d3SLarry Finger [entry_id]);
2654f1d2b4d3SLarry Finger }
2655f1d2b4d3SLarry Finger
2656f1d2b4d3SLarry Finger rtl_cam_add_one_entry(hw, macaddr, key_index,
2657f1d2b4d3SLarry Finger entry_id, enc_algo,
2658f1d2b4d3SLarry Finger CAM_CONFIG_NO_USEDK,
2659f1d2b4d3SLarry Finger rtlpriv->sec.key_buf[entry_id]);
2660f1d2b4d3SLarry Finger }
2661f1d2b4d3SLarry Finger }
2662f1d2b4d3SLarry Finger }
2663f1d2b4d3SLarry Finger }
2664f1d2b4d3SLarry Finger
rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw * hw,bool auto_load_fail,u8 * hwinfo)2665c18d8f50SLarry Finger void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
2666f1d2b4d3SLarry Finger bool auto_load_fail, u8 *hwinfo)
2667f1d2b4d3SLarry Finger {
2668f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
2669f1d2b4d3SLarry Finger struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params;
2670f1d2b4d3SLarry Finger u8 value;
2671f1d2b4d3SLarry Finger u32 tmpu_32;
2672f1d2b4d3SLarry Finger
2673f1d2b4d3SLarry Finger if (!auto_load_fail) {
2674f1d2b4d3SLarry Finger tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL);
2675f1d2b4d3SLarry Finger if (tmpu_32 & BIT(18))
2676f1d2b4d3SLarry Finger rtlpriv->btcoexist.btc_info.btcoexist = 1;
2677f1d2b4d3SLarry Finger else
26780de9b5dbSPing-Ke Shih rtlpriv->btcoexist.btc_info.btcoexist = 0;
2679af8a41ccSPing-Ke Shih value = hwinfo[EEPROM_RF_BT_SETTING_8723B];
2680f1d2b4d3SLarry Finger rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2681f1d2b4d3SLarry Finger rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1);
2682f1d2b4d3SLarry Finger rtlpriv->btcoexist.btc_info.single_ant_path =
2683f1d2b4d3SLarry Finger (value & 0x40 ? ANT_AUX : ANT_MAIN); /*0xc3[6]*/
2684af8a41ccSPing-Ke Shih } else {
2685f1d2b4d3SLarry Finger rtlpriv->btcoexist.btc_info.btcoexist = 0;
2686f1d2b4d3SLarry Finger rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2687c18d8f50SLarry Finger rtlpriv->btcoexist.btc_info.ant_num = ANT_X2;
26880ff78adeSPing-Ke Shih rtlpriv->btcoexist.btc_info.single_ant_path = ANT_MAIN;
2689c18d8f50SLarry Finger }
2690af8a41ccSPing-Ke Shih
26910ff78adeSPing-Ke Shih /* override ant_num / ant_path */
26920ff78adeSPing-Ke Shih if (mod_params->ant_sel) {
2693af8a41ccSPing-Ke Shih rtlpriv->btcoexist.btc_info.ant_num =
26940ff78adeSPing-Ke Shih (mod_params->ant_sel == 1 ? ANT_X1 : ANT_X2);
2695f1d2b4d3SLarry Finger
2696f1d2b4d3SLarry Finger rtlpriv->btcoexist.btc_info.single_ant_path =
2697f1d2b4d3SLarry Finger (mod_params->ant_sel == 1 ? ANT_AUX : ANT_MAIN);
2698f1d2b4d3SLarry Finger }
2699f1d2b4d3SLarry Finger }
2700f1d2b4d3SLarry Finger
rtl8723be_bt_reg_init(struct ieee80211_hw * hw)2701f1d2b4d3SLarry Finger void rtl8723be_bt_reg_init(struct ieee80211_hw *hw)
2702f1d2b4d3SLarry Finger {
2703f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
2704f1d2b4d3SLarry Finger
2705f1d2b4d3SLarry Finger /* 0:Low, 1:High, 2:From Efuse. */
2706f1d2b4d3SLarry Finger rtlpriv->btcoexist.reg_bt_iso = 2;
2707f1d2b4d3SLarry Finger /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */
2708f1d2b4d3SLarry Finger rtlpriv->btcoexist.reg_bt_sco = 3;
2709f1d2b4d3SLarry Finger /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
2710f1d2b4d3SLarry Finger rtlpriv->btcoexist.reg_bt_sco = 0;
2711f1d2b4d3SLarry Finger }
2712f1d2b4d3SLarry Finger
rtl8723be_bt_hw_init(struct ieee80211_hw * hw)2713f1d2b4d3SLarry Finger void rtl8723be_bt_hw_init(struct ieee80211_hw *hw)
2714f1d2b4d3SLarry Finger {
2715f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
2716f1d2b4d3SLarry Finger
2717f1d2b4d3SLarry Finger if (rtlpriv->cfg->ops->get_btc_status())
2718f1d2b4d3SLarry Finger rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv);
2719f1d2b4d3SLarry Finger
2720f1d2b4d3SLarry Finger }
2721f1d2b4d3SLarry Finger
rtl8723be_suspend(struct ieee80211_hw * hw)2722f1d2b4d3SLarry Finger void rtl8723be_suspend(struct ieee80211_hw *hw)
2723f1d2b4d3SLarry Finger {
2724f1d2b4d3SLarry Finger }
2725
rtl8723be_resume(struct ieee80211_hw * hw)2726 void rtl8723be_resume(struct ieee80211_hw *hw)
2727 {
2728 }
2729