blob: 239518bd31f15c3df797d118541030108b008f29 [file] [log] [blame]
Larry Fingera619d1a2014-02-28 15:16:50 -06001/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../efuse.h"
28#include "../base.h"
29#include "../regd.h"
30#include "../cam.h"
31#include "../ps.h"
32#include "../pci.h"
33#include "reg.h"
34#include "def.h"
35#include "phy.h"
Larry Finger5c99f042014-09-26 16:40:25 -050036#include "../rtl8723com/phy_common.h"
Larry Fingera619d1a2014-02-28 15:16:50 -060037#include "dm.h"
38#include "../rtl8723com/dm_common.h"
39#include "fw.h"
40#include "../rtl8723com/fw_common.h"
41#include "led.h"
42#include "hw.h"
Larry Finger34ed7802014-09-22 09:39:27 -050043#include "../pwrseqcmd.h"
Larry Fingera619d1a2014-02-28 15:16:50 -060044#include "pwrseq.h"
45#include "../btcoexist/rtl_btc.h"
46
47#define LLT_CONFIG 5
48
49static void _rtl8723be_return_beacon_queue_skb(struct ieee80211_hw *hw)
50{
51 struct rtl_priv *rtlpriv = rtl_priv(hw);
52 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
53 struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
Larry Finger5c99f042014-09-26 16:40:25 -050054 unsigned long flags;
Larry Fingera619d1a2014-02-28 15:16:50 -060055
Larry Finger5c99f042014-09-26 16:40:25 -050056 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
Larry Fingera619d1a2014-02-28 15:16:50 -060057 while (skb_queue_len(&ring->queue)) {
58 struct rtl_tx_desc *entry = &ring->desc[ring->idx];
59 struct sk_buff *skb = __skb_dequeue(&ring->queue);
60
61 pci_unmap_single(rtlpci->pdev,
62 rtlpriv->cfg->ops->get_desc(
Ping-Ke Shih0c07bd72017-09-29 14:47:53 -050063 hw,
Larry Fingera619d1a2014-02-28 15:16:50 -060064 (u8 *)entry, true, HW_DESC_TXBUFF_ADDR),
65 skb->len, PCI_DMA_TODEVICE);
66 kfree_skb(skb);
67 ring->idx = (ring->idx + 1) % ring->entries;
68 }
Larry Finger5c99f042014-09-26 16:40:25 -050069 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
Larry Fingera619d1a2014-02-28 15:16:50 -060070}
71
72static void _rtl8723be_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
73 u8 set_bits, u8 clear_bits)
74{
75 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
76 struct rtl_priv *rtlpriv = rtl_priv(hw);
77
78 rtlpci->reg_bcn_ctrl_val |= set_bits;
79 rtlpci->reg_bcn_ctrl_val &= ~clear_bits;
80
Larry Finger5c99f042014-09-26 16:40:25 -050081 rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlpci->reg_bcn_ctrl_val);
Larry Fingera619d1a2014-02-28 15:16:50 -060082}
83
84static void _rtl8723be_stop_tx_beacon(struct ieee80211_hw *hw)
85{
86 struct rtl_priv *rtlpriv = rtl_priv(hw);
87 u8 tmp1byte;
88
89 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
90 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6)));
91 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64);
92 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
93 tmp1byte &= ~(BIT(0));
94 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
95}
96
97static void _rtl8723be_resume_tx_beacon(struct ieee80211_hw *hw)
98{
99 struct rtl_priv *rtlpriv = rtl_priv(hw);
100 u8 tmp1byte;
101
102 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
103 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6));
104 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
105 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
106 tmp1byte |= BIT(1);
107 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
108}
109
110static void _rtl8723be_enable_bcn_sub_func(struct ieee80211_hw *hw)
111{
112 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(1));
113}
114
115static void _rtl8723be_disable_bcn_sub_func(struct ieee80211_hw *hw)
116{
117 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(1), 0);
118}
119
120static void _rtl8723be_set_fw_clock_on(struct ieee80211_hw *hw, u8 rpwm_val,
Larry Finger5c99f042014-09-26 16:40:25 -0500121 bool b_need_turn_off_ckk)
Larry Fingera619d1a2014-02-28 15:16:50 -0600122{
123 struct rtl_priv *rtlpriv = rtl_priv(hw);
124 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
Larry Finger5c99f042014-09-26 16:40:25 -0500125 bool b_support_remote_wake_up;
Larry Fingera619d1a2014-02-28 15:16:50 -0600126 u32 count = 0, isr_regaddr, content;
Larry Finger5c99f042014-09-26 16:40:25 -0500127 bool b_schedule_timer = b_need_turn_off_ckk;
Larry Fingera619d1a2014-02-28 15:16:50 -0600128 rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN,
Larry Finger5c99f042014-09-26 16:40:25 -0500129 (u8 *)(&b_support_remote_wake_up));
Larry Fingera619d1a2014-02-28 15:16:50 -0600130
131 if (!rtlhal->fw_ready)
132 return;
133 if (!rtlpriv->psc.fw_current_inpsmode)
134 return;
135
136 while (1) {
137 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
138 if (rtlhal->fw_clk_change_in_progress) {
139 while (rtlhal->fw_clk_change_in_progress) {
140 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
141 count++;
142 udelay(100);
143 if (count > 1000)
144 return;
145 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
146 }
147 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
148 } else {
149 rtlhal->fw_clk_change_in_progress = false;
150 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
151 break;
152 }
153 }
Larry Finger5c99f042014-09-26 16:40:25 -0500154
155 if (IS_IN_LOW_POWER_STATE(rtlhal->fw_ps_state)) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600156 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM,
Larry Finger5c99f042014-09-26 16:40:25 -0500157 (u8 *)(&rpwm_val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600158 if (FW_PS_IS_ACK(rpwm_val)) {
159 isr_regaddr = REG_HISR;
160 content = rtl_read_dword(rtlpriv, isr_regaddr);
161 while (!(content & IMR_CPWM) && (count < 500)) {
162 udelay(50);
163 count++;
164 content = rtl_read_dword(rtlpriv, isr_regaddr);
165 }
166
167 if (content & IMR_CPWM) {
168 rtl_write_word(rtlpriv, isr_regaddr, 0x0100);
Larry Finger5c99f042014-09-26 16:40:25 -0500169 rtlhal->fw_ps_state = FW_PS_STATE_RF_ON;
Larry Fingera619d1a2014-02-28 15:16:50 -0600170 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
Larry Finger5c99f042014-09-26 16:40:25 -0500171 "Receive CPWM INT!!! Set pHalData->FwPSState = %X\n",
Larry Fingera619d1a2014-02-28 15:16:50 -0600172 rtlhal->fw_ps_state);
173 }
174 }
Larry Finger5c99f042014-09-26 16:40:25 -0500175
Larry Fingera619d1a2014-02-28 15:16:50 -0600176 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
177 rtlhal->fw_clk_change_in_progress = false;
178 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
Larry Finger5c99f042014-09-26 16:40:25 -0500179 if (b_schedule_timer)
Larry Fingera619d1a2014-02-28 15:16:50 -0600180 mod_timer(&rtlpriv->works.fw_clockoff_timer,
181 jiffies + MSECS(10));
Larry Fingera619d1a2014-02-28 15:16:50 -0600182 } else {
183 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
184 rtlhal->fw_clk_change_in_progress = false;
185 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
186 }
187}
188
189static void _rtl8723be_set_fw_clock_off(struct ieee80211_hw *hw, u8 rpwm_val)
190{
191 struct rtl_priv *rtlpriv = rtl_priv(hw);
192 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
193 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
194 struct rtl8192_tx_ring *ring;
195 enum rf_pwrstate rtstate;
Larry Finger5c99f042014-09-26 16:40:25 -0500196 bool b_schedule_timer = false;
Larry Fingera619d1a2014-02-28 15:16:50 -0600197 u8 queue;
198
199 if (!rtlhal->fw_ready)
200 return;
201 if (!rtlpriv->psc.fw_current_inpsmode)
202 return;
203 if (!rtlhal->allow_sw_to_change_hwclc)
204 return;
205 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, (u8 *)(&rtstate));
206 if (rtstate == ERFOFF || rtlpriv->psc.inactive_pwrstate == ERFOFF)
207 return;
208
209 for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) {
210 ring = &rtlpci->tx_ring[queue];
211 if (skb_queue_len(&ring->queue)) {
Larry Finger5c99f042014-09-26 16:40:25 -0500212 b_schedule_timer = true;
Larry Fingera619d1a2014-02-28 15:16:50 -0600213 break;
214 }
215 }
Larry Finger5c99f042014-09-26 16:40:25 -0500216
217 if (b_schedule_timer) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600218 mod_timer(&rtlpriv->works.fw_clockoff_timer,
219 jiffies + MSECS(10));
220 return;
221 }
Larry Finger5c99f042014-09-26 16:40:25 -0500222
223 if (FW_PS_STATE(rtlhal->fw_ps_state) != FW_PS_STATE_RF_OFF_LOW_PWR) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600224 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
225 if (!rtlhal->fw_clk_change_in_progress) {
226 rtlhal->fw_clk_change_in_progress = true;
227 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
228 rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val);
229 rtl_write_word(rtlpriv, REG_HISR, 0x0100);
230 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
Larry Finger5c99f042014-09-26 16:40:25 -0500231 (u8 *)(&rpwm_val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600232 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
233 rtlhal->fw_clk_change_in_progress = false;
234 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
235 } else {
236 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
237 mod_timer(&rtlpriv->works.fw_clockoff_timer,
238 jiffies + MSECS(10));
239 }
240 }
Larry Finger5c99f042014-09-26 16:40:25 -0500241
Larry Fingera619d1a2014-02-28 15:16:50 -0600242}
243
244static void _rtl8723be_set_fw_ps_rf_on(struct ieee80211_hw *hw)
245{
246 u8 rpwm_val = 0;
Larry Finger5c99f042014-09-26 16:40:25 -0500247 rpwm_val |= (FW_PS_STATE_RF_OFF | FW_PS_ACK);
Larry Fingera619d1a2014-02-28 15:16:50 -0600248 _rtl8723be_set_fw_clock_on(hw, rpwm_val, true);
249}
250
251static void _rtl8723be_fwlps_leave(struct ieee80211_hw *hw)
252{
253 struct rtl_priv *rtlpriv = rtl_priv(hw);
254 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
255 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
256 bool fw_current_inps = false;
257 u8 rpwm_val = 0, fw_pwrmode = FW_PS_ACTIVE_MODE;
258
259 if (ppsc->low_power_enable) {
Larry Finger5c99f042014-09-26 16:40:25 -0500260 rpwm_val = (FW_PS_STATE_ALL_ON | FW_PS_ACK);/* RF on */
Larry Fingera619d1a2014-02-28 15:16:50 -0600261 _rtl8723be_set_fw_clock_on(hw, rpwm_val, false);
262 rtlhal->allow_sw_to_change_hwclc = false;
263 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
Larry Finger5c99f042014-09-26 16:40:25 -0500264 (u8 *)(&fw_pwrmode));
Larry Fingera619d1a2014-02-28 15:16:50 -0600265 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
266 (u8 *)(&fw_current_inps));
267 } else {
Larry Finger5c99f042014-09-26 16:40:25 -0500268 rpwm_val = FW_PS_STATE_ALL_ON; /* RF on */
269 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
270 (u8 *)(&rpwm_val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600271 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
Larry Finger5c99f042014-09-26 16:40:25 -0500272 (u8 *)(&fw_pwrmode));
Larry Fingera619d1a2014-02-28 15:16:50 -0600273 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
274 (u8 *)(&fw_current_inps));
275 }
Larry Finger5c99f042014-09-26 16:40:25 -0500276
Larry Fingera619d1a2014-02-28 15:16:50 -0600277}
278
279static void _rtl8723be_fwlps_enter(struct ieee80211_hw *hw)
280{
281 struct rtl_priv *rtlpriv = rtl_priv(hw);
282 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
283 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
284 bool fw_current_inps = true;
285 u8 rpwm_val;
286
287 if (ppsc->low_power_enable) {
Larry Finger5c99f042014-09-26 16:40:25 -0500288 rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR; /* RF off */
Larry Fingera619d1a2014-02-28 15:16:50 -0600289 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
290 (u8 *)(&fw_current_inps));
291 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
Larry Finger5c99f042014-09-26 16:40:25 -0500292 (u8 *)(&ppsc->fwctrl_psmode));
Larry Fingera619d1a2014-02-28 15:16:50 -0600293 rtlhal->allow_sw_to_change_hwclc = true;
294 _rtl8723be_set_fw_clock_off(hw, rpwm_val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600295 } else {
Larry Finger5c99f042014-09-26 16:40:25 -0500296 rpwm_val = FW_PS_STATE_RF_OFF; /* RF off */
Larry Fingera619d1a2014-02-28 15:16:50 -0600297 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
298 (u8 *)(&fw_current_inps));
299 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
Larry Finger5c99f042014-09-26 16:40:25 -0500300 (u8 *)(&ppsc->fwctrl_psmode));
301 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
302 (u8 *)(&rpwm_val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600303 }
Larry Finger5c99f042014-09-26 16:40:25 -0500304
Larry Fingera619d1a2014-02-28 15:16:50 -0600305}
306
307void rtl8723be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
308{
309 struct rtl_priv *rtlpriv = rtl_priv(hw);
310 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
311 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
312
313 switch (variable) {
314 case HW_VAR_RCR:
315 *((u32 *)(val)) = rtlpci->receive_config;
316 break;
317 case HW_VAR_RF_STATE:
318 *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
319 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500320 case HW_VAR_FWLPS_RF_ON:{
321 enum rf_pwrstate rfState;
Larry Fingera619d1a2014-02-28 15:16:50 -0600322 u32 val_rcr;
323
324 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE,
Larry Finger5c99f042014-09-26 16:40:25 -0500325 (u8 *)(&rfState));
326 if (rfState == ERFOFF) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600327 *((bool *)(val)) = true;
328 } else {
329 val_rcr = rtl_read_dword(rtlpriv, REG_RCR);
330 val_rcr &= 0x00070000;
331 if (val_rcr)
332 *((bool *)(val)) = false;
333 else
334 *((bool *)(val)) = true;
335 }
Larry Finger5c99f042014-09-26 16:40:25 -0500336 }
337 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600338 case HW_VAR_FW_PSMODE_STATUS:
339 *((bool *)(val)) = ppsc->fw_current_inpsmode;
340 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500341 case HW_VAR_CORRECT_TSF:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600342 u64 tsf;
343 u32 *ptsf_low = (u32 *)&tsf;
344 u32 *ptsf_high = ((u32 *)&tsf) + 1;
345
346 *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4));
347 *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
348
349 *((u64 *)(val)) = tsf;
Larry Finger5c99f042014-09-26 16:40:25 -0500350 }
351 break;
Larry Finger1cc49a52016-09-24 11:57:18 -0500352 case HAL_DEF_WOWLAN:
353 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600354 default:
Larry Finger5c99f042014-09-26 16:40:25 -0500355 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -0700356 "switch case %#x not processed\n", variable);
Larry Fingera619d1a2014-02-28 15:16:50 -0600357 break;
358 }
359}
360
Larry Finger5c99f042014-09-26 16:40:25 -0500361static void _rtl8723be_download_rsvd_page(struct ieee80211_hw *hw)
362{
363 struct rtl_priv *rtlpriv = rtl_priv(hw);
364 u8 tmp_regcr, tmp_reg422, bcnvalid_reg;
365 u8 count = 0, dlbcn_count = 0;
366 bool b_recover = false;
367
368 tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
369 rtl_write_byte(rtlpriv, REG_CR + 1,
370 (tmp_regcr | BIT(0)));
371
372 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3));
373 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0);
374
375 tmp_reg422 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
376 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422 & (~BIT(6)));
377 if (tmp_reg422 & BIT(6))
378 b_recover = true;
379
380 do {
381 bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL + 2);
382 rtl_write_byte(rtlpriv, REG_TDECTRL + 2,
383 (bcnvalid_reg | BIT(0)));
384 _rtl8723be_return_beacon_queue_skb(hw);
385
386 rtl8723be_set_fw_rsvdpagepkt(hw, 0);
387 bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL + 2);
388 count = 0;
389 while (!(bcnvalid_reg & BIT(0)) && count < 20) {
390 count++;
391 udelay(10);
392 bcnvalid_reg = rtl_read_byte(rtlpriv,
393 REG_TDECTRL + 2);
394 }
395 dlbcn_count++;
396 } while (!(bcnvalid_reg & BIT(0)) && dlbcn_count < 5);
397
398 if (bcnvalid_reg & BIT(0))
399 rtl_write_byte(rtlpriv, REG_TDECTRL + 2, BIT(0));
400
401 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
402 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4));
403
404 if (b_recover)
405 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422);
406
407 tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
408 rtl_write_byte(rtlpriv, REG_CR + 1, (tmp_regcr & ~(BIT(0))));
409}
410
Larry Fingera619d1a2014-02-28 15:16:50 -0600411void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
412{
413 struct rtl_priv *rtlpriv = rtl_priv(hw);
414 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
415 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
416 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
417 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
418 u8 idx;
419
420 switch (variable) {
421 case HW_VAR_ETHER_ADDR:
422 for (idx = 0; idx < ETH_ALEN; idx++)
423 rtl_write_byte(rtlpriv, (REG_MACID + idx), val[idx]);
424 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500425 case HW_VAR_BASIC_RATE:{
426 u16 b_rate_cfg = ((u16 *)val)[0];
Larry Fingera619d1a2014-02-28 15:16:50 -0600427 u8 rate_index = 0;
Larry Finger5c99f042014-09-26 16:40:25 -0500428 b_rate_cfg = b_rate_cfg & 0x15f;
429 b_rate_cfg |= 0x01;
430 rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff);
431 rtl_write_byte(rtlpriv, REG_RRSR + 1, (b_rate_cfg >> 8) & 0xff);
432 while (b_rate_cfg > 0x1) {
433 b_rate_cfg = (b_rate_cfg >> 1);
Larry Fingera619d1a2014-02-28 15:16:50 -0600434 rate_index++;
435 }
436 rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, rate_index);
Larry Finger5c99f042014-09-26 16:40:25 -0500437 }
438 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600439 case HW_VAR_BSSID:
440 for (idx = 0; idx < ETH_ALEN; idx++)
441 rtl_write_byte(rtlpriv, (REG_BSSID + idx), val[idx]);
Larry Finger5c99f042014-09-26 16:40:25 -0500442
Larry Fingera619d1a2014-02-28 15:16:50 -0600443 break;
444 case HW_VAR_SIFS:
445 rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]);
446 rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]);
447
448 rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]);
449 rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
450
451 if (!mac->ht_enable)
452 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, 0x0e0e);
453 else
454 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
455 *((u16 *)val));
456 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500457 case HW_VAR_SLOT_TIME:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600458 u8 e_aci;
459
460 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
461 "HW_VAR_SLOT_TIME %x\n", val[0]);
462
463 rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
464
465 for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
466 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
Larry Finger5c99f042014-09-26 16:40:25 -0500467 (u8 *)(&e_aci));
Larry Fingera619d1a2014-02-28 15:16:50 -0600468 }
Larry Finger5c99f042014-09-26 16:40:25 -0500469 }
470 break;
471 case HW_VAR_ACK_PREAMBLE:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600472 u8 reg_tmp;
Larry Finger5c99f042014-09-26 16:40:25 -0500473 u8 short_preamble = (bool)(*(u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600474 reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL + 2);
475 if (short_preamble) {
476 reg_tmp |= 0x02;
477 rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
478 } else {
479 reg_tmp &= 0xFD;
480 rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
481 }
Larry Finger5c99f042014-09-26 16:40:25 -0500482 }
Larry Fingera619d1a2014-02-28 15:16:50 -0600483 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500484 case HW_VAR_WPA_CONFIG:
485 rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val));
486 break;
487 case HW_VAR_AMPDU_MIN_SPACE:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600488 u8 min_spacing_to_set;
489 u8 sec_min_space;
490
Larry Finger5c99f042014-09-26 16:40:25 -0500491 min_spacing_to_set = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600492 if (min_spacing_to_set <= 7) {
493 sec_min_space = 0;
494
495 if (min_spacing_to_set < sec_min_space)
496 min_spacing_to_set = sec_min_space;
497
498 mac->min_space_cfg = ((mac->min_space_cfg & 0xf8) |
499 min_spacing_to_set);
500
501 *val = min_spacing_to_set;
502
503 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
504 "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
Larry Finger5c99f042014-09-26 16:40:25 -0500505 mac->min_space_cfg);
Larry Fingera619d1a2014-02-28 15:16:50 -0600506
507 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
508 mac->min_space_cfg);
509 }
Larry Finger5c99f042014-09-26 16:40:25 -0500510 }
511 break;
512 case HW_VAR_SHORTGI_DENSITY:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600513 u8 density_to_set;
514
Larry Finger5c99f042014-09-26 16:40:25 -0500515 density_to_set = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600516 mac->min_space_cfg |= (density_to_set << 3);
517
518 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
519 "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
Larry Finger5c99f042014-09-26 16:40:25 -0500520 mac->min_space_cfg);
Larry Fingera619d1a2014-02-28 15:16:50 -0600521
522 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
523 mac->min_space_cfg);
Larry Finger5c99f042014-09-26 16:40:25 -0500524 }
525 break;
526 case HW_VAR_AMPDU_FACTOR:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600527 u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9};
528 u8 factor_toset;
529 u8 *p_regtoset = NULL;
530 u8 index = 0;
531
532 p_regtoset = regtoset_normal;
533
Larry Finger5c99f042014-09-26 16:40:25 -0500534 factor_toset = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600535 if (factor_toset <= 3) {
536 factor_toset = (1 << (factor_toset + 2));
537 if (factor_toset > 0xf)
538 factor_toset = 0xf;
539
540 for (index = 0; index < 4; index++) {
541 if ((p_regtoset[index] & 0xf0) >
542 (factor_toset << 4))
543 p_regtoset[index] =
544 (p_regtoset[index] & 0x0f) |
545 (factor_toset << 4);
546
547 if ((p_regtoset[index] & 0x0f) > factor_toset)
548 p_regtoset[index] =
549 (p_regtoset[index] & 0xf0) |
550 (factor_toset);
551
552 rtl_write_byte(rtlpriv,
553 (REG_AGGLEN_LMT + index),
554 p_regtoset[index]);
Larry Finger5c99f042014-09-26 16:40:25 -0500555
Larry Fingera619d1a2014-02-28 15:16:50 -0600556 }
Larry Finger5c99f042014-09-26 16:40:25 -0500557
Larry Fingera619d1a2014-02-28 15:16:50 -0600558 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
559 "Set HW_VAR_AMPDU_FACTOR: %#x\n",
Larry Finger5c99f042014-09-26 16:40:25 -0500560 factor_toset);
Larry Fingera619d1a2014-02-28 15:16:50 -0600561 }
Larry Finger5c99f042014-09-26 16:40:25 -0500562 }
563 break;
564 case HW_VAR_AC_PARAM:{
565 u8 e_aci = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600566 rtl8723_dm_init_edca_turbo(hw);
567
568 if (rtlpci->acm_method != EACMWAY2_SW)
569 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
Larry Finger5c99f042014-09-26 16:40:25 -0500570 (u8 *)(&e_aci));
571 }
572 break;
573 case HW_VAR_ACM_CTRL:{
574 u8 e_aci = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600575 union aci_aifsn *p_aci_aifsn =
576 (union aci_aifsn *)(&(mac->ac[0].aifs));
577 u8 acm = p_aci_aifsn->f.acm;
578 u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);
579
580 acm_ctrl =
581 acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1);
582
583 if (acm) {
584 switch (e_aci) {
585 case AC0_BE:
586 acm_ctrl |= ACMHW_BEQEN;
587 break;
588 case AC2_VI:
589 acm_ctrl |= ACMHW_VIQEN;
590 break;
591 case AC3_VO:
592 acm_ctrl |= ACMHW_VOQEN;
593 break;
594 default:
595 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
Larry Finger5c99f042014-09-26 16:40:25 -0500596 "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
597 acm);
Larry Fingera619d1a2014-02-28 15:16:50 -0600598 break;
599 }
600 } else {
601 switch (e_aci) {
602 case AC0_BE:
603 acm_ctrl &= (~ACMHW_BEQEN);
604 break;
605 case AC2_VI:
606 acm_ctrl &= (~ACMHW_VIQEN);
607 break;
608 case AC3_VO:
Jes Sorensen52f57802015-02-06 17:24:32 -0500609 acm_ctrl &= (~ACMHW_VOQEN);
Larry Fingera619d1a2014-02-28 15:16:50 -0600610 break;
611 default:
Larry Finger5c99f042014-09-26 16:40:25 -0500612 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -0700613 "switch case %#x not processed\n",
614 e_aci);
Larry Fingera619d1a2014-02-28 15:16:50 -0600615 break;
616 }
617 }
Larry Finger5c99f042014-09-26 16:40:25 -0500618
Larry Fingera619d1a2014-02-28 15:16:50 -0600619 RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
Larry Finger5c99f042014-09-26 16:40:25 -0500620 "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
621 acm_ctrl);
Larry Fingera619d1a2014-02-28 15:16:50 -0600622 rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
Larry Finger5c99f042014-09-26 16:40:25 -0500623 }
624 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600625 case HW_VAR_RCR:
626 rtl_write_dword(rtlpriv, REG_RCR, ((u32 *)(val))[0]);
627 rtlpci->receive_config = ((u32 *)(val))[0];
628 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500629 case HW_VAR_RETRY_LIMIT:{
630 u8 retry_limit = ((u8 *)(val))[0];
Larry Fingera619d1a2014-02-28 15:16:50 -0600631
632 rtl_write_word(rtlpriv, REG_RL,
633 retry_limit << RETRY_LIMIT_SHORT_SHIFT |
634 retry_limit << RETRY_LIMIT_LONG_SHIFT);
Larry Finger5c99f042014-09-26 16:40:25 -0500635 }
636 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600637 case HW_VAR_DUAL_TSF_RST:
638 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
639 break;
640 case HW_VAR_EFUSE_BYTES:
641 rtlefuse->efuse_usedbytes = *((u16 *)val);
642 break;
643 case HW_VAR_EFUSE_USAGE:
Larry Finger5c99f042014-09-26 16:40:25 -0500644 rtlefuse->efuse_usedpercentage = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600645 break;
646 case HW_VAR_IO_CMD:
647 rtl8723be_phy_set_io_cmd(hw, (*(enum io_type *)val));
648 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500649 case HW_VAR_SET_RPWM:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600650 u8 rpwm_val;
651
652 rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM);
653 udelay(1);
654
655 if (rpwm_val & BIT(7)) {
Larry Finger5c99f042014-09-26 16:40:25 -0500656 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, (*(u8 *)val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600657 } else {
Larry Finger5c99f042014-09-26 16:40:25 -0500658 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
659 ((*(u8 *)val) | BIT(7)));
Larry Fingera619d1a2014-02-28 15:16:50 -0600660 }
Larry Finger5c99f042014-09-26 16:40:25 -0500661 }
662 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600663 case HW_VAR_H2C_FW_PWRMODE:
Larry Finger5c99f042014-09-26 16:40:25 -0500664 rtl8723be_set_fw_pwrmode_cmd(hw, (*(u8 *)val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600665 break;
666 case HW_VAR_FW_PSMODE_STATUS:
667 ppsc->fw_current_inpsmode = *((bool *)val);
668 break;
669 case HW_VAR_RESUME_CLK_ON:
670 _rtl8723be_set_fw_ps_rf_on(hw);
671 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500672 case HW_VAR_FW_LPS_ACTION:{
673 bool b_enter_fwlps = *((bool *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600674
Larry Finger5c99f042014-09-26 16:40:25 -0500675 if (b_enter_fwlps)
Larry Fingera619d1a2014-02-28 15:16:50 -0600676 _rtl8723be_fwlps_enter(hw);
677 else
678 _rtl8723be_fwlps_leave(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500679 }
680 break;
681 case HW_VAR_H2C_FW_JOINBSSRPT:{
682 u8 mstatus = (*(u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600683
684 if (mstatus == RT_MEDIA_CONNECT) {
685 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL);
Larry Finger5c99f042014-09-26 16:40:25 -0500686 _rtl8723be_download_rsvd_page(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -0600687 }
Larry Finger5c99f042014-09-26 16:40:25 -0500688 rtl8723be_set_fw_media_status_rpt_cmd(hw, mstatus);
689 }
Larry Fingera619d1a2014-02-28 15:16:50 -0600690 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500691 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
692 rtl8723be_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
693 break;
694 case HW_VAR_AID:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600695 u16 u2btmp;
696 u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
697 u2btmp &= 0xC000;
698 rtl_write_word(rtlpriv, REG_BCN_PSR_RPT,
699 (u2btmp | mac->assoc_id));
Larry Finger5c99f042014-09-26 16:40:25 -0500700 }
701 break;
702 case HW_VAR_CORRECT_TSF:{
703 u8 btype_ibss = ((u8 *)(val))[0];
Larry Fingera619d1a2014-02-28 15:16:50 -0600704
705 if (btype_ibss)
706 _rtl8723be_stop_tx_beacon(hw);
707
708 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3));
709
710 rtl_write_dword(rtlpriv, REG_TSFTR,
711 (u32) (mac->tsf & 0xffffffff));
712 rtl_write_dword(rtlpriv, REG_TSFTR + 4,
713 (u32) ((mac->tsf >> 32) & 0xffffffff));
714
715 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
716
717 if (btype_ibss)
718 _rtl8723be_resume_tx_beacon(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500719 }
720 break;
721 case HW_VAR_KEEP_ALIVE:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600722 u8 array[2];
723 array[0] = 0xff;
Larry Finger5c99f042014-09-26 16:40:25 -0500724 array[1] = *((u8 *)val);
725 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_KEEP_ALIVE_CTRL, 2, array);
726 }
727 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600728 default:
Larry Finger5c99f042014-09-26 16:40:25 -0500729 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -0700730 "switch case %#x not processed\n", variable);
Larry Fingera619d1a2014-02-28 15:16:50 -0600731 break;
732 }
733}
734
735static bool _rtl8723be_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
736{
737 struct rtl_priv *rtlpriv = rtl_priv(hw);
738 bool status = true;
Larry Finger5c99f042014-09-26 16:40:25 -0500739 long count = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -0600740 u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) |
741 _LLT_OP(_LLT_WRITE_ACCESS);
742
743 rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
744
745 do {
746 value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
747 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
748 break;
749
750 if (count > POLLING_LLT_THRESHOLD) {
Larry Finger4e2b4372016-12-15 12:23:00 -0600751 pr_err("Failed to polling write LLT done at address %d!\n",
752 address);
Larry Fingera619d1a2014-02-28 15:16:50 -0600753 status = false;
754 break;
755 }
756 } while (++count);
757
758 return status;
759}
760
761static bool _rtl8723be_llt_table_init(struct ieee80211_hw *hw)
762{
763 struct rtl_priv *rtlpriv = rtl_priv(hw);
764 unsigned short i;
765 u8 txpktbuf_bndy;
Larry Finger5c99f042014-09-26 16:40:25 -0500766 u8 maxPage;
Larry Fingera619d1a2014-02-28 15:16:50 -0600767 bool status;
768
Larry Finger5c99f042014-09-26 16:40:25 -0500769 maxPage = 255;
Larry Fingera619d1a2014-02-28 15:16:50 -0600770 txpktbuf_bndy = 245;
771
772 rtl_write_dword(rtlpriv, REG_TRXFF_BNDY,
773 (0x27FF0000 | txpktbuf_bndy));
774 rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy);
775
776 rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
777 rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
778
779 rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy);
780 rtl_write_byte(rtlpriv, REG_PBP, 0x31);
781 rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);
782
783 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
784 status = _rtl8723be_llt_write(hw, i, i + 1);
785 if (!status)
786 return status;
787 }
Larry Finger5c99f042014-09-26 16:40:25 -0500788
Larry Fingera619d1a2014-02-28 15:16:50 -0600789 status = _rtl8723be_llt_write(hw, (txpktbuf_bndy - 1), 0xFF);
790
791 if (!status)
792 return status;
793
Larry Finger5c99f042014-09-26 16:40:25 -0500794 for (i = txpktbuf_bndy; i < maxPage; i++) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600795 status = _rtl8723be_llt_write(hw, i, (i + 1));
796 if (!status)
797 return status;
798 }
Larry Finger5c99f042014-09-26 16:40:25 -0500799
800 status = _rtl8723be_llt_write(hw, maxPage, txpktbuf_bndy);
Larry Fingera619d1a2014-02-28 15:16:50 -0600801 if (!status)
802 return status;
803
804 rtl_write_dword(rtlpriv, REG_RQPN, 0x80e40808);
805 rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x00);
806
807 return true;
808}
809
810static void _rtl8723be_gen_refresh_led_state(struct ieee80211_hw *hw)
811{
812 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -0600813 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
Larry Fingerd5efe152017-02-07 09:14:21 -0600814 struct rtl_led *pled0 = &rtlpriv->ledctl.sw_led0;
Larry Fingera619d1a2014-02-28 15:16:50 -0600815
816 if (rtlpriv->rtlhal.up_first_time)
817 return;
818
819 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
820 rtl8723be_sw_led_on(hw, pled0);
821 else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT)
822 rtl8723be_sw_led_on(hw, pled0);
823 else
824 rtl8723be_sw_led_off(hw, pled0);
825}
826
827static bool _rtl8723be_init_mac(struct ieee80211_hw *hw)
828{
829 struct rtl_priv *rtlpriv = rtl_priv(hw);
830 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
Larry Finger5c99f042014-09-26 16:40:25 -0500831 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
Larry Fingera619d1a2014-02-28 15:16:50 -0600832 unsigned char bytetmp;
833 unsigned short wordtmp;
Larry Fingera619d1a2014-02-28 15:16:50 -0600834
835 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
836
837 /*Auto Power Down to CHIP-off State*/
838 bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) & (~BIT(7));
839 rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp);
840
Larry Fingera619d1a2014-02-28 15:16:50 -0600841 /* HW Power on sequence */
Larry Finger34ed7802014-09-22 09:39:27 -0500842 if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK,
843 PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,
844 RTL8723_NIC_ENABLE_FLOW)) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600845 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
846 "init MAC Fail as power on failure\n");
847 return false;
848 }
Larry Finger5c99f042014-09-26 16:40:25 -0500849
850 bytetmp = rtl_read_byte(rtlpriv, REG_MULTI_FUNC_CTRL);
851 rtl_write_byte(rtlpriv, REG_MULTI_FUNC_CTRL, bytetmp | BIT(3));
852
Larry Fingera619d1a2014-02-28 15:16:50 -0600853 bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO) | BIT(4);
854 rtl_write_byte(rtlpriv, REG_APS_FSMCO, bytetmp);
855
856 bytetmp = rtl_read_byte(rtlpriv, REG_CR);
857 bytetmp = 0xff;
858 rtl_write_byte(rtlpriv, REG_CR, bytetmp);
859 mdelay(2);
860
861 bytetmp = rtl_read_byte(rtlpriv, REG_HWSEQ_CTRL);
862 bytetmp |= 0x7f;
863 rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, bytetmp);
864 mdelay(2);
865
866 bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CFG + 3);
867 if (bytetmp & BIT(0)) {
868 bytetmp = rtl_read_byte(rtlpriv, 0x7c);
Larry Finger5c99f042014-09-26 16:40:25 -0500869 rtl_write_byte(rtlpriv, 0x7c, bytetmp | BIT(6));
Larry Fingera619d1a2014-02-28 15:16:50 -0600870 }
Larry Fingera619d1a2014-02-28 15:16:50 -0600871
Larry Finger5c99f042014-09-26 16:40:25 -0500872 bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CLKR);
873 rtl_write_byte(rtlpriv, REG_SYS_CLKR, bytetmp | BIT(3));
874 bytetmp = rtl_read_byte(rtlpriv, REG_GPIO_MUXCFG + 1);
875 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG + 1, bytetmp & (~BIT(4)));
Larry Fingera619d1a2014-02-28 15:16:50 -0600876
877 rtl_write_word(rtlpriv, REG_CR, 0x2ff);
878
Larry Finger5c99f042014-09-26 16:40:25 -0500879 if (!rtlhal->mac_func_enable) {
880 if (_rtl8723be_llt_table_init(hw) == false)
Larry Fingera619d1a2014-02-28 15:16:50 -0600881 return false;
882 }
Larry Finger5c99f042014-09-26 16:40:25 -0500883
Larry Fingera619d1a2014-02-28 15:16:50 -0600884 rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
885 rtl_write_dword(rtlpriv, REG_HISRE, 0xffffffff);
886
887 /* Enable FW Beamformer Interrupt */
888 bytetmp = rtl_read_byte(rtlpriv, REG_FWIMR + 3);
889 rtl_write_byte(rtlpriv, REG_FWIMR + 3, bytetmp | BIT(6));
890
891 wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL);
892 wordtmp &= 0xf;
893 wordtmp |= 0xF5B1;
894 rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp);
895
896 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F);
897 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
898 rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xFFFF);
899 rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config);
900
Larry Fingera619d1a2014-02-28 15:16:50 -0600901 rtl_write_dword(rtlpriv, REG_BCNQ_DESA,
902 ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) &
903 DMA_BIT_MASK(32));
904 rtl_write_dword(rtlpriv, REG_MGQ_DESA,
905 (u64) rtlpci->tx_ring[MGNT_QUEUE].dma &
906 DMA_BIT_MASK(32));
907 rtl_write_dword(rtlpriv, REG_VOQ_DESA,
908 (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32));
909 rtl_write_dword(rtlpriv, REG_VIQ_DESA,
910 (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32));
911 rtl_write_dword(rtlpriv, REG_BEQ_DESA,
912 (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32));
913 rtl_write_dword(rtlpriv, REG_BKQ_DESA,
914 (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32));
915 rtl_write_dword(rtlpriv, REG_HQ_DESA,
916 (u64) rtlpci->tx_ring[HIGH_QUEUE].dma &
917 DMA_BIT_MASK(32));
918 rtl_write_dword(rtlpriv, REG_RX_DESA,
919 (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma &
920 DMA_BIT_MASK(32));
921
922 bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 3);
923 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, bytetmp | 0x77);
924
925 rtl_write_dword(rtlpriv, REG_INT_MIG, 0);
926
Larry Finger5c99f042014-09-26 16:40:25 -0500927 rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0);
Larry Fingera619d1a2014-02-28 15:16:50 -0600928
929 rtl_write_byte(rtlpriv, REG_SECONDARY_CCA_CTRL, 0x3);
930
Larry Finger5c99f042014-09-26 16:40:25 -0500931 /* <20130114, Kordan> The following setting is
932 * only for DPDT and Fixed board type.
933 * TODO: A better solution is configure it
934 * according EFUSE during the run-time.
935 */
936 rtl_set_bbreg(hw, 0x64, BIT(20), 0x0);/* 0x66[4]=0 */
937 rtl_set_bbreg(hw, 0x64, BIT(24), 0x0);/* 0x66[8]=0 */
938 rtl_set_bbreg(hw, 0x40, BIT(4), 0x0)/* 0x40[4]=0 */;
939 rtl_set_bbreg(hw, 0x40, BIT(3), 0x1)/* 0x40[3]=1 */;
940 rtl_set_bbreg(hw, 0x4C, BIT(24) | BIT(23), 0x2)/* 0x4C[24:23]=10 */;
941 rtl_set_bbreg(hw, 0x944, BIT(1) | BIT(0), 0x3)/* 0x944[1:0]=11 */;
942 rtl_set_bbreg(hw, 0x930, MASKBYTE0, 0x77)/* 0x930[7:0]=77 */;
943 rtl_set_bbreg(hw, 0x38, BIT(11), 0x1)/* 0x38[11]=1 */;
Larry Fingera619d1a2014-02-28 15:16:50 -0600944
945 bytetmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
Larry Finger5c99f042014-09-26 16:40:25 -0500946 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, bytetmp & (~BIT(2)));
Larry Fingera619d1a2014-02-28 15:16:50 -0600947
Larry Finger5c99f042014-09-26 16:40:25 -0500948 _rtl8723be_gen_refresh_led_state(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -0600949 return true;
950}
951
952static void _rtl8723be_hw_configure(struct ieee80211_hw *hw)
953{
954 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500955 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
956 u32 reg_rrsr;
Larry Fingera619d1a2014-02-28 15:16:50 -0600957
Larry Finger5c99f042014-09-26 16:40:25 -0500958 reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
959 /* Init value for RRSR. */
960 rtl_write_dword(rtlpriv, REG_RRSR, reg_rrsr);
Larry Fingera619d1a2014-02-28 15:16:50 -0600961
Larry Finger5c99f042014-09-26 16:40:25 -0500962 /* ARFB table 9 for 11ac 5G 2SS */
963 rtl_write_dword(rtlpriv, REG_ARFR0 + 4, 0xfffff000);
964
965 /* ARFB table 10 for 11ac 5G 1SS */
966 rtl_write_dword(rtlpriv, REG_ARFR1 + 4, 0x003ff000);
967
968 /* CF-End setting. */
969 rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F00);
970
971 /* 0x456 = 0x70, sugguested by Zhilin */
972 rtl_write_byte(rtlpriv, REG_AMPDU_MAX_TIME, 0x70);
973
974 /* Set retry limit */
975 rtl_write_word(rtlpriv, REG_RL, 0x0707);
976
977 /* Set Data / Response auto rate fallack retry count */
978 rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000);
979 rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504);
980 rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000);
981 rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504);
982
983 rtlpci->reg_bcn_ctrl_val = 0x1d;
984 rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val);
985
986 /* TBTT prohibit hold time. Suggested by designer TimChen. */
987 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); /* 8 ms */
988
989 rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040);
990
991 /*For Rx TP. Suggested by SD1 Richard. Added by tynli. 2010.04.12.*/
992 rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666);
993
994 rtl_write_byte(rtlpriv, REG_HT_SINGLE_AMPDU, 0x80);
995
996 rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x20);
997
998 rtl_write_byte(rtlpriv, REG_MAX_AGGR_NUM, 0x1F);
999}
1000
1001static u8 _rtl8723be_dbi_read(struct rtl_priv *rtlpriv, u16 addr)
1002{
1003 u16 read_addr = addr & 0xfffc;
1004 u8 ret = 0, tmp = 0, count = 0;
1005
1006 rtl_write_word(rtlpriv, REG_DBI_ADDR, read_addr);
1007 rtl_write_byte(rtlpriv, REG_DBI_FLAG, 0x2);
1008 tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1009 count = 0;
1010 while (tmp && count < 20) {
1011 udelay(10);
1012 tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1013 count++;
1014 }
1015 if (0 == tmp) {
1016 read_addr = REG_DBI_RDATA + addr % 4;
1017 ret = rtl_read_byte(rtlpriv, read_addr);
1018 }
1019
1020 return ret;
1021}
1022
1023static void _rtl8723be_dbi_write(struct rtl_priv *rtlpriv, u16 addr, u8 data)
1024{
1025 u8 tmp = 0, count = 0;
1026 u16 write_addr = 0, remainder = addr % 4;
1027
1028 /* Write DBI 1Byte Data */
1029 write_addr = REG_DBI_WDATA + remainder;
1030 rtl_write_byte(rtlpriv, write_addr, data);
1031
1032 /* Write DBI 2Byte Address & Write Enable */
1033 write_addr = (addr & 0xfffc) | (BIT(0) << (remainder + 12));
1034 rtl_write_word(rtlpriv, REG_DBI_ADDR, write_addr);
1035
1036 /* Write DBI Write Flag */
1037 rtl_write_byte(rtlpriv, REG_DBI_FLAG, 0x1);
1038
1039 tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1040 count = 0;
1041 while (tmp && count < 20) {
1042 udelay(10);
1043 tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1044 count++;
1045 }
1046}
1047
1048static u16 _rtl8723be_mdio_read(struct rtl_priv *rtlpriv, u8 addr)
1049{
1050 u16 ret = 0;
1051 u8 tmp = 0, count = 0;
1052
1053 rtl_write_byte(rtlpriv, REG_MDIO_CTL, addr | BIT(6));
1054 tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(6);
1055 count = 0;
1056 while (tmp && count < 20) {
1057 udelay(10);
1058 tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(6);
1059 count++;
1060 }
1061
1062 if (0 == tmp)
1063 ret = rtl_read_word(rtlpriv, REG_MDIO_RDATA);
1064
1065 return ret;
1066}
1067
1068static void _rtl8723be_mdio_write(struct rtl_priv *rtlpriv, u8 addr, u16 data)
1069{
1070 u8 tmp = 0, count = 0;
1071
1072 rtl_write_word(rtlpriv, REG_MDIO_WDATA, data);
1073 rtl_write_byte(rtlpriv, REG_MDIO_CTL, addr | BIT(5));
1074 tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(5);
1075 count = 0;
1076 while (tmp && count < 20) {
1077 udelay(10);
1078 tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(5);
1079 count++;
1080 }
Larry Fingera619d1a2014-02-28 15:16:50 -06001081}
1082
1083static void _rtl8723be_enable_aspm_back_door(struct ieee80211_hw *hw)
1084{
1085 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -05001086 u8 tmp8 = 0;
1087 u16 tmp16 = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06001088
Larry Finger5c99f042014-09-26 16:40:25 -05001089 /* <Roger_Notes> Overwrite following ePHY parameter for
1090 * some platform compatibility issue,
1091 * especially when CLKReq is enabled, 2012.11.09.
1092 */
1093 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x01);
1094 if (tmp16 != 0x0663)
1095 _rtl8723be_mdio_write(rtlpriv, 0x01, 0x0663);
Larry Fingera619d1a2014-02-28 15:16:50 -06001096
Larry Finger5c99f042014-09-26 16:40:25 -05001097 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x04);
1098 if (tmp16 != 0x7544)
1099 _rtl8723be_mdio_write(rtlpriv, 0x04, 0x7544);
Larry Fingera619d1a2014-02-28 15:16:50 -06001100
Larry Finger5c99f042014-09-26 16:40:25 -05001101 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x06);
1102 if (tmp16 != 0xB880)
1103 _rtl8723be_mdio_write(rtlpriv, 0x06, 0xB880);
1104
1105 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x07);
1106 if (tmp16 != 0x4000)
1107 _rtl8723be_mdio_write(rtlpriv, 0x07, 0x4000);
1108
1109 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x08);
1110 if (tmp16 != 0x9003)
1111 _rtl8723be_mdio_write(rtlpriv, 0x08, 0x9003);
1112
1113 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x09);
1114 if (tmp16 != 0x0D03)
1115 _rtl8723be_mdio_write(rtlpriv, 0x09, 0x0D03);
1116
1117 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x0A);
1118 if (tmp16 != 0x4037)
1119 _rtl8723be_mdio_write(rtlpriv, 0x0A, 0x4037);
1120
1121 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x0B);
1122 if (tmp16 != 0x0070)
1123 _rtl8723be_mdio_write(rtlpriv, 0x0B, 0x0070);
1124
1125 /* Configuration Space offset 0x70f BIT7 is used to control L0S */
1126 tmp8 = _rtl8723be_dbi_read(rtlpriv, 0x70f);
1127 _rtl8723be_dbi_write(rtlpriv, 0x70f, tmp8 | BIT(7));
1128
1129 /* Configuration Space offset 0x719 Bit3 is for L1
1130 * BIT4 is for clock request
1131 */
1132 tmp8 = _rtl8723be_dbi_read(rtlpriv, 0x719);
1133 _rtl8723be_dbi_write(rtlpriv, 0x719, tmp8 | BIT(3) | BIT(4));
Larry Fingera619d1a2014-02-28 15:16:50 -06001134}
1135
1136void rtl8723be_enable_hw_security_config(struct ieee80211_hw *hw)
1137{
1138 struct rtl_priv *rtlpriv = rtl_priv(hw);
1139 u8 sec_reg_value;
1140
1141 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1142 "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
Larry Finger5c99f042014-09-26 16:40:25 -05001143 rtlpriv->sec.pairwise_enc_algorithm,
1144 rtlpriv->sec.group_enc_algorithm);
Larry Fingera619d1a2014-02-28 15:16:50 -06001145
1146 if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
1147 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1148 "not open hw encryption\n");
1149 return;
1150 }
Larry Finger5c99f042014-09-26 16:40:25 -05001151
Larry Fingera619d1a2014-02-28 15:16:50 -06001152 sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE;
1153
1154 if (rtlpriv->sec.use_defaultkey) {
1155 sec_reg_value |= SCR_TXUSEDK;
1156 sec_reg_value |= SCR_RXUSEDK;
1157 }
Larry Finger5c99f042014-09-26 16:40:25 -05001158
Larry Fingera619d1a2014-02-28 15:16:50 -06001159 sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
1160
1161 rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
1162
Larry Finger5c99f042014-09-26 16:40:25 -05001163 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1164 "The SECR-value %x\n", sec_reg_value);
Larry Fingera619d1a2014-02-28 15:16:50 -06001165
1166 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
1167}
1168
Larry Finger5c99f042014-09-26 16:40:25 -05001169static void _rtl8723be_poweroff_adapter(struct ieee80211_hw *hw)
1170{
1171 struct rtl_priv *rtlpriv = rtl_priv(hw);
1172 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1173 u8 u1b_tmp;
1174
1175 rtlhal->mac_func_enable = false;
1176 /* Combo (PCIe + USB) Card and PCIe-MF Card */
1177 /* 1. Run LPS WL RFOFF flow */
1178 rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1179 PWR_INTF_PCI_MSK, RTL8723_NIC_LPS_ENTER_FLOW);
1180
1181 /* 2. 0x1F[7:0] = 0 */
1182 /* turn off RF */
1183 /* rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); */
1184 if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) &&
1185 rtlhal->fw_ready) {
1186 rtl8723be_firmware_selfreset(hw);
1187 }
1188
1189 /* Reset MCU. Suggested by Filen. */
1190 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1191 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2))));
1192
1193 /* g. MCUFWDL 0x80[1:0]=0 */
1194 /* reset MCU ready status */
1195 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
1196
1197 /* HW card disable configuration. */
1198 rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1199 PWR_INTF_PCI_MSK, RTL8723_NIC_DISABLE_FLOW);
1200
1201 /* Reset MCU IO Wrapper */
1202 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1203 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0))));
1204 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1205 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1b_tmp | BIT(0));
1206
1207 /* 7. RSV_CTRL 0x1C[7:0] = 0x0E */
1208 /* lock ISO/CLK/Power control register */
1209 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e);
1210}
1211
1212static bool _rtl8723be_check_pcie_dma_hang(struct rtl_priv *rtlpriv)
1213{
1214 u8 tmp;
1215
1216 /* write reg 0x350 Bit[26]=1. Enable debug port. */
1217 tmp = rtl_read_byte(rtlpriv, REG_DBI_CTRL + 3);
1218 if (!(tmp & BIT(2))) {
1219 rtl_write_byte(rtlpriv, REG_DBI_CTRL + 3, (tmp | BIT(2)));
1220 mdelay(100); /* Suggested by DD Justin_tsai. */
1221 }
1222
1223 /* read reg 0x350 Bit[25] if 1 : RX hang
1224 * read reg 0x350 Bit[24] if 1 : TX hang
1225 */
1226 tmp = rtl_read_byte(rtlpriv, REG_DBI_CTRL + 3);
1227 if ((tmp & BIT(0)) || (tmp & BIT(1))) {
1228 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1229 "CheckPcieDMAHang8723BE(): true!!\n");
1230 return true;
1231 }
1232 return false;
1233}
1234
1235static void _rtl8723be_reset_pcie_interface_dma(struct rtl_priv *rtlpriv,
1236 bool mac_power_on)
1237{
1238 u8 tmp;
1239 bool release_mac_rx_pause;
1240 u8 backup_pcie_dma_pause;
1241
1242 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1243 "ResetPcieInterfaceDMA8723BE()\n");
1244
1245 /* Revise Note: Follow the document "PCIe RX DMA Hang Reset Flow_v03"
1246 * released by SD1 Alan.
1247 * 2013.05.07, by tynli.
1248 */
1249
1250 /* 1. disable register write lock
1251 * write 0x1C bit[1:0] = 2'h0
1252 * write 0xCC bit[2] = 1'b1
1253 */
1254 tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL);
1255 tmp &= ~(BIT(1) | BIT(0));
1256 rtl_write_byte(rtlpriv, REG_RSV_CTRL, tmp);
1257 tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2);
1258 tmp |= BIT(2);
1259 rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp);
1260
1261 /* 2. Check and pause TRX DMA
1262 * write 0x284 bit[18] = 1'b1
1263 * write 0x301 = 0xFF
1264 */
1265 tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1266 if (tmp & BIT(2)) {
1267 /* Already pause before the function for another purpose. */
1268 release_mac_rx_pause = false;
1269 } else {
1270 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, (tmp | BIT(2)));
1271 release_mac_rx_pause = true;
1272 }
1273
1274 backup_pcie_dma_pause = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 1);
1275 if (backup_pcie_dma_pause != 0xFF)
1276 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xFF);
1277
1278 if (mac_power_on) {
1279 /* 3. reset TRX function
1280 * write 0x100 = 0x00
1281 */
1282 rtl_write_byte(rtlpriv, REG_CR, 0);
1283 }
1284
1285 /* 4. Reset PCIe DMA
1286 * write 0x003 bit[0] = 0
1287 */
1288 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1289 tmp &= ~(BIT(0));
1290 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp);
1291
1292 /* 5. Enable PCIe DMA
1293 * write 0x003 bit[0] = 1
1294 */
1295 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1296 tmp |= BIT(0);
1297 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp);
1298
1299 if (mac_power_on) {
1300 /* 6. enable TRX function
1301 * write 0x100 = 0xFF
1302 */
1303 rtl_write_byte(rtlpriv, REG_CR, 0xFF);
1304
1305 /* We should init LLT & RQPN and
1306 * prepare Tx/Rx descrptor address later
1307 * because MAC function is reset.
1308 */
1309 }
1310
1311 /* 7. Restore PCIe autoload down bit
1312 * write 0xF8 bit[17] = 1'b1
1313 */
1314 tmp = rtl_read_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2);
1315 tmp |= BIT(1);
1316 rtl_write_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2, tmp);
1317
1318 /* In MAC power on state, BB and RF maybe in ON state,
1319 * if we release TRx DMA here
1320 * it will cause packets to be started to Tx/Rx,
1321 * so we release Tx/Rx DMA later.
1322 */
1323 if (!mac_power_on) {
1324 /* 8. release TRX DMA
1325 * write 0x284 bit[18] = 1'b0
1326 * write 0x301 = 0x00
1327 */
1328 if (release_mac_rx_pause) {
1329 tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1330 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL,
1331 (tmp & (~BIT(2))));
1332 }
1333 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1,
1334 backup_pcie_dma_pause);
1335 }
1336
1337 /* 9. lock system register
1338 * write 0xCC bit[2] = 1'b0
1339 */
1340 tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2);
1341 tmp &= ~(BIT(2));
1342 rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp);
1343}
1344
Larry Fingera619d1a2014-02-28 15:16:50 -06001345int rtl8723be_hw_init(struct ieee80211_hw *hw)
1346{
1347 struct rtl_priv *rtlpriv = rtl_priv(hw);
1348 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1349 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1350 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1351 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1352 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1353 bool rtstatus = true;
1354 int err;
1355 u8 tmp_u1b;
1356 unsigned long flags;
1357
1358 /* reenable interrupts to not interfere with other devices */
1359 local_save_flags(flags);
1360 local_irq_enable();
1361
Larry Finger5c99f042014-09-26 16:40:25 -05001362 rtlhal->fw_ready = false;
Larry Fingera619d1a2014-02-28 15:16:50 -06001363 rtlpriv->rtlhal.being_init_adapter = true;
1364 rtlpriv->intf_ops->disable_aspm(hw);
Larry Finger5c99f042014-09-26 16:40:25 -05001365
1366 tmp_u1b = rtl_read_byte(rtlpriv, REG_CR);
1367 if (tmp_u1b != 0 && tmp_u1b != 0xea) {
1368 rtlhal->mac_func_enable = true;
1369 } else {
1370 rtlhal->mac_func_enable = false;
1371 rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON;
1372 }
1373
1374 if (_rtl8723be_check_pcie_dma_hang(rtlpriv)) {
1375 _rtl8723be_reset_pcie_interface_dma(rtlpriv,
1376 rtlhal->mac_func_enable);
1377 rtlhal->mac_func_enable = false;
1378 }
1379 if (rtlhal->mac_func_enable) {
1380 _rtl8723be_poweroff_adapter(hw);
1381 rtlhal->mac_func_enable = false;
1382 }
Larry Fingera619d1a2014-02-28 15:16:50 -06001383 rtstatus = _rtl8723be_init_mac(hw);
1384 if (!rtstatus) {
Larry Finger4e2b4372016-12-15 12:23:00 -06001385 pr_err("Init MAC failed\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06001386 err = 1;
1387 goto exit;
1388 }
Larry Fingera619d1a2014-02-28 15:16:50 -06001389
Larry Finger5c99f042014-09-26 16:40:25 -05001390 tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CFG);
1391 rtl_write_byte(rtlpriv, REG_SYS_CFG, tmp_u1b & 0x7F);
1392
1393 err = rtl8723_download_fw(hw, true, FW_8723B_POLLING_TIMEOUT_COUNT);
Larry Fingera619d1a2014-02-28 15:16:50 -06001394 if (err) {
1395 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1396 "Failed to download FW. Init HW without FW now..\n");
1397 err = 1;
Larry Fingera619d1a2014-02-28 15:16:50 -06001398 goto exit;
Larry Fingera619d1a2014-02-28 15:16:50 -06001399 }
Larry Finger5c99f042014-09-26 16:40:25 -05001400 rtlhal->fw_ready = true;
1401
Larry Fingera619d1a2014-02-28 15:16:50 -06001402 rtlhal->last_hmeboxnum = 0;
1403 rtl8723be_phy_mac_config(hw);
1404 /* because last function modify RCR, so we update
1405 * rcr var here, or TP will unstable for receive_config
Larry Finger5c99f042014-09-26 16:40:25 -05001406 * is wrong, RX RCR_ACRC32 will cause TP unstable & Rx
Larry Fingera619d1a2014-02-28 15:16:50 -06001407 * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252
1408 */
1409 rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR);
1410 rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
1411 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
1412
1413 rtl8723be_phy_bb_config(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -06001414 rtl8723be_phy_rf_config(hw);
1415
1416 rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
1417 RF_CHNLBW, RFREG_OFFSET_MASK);
1418 rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1,
1419 RF_CHNLBW, RFREG_OFFSET_MASK);
1420 rtlphy->rfreg_chnlval[0] &= 0xFFF03FF;
1421 rtlphy->rfreg_chnlval[0] |= (BIT(10) | BIT(11));
1422
Larry Fingera619d1a2014-02-28 15:16:50 -06001423 _rtl8723be_hw_configure(hw);
Larry Finger5c99f042014-09-26 16:40:25 -05001424 rtlhal->mac_func_enable = true;
Larry Fingera619d1a2014-02-28 15:16:50 -06001425 rtl_cam_reset_all_entry(hw);
1426 rtl8723be_enable_hw_security_config(hw);
1427
1428 ppsc->rfpwr_state = ERFON;
1429
1430 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
1431 _rtl8723be_enable_aspm_back_door(hw);
1432 rtlpriv->intf_ops->enable_aspm(hw);
1433
1434 rtl8723be_bt_hw_init(hw);
1435
Larry Fingera619d1a2014-02-28 15:16:50 -06001436 if (ppsc->rfpwr_state == ERFON) {
Larry Finger5c99f042014-09-26 16:40:25 -05001437 rtl8723be_phy_set_rfpath_switch(hw, 1);
1438 /* when use 1ant NIC, iqk will disturb BT music
1439 * root cause is not clear now, is something
1440 * related with 'mdelay' and Reg[0x948]
1441 */
1442 if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2 ||
1443 !rtlpriv->cfg->ops->get_btc_status()) {
Ping-Ke Shiha7088392017-06-21 12:15:32 -05001444 rtl8723be_phy_iq_calibrate(hw,
1445 (rtlphy->iqk_initialized ?
1446 true : false));
Larry Finger5c99f042014-09-26 16:40:25 -05001447 rtlphy->iqk_initialized = true;
1448 }
Larry Fingera619d1a2014-02-28 15:16:50 -06001449 rtl8723be_dm_check_txpower_tracking(hw);
1450 rtl8723be_phy_lc_calibrate(hw);
1451 }
Larry Finger5c99f042014-09-26 16:40:25 -05001452 rtl_write_byte(rtlpriv, REG_NAV_UPPER, ((30000 + 127) / 128));
1453
1454 /* Release Rx DMA. */
1455 tmp_u1b = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1456 if (tmp_u1b & BIT(2)) {
1457 /* Release Rx DMA if needed */
1458 tmp_u1b &= (~BIT(2));
1459 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, tmp_u1b);
Larry Fingera619d1a2014-02-28 15:16:50 -06001460 }
Larry Finger5c99f042014-09-26 16:40:25 -05001461 /* Release Tx/Rx PCIE DMA. */
1462 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0);
1463
Larry Fingera619d1a2014-02-28 15:16:50 -06001464 rtl8723be_dm_init(hw);
1465exit:
1466 local_irq_restore(flags);
1467 rtlpriv->rtlhal.being_init_adapter = false;
1468 return err;
1469}
1470
1471static enum version_8723e _rtl8723be_read_chip_version(struct ieee80211_hw *hw)
1472{
1473 struct rtl_priv *rtlpriv = rtl_priv(hw);
1474 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1475 enum version_8723e version = VERSION_UNKNOWN;
Larry Fingera619d1a2014-02-28 15:16:50 -06001476 u32 value32;
1477
Larry Fingera619d1a2014-02-28 15:16:50 -06001478 value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG1);
1479 if ((value32 & (CHIP_8723B)) != CHIP_8723B)
Masanari Iida8a190232016-06-29 12:37:19 +09001480 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "unknown chip version\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06001481 else
Larry Finger5c99f042014-09-26 16:40:25 -05001482 version = (enum version_8723e)CHIP_8723B;
Larry Fingera619d1a2014-02-28 15:16:50 -06001483
Larry Finger5c99f042014-09-26 16:40:25 -05001484 rtlphy->rf_type = RF_1T1R;
Larry Fingera619d1a2014-02-28 15:16:50 -06001485
Larry Finger5c99f042014-09-26 16:40:25 -05001486 /* treat rtl8723be chip as MP version in default */
1487 version = (enum version_8723e)(version | NORMAL_CHIP);
1488
1489 value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
1490 /* cut version */
1491 version |= (enum version_8723e)(value32 & CHIP_VER_RTL_MASK);
1492 /* Manufacture */
1493 if (((value32 & EXT_VENDOR_ID) >> 18) == 0x01)
1494 version = (enum version_8723e)(version | CHIP_VENDOR_SMIC);
1495
Larry Fingera619d1a2014-02-28 15:16:50 -06001496 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1497 "Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
Larry Finger5c99f042014-09-26 16:40:25 -05001498 "RF_2T2R" : "RF_1T1R");
Larry Fingera619d1a2014-02-28 15:16:50 -06001499
1500 return version;
1501}
1502
1503static int _rtl8723be_set_media_status(struct ieee80211_hw *hw,
1504 enum nl80211_iftype type)
1505{
1506 struct rtl_priv *rtlpriv = rtl_priv(hw);
1507 u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc;
1508 enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
Larry Finger5c99f042014-09-26 16:40:25 -05001509 u8 mode = MSR_NOLINK;
Larry Fingera619d1a2014-02-28 15:16:50 -06001510
Larry Fingera619d1a2014-02-28 15:16:50 -06001511 switch (type) {
1512 case NL80211_IFTYPE_UNSPECIFIED:
Larry Finger5c99f042014-09-26 16:40:25 -05001513 mode = MSR_NOLINK;
Larry Fingera619d1a2014-02-28 15:16:50 -06001514 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1515 "Set Network type to NO LINK!\n");
1516 break;
1517 case NL80211_IFTYPE_ADHOC:
Larry Finger5c99f042014-09-26 16:40:25 -05001518 case NL80211_IFTYPE_MESH_POINT:
1519 mode = MSR_ADHOC;
Larry Fingera619d1a2014-02-28 15:16:50 -06001520 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1521 "Set Network type to Ad Hoc!\n");
1522 break;
1523 case NL80211_IFTYPE_STATION:
Larry Finger5c99f042014-09-26 16:40:25 -05001524 mode = MSR_INFRA;
Larry Fingera619d1a2014-02-28 15:16:50 -06001525 ledaction = LED_CTL_LINK;
1526 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1527 "Set Network type to STA!\n");
1528 break;
1529 case NL80211_IFTYPE_AP:
Larry Finger5c99f042014-09-26 16:40:25 -05001530 mode = MSR_AP;
1531 ledaction = LED_CTL_LINK;
Larry Fingera619d1a2014-02-28 15:16:50 -06001532 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1533 "Set Network type to AP!\n");
1534 break;
1535 default:
Larry Finger4e2b4372016-12-15 12:23:00 -06001536 pr_err("Network type %d not support!\n", type);
Larry Fingera619d1a2014-02-28 15:16:50 -06001537 return 1;
1538 }
Larry Finger5c99f042014-09-26 16:40:25 -05001539
1540 /* MSR_INFRA == Link in infrastructure network;
1541 * MSR_ADHOC == Link in ad hoc network;
1542 * Therefore, check link state is necessary.
1543 *
1544 * MSR_AP == AP mode; link state is not cared here.
1545 */
1546 if (mode != MSR_AP && rtlpriv->mac80211.link_state < MAC80211_LINKED) {
1547 mode = MSR_NOLINK;
1548 ledaction = LED_CTL_NO_LINK;
1549 }
1550
1551 if (mode == MSR_NOLINK || mode == MSR_INFRA) {
1552 _rtl8723be_stop_tx_beacon(hw);
1553 _rtl8723be_enable_bcn_sub_func(hw);
1554 } else if (mode == MSR_ADHOC || mode == MSR_AP) {
1555 _rtl8723be_resume_tx_beacon(hw);
1556 _rtl8723be_disable_bcn_sub_func(hw);
1557 } else {
1558 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1559 "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n",
1560 mode);
1561 }
1562
Taehee Yooe480e132015-03-20 19:31:33 +09001563 rtl_write_byte(rtlpriv, MSR, bt_msr | mode);
Larry Fingera619d1a2014-02-28 15:16:50 -06001564 rtlpriv->cfg->ops->led_control(hw, ledaction);
Larry Finger5c99f042014-09-26 16:40:25 -05001565 if (mode == MSR_AP)
Larry Fingera619d1a2014-02-28 15:16:50 -06001566 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1567 else
1568 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
1569 return 0;
1570}
1571
1572void rtl8723be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1573{
1574 struct rtl_priv *rtlpriv = rtl_priv(hw);
1575 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1576 u32 reg_rcr = rtlpci->receive_config;
1577
1578 if (rtlpriv->psc.rfpwr_state != ERFON)
1579 return;
1580
1581 if (check_bssid) {
1582 reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1583 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1584 (u8 *)(&reg_rcr));
1585 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4));
1586 } else if (!check_bssid) {
1587 reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
1588 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0);
1589 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1590 (u8 *)(&reg_rcr));
1591 }
Larry Finger5c99f042014-09-26 16:40:25 -05001592
Larry Fingera619d1a2014-02-28 15:16:50 -06001593}
1594
1595int rtl8723be_set_network_type(struct ieee80211_hw *hw,
1596 enum nl80211_iftype type)
1597{
1598 struct rtl_priv *rtlpriv = rtl_priv(hw);
1599
1600 if (_rtl8723be_set_media_status(hw, type))
1601 return -EOPNOTSUPP;
1602
1603 if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
1604 if (type != NL80211_IFTYPE_AP)
1605 rtl8723be_set_check_bssid(hw, true);
1606 } else {
1607 rtl8723be_set_check_bssid(hw, false);
1608 }
Larry Finger5c99f042014-09-26 16:40:25 -05001609
Larry Fingera619d1a2014-02-28 15:16:50 -06001610 return 0;
1611}
1612
1613/* don't set REG_EDCA_BE_PARAM here
1614 * because mac80211 will send pkt when scan
1615 */
1616void rtl8723be_set_qos(struct ieee80211_hw *hw, int aci)
1617{
1618 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -05001619
Larry Fingera619d1a2014-02-28 15:16:50 -06001620 rtl8723_dm_init_edca_turbo(hw);
1621 switch (aci) {
1622 case AC1_BK:
1623 rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f);
1624 break;
1625 case AC0_BE:
1626 break;
1627 case AC2_VI:
1628 rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322);
1629 break;
1630 case AC3_VO:
1631 rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
1632 break;
1633 default:
Larry Finger531940f2016-12-15 12:22:57 -06001634 WARN_ONCE(true, "rtl8723be: invalid aci: %d !\n", aci);
Larry Fingera619d1a2014-02-28 15:16:50 -06001635 break;
1636 }
1637}
1638
1639void rtl8723be_enable_interrupt(struct ieee80211_hw *hw)
1640{
1641 struct rtl_priv *rtlpriv = rtl_priv(hw);
1642 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1643
1644 rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
1645 rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
1646 rtlpci->irq_enabled = true;
Larry Finger5c99f042014-09-26 16:40:25 -05001647
Larry Fingera619d1a2014-02-28 15:16:50 -06001648 /*enable system interrupt*/
1649 rtl_write_dword(rtlpriv, REG_HSIMR, rtlpci->sys_irq_mask & 0xFFFFFFFF);
1650}
1651
1652void rtl8723be_disable_interrupt(struct ieee80211_hw *hw)
1653{
1654 struct rtl_priv *rtlpriv = rtl_priv(hw);
1655 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1656
1657 rtl_write_dword(rtlpriv, REG_HIMR, IMR_DISABLED);
1658 rtl_write_dword(rtlpriv, REG_HIMRE, IMR_DISABLED);
1659 rtlpci->irq_enabled = false;
Larry Finger5c99f042014-09-26 16:40:25 -05001660 /*synchronize_irq(rtlpci->pdev->irq);*/
Larry Fingera619d1a2014-02-28 15:16:50 -06001661}
1662
1663void rtl8723be_card_disable(struct ieee80211_hw *hw)
1664{
1665 struct rtl_priv *rtlpriv = rtl_priv(hw);
1666 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1667 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1668 enum nl80211_iftype opmode;
1669
1670 mac->link_state = MAC80211_NOLINK;
1671 opmode = NL80211_IFTYPE_UNSPECIFIED;
1672 _rtl8723be_set_media_status(hw, opmode);
1673 if (rtlpriv->rtlhal.driver_is_goingto_unload ||
1674 ppsc->rfoff_reason > RF_CHANGE_BY_PS)
1675 rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
1676 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1677 _rtl8723be_poweroff_adapter(hw);
1678
1679 /* after power off we should do iqk again */
Ping-Ke Shiha7088392017-06-21 12:15:32 -05001680 if (!rtlpriv->cfg->ops->get_btc_status())
1681 rtlpriv->phy.iqk_initialized = false;
Larry Fingera619d1a2014-02-28 15:16:50 -06001682}
1683
1684void rtl8723be_interrupt_recognized(struct ieee80211_hw *hw,
1685 u32 *p_inta, u32 *p_intb)
1686{
1687 struct rtl_priv *rtlpriv = rtl_priv(hw);
1688 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1689
1690 *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0];
1691 rtl_write_dword(rtlpriv, ISR, *p_inta);
1692
1693 *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) &
1694 rtlpci->irq_mask[1];
1695 rtl_write_dword(rtlpriv, REG_HISRE, *p_intb);
1696}
1697
1698void rtl8723be_set_beacon_related_registers(struct ieee80211_hw *hw)
1699{
1700 struct rtl_priv *rtlpriv = rtl_priv(hw);
1701 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1702 u16 bcn_interval, atim_window;
1703
1704 bcn_interval = mac->beacon_interval;
1705 atim_window = 2; /*FIX MERGE */
1706 rtl8723be_disable_interrupt(hw);
1707 rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
1708 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1709 rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
1710 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18);
1711 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18);
1712 rtl_write_byte(rtlpriv, 0x606, 0x30);
1713 rtl8723be_enable_interrupt(hw);
1714}
1715
1716void rtl8723be_set_beacon_interval(struct ieee80211_hw *hw)
1717{
1718 struct rtl_priv *rtlpriv = rtl_priv(hw);
1719 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1720 u16 bcn_interval = mac->beacon_interval;
1721
1722 RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
1723 "beacon_interval:%d\n", bcn_interval);
1724 rtl8723be_disable_interrupt(hw);
1725 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1726 rtl8723be_enable_interrupt(hw);
1727}
1728
1729void rtl8723be_update_interrupt_mask(struct ieee80211_hw *hw,
1730 u32 add_msr, u32 rm_msr)
1731{
1732 struct rtl_priv *rtlpriv = rtl_priv(hw);
1733 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1734
1735 RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
1736 "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr);
1737
1738 if (add_msr)
1739 rtlpci->irq_mask[0] |= add_msr;
1740 if (rm_msr)
1741 rtlpci->irq_mask[0] &= (~rm_msr);
1742 rtl8723be_disable_interrupt(hw);
1743 rtl8723be_enable_interrupt(hw);
1744}
1745
1746static u8 _rtl8723be_get_chnl_group(u8 chnl)
1747{
1748 u8 group;
1749
1750 if (chnl < 3)
1751 group = 0;
1752 else if (chnl < 9)
1753 group = 1;
1754 else
1755 group = 2;
1756 return group;
1757}
1758
1759static void _rtl8723be_read_power_value_fromprom(struct ieee80211_hw *hw,
1760 struct txpower_info_2g *pw2g,
1761 struct txpower_info_5g *pw5g,
1762 bool autoload_fail, u8 *hwinfo)
1763{
1764 struct rtl_priv *rtlpriv = rtl_priv(hw);
1765 u32 path, addr = EEPROM_TX_PWR_INX, group, cnt = 0;
1766
1767 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Larry Finger5c99f042014-09-26 16:40:25 -05001768 "hal_ReadPowerValueFromPROM8723BE(): PROMContent[0x%x]=0x%x\n",
Larry Fingera619d1a2014-02-28 15:16:50 -06001769 (addr + 1), hwinfo[addr + 1]);
Larry Finger5c99f042014-09-26 16:40:25 -05001770 if (0xFF == hwinfo[addr + 1]) /*YJ,add,120316*/
Larry Fingera619d1a2014-02-28 15:16:50 -06001771 autoload_fail = true;
1772
1773 if (autoload_fail) {
1774 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1775 "auto load fail : Use Default value!\n");
1776 for (path = 0; path < MAX_RF_PATH; path++) {
1777 /* 2.4G default value */
Larry Finger5c99f042014-09-26 16:40:25 -05001778 for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) {
Larry Fingera619d1a2014-02-28 15:16:50 -06001779 pw2g->index_cck_base[path][group] = 0x2D;
1780 pw2g->index_bw40_base[path][group] = 0x2D;
1781 }
1782 for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1783 if (cnt == 0) {
1784 pw2g->bw20_diff[path][0] = 0x02;
1785 pw2g->ofdm_diff[path][0] = 0x04;
1786 } else {
1787 pw2g->bw20_diff[path][cnt] = 0xFE;
1788 pw2g->bw40_diff[path][cnt] = 0xFE;
1789 pw2g->cck_diff[path][cnt] = 0xFE;
1790 pw2g->ofdm_diff[path][cnt] = 0xFE;
1791 }
1792 }
1793 }
1794 return;
1795 }
Larry Finger5c99f042014-09-26 16:40:25 -05001796
Larry Fingera619d1a2014-02-28 15:16:50 -06001797 for (path = 0; path < MAX_RF_PATH; path++) {
1798 /*2.4G default value*/
1799 for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
1800 pw2g->index_cck_base[path][group] = hwinfo[addr++];
1801 if (pw2g->index_cck_base[path][group] == 0xFF)
1802 pw2g->index_cck_base[path][group] = 0x2D;
Larry Finger5c99f042014-09-26 16:40:25 -05001803
Larry Fingera619d1a2014-02-28 15:16:50 -06001804 }
1805 for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) {
1806 pw2g->index_bw40_base[path][group] = hwinfo[addr++];
1807 if (pw2g->index_bw40_base[path][group] == 0xFF)
1808 pw2g->index_bw40_base[path][group] = 0x2D;
1809 }
1810 for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1811 if (cnt == 0) {
1812 pw2g->bw40_diff[path][cnt] = 0;
1813 if (hwinfo[addr] == 0xFF) {
1814 pw2g->bw20_diff[path][cnt] = 0x02;
1815 } else {
1816 pw2g->bw20_diff[path][cnt] =
1817 (hwinfo[addr] & 0xf0) >> 4;
1818 /*bit sign number to 8 bit sign number*/
1819 if (pw2g->bw20_diff[path][cnt] & BIT(3))
Larry Finger5c99f042014-09-26 16:40:25 -05001820 pw2g->bw20_diff[path][cnt] |=
1821 0xF0;
Larry Fingera619d1a2014-02-28 15:16:50 -06001822 }
Larry Finger5c99f042014-09-26 16:40:25 -05001823
Larry Fingera619d1a2014-02-28 15:16:50 -06001824 if (hwinfo[addr] == 0xFF) {
1825 pw2g->ofdm_diff[path][cnt] = 0x04;
1826 } else {
1827 pw2g->ofdm_diff[path][cnt] =
1828 (hwinfo[addr] & 0x0f);
1829 /*bit sign number to 8 bit sign number*/
1830 if (pw2g->ofdm_diff[path][cnt] & BIT(3))
1831 pw2g->ofdm_diff[path][cnt] |=
1832 0xF0;
1833 }
1834 pw2g->cck_diff[path][cnt] = 0;
1835 addr++;
1836 } else {
1837 if (hwinfo[addr] == 0xFF) {
1838 pw2g->bw40_diff[path][cnt] = 0xFE;
1839 } else {
1840 pw2g->bw40_diff[path][cnt] =
1841 (hwinfo[addr] & 0xf0) >> 4;
1842 if (pw2g->bw40_diff[path][cnt] & BIT(3))
1843 pw2g->bw40_diff[path][cnt] |=
1844 0xF0;
1845 }
Larry Finger5c99f042014-09-26 16:40:25 -05001846
Larry Fingera619d1a2014-02-28 15:16:50 -06001847 if (hwinfo[addr] == 0xFF) {
1848 pw2g->bw20_diff[path][cnt] = 0xFE;
1849 } else {
1850 pw2g->bw20_diff[path][cnt] =
1851 (hwinfo[addr] & 0x0f);
1852 if (pw2g->bw20_diff[path][cnt] & BIT(3))
1853 pw2g->bw20_diff[path][cnt] |=
1854 0xF0;
1855 }
1856 addr++;
1857
1858 if (hwinfo[addr] == 0xFF) {
1859 pw2g->ofdm_diff[path][cnt] = 0xFE;
1860 } else {
1861 pw2g->ofdm_diff[path][cnt] =
1862 (hwinfo[addr] & 0xf0) >> 4;
1863 if (pw2g->ofdm_diff[path][cnt] & BIT(3))
1864 pw2g->ofdm_diff[path][cnt] |=
1865 0xF0;
1866 }
Larry Finger5c99f042014-09-26 16:40:25 -05001867
1868 if (hwinfo[addr] == 0xFF)
Larry Fingera619d1a2014-02-28 15:16:50 -06001869 pw2g->cck_diff[path][cnt] = 0xFE;
Larry Finger5c99f042014-09-26 16:40:25 -05001870 else {
Larry Fingera619d1a2014-02-28 15:16:50 -06001871 pw2g->cck_diff[path][cnt] =
1872 (hwinfo[addr] & 0x0f);
1873 if (pw2g->cck_diff[path][cnt] & BIT(3))
1874 pw2g->cck_diff[path][cnt] |=
1875 0xF0;
1876 }
1877 addr++;
1878 }
1879 }
Larry Finger5c99f042014-09-26 16:40:25 -05001880
Larry Fingera619d1a2014-02-28 15:16:50 -06001881 /*5G default value*/
1882 for (group = 0; group < MAX_CHNL_GROUP_5G; group++) {
1883 pw5g->index_bw40_base[path][group] = hwinfo[addr++];
1884 if (pw5g->index_bw40_base[path][group] == 0xFF)
1885 pw5g->index_bw40_base[path][group] = 0xFE;
1886 }
Larry Finger5c99f042014-09-26 16:40:25 -05001887
Larry Fingera619d1a2014-02-28 15:16:50 -06001888 for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1889 if (cnt == 0) {
1890 pw5g->bw40_diff[path][cnt] = 0;
1891
1892 if (hwinfo[addr] == 0xFF) {
1893 pw5g->bw20_diff[path][cnt] = 0;
1894 } else {
1895 pw5g->bw20_diff[path][0] =
1896 (hwinfo[addr] & 0xf0) >> 4;
1897 if (pw5g->bw20_diff[path][cnt] & BIT(3))
1898 pw5g->bw20_diff[path][cnt] |=
1899 0xF0;
1900 }
Larry Finger5c99f042014-09-26 16:40:25 -05001901
1902 if (hwinfo[addr] == 0xFF)
Larry Fingera619d1a2014-02-28 15:16:50 -06001903 pw5g->ofdm_diff[path][cnt] = 0x04;
Larry Finger5c99f042014-09-26 16:40:25 -05001904 else {
Larry Fingera619d1a2014-02-28 15:16:50 -06001905 pw5g->ofdm_diff[path][0] =
1906 (hwinfo[addr] & 0x0f);
1907 if (pw5g->ofdm_diff[path][cnt] & BIT(3))
1908 pw5g->ofdm_diff[path][cnt] |=
1909 0xF0;
1910 }
1911 addr++;
1912 } else {
1913 if (hwinfo[addr] == 0xFF) {
1914 pw5g->bw40_diff[path][cnt] = 0xFE;
1915 } else {
1916 pw5g->bw40_diff[path][cnt] =
1917 (hwinfo[addr] & 0xf0) >> 4;
1918 if (pw5g->bw40_diff[path][cnt] & BIT(3))
1919 pw5g->bw40_diff[path][cnt] |= 0xF0;
1920 }
Larry Finger5c99f042014-09-26 16:40:25 -05001921
Larry Fingera619d1a2014-02-28 15:16:50 -06001922 if (hwinfo[addr] == 0xFF) {
1923 pw5g->bw20_diff[path][cnt] = 0xFE;
1924 } else {
1925 pw5g->bw20_diff[path][cnt] =
1926 (hwinfo[addr] & 0x0f);
1927 if (pw5g->bw20_diff[path][cnt] & BIT(3))
1928 pw5g->bw20_diff[path][cnt] |= 0xF0;
1929 }
1930 addr++;
1931 }
1932 }
Larry Finger5c99f042014-09-26 16:40:25 -05001933
Larry Fingera619d1a2014-02-28 15:16:50 -06001934 if (hwinfo[addr] == 0xFF) {
1935 pw5g->ofdm_diff[path][1] = 0xFE;
1936 pw5g->ofdm_diff[path][2] = 0xFE;
1937 } else {
1938 pw5g->ofdm_diff[path][1] = (hwinfo[addr] & 0xf0) >> 4;
1939 pw5g->ofdm_diff[path][2] = (hwinfo[addr] & 0x0f);
1940 }
1941 addr++;
1942
1943 if (hwinfo[addr] == 0xFF)
1944 pw5g->ofdm_diff[path][3] = 0xFE;
1945 else
1946 pw5g->ofdm_diff[path][3] = (hwinfo[addr] & 0x0f);
1947 addr++;
1948
1949 for (cnt = 1; cnt < MAX_TX_COUNT; cnt++) {
1950 if (pw5g->ofdm_diff[path][cnt] == 0xFF)
1951 pw5g->ofdm_diff[path][cnt] = 0xFE;
1952 else if (pw5g->ofdm_diff[path][cnt] & BIT(3))
1953 pw5g->ofdm_diff[path][cnt] |= 0xF0;
1954 }
1955 }
1956}
1957
1958static void _rtl8723be_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1959 bool autoload_fail,
1960 u8 *hwinfo)
1961{
1962 struct rtl_priv *rtlpriv = rtl_priv(hw);
1963 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1964 struct txpower_info_2g pw2g;
1965 struct txpower_info_5g pw5g;
1966 u8 rf_path, index;
1967 u8 i;
1968
1969 _rtl8723be_read_power_value_fromprom(hw, &pw2g, &pw5g, autoload_fail,
1970 hwinfo);
1971
1972 for (rf_path = 0; rf_path < 2; rf_path++) {
1973 for (i = 0; i < 14; i++) {
1974 index = _rtl8723be_get_chnl_group(i+1);
1975
1976 rtlefuse->txpwrlevel_cck[rf_path][i] =
1977 pw2g.index_cck_base[rf_path][index];
1978 rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
1979 pw2g.index_bw40_base[rf_path][index];
1980 }
1981 for (i = 0; i < MAX_TX_COUNT; i++) {
1982 rtlefuse->txpwr_ht20diff[rf_path][i] =
1983 pw2g.bw20_diff[rf_path][i];
1984 rtlefuse->txpwr_ht40diff[rf_path][i] =
1985 pw2g.bw40_diff[rf_path][i];
1986 rtlefuse->txpwr_legacyhtdiff[rf_path][i] =
1987 pw2g.ofdm_diff[rf_path][i];
1988 }
Larry Finger5c99f042014-09-26 16:40:25 -05001989
Larry Fingera619d1a2014-02-28 15:16:50 -06001990 for (i = 0; i < 14; i++) {
Larry Finger5c99f042014-09-26 16:40:25 -05001991 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1992 "RF(%d)-Ch(%d) [CCK / HT40_1S ] = [0x%x / 0x%x ]\n",
1993 rf_path, i,
Larry Fingera619d1a2014-02-28 15:16:50 -06001994 rtlefuse->txpwrlevel_cck[rf_path][i],
1995 rtlefuse->txpwrlevel_ht40_1s[rf_path][i]);
1996 }
1997 }
Larry Finger5c99f042014-09-26 16:40:25 -05001998
Larry Fingera619d1a2014-02-28 15:16:50 -06001999 if (!autoload_fail)
2000 rtlefuse->eeprom_thermalmeter =
2001 hwinfo[EEPROM_THERMAL_METER_88E];
2002 else
2003 rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
2004
2005 if (rtlefuse->eeprom_thermalmeter == 0xff || autoload_fail) {
2006 rtlefuse->apk_thermalmeterignore = true;
2007 rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
2008 }
Larry Finger5c99f042014-09-26 16:40:25 -05002009
Larry Fingera619d1a2014-02-28 15:16:50 -06002010 rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
Larry Finger5c99f042014-09-26 16:40:25 -05002011 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
Larry Fingera619d1a2014-02-28 15:16:50 -06002012 "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
2013
2014 if (!autoload_fail) {
2015 rtlefuse->eeprom_regulatory =
2016 hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0x07;/*bit0~2*/
2017 if (hwinfo[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
2018 rtlefuse->eeprom_regulatory = 0;
2019 } else {
2020 rtlefuse->eeprom_regulatory = 0;
2021 }
Larry Finger5c99f042014-09-26 16:40:25 -05002022 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
Larry Fingera619d1a2014-02-28 15:16:50 -06002023 "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
2024}
2025
Ping-Ke Shih7fe1fe752017-02-06 21:30:05 -06002026static u8 _rtl8723be_read_package_type(struct ieee80211_hw *hw)
2027{
2028 u8 package_type;
2029 u8 value;
2030
2031 efuse_power_switch(hw, false, true);
2032 if (!efuse_one_byte_read(hw, 0x1FB, &value))
2033 value = 0;
2034 efuse_power_switch(hw, false, false);
2035
2036 switch (value & 0x7) {
2037 case 0x4:
2038 package_type = PACKAGE_TFBGA79;
2039 break;
2040 case 0x5:
2041 package_type = PACKAGE_TFBGA90;
2042 break;
2043 case 0x6:
2044 package_type = PACKAGE_QFN68;
2045 break;
2046 case 0x7:
2047 package_type = PACKAGE_TFBGA80;
2048 break;
2049 default:
2050 package_type = PACKAGE_DEFAULT;
2051 break;
2052 }
2053
2054 return package_type;
2055}
2056
Larry Fingera619d1a2014-02-28 15:16:50 -06002057static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw,
2058 bool pseudo_test)
2059{
2060 struct rtl_priv *rtlpriv = rtl_priv(hw);
2061 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2062 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
Larry Finger9e9c9c22016-07-05 10:08:12 -05002063 int params[] = {RTL8723BE_EEPROM_ID, EEPROM_VID, EEPROM_DID,
2064 EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR,
2065 EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID,
2066 COUNTRY_CODE_WORLD_WIDE_13};
2067 u8 *hwinfo;
2068 int i;
Larry Fingera619d1a2014-02-28 15:16:50 -06002069 bool is_toshiba_smid1 = false;
2070 bool is_toshiba_smid2 = false;
2071 bool is_samsung_smid = false;
2072 bool is_lenovo_smid = false;
2073 u16 toshiba_smid1[] = {
2074 0x6151, 0x6152, 0x6154, 0x6155, 0x6177, 0x6178, 0x6179, 0x6180,
2075 0x7151, 0x7152, 0x7154, 0x7155, 0x7177, 0x7178, 0x7179, 0x7180,
2076 0x8151, 0x8152, 0x8154, 0x8155, 0x8181, 0x8182, 0x8184, 0x8185,
2077 0x9151, 0x9152, 0x9154, 0x9155, 0x9181, 0x9182, 0x9184, 0x9185
2078 };
2079 u16 toshiba_smid2[] = {
2080 0x6181, 0x6184, 0x6185, 0x7181, 0x7182, 0x7184, 0x7185, 0x8181,
2081 0x8182, 0x8184, 0x8185, 0x9181, 0x9182, 0x9184, 0x9185
2082 };
2083 u16 samsung_smid[] = {
2084 0x6191, 0x6192, 0x6193, 0x7191, 0x7192, 0x7193, 0x8191, 0x8192,
2085 0x8193, 0x9191, 0x9192, 0x9193
2086 };
2087 u16 lenovo_smid[] = {
2088 0x8195, 0x9195, 0x7194, 0x8200, 0x8201, 0x8202, 0x9199, 0x9200
2089 };
2090
2091 if (pseudo_test) {
2092 /* needs to be added */
2093 return;
2094 }
Larry Fingera619d1a2014-02-28 15:16:50 -06002095
Larry Finger9e9c9c22016-07-05 10:08:12 -05002096 hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL);
2097 if (!hwinfo)
Arnd Bergmann5345ea62016-05-30 17:26:16 +02002098 return;
2099
Larry Finger9e9c9c22016-07-05 10:08:12 -05002100 if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params))
2101 goto exit;
Larry Fingera619d1a2014-02-28 15:16:50 -06002102
2103 /*parse xtal*/
2104 rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_8723BE];
2105 if (rtlefuse->crystalcap == 0xFF)
2106 rtlefuse->crystalcap = 0x20;
2107
2108 _rtl8723be_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag,
2109 hwinfo);
2110
2111 rtl8723be_read_bt_coexist_info_from_hwpg(hw,
2112 rtlefuse->autoload_failflag,
2113 hwinfo);
2114
Ping-Ke Shih881d53a2017-07-02 13:12:32 -05002115 if (rtlpriv->btcoexist.btc_info.btcoexist == 1)
2116 rtlefuse->board_type |= BIT(2); /* ODM_BOARD_BT */
2117
2118 rtlhal->board_type = rtlefuse->board_type;
2119 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2120 "board_type = 0x%x\n", rtlefuse->board_type);
2121
Ping-Ke Shih7fe1fe752017-02-06 21:30:05 -06002122 rtlhal->package_type = _rtl8723be_read_package_type(hw);
2123
Shao Fub23cd222015-05-15 16:33:02 -05002124 /* set channel plan from efuse */
2125 rtlefuse->channel_plan = rtlefuse->eeprom_channelplan;
Larry Fingera619d1a2014-02-28 15:16:50 -06002126
2127 if (rtlhal->oem_id == RT_CID_DEFAULT) {
2128 /* Does this one have a Toshiba SMID from group 1? */
2129 for (i = 0; i < sizeof(toshiba_smid1) / sizeof(u16); i++) {
2130 if (rtlefuse->eeprom_smid == toshiba_smid1[i]) {
2131 is_toshiba_smid1 = true;
2132 break;
2133 }
2134 }
2135 /* Does this one have a Toshiba SMID from group 2? */
2136 for (i = 0; i < sizeof(toshiba_smid2) / sizeof(u16); i++) {
2137 if (rtlefuse->eeprom_smid == toshiba_smid2[i]) {
2138 is_toshiba_smid2 = true;
2139 break;
2140 }
2141 }
2142 /* Does this one have a Samsung SMID? */
2143 for (i = 0; i < sizeof(samsung_smid) / sizeof(u16); i++) {
2144 if (rtlefuse->eeprom_smid == samsung_smid[i]) {
2145 is_samsung_smid = true;
2146 break;
2147 }
2148 }
2149 /* Does this one have a Lenovo SMID? */
2150 for (i = 0; i < sizeof(lenovo_smid) / sizeof(u16); i++) {
2151 if (rtlefuse->eeprom_smid == lenovo_smid[i]) {
2152 is_lenovo_smid = true;
2153 break;
2154 }
2155 }
2156 switch (rtlefuse->eeprom_oemid) {
2157 case EEPROM_CID_DEFAULT:
2158 if (rtlefuse->eeprom_did == 0x8176) {
2159 if (rtlefuse->eeprom_svid == 0x10EC &&
2160 is_toshiba_smid1) {
2161 rtlhal->oem_id = RT_CID_TOSHIBA;
2162 } else if (rtlefuse->eeprom_svid == 0x1025) {
2163 rtlhal->oem_id = RT_CID_819X_ACER;
2164 } else if (rtlefuse->eeprom_svid == 0x10EC &&
2165 is_samsung_smid) {
2166 rtlhal->oem_id = RT_CID_819X_SAMSUNG;
2167 } else if (rtlefuse->eeprom_svid == 0x10EC &&
2168 is_lenovo_smid) {
2169 rtlhal->oem_id = RT_CID_819X_LENOVO;
2170 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
2171 rtlefuse->eeprom_smid == 0x8197) ||
2172 (rtlefuse->eeprom_svid == 0x10EC &&
2173 rtlefuse->eeprom_smid == 0x9196)) {
2174 rtlhal->oem_id = RT_CID_819X_CLEVO;
2175 } else if ((rtlefuse->eeprom_svid == 0x1028 &&
2176 rtlefuse->eeprom_smid == 0x8194) ||
2177 (rtlefuse->eeprom_svid == 0x1028 &&
2178 rtlefuse->eeprom_smid == 0x8198) ||
2179 (rtlefuse->eeprom_svid == 0x1028 &&
2180 rtlefuse->eeprom_smid == 0x9197) ||
2181 (rtlefuse->eeprom_svid == 0x1028 &&
2182 rtlefuse->eeprom_smid == 0x9198)) {
2183 rtlhal->oem_id = RT_CID_819X_DELL;
2184 } else if ((rtlefuse->eeprom_svid == 0x103C &&
2185 rtlefuse->eeprom_smid == 0x1629)) {
2186 rtlhal->oem_id = RT_CID_819X_HP;
2187 } else if ((rtlefuse->eeprom_svid == 0x1A32 &&
2188 rtlefuse->eeprom_smid == 0x2315)) {
2189 rtlhal->oem_id = RT_CID_819X_QMI;
2190 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
2191 rtlefuse->eeprom_smid == 0x8203)) {
2192 rtlhal->oem_id = RT_CID_819X_PRONETS;
2193 } else if ((rtlefuse->eeprom_svid == 0x1043 &&
2194 rtlefuse->eeprom_smid == 0x84B5)) {
2195 rtlhal->oem_id = RT_CID_819X_EDIMAX_ASUS;
2196 } else {
2197 rtlhal->oem_id = RT_CID_DEFAULT;
2198 }
2199 } else if (rtlefuse->eeprom_did == 0x8178) {
2200 if (rtlefuse->eeprom_svid == 0x10EC &&
2201 is_toshiba_smid2)
2202 rtlhal->oem_id = RT_CID_TOSHIBA;
2203 else if (rtlefuse->eeprom_svid == 0x1025)
2204 rtlhal->oem_id = RT_CID_819X_ACER;
2205 else if ((rtlefuse->eeprom_svid == 0x10EC &&
2206 rtlefuse->eeprom_smid == 0x8186))
2207 rtlhal->oem_id = RT_CID_819X_PRONETS;
2208 else if ((rtlefuse->eeprom_svid == 0x1043 &&
2209 rtlefuse->eeprom_smid == 0x84B6))
2210 rtlhal->oem_id =
2211 RT_CID_819X_EDIMAX_ASUS;
2212 else
2213 rtlhal->oem_id = RT_CID_DEFAULT;
2214 } else {
2215 rtlhal->oem_id = RT_CID_DEFAULT;
2216 }
2217 break;
2218 case EEPROM_CID_TOSHIBA:
2219 rtlhal->oem_id = RT_CID_TOSHIBA;
2220 break;
2221 case EEPROM_CID_CCX:
2222 rtlhal->oem_id = RT_CID_CCX;
2223 break;
2224 case EEPROM_CID_QMI:
2225 rtlhal->oem_id = RT_CID_819X_QMI;
2226 break;
2227 case EEPROM_CID_WHQL:
2228 break;
2229 default:
2230 rtlhal->oem_id = RT_CID_DEFAULT;
2231 break;
2232 }
2233 }
Larry Finger9e9c9c22016-07-05 10:08:12 -05002234exit:
2235 kfree(hwinfo);
Larry Fingera619d1a2014-02-28 15:16:50 -06002236}
2237
2238static void _rtl8723be_hal_customized_behavior(struct ieee80211_hw *hw)
2239{
2240 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -06002241 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2242
Larry Fingerd5efe152017-02-07 09:14:21 -06002243 rtlpriv->ledctl.led_opendrain = true;
Larry Fingera619d1a2014-02-28 15:16:50 -06002244 switch (rtlhal->oem_id) {
2245 case RT_CID_819X_HP:
Larry Fingerd5efe152017-02-07 09:14:21 -06002246 rtlpriv->ledctl.led_opendrain = true;
Larry Fingera619d1a2014-02-28 15:16:50 -06002247 break;
2248 case RT_CID_819X_LENOVO:
2249 case RT_CID_DEFAULT:
2250 case RT_CID_TOSHIBA:
2251 case RT_CID_CCX:
2252 case RT_CID_819X_ACER:
2253 case RT_CID_WHQL:
2254 default:
2255 break;
2256 }
2257 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2258 "RT Customized ID: 0x%02X\n", rtlhal->oem_id);
2259}
2260
2261void rtl8723be_read_eeprom_info(struct ieee80211_hw *hw)
2262{
2263 struct rtl_priv *rtlpriv = rtl_priv(hw);
2264 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2265 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2266 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2267 u8 tmp_u1b;
2268
2269 rtlhal->version = _rtl8723be_read_chip_version(hw);
2270 if (get_rf_type(rtlphy) == RF_1T1R)
2271 rtlpriv->dm.rfpath_rxenable[0] = true;
2272 else
2273 rtlpriv->dm.rfpath_rxenable[0] =
2274 rtlpriv->dm.rfpath_rxenable[1] = true;
2275 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
2276 rtlhal->version);
2277 tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
2278 if (tmp_u1b & BIT(4)) {
2279 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
2280 rtlefuse->epromtype = EEPROM_93C46;
2281 } else {
2282 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
2283 rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
2284 }
2285 if (tmp_u1b & BIT(5)) {
2286 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
2287 rtlefuse->autoload_failflag = false;
2288 _rtl8723be_read_adapter_info(hw, false);
2289 } else {
Larry Finger4e2b4372016-12-15 12:23:00 -06002290 pr_err("Autoload ERR!!\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06002291 }
2292 _rtl8723be_hal_customized_behavior(hw);
2293}
2294
Larry Fingera619d1a2014-02-28 15:16:50 -06002295static u8 _rtl8723be_mrate_idx_to_arfr_id(struct ieee80211_hw *hw,
2296 u8 rate_index)
2297{
2298 u8 ret = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002299 switch (rate_index) {
2300 case RATR_INX_WIRELESS_NGB:
2301 ret = 1;
2302 break;
2303 case RATR_INX_WIRELESS_N:
2304 case RATR_INX_WIRELESS_NG:
2305 ret = 5;
2306 break;
2307 case RATR_INX_WIRELESS_NB:
2308 ret = 3;
2309 break;
2310 case RATR_INX_WIRELESS_GB:
2311 ret = 6;
2312 break;
2313 case RATR_INX_WIRELESS_G:
2314 ret = 7;
2315 break;
2316 case RATR_INX_WIRELESS_B:
2317 ret = 8;
2318 break;
2319 default:
2320 ret = 0;
2321 break;
2322 }
2323 return ret;
2324}
2325
2326static void rtl8723be_update_hal_rate_mask(struct ieee80211_hw *hw,
2327 struct ieee80211_sta *sta,
Ping-Ke Shih1d22b172017-09-29 14:47:59 -05002328 u8 rssi_level, bool update_bw)
Larry Fingera619d1a2014-02-28 15:16:50 -06002329{
2330 struct rtl_priv *rtlpriv = rtl_priv(hw);
2331 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2332 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2333 struct rtl_sta_info *sta_entry = NULL;
2334 u32 ratr_bitmap;
2335 u8 ratr_index;
2336 u8 curtxbw_40mhz = (sta->ht_cap.cap &
Larry Finger5c99f042014-09-26 16:40:25 -05002337 IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002338 u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
Larry Finger5c99f042014-09-26 16:40:25 -05002339 1 : 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002340 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
Larry Finger5c99f042014-09-26 16:40:25 -05002341 1 : 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002342 enum wireless_mode wirelessmode = 0;
2343 bool shortgi = false;
2344 u8 rate_mask[7];
2345 u8 macid = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002346
2347 sta_entry = (struct rtl_sta_info *)sta->drv_priv;
2348 wirelessmode = sta_entry->wireless_mode;
2349 if (mac->opmode == NL80211_IFTYPE_STATION ||
2350 mac->opmode == NL80211_IFTYPE_MESH_POINT)
2351 curtxbw_40mhz = mac->bw_40;
2352 else if (mac->opmode == NL80211_IFTYPE_AP ||
2353 mac->opmode == NL80211_IFTYPE_ADHOC)
2354 macid = sta->aid + 1;
2355
2356 ratr_bitmap = sta->supp_rates[0];
2357
2358 if (mac->opmode == NL80211_IFTYPE_ADHOC)
2359 ratr_bitmap = 0xfff;
2360
2361 ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
2362 sta->ht_cap.mcs.rx_mask[0] << 12);
2363 switch (wirelessmode) {
2364 case WIRELESS_MODE_B:
2365 ratr_index = RATR_INX_WIRELESS_B;
2366 if (ratr_bitmap & 0x0000000c)
2367 ratr_bitmap &= 0x0000000d;
2368 else
2369 ratr_bitmap &= 0x0000000f;
2370 break;
2371 case WIRELESS_MODE_G:
2372 ratr_index = RATR_INX_WIRELESS_GB;
2373
2374 if (rssi_level == 1)
2375 ratr_bitmap &= 0x00000f00;
2376 else if (rssi_level == 2)
2377 ratr_bitmap &= 0x00000ff0;
2378 else
2379 ratr_bitmap &= 0x00000ff5;
2380 break;
Larry Fingera619d1a2014-02-28 15:16:50 -06002381 case WIRELESS_MODE_N_24G:
2382 case WIRELESS_MODE_N_5G:
2383 ratr_index = RATR_INX_WIRELESS_NGB;
Larry Finger5c99f042014-09-26 16:40:25 -05002384 if (rtlphy->rf_type == RF_1T1R) {
2385 if (curtxbw_40mhz) {
2386 if (rssi_level == 1)
2387 ratr_bitmap &= 0x000f0000;
2388 else if (rssi_level == 2)
2389 ratr_bitmap &= 0x000ff000;
2390 else
2391 ratr_bitmap &= 0x000ff015;
Larry Fingera619d1a2014-02-28 15:16:50 -06002392 } else {
Larry Finger5c99f042014-09-26 16:40:25 -05002393 if (rssi_level == 1)
2394 ratr_bitmap &= 0x000f0000;
2395 else if (rssi_level == 2)
2396 ratr_bitmap &= 0x000ff000;
2397 else
2398 ratr_bitmap &= 0x000ff005;
2399 }
2400 } else {
2401 if (curtxbw_40mhz) {
2402 if (rssi_level == 1)
2403 ratr_bitmap &= 0x0f8f0000;
2404 else if (rssi_level == 2)
2405 ratr_bitmap &= 0x0f8ff000;
2406 else
2407 ratr_bitmap &= 0x0f8ff015;
2408 } else {
2409 if (rssi_level == 1)
2410 ratr_bitmap &= 0x0f8f0000;
2411 else if (rssi_level == 2)
2412 ratr_bitmap &= 0x0f8ff000;
2413 else
2414 ratr_bitmap &= 0x0f8ff005;
Larry Fingera619d1a2014-02-28 15:16:50 -06002415 }
2416 }
2417 if ((curtxbw_40mhz && curshortgi_40mhz) ||
2418 (!curtxbw_40mhz && curshortgi_20mhz)) {
2419 if (macid == 0)
2420 shortgi = true;
2421 else if (macid == 1)
2422 shortgi = false;
2423 }
2424 break;
2425 default:
2426 ratr_index = RATR_INX_WIRELESS_NGB;
2427
2428 if (rtlphy->rf_type == RF_1T2R)
2429 ratr_bitmap &= 0x000ff0ff;
2430 else
2431 ratr_bitmap &= 0x0f0ff0ff;
2432 break;
2433 }
Larry Finger5c99f042014-09-26 16:40:25 -05002434
Larry Fingera619d1a2014-02-28 15:16:50 -06002435 sta_entry->ratr_index = ratr_index;
2436
2437 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2438 "ratr_bitmap :%x\n", ratr_bitmap);
Larry Finger5c99f042014-09-26 16:40:25 -05002439 *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
2440 (ratr_index << 28);
Larry Fingera619d1a2014-02-28 15:16:50 -06002441 rate_mask[0] = macid;
2442 rate_mask[1] = _rtl8723be_mrate_idx_to_arfr_id(hw, ratr_index) |
Larry Finger5c99f042014-09-26 16:40:25 -05002443 (shortgi ? 0x80 : 0x00);
Ping-Ke Shih1d22b172017-09-29 14:47:59 -05002444 rate_mask[2] = curtxbw_40mhz | ((!update_bw) << 3);
Larry Fingera619d1a2014-02-28 15:16:50 -06002445
2446 rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff);
2447 rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >> 8);
2448 rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16);
2449 rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24);
2450
2451 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2452 "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x:%x:%x\n",
2453 ratr_index, ratr_bitmap,
2454 rate_mask[0], rate_mask[1],
2455 rate_mask[2], rate_mask[3],
2456 rate_mask[4], rate_mask[5],
2457 rate_mask[6]);
Larry Finger5c99f042014-09-26 16:40:25 -05002458 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_RA_MASK, 7, rate_mask);
Larry Fingera619d1a2014-02-28 15:16:50 -06002459 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
2460}
2461
2462void rtl8723be_update_hal_rate_tbl(struct ieee80211_hw *hw,
2463 struct ieee80211_sta *sta,
Ping-Ke Shih1d22b172017-09-29 14:47:59 -05002464 u8 rssi_level, bool update_bw)
Larry Fingera619d1a2014-02-28 15:16:50 -06002465{
2466 struct rtl_priv *rtlpriv = rtl_priv(hw);
2467 if (rtlpriv->dm.useramask)
Ping-Ke Shih1d22b172017-09-29 14:47:59 -05002468 rtl8723be_update_hal_rate_mask(hw, sta, rssi_level, update_bw);
Larry Fingera619d1a2014-02-28 15:16:50 -06002469}
2470
2471void rtl8723be_update_channel_access_setting(struct ieee80211_hw *hw)
2472{
2473 struct rtl_priv *rtlpriv = rtl_priv(hw);
2474 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2475 u16 sifs_timer;
2476
Joe Perches9cb76aa2014-03-24 10:46:20 -07002477 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);
Larry Fingera619d1a2014-02-28 15:16:50 -06002478 if (!mac->ht_enable)
2479 sifs_timer = 0x0a0a;
2480 else
2481 sifs_timer = 0x0e0e;
2482 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
2483}
2484
2485bool rtl8723be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
2486{
2487 struct rtl_priv *rtlpriv = rtl_priv(hw);
2488 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2489 struct rtl_phy *rtlphy = &(rtlpriv->phy);
Christos Gkekas76d7b122017-10-11 22:15:15 +01002490 enum rf_pwrstate e_rfpowerstate_toset;
Larry Fingera619d1a2014-02-28 15:16:50 -06002491 u8 u1tmp;
Larry Finger5c99f042014-09-26 16:40:25 -05002492 bool b_actuallyset = false;
Larry Fingera619d1a2014-02-28 15:16:50 -06002493
2494 if (rtlpriv->rtlhal.being_init_adapter)
2495 return false;
2496
2497 if (ppsc->swrf_processing)
2498 return false;
2499
2500 spin_lock(&rtlpriv->locks.rf_ps_lock);
2501 if (ppsc->rfchange_inprogress) {
2502 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2503 return false;
2504 } else {
2505 ppsc->rfchange_inprogress = true;
2506 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2507 }
Larry Finger5c99f042014-09-26 16:40:25 -05002508
Larry Fingera619d1a2014-02-28 15:16:50 -06002509 rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2,
2510 rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2) & ~(BIT(1)));
2511
2512 u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2);
2513
2514 if (rtlphy->polarity_ctl)
2515 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON;
2516 else
2517 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF;
2518
Larry Finger5c99f042014-09-26 16:40:25 -05002519 if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002520 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2521 "GPIOChangeRF - HW Radio ON, RF ON\n");
2522
2523 e_rfpowerstate_toset = ERFON;
2524 ppsc->hwradiooff = false;
Larry Finger5c99f042014-09-26 16:40:25 -05002525 b_actuallyset = true;
2526 } else if (!ppsc->hwradiooff && (e_rfpowerstate_toset == ERFOFF)) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002527 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2528 "GPIOChangeRF - HW Radio OFF, RF OFF\n");
2529
2530 e_rfpowerstate_toset = ERFOFF;
2531 ppsc->hwradiooff = true;
Larry Finger5c99f042014-09-26 16:40:25 -05002532 b_actuallyset = true;
Larry Fingera619d1a2014-02-28 15:16:50 -06002533 }
Larry Finger5c99f042014-09-26 16:40:25 -05002534
2535 if (b_actuallyset) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002536 spin_lock(&rtlpriv->locks.rf_ps_lock);
2537 ppsc->rfchange_inprogress = false;
2538 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2539 } else {
2540 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
2541 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2542
2543 spin_lock(&rtlpriv->locks.rf_ps_lock);
2544 ppsc->rfchange_inprogress = false;
2545 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2546 }
Larry Finger5c99f042014-09-26 16:40:25 -05002547
Larry Fingera619d1a2014-02-28 15:16:50 -06002548 *valid = 1;
2549 return !ppsc->hwradiooff;
Larry Finger5c99f042014-09-26 16:40:25 -05002550
Larry Fingera619d1a2014-02-28 15:16:50 -06002551}
2552
2553void rtl8723be_set_key(struct ieee80211_hw *hw, u32 key_index,
2554 u8 *p_macaddr, bool is_group, u8 enc_algo,
2555 bool is_wepkey, bool clear_all)
2556{
2557 struct rtl_priv *rtlpriv = rtl_priv(hw);
2558 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2559 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2560 u8 *macaddr = p_macaddr;
2561 u32 entry_id = 0;
2562 bool is_pairwise = false;
2563
2564 static u8 cam_const_addr[4][6] = {
2565 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
2566 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
2567 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
2568 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
2569 };
2570 static u8 cam_const_broad[] = {
2571 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2572 };
2573
2574 if (clear_all) {
2575 u8 idx = 0;
2576 u8 cam_offset = 0;
2577 u8 clear_number = 5;
2578
2579 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
2580
2581 for (idx = 0; idx < clear_number; idx++) {
2582 rtl_cam_mark_invalid(hw, cam_offset + idx);
2583 rtl_cam_empty_entry(hw, cam_offset + idx);
2584
2585 if (idx < 5) {
2586 memset(rtlpriv->sec.key_buf[idx], 0,
2587 MAX_KEY_LEN);
2588 rtlpriv->sec.key_len[idx] = 0;
2589 }
2590 }
Larry Finger5c99f042014-09-26 16:40:25 -05002591
Larry Fingera619d1a2014-02-28 15:16:50 -06002592 } else {
2593 switch (enc_algo) {
2594 case WEP40_ENCRYPTION:
2595 enc_algo = CAM_WEP40;
2596 break;
2597 case WEP104_ENCRYPTION:
2598 enc_algo = CAM_WEP104;
2599 break;
2600 case TKIP_ENCRYPTION:
2601 enc_algo = CAM_TKIP;
2602 break;
2603 case AESCCMP_ENCRYPTION:
2604 enc_algo = CAM_AES;
2605 break;
2606 default:
Larry Finger5c99f042014-09-26 16:40:25 -05002607 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -07002608 "switch case %#x not processed\n", enc_algo);
Larry Fingera619d1a2014-02-28 15:16:50 -06002609 enc_algo = CAM_TKIP;
2610 break;
2611 }
2612
2613 if (is_wepkey || rtlpriv->sec.use_defaultkey) {
2614 macaddr = cam_const_addr[key_index];
2615 entry_id = key_index;
2616 } else {
2617 if (is_group) {
2618 macaddr = cam_const_broad;
2619 entry_id = key_index;
2620 } else {
2621 if (mac->opmode == NL80211_IFTYPE_AP) {
2622 entry_id = rtl_cam_get_free_entry(hw,
2623 p_macaddr);
2624 if (entry_id >= TOTAL_CAM_ENTRY) {
Larry Finger4e2b4372016-12-15 12:23:00 -06002625 pr_err("Can not find free hw security cam entry\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06002626 return;
2627 }
2628 } else {
2629 entry_id = CAM_PAIRWISE_KEY_POSITION;
2630 }
Larry Finger5c99f042014-09-26 16:40:25 -05002631
Larry Fingera619d1a2014-02-28 15:16:50 -06002632 key_index = PAIRWISE_KEYIDX;
2633 is_pairwise = true;
2634 }
2635 }
Larry Finger5c99f042014-09-26 16:40:25 -05002636
Larry Fingera619d1a2014-02-28 15:16:50 -06002637 if (rtlpriv->sec.key_len[key_index] == 0) {
2638 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2639 "delete one entry, entry_id is %d\n",
Larry Finger5c99f042014-09-26 16:40:25 -05002640 entry_id);
Larry Fingera619d1a2014-02-28 15:16:50 -06002641 if (mac->opmode == NL80211_IFTYPE_AP)
2642 rtl_cam_del_entry(hw, p_macaddr);
2643 rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
2644 } else {
2645 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2646 "add one entry\n");
2647 if (is_pairwise) {
2648 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
Colin Ian King6b9e6f62017-05-03 23:55:43 +01002649 "set Pairwise key\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06002650
2651 rtl_cam_add_one_entry(hw, macaddr, key_index,
Larry Finger5c99f042014-09-26 16:40:25 -05002652 entry_id, enc_algo,
2653 CAM_CONFIG_NO_USEDK,
2654 rtlpriv->sec.key_buf[key_index]);
Larry Fingera619d1a2014-02-28 15:16:50 -06002655 } else {
2656 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2657 "set group key\n");
2658
2659 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
2660 rtl_cam_add_one_entry(hw,
2661 rtlefuse->dev_addr,
2662 PAIRWISE_KEYIDX,
2663 CAM_PAIRWISE_KEY_POSITION,
2664 enc_algo,
2665 CAM_CONFIG_NO_USEDK,
2666 rtlpriv->sec.key_buf
2667 [entry_id]);
2668 }
Larry Finger5c99f042014-09-26 16:40:25 -05002669
Larry Fingera619d1a2014-02-28 15:16:50 -06002670 rtl_cam_add_one_entry(hw, macaddr, key_index,
Larry Finger5c99f042014-09-26 16:40:25 -05002671 entry_id, enc_algo,
2672 CAM_CONFIG_NO_USEDK,
2673 rtlpriv->sec.key_buf[entry_id]);
Larry Fingera619d1a2014-02-28 15:16:50 -06002674 }
2675 }
2676 }
2677}
2678
2679void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
2680 bool auto_load_fail, u8 *hwinfo)
2681{
2682 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Fingerc18d8f52016-03-16 13:33:34 -05002683 struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params;
Larry Fingera619d1a2014-02-28 15:16:50 -06002684 u8 value;
2685 u32 tmpu_32;
2686
2687 if (!auto_load_fail) {
2688 tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL);
2689 if (tmpu_32 & BIT(18))
2690 rtlpriv->btcoexist.btc_info.btcoexist = 1;
2691 else
2692 rtlpriv->btcoexist.btc_info.btcoexist = 0;
Larry Finger5c99f042014-09-26 16:40:25 -05002693 value = hwinfo[EEPROM_RF_BT_SETTING_8723B];
Larry Fingera619d1a2014-02-28 15:16:50 -06002694 rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2695 rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1);
Ping-Ke Shih0de9b5d2017-02-06 21:30:04 -06002696 rtlpriv->btcoexist.btc_info.single_ant_path =
2697 (value & 0x40); /*0xc3[6]*/
Larry Fingera619d1a2014-02-28 15:16:50 -06002698 } else {
2699 rtlpriv->btcoexist.btc_info.btcoexist = 0;
2700 rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2701 rtlpriv->btcoexist.btc_info.ant_num = ANT_X2;
Ping-Ke Shihdb8cb002017-02-06 21:30:03 -06002702 rtlpriv->btcoexist.btc_info.single_ant_path = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002703 }
Larry Finger5c99f042014-09-26 16:40:25 -05002704
Larry Fingerc18d8f52016-03-16 13:33:34 -05002705 /* override ant_num / ant_path */
Ping-Ke Shih0ff78ad2017-02-06 21:30:07 -06002706 if (mod_params->ant_sel) {
Larry Fingerc18d8f52016-03-16 13:33:34 -05002707 rtlpriv->btcoexist.btc_info.ant_num =
2708 (mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1);
Ping-Ke Shih0ff78ad2017-02-06 21:30:07 -06002709
2710 rtlpriv->btcoexist.btc_info.single_ant_path =
2711 (mod_params->ant_sel == 1 ? 0 : 1);
2712 }
Larry Fingera619d1a2014-02-28 15:16:50 -06002713}
2714
2715void rtl8723be_bt_reg_init(struct ieee80211_hw *hw)
2716{
2717 struct rtl_priv *rtlpriv = rtl_priv(hw);
2718
2719 /* 0:Low, 1:High, 2:From Efuse. */
2720 rtlpriv->btcoexist.reg_bt_iso = 2;
2721 /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */
2722 rtlpriv->btcoexist.reg_bt_sco = 3;
2723 /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
2724 rtlpriv->btcoexist.reg_bt_sco = 0;
2725}
2726
2727void rtl8723be_bt_hw_init(struct ieee80211_hw *hw)
2728{
2729 struct rtl_priv *rtlpriv = rtl_priv(hw);
2730
2731 if (rtlpriv->cfg->ops->get_btc_status())
2732 rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv);
Larry Finger5c99f042014-09-26 16:40:25 -05002733
Larry Fingera619d1a2014-02-28 15:16:50 -06002734}
2735
2736void rtl8723be_suspend(struct ieee80211_hw *hw)
2737{
2738}
2739
2740void rtl8723be_resume(struct ieee80211_hw *hw)
2741{
2742}