blob: 2a7ad5ffe997d1b2e65e9d62d9303830df74477a [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(
63 (u8 *)entry, true, HW_DESC_TXBUFF_ADDR),
64 skb->len, PCI_DMA_TODEVICE);
65 kfree_skb(skb);
66 ring->idx = (ring->idx + 1) % ring->entries;
67 }
Larry Finger5c99f042014-09-26 16:40:25 -050068 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
Larry Fingera619d1a2014-02-28 15:16:50 -060069}
70
71static void _rtl8723be_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
72 u8 set_bits, u8 clear_bits)
73{
74 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
75 struct rtl_priv *rtlpriv = rtl_priv(hw);
76
77 rtlpci->reg_bcn_ctrl_val |= set_bits;
78 rtlpci->reg_bcn_ctrl_val &= ~clear_bits;
79
Larry Finger5c99f042014-09-26 16:40:25 -050080 rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlpci->reg_bcn_ctrl_val);
Larry Fingera619d1a2014-02-28 15:16:50 -060081}
82
83static void _rtl8723be_stop_tx_beacon(struct ieee80211_hw *hw)
84{
85 struct rtl_priv *rtlpriv = rtl_priv(hw);
86 u8 tmp1byte;
87
88 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
89 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6)));
90 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64);
91 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
92 tmp1byte &= ~(BIT(0));
93 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
94}
95
96static void _rtl8723be_resume_tx_beacon(struct ieee80211_hw *hw)
97{
98 struct rtl_priv *rtlpriv = rtl_priv(hw);
99 u8 tmp1byte;
100
101 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
102 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6));
103 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
104 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
105 tmp1byte |= BIT(1);
106 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
107}
108
109static void _rtl8723be_enable_bcn_sub_func(struct ieee80211_hw *hw)
110{
111 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(1));
112}
113
114static void _rtl8723be_disable_bcn_sub_func(struct ieee80211_hw *hw)
115{
116 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(1), 0);
117}
118
119static void _rtl8723be_set_fw_clock_on(struct ieee80211_hw *hw, u8 rpwm_val,
Larry Finger5c99f042014-09-26 16:40:25 -0500120 bool b_need_turn_off_ckk)
Larry Fingera619d1a2014-02-28 15:16:50 -0600121{
122 struct rtl_priv *rtlpriv = rtl_priv(hw);
123 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
Larry Finger5c99f042014-09-26 16:40:25 -0500124 bool b_support_remote_wake_up;
Larry Fingera619d1a2014-02-28 15:16:50 -0600125 u32 count = 0, isr_regaddr, content;
Larry Finger5c99f042014-09-26 16:40:25 -0500126 bool b_schedule_timer = b_need_turn_off_ckk;
Larry Fingera619d1a2014-02-28 15:16:50 -0600127 rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN,
Larry Finger5c99f042014-09-26 16:40:25 -0500128 (u8 *)(&b_support_remote_wake_up));
Larry Fingera619d1a2014-02-28 15:16:50 -0600129
130 if (!rtlhal->fw_ready)
131 return;
132 if (!rtlpriv->psc.fw_current_inpsmode)
133 return;
134
135 while (1) {
136 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
137 if (rtlhal->fw_clk_change_in_progress) {
138 while (rtlhal->fw_clk_change_in_progress) {
139 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
140 count++;
141 udelay(100);
142 if (count > 1000)
143 return;
144 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
145 }
146 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
147 } else {
148 rtlhal->fw_clk_change_in_progress = false;
149 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
150 break;
151 }
152 }
Larry Finger5c99f042014-09-26 16:40:25 -0500153
154 if (IS_IN_LOW_POWER_STATE(rtlhal->fw_ps_state)) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600155 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM,
Larry Finger5c99f042014-09-26 16:40:25 -0500156 (u8 *)(&rpwm_val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600157 if (FW_PS_IS_ACK(rpwm_val)) {
158 isr_regaddr = REG_HISR;
159 content = rtl_read_dword(rtlpriv, isr_regaddr);
160 while (!(content & IMR_CPWM) && (count < 500)) {
161 udelay(50);
162 count++;
163 content = rtl_read_dword(rtlpriv, isr_regaddr);
164 }
165
166 if (content & IMR_CPWM) {
167 rtl_write_word(rtlpriv, isr_regaddr, 0x0100);
Larry Finger5c99f042014-09-26 16:40:25 -0500168 rtlhal->fw_ps_state = FW_PS_STATE_RF_ON;
Larry Fingera619d1a2014-02-28 15:16:50 -0600169 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
Larry Finger5c99f042014-09-26 16:40:25 -0500170 "Receive CPWM INT!!! Set pHalData->FwPSState = %X\n",
Larry Fingera619d1a2014-02-28 15:16:50 -0600171 rtlhal->fw_ps_state);
172 }
173 }
Larry Finger5c99f042014-09-26 16:40:25 -0500174
Larry Fingera619d1a2014-02-28 15:16:50 -0600175 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
176 rtlhal->fw_clk_change_in_progress = false;
177 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
Larry Finger5c99f042014-09-26 16:40:25 -0500178 if (b_schedule_timer)
Larry Fingera619d1a2014-02-28 15:16:50 -0600179 mod_timer(&rtlpriv->works.fw_clockoff_timer,
180 jiffies + MSECS(10));
Larry Fingera619d1a2014-02-28 15:16:50 -0600181 } else {
182 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
183 rtlhal->fw_clk_change_in_progress = false;
184 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
185 }
186}
187
188static void _rtl8723be_set_fw_clock_off(struct ieee80211_hw *hw, u8 rpwm_val)
189{
190 struct rtl_priv *rtlpriv = rtl_priv(hw);
191 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
192 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
193 struct rtl8192_tx_ring *ring;
194 enum rf_pwrstate rtstate;
Larry Finger5c99f042014-09-26 16:40:25 -0500195 bool b_schedule_timer = false;
Larry Fingera619d1a2014-02-28 15:16:50 -0600196 u8 queue;
197
198 if (!rtlhal->fw_ready)
199 return;
200 if (!rtlpriv->psc.fw_current_inpsmode)
201 return;
202 if (!rtlhal->allow_sw_to_change_hwclc)
203 return;
204 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, (u8 *)(&rtstate));
205 if (rtstate == ERFOFF || rtlpriv->psc.inactive_pwrstate == ERFOFF)
206 return;
207
208 for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) {
209 ring = &rtlpci->tx_ring[queue];
210 if (skb_queue_len(&ring->queue)) {
Larry Finger5c99f042014-09-26 16:40:25 -0500211 b_schedule_timer = true;
Larry Fingera619d1a2014-02-28 15:16:50 -0600212 break;
213 }
214 }
Larry Finger5c99f042014-09-26 16:40:25 -0500215
216 if (b_schedule_timer) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600217 mod_timer(&rtlpriv->works.fw_clockoff_timer,
218 jiffies + MSECS(10));
219 return;
220 }
Larry Finger5c99f042014-09-26 16:40:25 -0500221
222 if (FW_PS_STATE(rtlhal->fw_ps_state) != FW_PS_STATE_RF_OFF_LOW_PWR) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600223 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
224 if (!rtlhal->fw_clk_change_in_progress) {
225 rtlhal->fw_clk_change_in_progress = true;
226 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
227 rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val);
228 rtl_write_word(rtlpriv, REG_HISR, 0x0100);
229 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
Larry Finger5c99f042014-09-26 16:40:25 -0500230 (u8 *)(&rpwm_val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600231 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
232 rtlhal->fw_clk_change_in_progress = false;
233 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
234 } else {
235 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
236 mod_timer(&rtlpriv->works.fw_clockoff_timer,
237 jiffies + MSECS(10));
238 }
239 }
Larry Finger5c99f042014-09-26 16:40:25 -0500240
Larry Fingera619d1a2014-02-28 15:16:50 -0600241}
242
243static void _rtl8723be_set_fw_ps_rf_on(struct ieee80211_hw *hw)
244{
245 u8 rpwm_val = 0;
Larry Finger5c99f042014-09-26 16:40:25 -0500246 rpwm_val |= (FW_PS_STATE_RF_OFF | FW_PS_ACK);
Larry Fingera619d1a2014-02-28 15:16:50 -0600247 _rtl8723be_set_fw_clock_on(hw, rpwm_val, true);
248}
249
250static void _rtl8723be_fwlps_leave(struct ieee80211_hw *hw)
251{
252 struct rtl_priv *rtlpriv = rtl_priv(hw);
253 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
254 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
255 bool fw_current_inps = false;
256 u8 rpwm_val = 0, fw_pwrmode = FW_PS_ACTIVE_MODE;
257
258 if (ppsc->low_power_enable) {
Larry Finger5c99f042014-09-26 16:40:25 -0500259 rpwm_val = (FW_PS_STATE_ALL_ON | FW_PS_ACK);/* RF on */
Larry Fingera619d1a2014-02-28 15:16:50 -0600260 _rtl8723be_set_fw_clock_on(hw, rpwm_val, false);
261 rtlhal->allow_sw_to_change_hwclc = false;
262 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
Larry Finger5c99f042014-09-26 16:40:25 -0500263 (u8 *)(&fw_pwrmode));
Larry Fingera619d1a2014-02-28 15:16:50 -0600264 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
265 (u8 *)(&fw_current_inps));
266 } else {
Larry Finger5c99f042014-09-26 16:40:25 -0500267 rpwm_val = FW_PS_STATE_ALL_ON; /* RF on */
268 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
269 (u8 *)(&rpwm_val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600270 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
Larry Finger5c99f042014-09-26 16:40:25 -0500271 (u8 *)(&fw_pwrmode));
Larry Fingera619d1a2014-02-28 15:16:50 -0600272 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
273 (u8 *)(&fw_current_inps));
274 }
Larry Finger5c99f042014-09-26 16:40:25 -0500275
Larry Fingera619d1a2014-02-28 15:16:50 -0600276}
277
278static void _rtl8723be_fwlps_enter(struct ieee80211_hw *hw)
279{
280 struct rtl_priv *rtlpriv = rtl_priv(hw);
281 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
282 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
283 bool fw_current_inps = true;
284 u8 rpwm_val;
285
286 if (ppsc->low_power_enable) {
Larry Finger5c99f042014-09-26 16:40:25 -0500287 rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR; /* RF off */
Larry Fingera619d1a2014-02-28 15:16:50 -0600288 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
289 (u8 *)(&fw_current_inps));
290 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
Larry Finger5c99f042014-09-26 16:40:25 -0500291 (u8 *)(&ppsc->fwctrl_psmode));
Larry Fingera619d1a2014-02-28 15:16:50 -0600292 rtlhal->allow_sw_to_change_hwclc = true;
293 _rtl8723be_set_fw_clock_off(hw, rpwm_val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600294 } else {
Larry Finger5c99f042014-09-26 16:40:25 -0500295 rpwm_val = FW_PS_STATE_RF_OFF; /* RF off */
Larry Fingera619d1a2014-02-28 15:16:50 -0600296 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
297 (u8 *)(&fw_current_inps));
298 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
Larry Finger5c99f042014-09-26 16:40:25 -0500299 (u8 *)(&ppsc->fwctrl_psmode));
300 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
301 (u8 *)(&rpwm_val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600302 }
Larry Finger5c99f042014-09-26 16:40:25 -0500303
Larry Fingera619d1a2014-02-28 15:16:50 -0600304}
305
306void rtl8723be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
307{
308 struct rtl_priv *rtlpriv = rtl_priv(hw);
309 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
310 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
311
312 switch (variable) {
313 case HW_VAR_RCR:
314 *((u32 *)(val)) = rtlpci->receive_config;
315 break;
316 case HW_VAR_RF_STATE:
317 *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
318 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500319 case HW_VAR_FWLPS_RF_ON:{
320 enum rf_pwrstate rfState;
Larry Fingera619d1a2014-02-28 15:16:50 -0600321 u32 val_rcr;
322
323 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE,
Larry Finger5c99f042014-09-26 16:40:25 -0500324 (u8 *)(&rfState));
325 if (rfState == ERFOFF) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600326 *((bool *)(val)) = true;
327 } else {
328 val_rcr = rtl_read_dword(rtlpriv, REG_RCR);
329 val_rcr &= 0x00070000;
330 if (val_rcr)
331 *((bool *)(val)) = false;
332 else
333 *((bool *)(val)) = true;
334 }
Larry Finger5c99f042014-09-26 16:40:25 -0500335 }
336 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600337 case HW_VAR_FW_PSMODE_STATUS:
338 *((bool *)(val)) = ppsc->fw_current_inpsmode;
339 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500340 case HW_VAR_CORRECT_TSF:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600341 u64 tsf;
342 u32 *ptsf_low = (u32 *)&tsf;
343 u32 *ptsf_high = ((u32 *)&tsf) + 1;
344
345 *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4));
346 *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
347
348 *((u64 *)(val)) = tsf;
Larry Finger5c99f042014-09-26 16:40:25 -0500349 }
350 break;
Larry Finger1cc49a52016-09-24 11:57:18 -0500351 case HAL_DEF_WOWLAN:
352 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600353 default:
Larry Finger5c99f042014-09-26 16:40:25 -0500354 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -0700355 "switch case %#x not processed\n", variable);
Larry Fingera619d1a2014-02-28 15:16:50 -0600356 break;
357 }
358}
359
Larry Finger5c99f042014-09-26 16:40:25 -0500360static void _rtl8723be_download_rsvd_page(struct ieee80211_hw *hw)
361{
362 struct rtl_priv *rtlpriv = rtl_priv(hw);
363 u8 tmp_regcr, tmp_reg422, bcnvalid_reg;
364 u8 count = 0, dlbcn_count = 0;
365 bool b_recover = false;
366
367 tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
368 rtl_write_byte(rtlpriv, REG_CR + 1,
369 (tmp_regcr | BIT(0)));
370
371 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3));
372 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0);
373
374 tmp_reg422 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
375 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422 & (~BIT(6)));
376 if (tmp_reg422 & BIT(6))
377 b_recover = true;
378
379 do {
380 bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL + 2);
381 rtl_write_byte(rtlpriv, REG_TDECTRL + 2,
382 (bcnvalid_reg | BIT(0)));
383 _rtl8723be_return_beacon_queue_skb(hw);
384
385 rtl8723be_set_fw_rsvdpagepkt(hw, 0);
386 bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL + 2);
387 count = 0;
388 while (!(bcnvalid_reg & BIT(0)) && count < 20) {
389 count++;
390 udelay(10);
391 bcnvalid_reg = rtl_read_byte(rtlpriv,
392 REG_TDECTRL + 2);
393 }
394 dlbcn_count++;
395 } while (!(bcnvalid_reg & BIT(0)) && dlbcn_count < 5);
396
397 if (bcnvalid_reg & BIT(0))
398 rtl_write_byte(rtlpriv, REG_TDECTRL + 2, BIT(0));
399
400 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
401 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4));
402
403 if (b_recover)
404 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422);
405
406 tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
407 rtl_write_byte(rtlpriv, REG_CR + 1, (tmp_regcr & ~(BIT(0))));
408}
409
Larry Fingera619d1a2014-02-28 15:16:50 -0600410void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
411{
412 struct rtl_priv *rtlpriv = rtl_priv(hw);
413 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
414 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
415 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
416 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
417 u8 idx;
418
419 switch (variable) {
420 case HW_VAR_ETHER_ADDR:
421 for (idx = 0; idx < ETH_ALEN; idx++)
422 rtl_write_byte(rtlpriv, (REG_MACID + idx), val[idx]);
423 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500424 case HW_VAR_BASIC_RATE:{
425 u16 b_rate_cfg = ((u16 *)val)[0];
Larry Fingera619d1a2014-02-28 15:16:50 -0600426 u8 rate_index = 0;
Larry Finger5c99f042014-09-26 16:40:25 -0500427 b_rate_cfg = b_rate_cfg & 0x15f;
428 b_rate_cfg |= 0x01;
429 rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff);
430 rtl_write_byte(rtlpriv, REG_RRSR + 1, (b_rate_cfg >> 8) & 0xff);
431 while (b_rate_cfg > 0x1) {
432 b_rate_cfg = (b_rate_cfg >> 1);
Larry Fingera619d1a2014-02-28 15:16:50 -0600433 rate_index++;
434 }
435 rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, rate_index);
Larry Finger5c99f042014-09-26 16:40:25 -0500436 }
437 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600438 case HW_VAR_BSSID:
439 for (idx = 0; idx < ETH_ALEN; idx++)
440 rtl_write_byte(rtlpriv, (REG_BSSID + idx), val[idx]);
Larry Finger5c99f042014-09-26 16:40:25 -0500441
Larry Fingera619d1a2014-02-28 15:16:50 -0600442 break;
443 case HW_VAR_SIFS:
444 rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]);
445 rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]);
446
447 rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]);
448 rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
449
450 if (!mac->ht_enable)
451 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, 0x0e0e);
452 else
453 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
454 *((u16 *)val));
455 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500456 case HW_VAR_SLOT_TIME:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600457 u8 e_aci;
458
459 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
460 "HW_VAR_SLOT_TIME %x\n", val[0]);
461
462 rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
463
464 for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
465 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
Larry Finger5c99f042014-09-26 16:40:25 -0500466 (u8 *)(&e_aci));
Larry Fingera619d1a2014-02-28 15:16:50 -0600467 }
Larry Finger5c99f042014-09-26 16:40:25 -0500468 }
469 break;
470 case HW_VAR_ACK_PREAMBLE:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600471 u8 reg_tmp;
Larry Finger5c99f042014-09-26 16:40:25 -0500472 u8 short_preamble = (bool)(*(u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600473 reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL + 2);
474 if (short_preamble) {
475 reg_tmp |= 0x02;
476 rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
477 } else {
478 reg_tmp &= 0xFD;
479 rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
480 }
Larry Finger5c99f042014-09-26 16:40:25 -0500481 }
Larry Fingera619d1a2014-02-28 15:16:50 -0600482 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500483 case HW_VAR_WPA_CONFIG:
484 rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val));
485 break;
486 case HW_VAR_AMPDU_MIN_SPACE:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600487 u8 min_spacing_to_set;
488 u8 sec_min_space;
489
Larry Finger5c99f042014-09-26 16:40:25 -0500490 min_spacing_to_set = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600491 if (min_spacing_to_set <= 7) {
492 sec_min_space = 0;
493
494 if (min_spacing_to_set < sec_min_space)
495 min_spacing_to_set = sec_min_space;
496
497 mac->min_space_cfg = ((mac->min_space_cfg & 0xf8) |
498 min_spacing_to_set);
499
500 *val = min_spacing_to_set;
501
502 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
503 "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
Larry Finger5c99f042014-09-26 16:40:25 -0500504 mac->min_space_cfg);
Larry Fingera619d1a2014-02-28 15:16:50 -0600505
506 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
507 mac->min_space_cfg);
508 }
Larry Finger5c99f042014-09-26 16:40:25 -0500509 }
510 break;
511 case HW_VAR_SHORTGI_DENSITY:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600512 u8 density_to_set;
513
Larry Finger5c99f042014-09-26 16:40:25 -0500514 density_to_set = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600515 mac->min_space_cfg |= (density_to_set << 3);
516
517 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
518 "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
Larry Finger5c99f042014-09-26 16:40:25 -0500519 mac->min_space_cfg);
Larry Fingera619d1a2014-02-28 15:16:50 -0600520
521 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
522 mac->min_space_cfg);
Larry Finger5c99f042014-09-26 16:40:25 -0500523 }
524 break;
525 case HW_VAR_AMPDU_FACTOR:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600526 u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9};
527 u8 factor_toset;
528 u8 *p_regtoset = NULL;
529 u8 index = 0;
530
531 p_regtoset = regtoset_normal;
532
Larry Finger5c99f042014-09-26 16:40:25 -0500533 factor_toset = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600534 if (factor_toset <= 3) {
535 factor_toset = (1 << (factor_toset + 2));
536 if (factor_toset > 0xf)
537 factor_toset = 0xf;
538
539 for (index = 0; index < 4; index++) {
540 if ((p_regtoset[index] & 0xf0) >
541 (factor_toset << 4))
542 p_regtoset[index] =
543 (p_regtoset[index] & 0x0f) |
544 (factor_toset << 4);
545
546 if ((p_regtoset[index] & 0x0f) > factor_toset)
547 p_regtoset[index] =
548 (p_regtoset[index] & 0xf0) |
549 (factor_toset);
550
551 rtl_write_byte(rtlpriv,
552 (REG_AGGLEN_LMT + index),
553 p_regtoset[index]);
Larry Finger5c99f042014-09-26 16:40:25 -0500554
Larry Fingera619d1a2014-02-28 15:16:50 -0600555 }
Larry Finger5c99f042014-09-26 16:40:25 -0500556
Larry Fingera619d1a2014-02-28 15:16:50 -0600557 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
558 "Set HW_VAR_AMPDU_FACTOR: %#x\n",
Larry Finger5c99f042014-09-26 16:40:25 -0500559 factor_toset);
Larry Fingera619d1a2014-02-28 15:16:50 -0600560 }
Larry Finger5c99f042014-09-26 16:40:25 -0500561 }
562 break;
563 case HW_VAR_AC_PARAM:{
564 u8 e_aci = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600565 rtl8723_dm_init_edca_turbo(hw);
566
567 if (rtlpci->acm_method != EACMWAY2_SW)
568 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
Larry Finger5c99f042014-09-26 16:40:25 -0500569 (u8 *)(&e_aci));
570 }
571 break;
572 case HW_VAR_ACM_CTRL:{
573 u8 e_aci = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600574 union aci_aifsn *p_aci_aifsn =
575 (union aci_aifsn *)(&(mac->ac[0].aifs));
576 u8 acm = p_aci_aifsn->f.acm;
577 u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);
578
579 acm_ctrl =
580 acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1);
581
582 if (acm) {
583 switch (e_aci) {
584 case AC0_BE:
585 acm_ctrl |= ACMHW_BEQEN;
586 break;
587 case AC2_VI:
588 acm_ctrl |= ACMHW_VIQEN;
589 break;
590 case AC3_VO:
591 acm_ctrl |= ACMHW_VOQEN;
592 break;
593 default:
594 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
Larry Finger5c99f042014-09-26 16:40:25 -0500595 "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
596 acm);
Larry Fingera619d1a2014-02-28 15:16:50 -0600597 break;
598 }
599 } else {
600 switch (e_aci) {
601 case AC0_BE:
602 acm_ctrl &= (~ACMHW_BEQEN);
603 break;
604 case AC2_VI:
605 acm_ctrl &= (~ACMHW_VIQEN);
606 break;
607 case AC3_VO:
Jes Sorensen52f57802015-02-06 17:24:32 -0500608 acm_ctrl &= (~ACMHW_VOQEN);
Larry Fingera619d1a2014-02-28 15:16:50 -0600609 break;
610 default:
Larry Finger5c99f042014-09-26 16:40:25 -0500611 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -0700612 "switch case %#x not processed\n",
613 e_aci);
Larry Fingera619d1a2014-02-28 15:16:50 -0600614 break;
615 }
616 }
Larry Finger5c99f042014-09-26 16:40:25 -0500617
Larry Fingera619d1a2014-02-28 15:16:50 -0600618 RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
Larry Finger5c99f042014-09-26 16:40:25 -0500619 "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
620 acm_ctrl);
Larry Fingera619d1a2014-02-28 15:16:50 -0600621 rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
Larry Finger5c99f042014-09-26 16:40:25 -0500622 }
623 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600624 case HW_VAR_RCR:
625 rtl_write_dword(rtlpriv, REG_RCR, ((u32 *)(val))[0]);
626 rtlpci->receive_config = ((u32 *)(val))[0];
627 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500628 case HW_VAR_RETRY_LIMIT:{
629 u8 retry_limit = ((u8 *)(val))[0];
Larry Fingera619d1a2014-02-28 15:16:50 -0600630
631 rtl_write_word(rtlpriv, REG_RL,
632 retry_limit << RETRY_LIMIT_SHORT_SHIFT |
633 retry_limit << RETRY_LIMIT_LONG_SHIFT);
Larry Finger5c99f042014-09-26 16:40:25 -0500634 }
635 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600636 case HW_VAR_DUAL_TSF_RST:
637 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
638 break;
639 case HW_VAR_EFUSE_BYTES:
640 rtlefuse->efuse_usedbytes = *((u16 *)val);
641 break;
642 case HW_VAR_EFUSE_USAGE:
Larry Finger5c99f042014-09-26 16:40:25 -0500643 rtlefuse->efuse_usedpercentage = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600644 break;
645 case HW_VAR_IO_CMD:
646 rtl8723be_phy_set_io_cmd(hw, (*(enum io_type *)val));
647 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500648 case HW_VAR_SET_RPWM:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600649 u8 rpwm_val;
650
651 rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM);
652 udelay(1);
653
654 if (rpwm_val & BIT(7)) {
Larry Finger5c99f042014-09-26 16:40:25 -0500655 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, (*(u8 *)val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600656 } else {
Larry Finger5c99f042014-09-26 16:40:25 -0500657 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
658 ((*(u8 *)val) | BIT(7)));
Larry Fingera619d1a2014-02-28 15:16:50 -0600659 }
Larry Finger5c99f042014-09-26 16:40:25 -0500660 }
661 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600662 case HW_VAR_H2C_FW_PWRMODE:
Larry Finger5c99f042014-09-26 16:40:25 -0500663 rtl8723be_set_fw_pwrmode_cmd(hw, (*(u8 *)val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600664 break;
665 case HW_VAR_FW_PSMODE_STATUS:
666 ppsc->fw_current_inpsmode = *((bool *)val);
667 break;
668 case HW_VAR_RESUME_CLK_ON:
669 _rtl8723be_set_fw_ps_rf_on(hw);
670 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500671 case HW_VAR_FW_LPS_ACTION:{
672 bool b_enter_fwlps = *((bool *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600673
Larry Finger5c99f042014-09-26 16:40:25 -0500674 if (b_enter_fwlps)
Larry Fingera619d1a2014-02-28 15:16:50 -0600675 _rtl8723be_fwlps_enter(hw);
676 else
677 _rtl8723be_fwlps_leave(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500678 }
679 break;
680 case HW_VAR_H2C_FW_JOINBSSRPT:{
681 u8 mstatus = (*(u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600682
683 if (mstatus == RT_MEDIA_CONNECT) {
684 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL);
Larry Finger5c99f042014-09-26 16:40:25 -0500685 _rtl8723be_download_rsvd_page(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -0600686 }
Larry Finger5c99f042014-09-26 16:40:25 -0500687 rtl8723be_set_fw_media_status_rpt_cmd(hw, mstatus);
688 }
Larry Fingera619d1a2014-02-28 15:16:50 -0600689 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500690 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
691 rtl8723be_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
692 break;
693 case HW_VAR_AID:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600694 u16 u2btmp;
695 u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
696 u2btmp &= 0xC000;
697 rtl_write_word(rtlpriv, REG_BCN_PSR_RPT,
698 (u2btmp | mac->assoc_id));
Larry Finger5c99f042014-09-26 16:40:25 -0500699 }
700 break;
701 case HW_VAR_CORRECT_TSF:{
702 u8 btype_ibss = ((u8 *)(val))[0];
Larry Fingera619d1a2014-02-28 15:16:50 -0600703
704 if (btype_ibss)
705 _rtl8723be_stop_tx_beacon(hw);
706
707 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3));
708
709 rtl_write_dword(rtlpriv, REG_TSFTR,
710 (u32) (mac->tsf & 0xffffffff));
711 rtl_write_dword(rtlpriv, REG_TSFTR + 4,
712 (u32) ((mac->tsf >> 32) & 0xffffffff));
713
714 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
715
716 if (btype_ibss)
717 _rtl8723be_resume_tx_beacon(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500718 }
719 break;
720 case HW_VAR_KEEP_ALIVE:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600721 u8 array[2];
722 array[0] = 0xff;
Larry Finger5c99f042014-09-26 16:40:25 -0500723 array[1] = *((u8 *)val);
724 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_KEEP_ALIVE_CTRL, 2, array);
725 }
726 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600727 default:
Larry Finger5c99f042014-09-26 16:40:25 -0500728 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -0700729 "switch case %#x not processed\n", variable);
Larry Fingera619d1a2014-02-28 15:16:50 -0600730 break;
731 }
732}
733
734static bool _rtl8723be_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
735{
736 struct rtl_priv *rtlpriv = rtl_priv(hw);
737 bool status = true;
Larry Finger5c99f042014-09-26 16:40:25 -0500738 long count = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -0600739 u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) |
740 _LLT_OP(_LLT_WRITE_ACCESS);
741
742 rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
743
744 do {
745 value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
746 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
747 break;
748
749 if (count > POLLING_LLT_THRESHOLD) {
Larry Finger4e2b4372016-12-15 12:23:00 -0600750 pr_err("Failed to polling write LLT done at address %d!\n",
751 address);
Larry Fingera619d1a2014-02-28 15:16:50 -0600752 status = false;
753 break;
754 }
755 } while (++count);
756
757 return status;
758}
759
760static bool _rtl8723be_llt_table_init(struct ieee80211_hw *hw)
761{
762 struct rtl_priv *rtlpriv = rtl_priv(hw);
763 unsigned short i;
764 u8 txpktbuf_bndy;
Larry Finger5c99f042014-09-26 16:40:25 -0500765 u8 maxPage;
Larry Fingera619d1a2014-02-28 15:16:50 -0600766 bool status;
767
Larry Finger5c99f042014-09-26 16:40:25 -0500768 maxPage = 255;
Larry Fingera619d1a2014-02-28 15:16:50 -0600769 txpktbuf_bndy = 245;
770
771 rtl_write_dword(rtlpriv, REG_TRXFF_BNDY,
772 (0x27FF0000 | txpktbuf_bndy));
773 rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy);
774
775 rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
776 rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
777
778 rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy);
779 rtl_write_byte(rtlpriv, REG_PBP, 0x31);
780 rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);
781
782 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
783 status = _rtl8723be_llt_write(hw, i, i + 1);
784 if (!status)
785 return status;
786 }
Larry Finger5c99f042014-09-26 16:40:25 -0500787
Larry Fingera619d1a2014-02-28 15:16:50 -0600788 status = _rtl8723be_llt_write(hw, (txpktbuf_bndy - 1), 0xFF);
789
790 if (!status)
791 return status;
792
Larry Finger5c99f042014-09-26 16:40:25 -0500793 for (i = txpktbuf_bndy; i < maxPage; i++) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600794 status = _rtl8723be_llt_write(hw, i, (i + 1));
795 if (!status)
796 return status;
797 }
Larry Finger5c99f042014-09-26 16:40:25 -0500798
799 status = _rtl8723be_llt_write(hw, maxPage, txpktbuf_bndy);
Larry Fingera619d1a2014-02-28 15:16:50 -0600800 if (!status)
801 return status;
802
803 rtl_write_dword(rtlpriv, REG_RQPN, 0x80e40808);
804 rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x00);
805
806 return true;
807}
808
809static void _rtl8723be_gen_refresh_led_state(struct ieee80211_hw *hw)
810{
811 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -0600812 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
Larry Fingerd5efe152017-02-07 09:14:21 -0600813 struct rtl_led *pled0 = &rtlpriv->ledctl.sw_led0;
Larry Fingera619d1a2014-02-28 15:16:50 -0600814
815 if (rtlpriv->rtlhal.up_first_time)
816 return;
817
818 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
819 rtl8723be_sw_led_on(hw, pled0);
820 else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT)
821 rtl8723be_sw_led_on(hw, pled0);
822 else
823 rtl8723be_sw_led_off(hw, pled0);
824}
825
826static bool _rtl8723be_init_mac(struct ieee80211_hw *hw)
827{
828 struct rtl_priv *rtlpriv = rtl_priv(hw);
829 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
Larry Finger5c99f042014-09-26 16:40:25 -0500830 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
Larry Fingera619d1a2014-02-28 15:16:50 -0600831 unsigned char bytetmp;
832 unsigned short wordtmp;
Larry Fingera619d1a2014-02-28 15:16:50 -0600833
834 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
835
836 /*Auto Power Down to CHIP-off State*/
837 bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) & (~BIT(7));
838 rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp);
839
Larry Fingera619d1a2014-02-28 15:16:50 -0600840 /* HW Power on sequence */
Larry Finger34ed7802014-09-22 09:39:27 -0500841 if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK,
842 PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,
843 RTL8723_NIC_ENABLE_FLOW)) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600844 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
845 "init MAC Fail as power on failure\n");
846 return false;
847 }
Larry Finger5c99f042014-09-26 16:40:25 -0500848
Ping-Ke Shihf95d95a2017-06-18 11:12:41 -0500849 if (rtlpriv->cfg->ops->get_btc_status())
850 rtlpriv->btcoexist.btc_ops->btc_power_on_setting(rtlpriv);
851
Larry Finger5c99f042014-09-26 16:40:25 -0500852 bytetmp = rtl_read_byte(rtlpriv, REG_MULTI_FUNC_CTRL);
853 rtl_write_byte(rtlpriv, REG_MULTI_FUNC_CTRL, bytetmp | BIT(3));
854
Larry Fingera619d1a2014-02-28 15:16:50 -0600855 bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO) | BIT(4);
856 rtl_write_byte(rtlpriv, REG_APS_FSMCO, bytetmp);
857
858 bytetmp = rtl_read_byte(rtlpriv, REG_CR);
859 bytetmp = 0xff;
860 rtl_write_byte(rtlpriv, REG_CR, bytetmp);
861 mdelay(2);
862
863 bytetmp = rtl_read_byte(rtlpriv, REG_HWSEQ_CTRL);
864 bytetmp |= 0x7f;
865 rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, bytetmp);
866 mdelay(2);
867
868 bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CFG + 3);
869 if (bytetmp & BIT(0)) {
870 bytetmp = rtl_read_byte(rtlpriv, 0x7c);
Larry Finger5c99f042014-09-26 16:40:25 -0500871 rtl_write_byte(rtlpriv, 0x7c, bytetmp | BIT(6));
Larry Fingera619d1a2014-02-28 15:16:50 -0600872 }
Larry Fingera619d1a2014-02-28 15:16:50 -0600873
Larry Finger5c99f042014-09-26 16:40:25 -0500874 bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CLKR);
875 rtl_write_byte(rtlpriv, REG_SYS_CLKR, bytetmp | BIT(3));
876 bytetmp = rtl_read_byte(rtlpriv, REG_GPIO_MUXCFG + 1);
877 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG + 1, bytetmp & (~BIT(4)));
Larry Fingera619d1a2014-02-28 15:16:50 -0600878
879 rtl_write_word(rtlpriv, REG_CR, 0x2ff);
880
Larry Finger5c99f042014-09-26 16:40:25 -0500881 if (!rtlhal->mac_func_enable) {
882 if (_rtl8723be_llt_table_init(hw) == false)
Larry Fingera619d1a2014-02-28 15:16:50 -0600883 return false;
884 }
Larry Finger5c99f042014-09-26 16:40:25 -0500885
Larry Fingera619d1a2014-02-28 15:16:50 -0600886 rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
887 rtl_write_dword(rtlpriv, REG_HISRE, 0xffffffff);
888
889 /* Enable FW Beamformer Interrupt */
890 bytetmp = rtl_read_byte(rtlpriv, REG_FWIMR + 3);
891 rtl_write_byte(rtlpriv, REG_FWIMR + 3, bytetmp | BIT(6));
892
893 wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL);
894 wordtmp &= 0xf;
895 wordtmp |= 0xF5B1;
896 rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp);
897
898 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F);
899 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
900 rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xFFFF);
901 rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config);
902
Larry Fingera619d1a2014-02-28 15:16:50 -0600903 rtl_write_dword(rtlpriv, REG_BCNQ_DESA,
904 ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) &
905 DMA_BIT_MASK(32));
906 rtl_write_dword(rtlpriv, REG_MGQ_DESA,
907 (u64) rtlpci->tx_ring[MGNT_QUEUE].dma &
908 DMA_BIT_MASK(32));
909 rtl_write_dword(rtlpriv, REG_VOQ_DESA,
910 (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32));
911 rtl_write_dword(rtlpriv, REG_VIQ_DESA,
912 (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32));
913 rtl_write_dword(rtlpriv, REG_BEQ_DESA,
914 (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32));
915 rtl_write_dword(rtlpriv, REG_BKQ_DESA,
916 (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32));
917 rtl_write_dword(rtlpriv, REG_HQ_DESA,
918 (u64) rtlpci->tx_ring[HIGH_QUEUE].dma &
919 DMA_BIT_MASK(32));
920 rtl_write_dword(rtlpriv, REG_RX_DESA,
921 (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma &
922 DMA_BIT_MASK(32));
923
924 bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 3);
925 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, bytetmp | 0x77);
926
927 rtl_write_dword(rtlpriv, REG_INT_MIG, 0);
928
Larry Finger5c99f042014-09-26 16:40:25 -0500929 rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0);
Larry Fingera619d1a2014-02-28 15:16:50 -0600930
931 rtl_write_byte(rtlpriv, REG_SECONDARY_CCA_CTRL, 0x3);
932
Larry Finger5c99f042014-09-26 16:40:25 -0500933 /* <20130114, Kordan> The following setting is
934 * only for DPDT and Fixed board type.
935 * TODO: A better solution is configure it
936 * according EFUSE during the run-time.
937 */
938 rtl_set_bbreg(hw, 0x64, BIT(20), 0x0);/* 0x66[4]=0 */
939 rtl_set_bbreg(hw, 0x64, BIT(24), 0x0);/* 0x66[8]=0 */
940 rtl_set_bbreg(hw, 0x40, BIT(4), 0x0)/* 0x40[4]=0 */;
941 rtl_set_bbreg(hw, 0x40, BIT(3), 0x1)/* 0x40[3]=1 */;
942 rtl_set_bbreg(hw, 0x4C, BIT(24) | BIT(23), 0x2)/* 0x4C[24:23]=10 */;
943 rtl_set_bbreg(hw, 0x944, BIT(1) | BIT(0), 0x3)/* 0x944[1:0]=11 */;
944 rtl_set_bbreg(hw, 0x930, MASKBYTE0, 0x77)/* 0x930[7:0]=77 */;
945 rtl_set_bbreg(hw, 0x38, BIT(11), 0x1)/* 0x38[11]=1 */;
Larry Fingera619d1a2014-02-28 15:16:50 -0600946
947 bytetmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
Larry Finger5c99f042014-09-26 16:40:25 -0500948 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, bytetmp & (~BIT(2)));
Larry Fingera619d1a2014-02-28 15:16:50 -0600949
Larry Finger5c99f042014-09-26 16:40:25 -0500950 _rtl8723be_gen_refresh_led_state(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -0600951 return true;
952}
953
954static void _rtl8723be_hw_configure(struct ieee80211_hw *hw)
955{
956 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500957 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
958 u32 reg_rrsr;
Larry Fingera619d1a2014-02-28 15:16:50 -0600959
Larry Finger5c99f042014-09-26 16:40:25 -0500960 reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
961 /* Init value for RRSR. */
962 rtl_write_dword(rtlpriv, REG_RRSR, reg_rrsr);
Larry Fingera619d1a2014-02-28 15:16:50 -0600963
Larry Finger5c99f042014-09-26 16:40:25 -0500964 /* ARFB table 9 for 11ac 5G 2SS */
965 rtl_write_dword(rtlpriv, REG_ARFR0 + 4, 0xfffff000);
966
967 /* ARFB table 10 for 11ac 5G 1SS */
968 rtl_write_dword(rtlpriv, REG_ARFR1 + 4, 0x003ff000);
969
970 /* CF-End setting. */
971 rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F00);
972
973 /* 0x456 = 0x70, sugguested by Zhilin */
974 rtl_write_byte(rtlpriv, REG_AMPDU_MAX_TIME, 0x70);
975
976 /* Set retry limit */
977 rtl_write_word(rtlpriv, REG_RL, 0x0707);
978
979 /* Set Data / Response auto rate fallack retry count */
980 rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000);
981 rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504);
982 rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000);
983 rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504);
984
985 rtlpci->reg_bcn_ctrl_val = 0x1d;
986 rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val);
987
988 /* TBTT prohibit hold time. Suggested by designer TimChen. */
989 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); /* 8 ms */
990
991 rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040);
992
993 /*For Rx TP. Suggested by SD1 Richard. Added by tynli. 2010.04.12.*/
994 rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666);
995
996 rtl_write_byte(rtlpriv, REG_HT_SINGLE_AMPDU, 0x80);
997
998 rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x20);
999
1000 rtl_write_byte(rtlpriv, REG_MAX_AGGR_NUM, 0x1F);
1001}
1002
1003static u8 _rtl8723be_dbi_read(struct rtl_priv *rtlpriv, u16 addr)
1004{
1005 u16 read_addr = addr & 0xfffc;
1006 u8 ret = 0, tmp = 0, count = 0;
1007
1008 rtl_write_word(rtlpriv, REG_DBI_ADDR, read_addr);
1009 rtl_write_byte(rtlpriv, REG_DBI_FLAG, 0x2);
1010 tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1011 count = 0;
1012 while (tmp && count < 20) {
1013 udelay(10);
1014 tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1015 count++;
1016 }
1017 if (0 == tmp) {
1018 read_addr = REG_DBI_RDATA + addr % 4;
1019 ret = rtl_read_byte(rtlpriv, read_addr);
1020 }
1021
1022 return ret;
1023}
1024
1025static void _rtl8723be_dbi_write(struct rtl_priv *rtlpriv, u16 addr, u8 data)
1026{
1027 u8 tmp = 0, count = 0;
1028 u16 write_addr = 0, remainder = addr % 4;
1029
1030 /* Write DBI 1Byte Data */
1031 write_addr = REG_DBI_WDATA + remainder;
1032 rtl_write_byte(rtlpriv, write_addr, data);
1033
1034 /* Write DBI 2Byte Address & Write Enable */
1035 write_addr = (addr & 0xfffc) | (BIT(0) << (remainder + 12));
1036 rtl_write_word(rtlpriv, REG_DBI_ADDR, write_addr);
1037
1038 /* Write DBI Write Flag */
1039 rtl_write_byte(rtlpriv, REG_DBI_FLAG, 0x1);
1040
1041 tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1042 count = 0;
1043 while (tmp && count < 20) {
1044 udelay(10);
1045 tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1046 count++;
1047 }
1048}
1049
1050static u16 _rtl8723be_mdio_read(struct rtl_priv *rtlpriv, u8 addr)
1051{
1052 u16 ret = 0;
1053 u8 tmp = 0, count = 0;
1054
1055 rtl_write_byte(rtlpriv, REG_MDIO_CTL, addr | BIT(6));
1056 tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(6);
1057 count = 0;
1058 while (tmp && count < 20) {
1059 udelay(10);
1060 tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(6);
1061 count++;
1062 }
1063
1064 if (0 == tmp)
1065 ret = rtl_read_word(rtlpriv, REG_MDIO_RDATA);
1066
1067 return ret;
1068}
1069
1070static void _rtl8723be_mdio_write(struct rtl_priv *rtlpriv, u8 addr, u16 data)
1071{
1072 u8 tmp = 0, count = 0;
1073
1074 rtl_write_word(rtlpriv, REG_MDIO_WDATA, data);
1075 rtl_write_byte(rtlpriv, REG_MDIO_CTL, addr | BIT(5));
1076 tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(5);
1077 count = 0;
1078 while (tmp && count < 20) {
1079 udelay(10);
1080 tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(5);
1081 count++;
1082 }
Larry Fingera619d1a2014-02-28 15:16:50 -06001083}
1084
1085static void _rtl8723be_enable_aspm_back_door(struct ieee80211_hw *hw)
1086{
1087 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -05001088 u8 tmp8 = 0;
1089 u16 tmp16 = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06001090
Larry Finger5c99f042014-09-26 16:40:25 -05001091 /* <Roger_Notes> Overwrite following ePHY parameter for
1092 * some platform compatibility issue,
1093 * especially when CLKReq is enabled, 2012.11.09.
1094 */
1095 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x01);
1096 if (tmp16 != 0x0663)
1097 _rtl8723be_mdio_write(rtlpriv, 0x01, 0x0663);
Larry Fingera619d1a2014-02-28 15:16:50 -06001098
Larry Finger5c99f042014-09-26 16:40:25 -05001099 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x04);
1100 if (tmp16 != 0x7544)
1101 _rtl8723be_mdio_write(rtlpriv, 0x04, 0x7544);
Larry Fingera619d1a2014-02-28 15:16:50 -06001102
Larry Finger5c99f042014-09-26 16:40:25 -05001103 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x06);
1104 if (tmp16 != 0xB880)
1105 _rtl8723be_mdio_write(rtlpriv, 0x06, 0xB880);
1106
1107 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x07);
1108 if (tmp16 != 0x4000)
1109 _rtl8723be_mdio_write(rtlpriv, 0x07, 0x4000);
1110
1111 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x08);
1112 if (tmp16 != 0x9003)
1113 _rtl8723be_mdio_write(rtlpriv, 0x08, 0x9003);
1114
1115 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x09);
1116 if (tmp16 != 0x0D03)
1117 _rtl8723be_mdio_write(rtlpriv, 0x09, 0x0D03);
1118
1119 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x0A);
1120 if (tmp16 != 0x4037)
1121 _rtl8723be_mdio_write(rtlpriv, 0x0A, 0x4037);
1122
1123 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x0B);
1124 if (tmp16 != 0x0070)
1125 _rtl8723be_mdio_write(rtlpriv, 0x0B, 0x0070);
1126
1127 /* Configuration Space offset 0x70f BIT7 is used to control L0S */
1128 tmp8 = _rtl8723be_dbi_read(rtlpriv, 0x70f);
1129 _rtl8723be_dbi_write(rtlpriv, 0x70f, tmp8 | BIT(7));
1130
1131 /* Configuration Space offset 0x719 Bit3 is for L1
1132 * BIT4 is for clock request
1133 */
1134 tmp8 = _rtl8723be_dbi_read(rtlpriv, 0x719);
1135 _rtl8723be_dbi_write(rtlpriv, 0x719, tmp8 | BIT(3) | BIT(4));
Larry Fingera619d1a2014-02-28 15:16:50 -06001136}
1137
1138void rtl8723be_enable_hw_security_config(struct ieee80211_hw *hw)
1139{
1140 struct rtl_priv *rtlpriv = rtl_priv(hw);
1141 u8 sec_reg_value;
1142
1143 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1144 "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
Larry Finger5c99f042014-09-26 16:40:25 -05001145 rtlpriv->sec.pairwise_enc_algorithm,
1146 rtlpriv->sec.group_enc_algorithm);
Larry Fingera619d1a2014-02-28 15:16:50 -06001147
1148 if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
1149 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1150 "not open hw encryption\n");
1151 return;
1152 }
Larry Finger5c99f042014-09-26 16:40:25 -05001153
Larry Fingera619d1a2014-02-28 15:16:50 -06001154 sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE;
1155
1156 if (rtlpriv->sec.use_defaultkey) {
1157 sec_reg_value |= SCR_TXUSEDK;
1158 sec_reg_value |= SCR_RXUSEDK;
1159 }
Larry Finger5c99f042014-09-26 16:40:25 -05001160
Larry Fingera619d1a2014-02-28 15:16:50 -06001161 sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
1162
1163 rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
1164
Larry Finger5c99f042014-09-26 16:40:25 -05001165 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1166 "The SECR-value %x\n", sec_reg_value);
Larry Fingera619d1a2014-02-28 15:16:50 -06001167
1168 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
1169}
1170
Larry Finger5c99f042014-09-26 16:40:25 -05001171static void _rtl8723be_poweroff_adapter(struct ieee80211_hw *hw)
1172{
1173 struct rtl_priv *rtlpriv = rtl_priv(hw);
1174 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1175 u8 u1b_tmp;
1176
1177 rtlhal->mac_func_enable = false;
1178 /* Combo (PCIe + USB) Card and PCIe-MF Card */
1179 /* 1. Run LPS WL RFOFF flow */
1180 rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1181 PWR_INTF_PCI_MSK, RTL8723_NIC_LPS_ENTER_FLOW);
1182
1183 /* 2. 0x1F[7:0] = 0 */
1184 /* turn off RF */
1185 /* rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); */
1186 if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) &&
1187 rtlhal->fw_ready) {
1188 rtl8723be_firmware_selfreset(hw);
1189 }
1190
1191 /* Reset MCU. Suggested by Filen. */
1192 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1193 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2))));
1194
1195 /* g. MCUFWDL 0x80[1:0]=0 */
1196 /* reset MCU ready status */
1197 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
1198
1199 /* HW card disable configuration. */
1200 rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1201 PWR_INTF_PCI_MSK, RTL8723_NIC_DISABLE_FLOW);
1202
1203 /* Reset MCU IO Wrapper */
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 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1207 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1b_tmp | BIT(0));
1208
1209 /* 7. RSV_CTRL 0x1C[7:0] = 0x0E */
1210 /* lock ISO/CLK/Power control register */
1211 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e);
1212}
1213
1214static bool _rtl8723be_check_pcie_dma_hang(struct rtl_priv *rtlpriv)
1215{
1216 u8 tmp;
1217
1218 /* write reg 0x350 Bit[26]=1. Enable debug port. */
1219 tmp = rtl_read_byte(rtlpriv, REG_DBI_CTRL + 3);
1220 if (!(tmp & BIT(2))) {
1221 rtl_write_byte(rtlpriv, REG_DBI_CTRL + 3, (tmp | BIT(2)));
1222 mdelay(100); /* Suggested by DD Justin_tsai. */
1223 }
1224
1225 /* read reg 0x350 Bit[25] if 1 : RX hang
1226 * read reg 0x350 Bit[24] if 1 : TX hang
1227 */
1228 tmp = rtl_read_byte(rtlpriv, REG_DBI_CTRL + 3);
1229 if ((tmp & BIT(0)) || (tmp & BIT(1))) {
1230 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1231 "CheckPcieDMAHang8723BE(): true!!\n");
1232 return true;
1233 }
1234 return false;
1235}
1236
1237static void _rtl8723be_reset_pcie_interface_dma(struct rtl_priv *rtlpriv,
1238 bool mac_power_on)
1239{
1240 u8 tmp;
1241 bool release_mac_rx_pause;
1242 u8 backup_pcie_dma_pause;
1243
1244 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1245 "ResetPcieInterfaceDMA8723BE()\n");
1246
1247 /* Revise Note: Follow the document "PCIe RX DMA Hang Reset Flow_v03"
1248 * released by SD1 Alan.
1249 * 2013.05.07, by tynli.
1250 */
1251
1252 /* 1. disable register write lock
1253 * write 0x1C bit[1:0] = 2'h0
1254 * write 0xCC bit[2] = 1'b1
1255 */
1256 tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL);
1257 tmp &= ~(BIT(1) | BIT(0));
1258 rtl_write_byte(rtlpriv, REG_RSV_CTRL, tmp);
1259 tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2);
1260 tmp |= BIT(2);
1261 rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp);
1262
1263 /* 2. Check and pause TRX DMA
1264 * write 0x284 bit[18] = 1'b1
1265 * write 0x301 = 0xFF
1266 */
1267 tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1268 if (tmp & BIT(2)) {
1269 /* Already pause before the function for another purpose. */
1270 release_mac_rx_pause = false;
1271 } else {
1272 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, (tmp | BIT(2)));
1273 release_mac_rx_pause = true;
1274 }
1275
1276 backup_pcie_dma_pause = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 1);
1277 if (backup_pcie_dma_pause != 0xFF)
1278 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xFF);
1279
1280 if (mac_power_on) {
1281 /* 3. reset TRX function
1282 * write 0x100 = 0x00
1283 */
1284 rtl_write_byte(rtlpriv, REG_CR, 0);
1285 }
1286
1287 /* 4. Reset PCIe DMA
1288 * write 0x003 bit[0] = 0
1289 */
1290 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1291 tmp &= ~(BIT(0));
1292 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp);
1293
1294 /* 5. Enable PCIe DMA
1295 * write 0x003 bit[0] = 1
1296 */
1297 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1298 tmp |= BIT(0);
1299 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp);
1300
1301 if (mac_power_on) {
1302 /* 6. enable TRX function
1303 * write 0x100 = 0xFF
1304 */
1305 rtl_write_byte(rtlpriv, REG_CR, 0xFF);
1306
1307 /* We should init LLT & RQPN and
1308 * prepare Tx/Rx descrptor address later
1309 * because MAC function is reset.
1310 */
1311 }
1312
1313 /* 7. Restore PCIe autoload down bit
1314 * write 0xF8 bit[17] = 1'b1
1315 */
1316 tmp = rtl_read_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2);
1317 tmp |= BIT(1);
1318 rtl_write_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2, tmp);
1319
1320 /* In MAC power on state, BB and RF maybe in ON state,
1321 * if we release TRx DMA here
1322 * it will cause packets to be started to Tx/Rx,
1323 * so we release Tx/Rx DMA later.
1324 */
1325 if (!mac_power_on) {
1326 /* 8. release TRX DMA
1327 * write 0x284 bit[18] = 1'b0
1328 * write 0x301 = 0x00
1329 */
1330 if (release_mac_rx_pause) {
1331 tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1332 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL,
1333 (tmp & (~BIT(2))));
1334 }
1335 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1,
1336 backup_pcie_dma_pause);
1337 }
1338
1339 /* 9. lock system register
1340 * write 0xCC bit[2] = 1'b0
1341 */
1342 tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2);
1343 tmp &= ~(BIT(2));
1344 rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp);
1345}
1346
Larry Fingera619d1a2014-02-28 15:16:50 -06001347int rtl8723be_hw_init(struct ieee80211_hw *hw)
1348{
1349 struct rtl_priv *rtlpriv = rtl_priv(hw);
1350 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1351 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1352 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1353 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1354 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1355 bool rtstatus = true;
1356 int err;
1357 u8 tmp_u1b;
1358 unsigned long flags;
1359
1360 /* reenable interrupts to not interfere with other devices */
1361 local_save_flags(flags);
1362 local_irq_enable();
1363
Larry Finger5c99f042014-09-26 16:40:25 -05001364 rtlhal->fw_ready = false;
Larry Fingera619d1a2014-02-28 15:16:50 -06001365 rtlpriv->rtlhal.being_init_adapter = true;
1366 rtlpriv->intf_ops->disable_aspm(hw);
Larry Finger5c99f042014-09-26 16:40:25 -05001367
1368 tmp_u1b = rtl_read_byte(rtlpriv, REG_CR);
1369 if (tmp_u1b != 0 && tmp_u1b != 0xea) {
1370 rtlhal->mac_func_enable = true;
1371 } else {
1372 rtlhal->mac_func_enable = false;
1373 rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON;
1374 }
1375
1376 if (_rtl8723be_check_pcie_dma_hang(rtlpriv)) {
1377 _rtl8723be_reset_pcie_interface_dma(rtlpriv,
1378 rtlhal->mac_func_enable);
1379 rtlhal->mac_func_enable = false;
1380 }
1381 if (rtlhal->mac_func_enable) {
1382 _rtl8723be_poweroff_adapter(hw);
1383 rtlhal->mac_func_enable = false;
1384 }
Larry Fingera619d1a2014-02-28 15:16:50 -06001385 rtstatus = _rtl8723be_init_mac(hw);
1386 if (!rtstatus) {
Larry Finger4e2b4372016-12-15 12:23:00 -06001387 pr_err("Init MAC failed\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06001388 err = 1;
1389 goto exit;
1390 }
Larry Fingera619d1a2014-02-28 15:16:50 -06001391
Larry Finger5c99f042014-09-26 16:40:25 -05001392 tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CFG);
1393 rtl_write_byte(rtlpriv, REG_SYS_CFG, tmp_u1b & 0x7F);
1394
1395 err = rtl8723_download_fw(hw, true, FW_8723B_POLLING_TIMEOUT_COUNT);
Larry Fingera619d1a2014-02-28 15:16:50 -06001396 if (err) {
1397 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1398 "Failed to download FW. Init HW without FW now..\n");
1399 err = 1;
Larry Fingera619d1a2014-02-28 15:16:50 -06001400 goto exit;
Larry Fingera619d1a2014-02-28 15:16:50 -06001401 }
Larry Finger5c99f042014-09-26 16:40:25 -05001402 rtlhal->fw_ready = true;
1403
Larry Fingera619d1a2014-02-28 15:16:50 -06001404 rtlhal->last_hmeboxnum = 0;
1405 rtl8723be_phy_mac_config(hw);
1406 /* because last function modify RCR, so we update
1407 * rcr var here, or TP will unstable for receive_config
Larry Finger5c99f042014-09-26 16:40:25 -05001408 * is wrong, RX RCR_ACRC32 will cause TP unstable & Rx
Larry Fingera619d1a2014-02-28 15:16:50 -06001409 * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252
1410 */
1411 rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR);
1412 rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
1413 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
1414
1415 rtl8723be_phy_bb_config(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -06001416 rtl8723be_phy_rf_config(hw);
1417
1418 rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
1419 RF_CHNLBW, RFREG_OFFSET_MASK);
1420 rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1,
1421 RF_CHNLBW, RFREG_OFFSET_MASK);
1422 rtlphy->rfreg_chnlval[0] &= 0xFFF03FF;
1423 rtlphy->rfreg_chnlval[0] |= (BIT(10) | BIT(11));
1424
Larry Fingera619d1a2014-02-28 15:16:50 -06001425 _rtl8723be_hw_configure(hw);
Larry Finger5c99f042014-09-26 16:40:25 -05001426 rtlhal->mac_func_enable = true;
Larry Fingera619d1a2014-02-28 15:16:50 -06001427 rtl_cam_reset_all_entry(hw);
1428 rtl8723be_enable_hw_security_config(hw);
1429
1430 ppsc->rfpwr_state = ERFON;
1431
1432 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
1433 _rtl8723be_enable_aspm_back_door(hw);
1434 rtlpriv->intf_ops->enable_aspm(hw);
1435
1436 rtl8723be_bt_hw_init(hw);
1437
Larry Fingera619d1a2014-02-28 15:16:50 -06001438 if (ppsc->rfpwr_state == ERFON) {
Larry Finger5c99f042014-09-26 16:40:25 -05001439 rtl8723be_phy_set_rfpath_switch(hw, 1);
1440 /* when use 1ant NIC, iqk will disturb BT music
1441 * root cause is not clear now, is something
1442 * related with 'mdelay' and Reg[0x948]
1443 */
1444 if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2 ||
1445 !rtlpriv->cfg->ops->get_btc_status()) {
Ping-Ke Shiha7088392017-06-21 12:15:32 -05001446 rtl8723be_phy_iq_calibrate(hw,
1447 (rtlphy->iqk_initialized ?
1448 true : false));
Larry Finger5c99f042014-09-26 16:40:25 -05001449 rtlphy->iqk_initialized = true;
1450 }
Larry Fingera619d1a2014-02-28 15:16:50 -06001451 rtl8723be_dm_check_txpower_tracking(hw);
1452 rtl8723be_phy_lc_calibrate(hw);
1453 }
Larry Finger5c99f042014-09-26 16:40:25 -05001454 rtl_write_byte(rtlpriv, REG_NAV_UPPER, ((30000 + 127) / 128));
1455
1456 /* Release Rx DMA. */
1457 tmp_u1b = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1458 if (tmp_u1b & BIT(2)) {
1459 /* Release Rx DMA if needed */
1460 tmp_u1b &= (~BIT(2));
1461 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, tmp_u1b);
Larry Fingera619d1a2014-02-28 15:16:50 -06001462 }
Larry Finger5c99f042014-09-26 16:40:25 -05001463 /* Release Tx/Rx PCIE DMA. */
1464 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0);
1465
Larry Fingera619d1a2014-02-28 15:16:50 -06001466 rtl8723be_dm_init(hw);
1467exit:
1468 local_irq_restore(flags);
1469 rtlpriv->rtlhal.being_init_adapter = false;
1470 return err;
1471}
1472
1473static enum version_8723e _rtl8723be_read_chip_version(struct ieee80211_hw *hw)
1474{
1475 struct rtl_priv *rtlpriv = rtl_priv(hw);
1476 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1477 enum version_8723e version = VERSION_UNKNOWN;
Larry Fingera619d1a2014-02-28 15:16:50 -06001478 u32 value32;
1479
Larry Fingera619d1a2014-02-28 15:16:50 -06001480 value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG1);
1481 if ((value32 & (CHIP_8723B)) != CHIP_8723B)
Masanari Iida8a190232016-06-29 12:37:19 +09001482 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "unknown chip version\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06001483 else
Larry Finger5c99f042014-09-26 16:40:25 -05001484 version = (enum version_8723e)CHIP_8723B;
Larry Fingera619d1a2014-02-28 15:16:50 -06001485
Larry Finger5c99f042014-09-26 16:40:25 -05001486 rtlphy->rf_type = RF_1T1R;
Larry Fingera619d1a2014-02-28 15:16:50 -06001487
Larry Finger5c99f042014-09-26 16:40:25 -05001488 /* treat rtl8723be chip as MP version in default */
1489 version = (enum version_8723e)(version | NORMAL_CHIP);
1490
1491 value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
1492 /* cut version */
1493 version |= (enum version_8723e)(value32 & CHIP_VER_RTL_MASK);
1494 /* Manufacture */
1495 if (((value32 & EXT_VENDOR_ID) >> 18) == 0x01)
1496 version = (enum version_8723e)(version | CHIP_VENDOR_SMIC);
1497
Larry Fingera619d1a2014-02-28 15:16:50 -06001498 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1499 "Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
Larry Finger5c99f042014-09-26 16:40:25 -05001500 "RF_2T2R" : "RF_1T1R");
Larry Fingera619d1a2014-02-28 15:16:50 -06001501
1502 return version;
1503}
1504
1505static int _rtl8723be_set_media_status(struct ieee80211_hw *hw,
1506 enum nl80211_iftype type)
1507{
1508 struct rtl_priv *rtlpriv = rtl_priv(hw);
1509 u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc;
1510 enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
Larry Finger5c99f042014-09-26 16:40:25 -05001511 u8 mode = MSR_NOLINK;
Larry Fingera619d1a2014-02-28 15:16:50 -06001512
Larry Fingera619d1a2014-02-28 15:16:50 -06001513 switch (type) {
1514 case NL80211_IFTYPE_UNSPECIFIED:
Larry Finger5c99f042014-09-26 16:40:25 -05001515 mode = MSR_NOLINK;
Larry Fingera619d1a2014-02-28 15:16:50 -06001516 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1517 "Set Network type to NO LINK!\n");
1518 break;
1519 case NL80211_IFTYPE_ADHOC:
Larry Finger5c99f042014-09-26 16:40:25 -05001520 case NL80211_IFTYPE_MESH_POINT:
1521 mode = MSR_ADHOC;
Larry Fingera619d1a2014-02-28 15:16:50 -06001522 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1523 "Set Network type to Ad Hoc!\n");
1524 break;
1525 case NL80211_IFTYPE_STATION:
Larry Finger5c99f042014-09-26 16:40:25 -05001526 mode = MSR_INFRA;
Larry Fingera619d1a2014-02-28 15:16:50 -06001527 ledaction = LED_CTL_LINK;
1528 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1529 "Set Network type to STA!\n");
1530 break;
1531 case NL80211_IFTYPE_AP:
Larry Finger5c99f042014-09-26 16:40:25 -05001532 mode = MSR_AP;
1533 ledaction = LED_CTL_LINK;
Larry Fingera619d1a2014-02-28 15:16:50 -06001534 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1535 "Set Network type to AP!\n");
1536 break;
1537 default:
Larry Finger4e2b4372016-12-15 12:23:00 -06001538 pr_err("Network type %d not support!\n", type);
Larry Fingera619d1a2014-02-28 15:16:50 -06001539 return 1;
1540 }
Larry Finger5c99f042014-09-26 16:40:25 -05001541
1542 /* MSR_INFRA == Link in infrastructure network;
1543 * MSR_ADHOC == Link in ad hoc network;
1544 * Therefore, check link state is necessary.
1545 *
1546 * MSR_AP == AP mode; link state is not cared here.
1547 */
1548 if (mode != MSR_AP && rtlpriv->mac80211.link_state < MAC80211_LINKED) {
1549 mode = MSR_NOLINK;
1550 ledaction = LED_CTL_NO_LINK;
1551 }
1552
1553 if (mode == MSR_NOLINK || mode == MSR_INFRA) {
1554 _rtl8723be_stop_tx_beacon(hw);
1555 _rtl8723be_enable_bcn_sub_func(hw);
1556 } else if (mode == MSR_ADHOC || mode == MSR_AP) {
1557 _rtl8723be_resume_tx_beacon(hw);
1558 _rtl8723be_disable_bcn_sub_func(hw);
1559 } else {
1560 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1561 "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n",
1562 mode);
1563 }
1564
Taehee Yooe480e132015-03-20 19:31:33 +09001565 rtl_write_byte(rtlpriv, MSR, bt_msr | mode);
Larry Fingera619d1a2014-02-28 15:16:50 -06001566 rtlpriv->cfg->ops->led_control(hw, ledaction);
Larry Finger5c99f042014-09-26 16:40:25 -05001567 if (mode == MSR_AP)
Larry Fingera619d1a2014-02-28 15:16:50 -06001568 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1569 else
1570 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
1571 return 0;
1572}
1573
1574void rtl8723be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1575{
1576 struct rtl_priv *rtlpriv = rtl_priv(hw);
1577 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1578 u32 reg_rcr = rtlpci->receive_config;
1579
1580 if (rtlpriv->psc.rfpwr_state != ERFON)
1581 return;
1582
1583 if (check_bssid) {
1584 reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1585 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1586 (u8 *)(&reg_rcr));
1587 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4));
1588 } else if (!check_bssid) {
1589 reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
1590 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0);
1591 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1592 (u8 *)(&reg_rcr));
1593 }
Larry Finger5c99f042014-09-26 16:40:25 -05001594
Larry Fingera619d1a2014-02-28 15:16:50 -06001595}
1596
1597int rtl8723be_set_network_type(struct ieee80211_hw *hw,
1598 enum nl80211_iftype type)
1599{
1600 struct rtl_priv *rtlpriv = rtl_priv(hw);
1601
1602 if (_rtl8723be_set_media_status(hw, type))
1603 return -EOPNOTSUPP;
1604
1605 if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
1606 if (type != NL80211_IFTYPE_AP)
1607 rtl8723be_set_check_bssid(hw, true);
1608 } else {
1609 rtl8723be_set_check_bssid(hw, false);
1610 }
Larry Finger5c99f042014-09-26 16:40:25 -05001611
Larry Fingera619d1a2014-02-28 15:16:50 -06001612 return 0;
1613}
1614
1615/* don't set REG_EDCA_BE_PARAM here
1616 * because mac80211 will send pkt when scan
1617 */
1618void rtl8723be_set_qos(struct ieee80211_hw *hw, int aci)
1619{
1620 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -05001621
Larry Fingera619d1a2014-02-28 15:16:50 -06001622 rtl8723_dm_init_edca_turbo(hw);
1623 switch (aci) {
1624 case AC1_BK:
1625 rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f);
1626 break;
1627 case AC0_BE:
1628 break;
1629 case AC2_VI:
1630 rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322);
1631 break;
1632 case AC3_VO:
1633 rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
1634 break;
1635 default:
Larry Finger531940f2016-12-15 12:22:57 -06001636 WARN_ONCE(true, "rtl8723be: invalid aci: %d !\n", aci);
Larry Fingera619d1a2014-02-28 15:16:50 -06001637 break;
1638 }
1639}
1640
1641void rtl8723be_enable_interrupt(struct ieee80211_hw *hw)
1642{
1643 struct rtl_priv *rtlpriv = rtl_priv(hw);
1644 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1645
1646 rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
1647 rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
1648 rtlpci->irq_enabled = true;
Larry Finger5c99f042014-09-26 16:40:25 -05001649
Larry Fingera619d1a2014-02-28 15:16:50 -06001650 /*enable system interrupt*/
1651 rtl_write_dword(rtlpriv, REG_HSIMR, rtlpci->sys_irq_mask & 0xFFFFFFFF);
1652}
1653
1654void rtl8723be_disable_interrupt(struct ieee80211_hw *hw)
1655{
1656 struct rtl_priv *rtlpriv = rtl_priv(hw);
1657 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1658
1659 rtl_write_dword(rtlpriv, REG_HIMR, IMR_DISABLED);
1660 rtl_write_dword(rtlpriv, REG_HIMRE, IMR_DISABLED);
1661 rtlpci->irq_enabled = false;
Larry Finger5c99f042014-09-26 16:40:25 -05001662 /*synchronize_irq(rtlpci->pdev->irq);*/
Larry Fingera619d1a2014-02-28 15:16:50 -06001663}
1664
1665void rtl8723be_card_disable(struct ieee80211_hw *hw)
1666{
1667 struct rtl_priv *rtlpriv = rtl_priv(hw);
1668 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1669 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1670 enum nl80211_iftype opmode;
1671
1672 mac->link_state = MAC80211_NOLINK;
1673 opmode = NL80211_IFTYPE_UNSPECIFIED;
1674 _rtl8723be_set_media_status(hw, opmode);
1675 if (rtlpriv->rtlhal.driver_is_goingto_unload ||
1676 ppsc->rfoff_reason > RF_CHANGE_BY_PS)
1677 rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
1678 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1679 _rtl8723be_poweroff_adapter(hw);
1680
1681 /* after power off we should do iqk again */
Ping-Ke Shiha7088392017-06-21 12:15:32 -05001682 if (!rtlpriv->cfg->ops->get_btc_status())
1683 rtlpriv->phy.iqk_initialized = false;
Larry Fingera619d1a2014-02-28 15:16:50 -06001684}
1685
1686void rtl8723be_interrupt_recognized(struct ieee80211_hw *hw,
1687 u32 *p_inta, u32 *p_intb)
1688{
1689 struct rtl_priv *rtlpriv = rtl_priv(hw);
1690 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1691
1692 *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0];
1693 rtl_write_dword(rtlpriv, ISR, *p_inta);
1694
1695 *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) &
1696 rtlpci->irq_mask[1];
1697 rtl_write_dword(rtlpriv, REG_HISRE, *p_intb);
1698}
1699
1700void rtl8723be_set_beacon_related_registers(struct ieee80211_hw *hw)
1701{
1702 struct rtl_priv *rtlpriv = rtl_priv(hw);
1703 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1704 u16 bcn_interval, atim_window;
1705
1706 bcn_interval = mac->beacon_interval;
1707 atim_window = 2; /*FIX MERGE */
1708 rtl8723be_disable_interrupt(hw);
1709 rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
1710 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1711 rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
1712 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18);
1713 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18);
1714 rtl_write_byte(rtlpriv, 0x606, 0x30);
1715 rtl8723be_enable_interrupt(hw);
1716}
1717
1718void rtl8723be_set_beacon_interval(struct ieee80211_hw *hw)
1719{
1720 struct rtl_priv *rtlpriv = rtl_priv(hw);
1721 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1722 u16 bcn_interval = mac->beacon_interval;
1723
1724 RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
1725 "beacon_interval:%d\n", bcn_interval);
1726 rtl8723be_disable_interrupt(hw);
1727 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1728 rtl8723be_enable_interrupt(hw);
1729}
1730
1731void rtl8723be_update_interrupt_mask(struct ieee80211_hw *hw,
1732 u32 add_msr, u32 rm_msr)
1733{
1734 struct rtl_priv *rtlpriv = rtl_priv(hw);
1735 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1736
1737 RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
1738 "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr);
1739
1740 if (add_msr)
1741 rtlpci->irq_mask[0] |= add_msr;
1742 if (rm_msr)
1743 rtlpci->irq_mask[0] &= (~rm_msr);
1744 rtl8723be_disable_interrupt(hw);
1745 rtl8723be_enable_interrupt(hw);
1746}
1747
1748static u8 _rtl8723be_get_chnl_group(u8 chnl)
1749{
1750 u8 group;
1751
1752 if (chnl < 3)
1753 group = 0;
1754 else if (chnl < 9)
1755 group = 1;
1756 else
1757 group = 2;
1758 return group;
1759}
1760
1761static void _rtl8723be_read_power_value_fromprom(struct ieee80211_hw *hw,
1762 struct txpower_info_2g *pw2g,
1763 struct txpower_info_5g *pw5g,
1764 bool autoload_fail, u8 *hwinfo)
1765{
1766 struct rtl_priv *rtlpriv = rtl_priv(hw);
1767 u32 path, addr = EEPROM_TX_PWR_INX, group, cnt = 0;
1768
1769 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Larry Finger5c99f042014-09-26 16:40:25 -05001770 "hal_ReadPowerValueFromPROM8723BE(): PROMContent[0x%x]=0x%x\n",
Larry Fingera619d1a2014-02-28 15:16:50 -06001771 (addr + 1), hwinfo[addr + 1]);
Larry Finger5c99f042014-09-26 16:40:25 -05001772 if (0xFF == hwinfo[addr + 1]) /*YJ,add,120316*/
Larry Fingera619d1a2014-02-28 15:16:50 -06001773 autoload_fail = true;
1774
1775 if (autoload_fail) {
1776 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1777 "auto load fail : Use Default value!\n");
1778 for (path = 0; path < MAX_RF_PATH; path++) {
1779 /* 2.4G default value */
Larry Finger5c99f042014-09-26 16:40:25 -05001780 for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) {
Larry Fingera619d1a2014-02-28 15:16:50 -06001781 pw2g->index_cck_base[path][group] = 0x2D;
1782 pw2g->index_bw40_base[path][group] = 0x2D;
1783 }
1784 for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1785 if (cnt == 0) {
1786 pw2g->bw20_diff[path][0] = 0x02;
1787 pw2g->ofdm_diff[path][0] = 0x04;
1788 } else {
1789 pw2g->bw20_diff[path][cnt] = 0xFE;
1790 pw2g->bw40_diff[path][cnt] = 0xFE;
1791 pw2g->cck_diff[path][cnt] = 0xFE;
1792 pw2g->ofdm_diff[path][cnt] = 0xFE;
1793 }
1794 }
1795 }
1796 return;
1797 }
Larry Finger5c99f042014-09-26 16:40:25 -05001798
Larry Fingera619d1a2014-02-28 15:16:50 -06001799 for (path = 0; path < MAX_RF_PATH; path++) {
1800 /*2.4G default value*/
1801 for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
1802 pw2g->index_cck_base[path][group] = hwinfo[addr++];
1803 if (pw2g->index_cck_base[path][group] == 0xFF)
1804 pw2g->index_cck_base[path][group] = 0x2D;
Larry Finger5c99f042014-09-26 16:40:25 -05001805
Larry Fingera619d1a2014-02-28 15:16:50 -06001806 }
1807 for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) {
1808 pw2g->index_bw40_base[path][group] = hwinfo[addr++];
1809 if (pw2g->index_bw40_base[path][group] == 0xFF)
1810 pw2g->index_bw40_base[path][group] = 0x2D;
1811 }
1812 for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1813 if (cnt == 0) {
1814 pw2g->bw40_diff[path][cnt] = 0;
1815 if (hwinfo[addr] == 0xFF) {
1816 pw2g->bw20_diff[path][cnt] = 0x02;
1817 } else {
1818 pw2g->bw20_diff[path][cnt] =
1819 (hwinfo[addr] & 0xf0) >> 4;
1820 /*bit sign number to 8 bit sign number*/
1821 if (pw2g->bw20_diff[path][cnt] & BIT(3))
Larry Finger5c99f042014-09-26 16:40:25 -05001822 pw2g->bw20_diff[path][cnt] |=
1823 0xF0;
Larry Fingera619d1a2014-02-28 15:16:50 -06001824 }
Larry Finger5c99f042014-09-26 16:40:25 -05001825
Larry Fingera619d1a2014-02-28 15:16:50 -06001826 if (hwinfo[addr] == 0xFF) {
1827 pw2g->ofdm_diff[path][cnt] = 0x04;
1828 } else {
1829 pw2g->ofdm_diff[path][cnt] =
1830 (hwinfo[addr] & 0x0f);
1831 /*bit sign number to 8 bit sign number*/
1832 if (pw2g->ofdm_diff[path][cnt] & BIT(3))
1833 pw2g->ofdm_diff[path][cnt] |=
1834 0xF0;
1835 }
1836 pw2g->cck_diff[path][cnt] = 0;
1837 addr++;
1838 } else {
1839 if (hwinfo[addr] == 0xFF) {
1840 pw2g->bw40_diff[path][cnt] = 0xFE;
1841 } else {
1842 pw2g->bw40_diff[path][cnt] =
1843 (hwinfo[addr] & 0xf0) >> 4;
1844 if (pw2g->bw40_diff[path][cnt] & BIT(3))
1845 pw2g->bw40_diff[path][cnt] |=
1846 0xF0;
1847 }
Larry Finger5c99f042014-09-26 16:40:25 -05001848
Larry Fingera619d1a2014-02-28 15:16:50 -06001849 if (hwinfo[addr] == 0xFF) {
1850 pw2g->bw20_diff[path][cnt] = 0xFE;
1851 } else {
1852 pw2g->bw20_diff[path][cnt] =
1853 (hwinfo[addr] & 0x0f);
1854 if (pw2g->bw20_diff[path][cnt] & BIT(3))
1855 pw2g->bw20_diff[path][cnt] |=
1856 0xF0;
1857 }
1858 addr++;
1859
1860 if (hwinfo[addr] == 0xFF) {
1861 pw2g->ofdm_diff[path][cnt] = 0xFE;
1862 } else {
1863 pw2g->ofdm_diff[path][cnt] =
1864 (hwinfo[addr] & 0xf0) >> 4;
1865 if (pw2g->ofdm_diff[path][cnt] & BIT(3))
1866 pw2g->ofdm_diff[path][cnt] |=
1867 0xF0;
1868 }
Larry Finger5c99f042014-09-26 16:40:25 -05001869
1870 if (hwinfo[addr] == 0xFF)
Larry Fingera619d1a2014-02-28 15:16:50 -06001871 pw2g->cck_diff[path][cnt] = 0xFE;
Larry Finger5c99f042014-09-26 16:40:25 -05001872 else {
Larry Fingera619d1a2014-02-28 15:16:50 -06001873 pw2g->cck_diff[path][cnt] =
1874 (hwinfo[addr] & 0x0f);
1875 if (pw2g->cck_diff[path][cnt] & BIT(3))
1876 pw2g->cck_diff[path][cnt] |=
1877 0xF0;
1878 }
1879 addr++;
1880 }
1881 }
Larry Finger5c99f042014-09-26 16:40:25 -05001882
Larry Fingera619d1a2014-02-28 15:16:50 -06001883 /*5G default value*/
1884 for (group = 0; group < MAX_CHNL_GROUP_5G; group++) {
1885 pw5g->index_bw40_base[path][group] = hwinfo[addr++];
1886 if (pw5g->index_bw40_base[path][group] == 0xFF)
1887 pw5g->index_bw40_base[path][group] = 0xFE;
1888 }
Larry Finger5c99f042014-09-26 16:40:25 -05001889
Larry Fingera619d1a2014-02-28 15:16:50 -06001890 for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1891 if (cnt == 0) {
1892 pw5g->bw40_diff[path][cnt] = 0;
1893
1894 if (hwinfo[addr] == 0xFF) {
1895 pw5g->bw20_diff[path][cnt] = 0;
1896 } else {
1897 pw5g->bw20_diff[path][0] =
1898 (hwinfo[addr] & 0xf0) >> 4;
1899 if (pw5g->bw20_diff[path][cnt] & BIT(3))
1900 pw5g->bw20_diff[path][cnt] |=
1901 0xF0;
1902 }
Larry Finger5c99f042014-09-26 16:40:25 -05001903
1904 if (hwinfo[addr] == 0xFF)
Larry Fingera619d1a2014-02-28 15:16:50 -06001905 pw5g->ofdm_diff[path][cnt] = 0x04;
Larry Finger5c99f042014-09-26 16:40:25 -05001906 else {
Larry Fingera619d1a2014-02-28 15:16:50 -06001907 pw5g->ofdm_diff[path][0] =
1908 (hwinfo[addr] & 0x0f);
1909 if (pw5g->ofdm_diff[path][cnt] & BIT(3))
1910 pw5g->ofdm_diff[path][cnt] |=
1911 0xF0;
1912 }
1913 addr++;
1914 } else {
1915 if (hwinfo[addr] == 0xFF) {
1916 pw5g->bw40_diff[path][cnt] = 0xFE;
1917 } else {
1918 pw5g->bw40_diff[path][cnt] =
1919 (hwinfo[addr] & 0xf0) >> 4;
1920 if (pw5g->bw40_diff[path][cnt] & BIT(3))
1921 pw5g->bw40_diff[path][cnt] |= 0xF0;
1922 }
Larry Finger5c99f042014-09-26 16:40:25 -05001923
Larry Fingera619d1a2014-02-28 15:16:50 -06001924 if (hwinfo[addr] == 0xFF) {
1925 pw5g->bw20_diff[path][cnt] = 0xFE;
1926 } else {
1927 pw5g->bw20_diff[path][cnt] =
1928 (hwinfo[addr] & 0x0f);
1929 if (pw5g->bw20_diff[path][cnt] & BIT(3))
1930 pw5g->bw20_diff[path][cnt] |= 0xF0;
1931 }
1932 addr++;
1933 }
1934 }
Larry Finger5c99f042014-09-26 16:40:25 -05001935
Larry Fingera619d1a2014-02-28 15:16:50 -06001936 if (hwinfo[addr] == 0xFF) {
1937 pw5g->ofdm_diff[path][1] = 0xFE;
1938 pw5g->ofdm_diff[path][2] = 0xFE;
1939 } else {
1940 pw5g->ofdm_diff[path][1] = (hwinfo[addr] & 0xf0) >> 4;
1941 pw5g->ofdm_diff[path][2] = (hwinfo[addr] & 0x0f);
1942 }
1943 addr++;
1944
1945 if (hwinfo[addr] == 0xFF)
1946 pw5g->ofdm_diff[path][3] = 0xFE;
1947 else
1948 pw5g->ofdm_diff[path][3] = (hwinfo[addr] & 0x0f);
1949 addr++;
1950
1951 for (cnt = 1; cnt < MAX_TX_COUNT; cnt++) {
1952 if (pw5g->ofdm_diff[path][cnt] == 0xFF)
1953 pw5g->ofdm_diff[path][cnt] = 0xFE;
1954 else if (pw5g->ofdm_diff[path][cnt] & BIT(3))
1955 pw5g->ofdm_diff[path][cnt] |= 0xF0;
1956 }
1957 }
1958}
1959
1960static void _rtl8723be_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1961 bool autoload_fail,
1962 u8 *hwinfo)
1963{
1964 struct rtl_priv *rtlpriv = rtl_priv(hw);
1965 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1966 struct txpower_info_2g pw2g;
1967 struct txpower_info_5g pw5g;
1968 u8 rf_path, index;
1969 u8 i;
1970
1971 _rtl8723be_read_power_value_fromprom(hw, &pw2g, &pw5g, autoload_fail,
1972 hwinfo);
1973
1974 for (rf_path = 0; rf_path < 2; rf_path++) {
1975 for (i = 0; i < 14; i++) {
1976 index = _rtl8723be_get_chnl_group(i+1);
1977
1978 rtlefuse->txpwrlevel_cck[rf_path][i] =
1979 pw2g.index_cck_base[rf_path][index];
1980 rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
1981 pw2g.index_bw40_base[rf_path][index];
1982 }
1983 for (i = 0; i < MAX_TX_COUNT; i++) {
1984 rtlefuse->txpwr_ht20diff[rf_path][i] =
1985 pw2g.bw20_diff[rf_path][i];
1986 rtlefuse->txpwr_ht40diff[rf_path][i] =
1987 pw2g.bw40_diff[rf_path][i];
1988 rtlefuse->txpwr_legacyhtdiff[rf_path][i] =
1989 pw2g.ofdm_diff[rf_path][i];
1990 }
Larry Finger5c99f042014-09-26 16:40:25 -05001991
Larry Fingera619d1a2014-02-28 15:16:50 -06001992 for (i = 0; i < 14; i++) {
Larry Finger5c99f042014-09-26 16:40:25 -05001993 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1994 "RF(%d)-Ch(%d) [CCK / HT40_1S ] = [0x%x / 0x%x ]\n",
1995 rf_path, i,
Larry Fingera619d1a2014-02-28 15:16:50 -06001996 rtlefuse->txpwrlevel_cck[rf_path][i],
1997 rtlefuse->txpwrlevel_ht40_1s[rf_path][i]);
1998 }
1999 }
Larry Finger5c99f042014-09-26 16:40:25 -05002000
Larry Fingera619d1a2014-02-28 15:16:50 -06002001 if (!autoload_fail)
2002 rtlefuse->eeprom_thermalmeter =
2003 hwinfo[EEPROM_THERMAL_METER_88E];
2004 else
2005 rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
2006
2007 if (rtlefuse->eeprom_thermalmeter == 0xff || autoload_fail) {
2008 rtlefuse->apk_thermalmeterignore = true;
2009 rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
2010 }
Larry Finger5c99f042014-09-26 16:40:25 -05002011
Larry Fingera619d1a2014-02-28 15:16:50 -06002012 rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
Larry Finger5c99f042014-09-26 16:40:25 -05002013 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
Larry Fingera619d1a2014-02-28 15:16:50 -06002014 "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
2015
2016 if (!autoload_fail) {
2017 rtlefuse->eeprom_regulatory =
2018 hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0x07;/*bit0~2*/
2019 if (hwinfo[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
2020 rtlefuse->eeprom_regulatory = 0;
2021 } else {
2022 rtlefuse->eeprom_regulatory = 0;
2023 }
Larry Finger5c99f042014-09-26 16:40:25 -05002024 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
Larry Fingera619d1a2014-02-28 15:16:50 -06002025 "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
2026}
2027
Ping-Ke Shih7fe1fe752017-02-06 21:30:05 -06002028static u8 _rtl8723be_read_package_type(struct ieee80211_hw *hw)
2029{
2030 u8 package_type;
2031 u8 value;
2032
2033 efuse_power_switch(hw, false, true);
2034 if (!efuse_one_byte_read(hw, 0x1FB, &value))
2035 value = 0;
2036 efuse_power_switch(hw, false, false);
2037
2038 switch (value & 0x7) {
2039 case 0x4:
2040 package_type = PACKAGE_TFBGA79;
2041 break;
2042 case 0x5:
2043 package_type = PACKAGE_TFBGA90;
2044 break;
2045 case 0x6:
2046 package_type = PACKAGE_QFN68;
2047 break;
2048 case 0x7:
2049 package_type = PACKAGE_TFBGA80;
2050 break;
2051 default:
2052 package_type = PACKAGE_DEFAULT;
2053 break;
2054 }
2055
2056 return package_type;
2057}
2058
Larry Fingera619d1a2014-02-28 15:16:50 -06002059static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw,
2060 bool pseudo_test)
2061{
2062 struct rtl_priv *rtlpriv = rtl_priv(hw);
2063 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2064 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
Larry Finger9e9c9c22016-07-05 10:08:12 -05002065 int params[] = {RTL8723BE_EEPROM_ID, EEPROM_VID, EEPROM_DID,
2066 EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR,
2067 EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID,
2068 COUNTRY_CODE_WORLD_WIDE_13};
2069 u8 *hwinfo;
2070 int i;
Larry Fingera619d1a2014-02-28 15:16:50 -06002071 bool is_toshiba_smid1 = false;
2072 bool is_toshiba_smid2 = false;
2073 bool is_samsung_smid = false;
2074 bool is_lenovo_smid = false;
2075 u16 toshiba_smid1[] = {
2076 0x6151, 0x6152, 0x6154, 0x6155, 0x6177, 0x6178, 0x6179, 0x6180,
2077 0x7151, 0x7152, 0x7154, 0x7155, 0x7177, 0x7178, 0x7179, 0x7180,
2078 0x8151, 0x8152, 0x8154, 0x8155, 0x8181, 0x8182, 0x8184, 0x8185,
2079 0x9151, 0x9152, 0x9154, 0x9155, 0x9181, 0x9182, 0x9184, 0x9185
2080 };
2081 u16 toshiba_smid2[] = {
2082 0x6181, 0x6184, 0x6185, 0x7181, 0x7182, 0x7184, 0x7185, 0x8181,
2083 0x8182, 0x8184, 0x8185, 0x9181, 0x9182, 0x9184, 0x9185
2084 };
2085 u16 samsung_smid[] = {
2086 0x6191, 0x6192, 0x6193, 0x7191, 0x7192, 0x7193, 0x8191, 0x8192,
2087 0x8193, 0x9191, 0x9192, 0x9193
2088 };
2089 u16 lenovo_smid[] = {
2090 0x8195, 0x9195, 0x7194, 0x8200, 0x8201, 0x8202, 0x9199, 0x9200
2091 };
2092
2093 if (pseudo_test) {
2094 /* needs to be added */
2095 return;
2096 }
Larry Fingera619d1a2014-02-28 15:16:50 -06002097
Larry Finger9e9c9c22016-07-05 10:08:12 -05002098 hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL);
2099 if (!hwinfo)
Arnd Bergmann5345ea62016-05-30 17:26:16 +02002100 return;
2101
Larry Finger9e9c9c22016-07-05 10:08:12 -05002102 if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params))
2103 goto exit;
Larry Fingera619d1a2014-02-28 15:16:50 -06002104
2105 /*parse xtal*/
2106 rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_8723BE];
2107 if (rtlefuse->crystalcap == 0xFF)
2108 rtlefuse->crystalcap = 0x20;
2109
2110 _rtl8723be_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag,
2111 hwinfo);
2112
2113 rtl8723be_read_bt_coexist_info_from_hwpg(hw,
2114 rtlefuse->autoload_failflag,
2115 hwinfo);
2116
Ping-Ke Shih7fe1fe752017-02-06 21:30:05 -06002117 rtlhal->package_type = _rtl8723be_read_package_type(hw);
2118
Shao Fub23cd222015-05-15 16:33:02 -05002119 /* set channel plan from efuse */
2120 rtlefuse->channel_plan = rtlefuse->eeprom_channelplan;
Larry Fingera619d1a2014-02-28 15:16:50 -06002121
2122 if (rtlhal->oem_id == RT_CID_DEFAULT) {
2123 /* Does this one have a Toshiba SMID from group 1? */
2124 for (i = 0; i < sizeof(toshiba_smid1) / sizeof(u16); i++) {
2125 if (rtlefuse->eeprom_smid == toshiba_smid1[i]) {
2126 is_toshiba_smid1 = true;
2127 break;
2128 }
2129 }
2130 /* Does this one have a Toshiba SMID from group 2? */
2131 for (i = 0; i < sizeof(toshiba_smid2) / sizeof(u16); i++) {
2132 if (rtlefuse->eeprom_smid == toshiba_smid2[i]) {
2133 is_toshiba_smid2 = true;
2134 break;
2135 }
2136 }
2137 /* Does this one have a Samsung SMID? */
2138 for (i = 0; i < sizeof(samsung_smid) / sizeof(u16); i++) {
2139 if (rtlefuse->eeprom_smid == samsung_smid[i]) {
2140 is_samsung_smid = true;
2141 break;
2142 }
2143 }
2144 /* Does this one have a Lenovo SMID? */
2145 for (i = 0; i < sizeof(lenovo_smid) / sizeof(u16); i++) {
2146 if (rtlefuse->eeprom_smid == lenovo_smid[i]) {
2147 is_lenovo_smid = true;
2148 break;
2149 }
2150 }
2151 switch (rtlefuse->eeprom_oemid) {
2152 case EEPROM_CID_DEFAULT:
2153 if (rtlefuse->eeprom_did == 0x8176) {
2154 if (rtlefuse->eeprom_svid == 0x10EC &&
2155 is_toshiba_smid1) {
2156 rtlhal->oem_id = RT_CID_TOSHIBA;
2157 } else if (rtlefuse->eeprom_svid == 0x1025) {
2158 rtlhal->oem_id = RT_CID_819X_ACER;
2159 } else if (rtlefuse->eeprom_svid == 0x10EC &&
2160 is_samsung_smid) {
2161 rtlhal->oem_id = RT_CID_819X_SAMSUNG;
2162 } else if (rtlefuse->eeprom_svid == 0x10EC &&
2163 is_lenovo_smid) {
2164 rtlhal->oem_id = RT_CID_819X_LENOVO;
2165 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
2166 rtlefuse->eeprom_smid == 0x8197) ||
2167 (rtlefuse->eeprom_svid == 0x10EC &&
2168 rtlefuse->eeprom_smid == 0x9196)) {
2169 rtlhal->oem_id = RT_CID_819X_CLEVO;
2170 } else if ((rtlefuse->eeprom_svid == 0x1028 &&
2171 rtlefuse->eeprom_smid == 0x8194) ||
2172 (rtlefuse->eeprom_svid == 0x1028 &&
2173 rtlefuse->eeprom_smid == 0x8198) ||
2174 (rtlefuse->eeprom_svid == 0x1028 &&
2175 rtlefuse->eeprom_smid == 0x9197) ||
2176 (rtlefuse->eeprom_svid == 0x1028 &&
2177 rtlefuse->eeprom_smid == 0x9198)) {
2178 rtlhal->oem_id = RT_CID_819X_DELL;
2179 } else if ((rtlefuse->eeprom_svid == 0x103C &&
2180 rtlefuse->eeprom_smid == 0x1629)) {
2181 rtlhal->oem_id = RT_CID_819X_HP;
2182 } else if ((rtlefuse->eeprom_svid == 0x1A32 &&
2183 rtlefuse->eeprom_smid == 0x2315)) {
2184 rtlhal->oem_id = RT_CID_819X_QMI;
2185 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
2186 rtlefuse->eeprom_smid == 0x8203)) {
2187 rtlhal->oem_id = RT_CID_819X_PRONETS;
2188 } else if ((rtlefuse->eeprom_svid == 0x1043 &&
2189 rtlefuse->eeprom_smid == 0x84B5)) {
2190 rtlhal->oem_id = RT_CID_819X_EDIMAX_ASUS;
2191 } else {
2192 rtlhal->oem_id = RT_CID_DEFAULT;
2193 }
2194 } else if (rtlefuse->eeprom_did == 0x8178) {
2195 if (rtlefuse->eeprom_svid == 0x10EC &&
2196 is_toshiba_smid2)
2197 rtlhal->oem_id = RT_CID_TOSHIBA;
2198 else if (rtlefuse->eeprom_svid == 0x1025)
2199 rtlhal->oem_id = RT_CID_819X_ACER;
2200 else if ((rtlefuse->eeprom_svid == 0x10EC &&
2201 rtlefuse->eeprom_smid == 0x8186))
2202 rtlhal->oem_id = RT_CID_819X_PRONETS;
2203 else if ((rtlefuse->eeprom_svid == 0x1043 &&
2204 rtlefuse->eeprom_smid == 0x84B6))
2205 rtlhal->oem_id =
2206 RT_CID_819X_EDIMAX_ASUS;
2207 else
2208 rtlhal->oem_id = RT_CID_DEFAULT;
2209 } else {
2210 rtlhal->oem_id = RT_CID_DEFAULT;
2211 }
2212 break;
2213 case EEPROM_CID_TOSHIBA:
2214 rtlhal->oem_id = RT_CID_TOSHIBA;
2215 break;
2216 case EEPROM_CID_CCX:
2217 rtlhal->oem_id = RT_CID_CCX;
2218 break;
2219 case EEPROM_CID_QMI:
2220 rtlhal->oem_id = RT_CID_819X_QMI;
2221 break;
2222 case EEPROM_CID_WHQL:
2223 break;
2224 default:
2225 rtlhal->oem_id = RT_CID_DEFAULT;
2226 break;
2227 }
2228 }
Larry Finger9e9c9c22016-07-05 10:08:12 -05002229exit:
2230 kfree(hwinfo);
Larry Fingera619d1a2014-02-28 15:16:50 -06002231}
2232
2233static void _rtl8723be_hal_customized_behavior(struct ieee80211_hw *hw)
2234{
2235 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -06002236 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2237
Larry Fingerd5efe152017-02-07 09:14:21 -06002238 rtlpriv->ledctl.led_opendrain = true;
Larry Fingera619d1a2014-02-28 15:16:50 -06002239 switch (rtlhal->oem_id) {
2240 case RT_CID_819X_HP:
Larry Fingerd5efe152017-02-07 09:14:21 -06002241 rtlpriv->ledctl.led_opendrain = true;
Larry Fingera619d1a2014-02-28 15:16:50 -06002242 break;
2243 case RT_CID_819X_LENOVO:
2244 case RT_CID_DEFAULT:
2245 case RT_CID_TOSHIBA:
2246 case RT_CID_CCX:
2247 case RT_CID_819X_ACER:
2248 case RT_CID_WHQL:
2249 default:
2250 break;
2251 }
2252 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2253 "RT Customized ID: 0x%02X\n", rtlhal->oem_id);
2254}
2255
2256void rtl8723be_read_eeprom_info(struct ieee80211_hw *hw)
2257{
2258 struct rtl_priv *rtlpriv = rtl_priv(hw);
2259 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2260 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2261 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2262 u8 tmp_u1b;
2263
2264 rtlhal->version = _rtl8723be_read_chip_version(hw);
2265 if (get_rf_type(rtlphy) == RF_1T1R)
2266 rtlpriv->dm.rfpath_rxenable[0] = true;
2267 else
2268 rtlpriv->dm.rfpath_rxenable[0] =
2269 rtlpriv->dm.rfpath_rxenable[1] = true;
2270 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
2271 rtlhal->version);
2272 tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
2273 if (tmp_u1b & BIT(4)) {
2274 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
2275 rtlefuse->epromtype = EEPROM_93C46;
2276 } else {
2277 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
2278 rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
2279 }
2280 if (tmp_u1b & BIT(5)) {
2281 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
2282 rtlefuse->autoload_failflag = false;
2283 _rtl8723be_read_adapter_info(hw, false);
2284 } else {
Larry Finger4e2b4372016-12-15 12:23:00 -06002285 pr_err("Autoload ERR!!\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06002286 }
2287 _rtl8723be_hal_customized_behavior(hw);
2288}
2289
Larry Fingera619d1a2014-02-28 15:16:50 -06002290static u8 _rtl8723be_mrate_idx_to_arfr_id(struct ieee80211_hw *hw,
2291 u8 rate_index)
2292{
2293 u8 ret = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002294 switch (rate_index) {
2295 case RATR_INX_WIRELESS_NGB:
2296 ret = 1;
2297 break;
2298 case RATR_INX_WIRELESS_N:
2299 case RATR_INX_WIRELESS_NG:
2300 ret = 5;
2301 break;
2302 case RATR_INX_WIRELESS_NB:
2303 ret = 3;
2304 break;
2305 case RATR_INX_WIRELESS_GB:
2306 ret = 6;
2307 break;
2308 case RATR_INX_WIRELESS_G:
2309 ret = 7;
2310 break;
2311 case RATR_INX_WIRELESS_B:
2312 ret = 8;
2313 break;
2314 default:
2315 ret = 0;
2316 break;
2317 }
2318 return ret;
2319}
2320
2321static void rtl8723be_update_hal_rate_mask(struct ieee80211_hw *hw,
2322 struct ieee80211_sta *sta,
2323 u8 rssi_level)
2324{
2325 struct rtl_priv *rtlpriv = rtl_priv(hw);
2326 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2327 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2328 struct rtl_sta_info *sta_entry = NULL;
2329 u32 ratr_bitmap;
2330 u8 ratr_index;
2331 u8 curtxbw_40mhz = (sta->ht_cap.cap &
Larry Finger5c99f042014-09-26 16:40:25 -05002332 IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002333 u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
Larry Finger5c99f042014-09-26 16:40:25 -05002334 1 : 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002335 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
Larry Finger5c99f042014-09-26 16:40:25 -05002336 1 : 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002337 enum wireless_mode wirelessmode = 0;
2338 bool shortgi = false;
2339 u8 rate_mask[7];
2340 u8 macid = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002341
2342 sta_entry = (struct rtl_sta_info *)sta->drv_priv;
2343 wirelessmode = sta_entry->wireless_mode;
2344 if (mac->opmode == NL80211_IFTYPE_STATION ||
2345 mac->opmode == NL80211_IFTYPE_MESH_POINT)
2346 curtxbw_40mhz = mac->bw_40;
2347 else if (mac->opmode == NL80211_IFTYPE_AP ||
2348 mac->opmode == NL80211_IFTYPE_ADHOC)
2349 macid = sta->aid + 1;
2350
2351 ratr_bitmap = sta->supp_rates[0];
2352
2353 if (mac->opmode == NL80211_IFTYPE_ADHOC)
2354 ratr_bitmap = 0xfff;
2355
2356 ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
2357 sta->ht_cap.mcs.rx_mask[0] << 12);
2358 switch (wirelessmode) {
2359 case WIRELESS_MODE_B:
2360 ratr_index = RATR_INX_WIRELESS_B;
2361 if (ratr_bitmap & 0x0000000c)
2362 ratr_bitmap &= 0x0000000d;
2363 else
2364 ratr_bitmap &= 0x0000000f;
2365 break;
2366 case WIRELESS_MODE_G:
2367 ratr_index = RATR_INX_WIRELESS_GB;
2368
2369 if (rssi_level == 1)
2370 ratr_bitmap &= 0x00000f00;
2371 else if (rssi_level == 2)
2372 ratr_bitmap &= 0x00000ff0;
2373 else
2374 ratr_bitmap &= 0x00000ff5;
2375 break;
Larry Fingera619d1a2014-02-28 15:16:50 -06002376 case WIRELESS_MODE_N_24G:
2377 case WIRELESS_MODE_N_5G:
2378 ratr_index = RATR_INX_WIRELESS_NGB;
Larry Finger5c99f042014-09-26 16:40:25 -05002379 if (rtlphy->rf_type == RF_1T1R) {
2380 if (curtxbw_40mhz) {
2381 if (rssi_level == 1)
2382 ratr_bitmap &= 0x000f0000;
2383 else if (rssi_level == 2)
2384 ratr_bitmap &= 0x000ff000;
2385 else
2386 ratr_bitmap &= 0x000ff015;
Larry Fingera619d1a2014-02-28 15:16:50 -06002387 } else {
Larry Finger5c99f042014-09-26 16:40:25 -05002388 if (rssi_level == 1)
2389 ratr_bitmap &= 0x000f0000;
2390 else if (rssi_level == 2)
2391 ratr_bitmap &= 0x000ff000;
2392 else
2393 ratr_bitmap &= 0x000ff005;
2394 }
2395 } else {
2396 if (curtxbw_40mhz) {
2397 if (rssi_level == 1)
2398 ratr_bitmap &= 0x0f8f0000;
2399 else if (rssi_level == 2)
2400 ratr_bitmap &= 0x0f8ff000;
2401 else
2402 ratr_bitmap &= 0x0f8ff015;
2403 } else {
2404 if (rssi_level == 1)
2405 ratr_bitmap &= 0x0f8f0000;
2406 else if (rssi_level == 2)
2407 ratr_bitmap &= 0x0f8ff000;
2408 else
2409 ratr_bitmap &= 0x0f8ff005;
Larry Fingera619d1a2014-02-28 15:16:50 -06002410 }
2411 }
2412 if ((curtxbw_40mhz && curshortgi_40mhz) ||
2413 (!curtxbw_40mhz && curshortgi_20mhz)) {
2414 if (macid == 0)
2415 shortgi = true;
2416 else if (macid == 1)
2417 shortgi = false;
2418 }
2419 break;
2420 default:
2421 ratr_index = RATR_INX_WIRELESS_NGB;
2422
2423 if (rtlphy->rf_type == RF_1T2R)
2424 ratr_bitmap &= 0x000ff0ff;
2425 else
2426 ratr_bitmap &= 0x0f0ff0ff;
2427 break;
2428 }
Larry Finger5c99f042014-09-26 16:40:25 -05002429
Larry Fingera619d1a2014-02-28 15:16:50 -06002430 sta_entry->ratr_index = ratr_index;
2431
2432 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2433 "ratr_bitmap :%x\n", ratr_bitmap);
Larry Finger5c99f042014-09-26 16:40:25 -05002434 *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
2435 (ratr_index << 28);
Larry Fingera619d1a2014-02-28 15:16:50 -06002436 rate_mask[0] = macid;
2437 rate_mask[1] = _rtl8723be_mrate_idx_to_arfr_id(hw, ratr_index) |
Larry Finger5c99f042014-09-26 16:40:25 -05002438 (shortgi ? 0x80 : 0x00);
Larry Fingera619d1a2014-02-28 15:16:50 -06002439 rate_mask[2] = curtxbw_40mhz;
Larry Fingera619d1a2014-02-28 15:16:50 -06002440
2441 rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff);
2442 rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >> 8);
2443 rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16);
2444 rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24);
2445
2446 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2447 "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x:%x:%x\n",
2448 ratr_index, ratr_bitmap,
2449 rate_mask[0], rate_mask[1],
2450 rate_mask[2], rate_mask[3],
2451 rate_mask[4], rate_mask[5],
2452 rate_mask[6]);
Larry Finger5c99f042014-09-26 16:40:25 -05002453 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_RA_MASK, 7, rate_mask);
Larry Fingera619d1a2014-02-28 15:16:50 -06002454 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
2455}
2456
2457void rtl8723be_update_hal_rate_tbl(struct ieee80211_hw *hw,
2458 struct ieee80211_sta *sta,
2459 u8 rssi_level)
2460{
2461 struct rtl_priv *rtlpriv = rtl_priv(hw);
2462 if (rtlpriv->dm.useramask)
2463 rtl8723be_update_hal_rate_mask(hw, sta, rssi_level);
Larry Fingera619d1a2014-02-28 15:16:50 -06002464}
2465
2466void rtl8723be_update_channel_access_setting(struct ieee80211_hw *hw)
2467{
2468 struct rtl_priv *rtlpriv = rtl_priv(hw);
2469 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2470 u16 sifs_timer;
2471
Joe Perches9cb76aa2014-03-24 10:46:20 -07002472 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);
Larry Fingera619d1a2014-02-28 15:16:50 -06002473 if (!mac->ht_enable)
2474 sifs_timer = 0x0a0a;
2475 else
2476 sifs_timer = 0x0e0e;
2477 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
2478}
2479
2480bool rtl8723be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
2481{
2482 struct rtl_priv *rtlpriv = rtl_priv(hw);
2483 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2484 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2485 enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate;
2486 u8 u1tmp;
Larry Finger5c99f042014-09-26 16:40:25 -05002487 bool b_actuallyset = false;
Larry Fingera619d1a2014-02-28 15:16:50 -06002488
2489 if (rtlpriv->rtlhal.being_init_adapter)
2490 return false;
2491
2492 if (ppsc->swrf_processing)
2493 return false;
2494
2495 spin_lock(&rtlpriv->locks.rf_ps_lock);
2496 if (ppsc->rfchange_inprogress) {
2497 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2498 return false;
2499 } else {
2500 ppsc->rfchange_inprogress = true;
2501 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2502 }
Larry Finger5c99f042014-09-26 16:40:25 -05002503
Larry Fingera619d1a2014-02-28 15:16:50 -06002504 cur_rfstate = ppsc->rfpwr_state;
2505
2506 rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2,
2507 rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2) & ~(BIT(1)));
2508
2509 u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2);
2510
2511 if (rtlphy->polarity_ctl)
2512 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON;
2513 else
2514 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF;
2515
Larry Finger5c99f042014-09-26 16:40:25 -05002516 if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002517 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2518 "GPIOChangeRF - HW Radio ON, RF ON\n");
2519
2520 e_rfpowerstate_toset = ERFON;
2521 ppsc->hwradiooff = false;
Larry Finger5c99f042014-09-26 16:40:25 -05002522 b_actuallyset = true;
2523 } else if (!ppsc->hwradiooff && (e_rfpowerstate_toset == ERFOFF)) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002524 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2525 "GPIOChangeRF - HW Radio OFF, RF OFF\n");
2526
2527 e_rfpowerstate_toset = ERFOFF;
2528 ppsc->hwradiooff = true;
Larry Finger5c99f042014-09-26 16:40:25 -05002529 b_actuallyset = true;
Larry Fingera619d1a2014-02-28 15:16:50 -06002530 }
Larry Finger5c99f042014-09-26 16:40:25 -05002531
2532 if (b_actuallyset) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002533 spin_lock(&rtlpriv->locks.rf_ps_lock);
2534 ppsc->rfchange_inprogress = false;
2535 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2536 } else {
2537 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
2538 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2539
2540 spin_lock(&rtlpriv->locks.rf_ps_lock);
2541 ppsc->rfchange_inprogress = false;
2542 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2543 }
Larry Finger5c99f042014-09-26 16:40:25 -05002544
Larry Fingera619d1a2014-02-28 15:16:50 -06002545 *valid = 1;
2546 return !ppsc->hwradiooff;
Larry Finger5c99f042014-09-26 16:40:25 -05002547
Larry Fingera619d1a2014-02-28 15:16:50 -06002548}
2549
2550void rtl8723be_set_key(struct ieee80211_hw *hw, u32 key_index,
2551 u8 *p_macaddr, bool is_group, u8 enc_algo,
2552 bool is_wepkey, bool clear_all)
2553{
2554 struct rtl_priv *rtlpriv = rtl_priv(hw);
2555 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2556 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2557 u8 *macaddr = p_macaddr;
2558 u32 entry_id = 0;
2559 bool is_pairwise = false;
2560
2561 static u8 cam_const_addr[4][6] = {
2562 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
2563 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
2564 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
2565 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
2566 };
2567 static u8 cam_const_broad[] = {
2568 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2569 };
2570
2571 if (clear_all) {
2572 u8 idx = 0;
2573 u8 cam_offset = 0;
2574 u8 clear_number = 5;
2575
2576 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
2577
2578 for (idx = 0; idx < clear_number; idx++) {
2579 rtl_cam_mark_invalid(hw, cam_offset + idx);
2580 rtl_cam_empty_entry(hw, cam_offset + idx);
2581
2582 if (idx < 5) {
2583 memset(rtlpriv->sec.key_buf[idx], 0,
2584 MAX_KEY_LEN);
2585 rtlpriv->sec.key_len[idx] = 0;
2586 }
2587 }
Larry Finger5c99f042014-09-26 16:40:25 -05002588
Larry Fingera619d1a2014-02-28 15:16:50 -06002589 } else {
2590 switch (enc_algo) {
2591 case WEP40_ENCRYPTION:
2592 enc_algo = CAM_WEP40;
2593 break;
2594 case WEP104_ENCRYPTION:
2595 enc_algo = CAM_WEP104;
2596 break;
2597 case TKIP_ENCRYPTION:
2598 enc_algo = CAM_TKIP;
2599 break;
2600 case AESCCMP_ENCRYPTION:
2601 enc_algo = CAM_AES;
2602 break;
2603 default:
Larry Finger5c99f042014-09-26 16:40:25 -05002604 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -07002605 "switch case %#x not processed\n", enc_algo);
Larry Fingera619d1a2014-02-28 15:16:50 -06002606 enc_algo = CAM_TKIP;
2607 break;
2608 }
2609
2610 if (is_wepkey || rtlpriv->sec.use_defaultkey) {
2611 macaddr = cam_const_addr[key_index];
2612 entry_id = key_index;
2613 } else {
2614 if (is_group) {
2615 macaddr = cam_const_broad;
2616 entry_id = key_index;
2617 } else {
2618 if (mac->opmode == NL80211_IFTYPE_AP) {
2619 entry_id = rtl_cam_get_free_entry(hw,
2620 p_macaddr);
2621 if (entry_id >= TOTAL_CAM_ENTRY) {
Larry Finger4e2b4372016-12-15 12:23:00 -06002622 pr_err("Can not find free hw security cam entry\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06002623 return;
2624 }
2625 } else {
2626 entry_id = CAM_PAIRWISE_KEY_POSITION;
2627 }
Larry Finger5c99f042014-09-26 16:40:25 -05002628
Larry Fingera619d1a2014-02-28 15:16:50 -06002629 key_index = PAIRWISE_KEYIDX;
2630 is_pairwise = true;
2631 }
2632 }
Larry Finger5c99f042014-09-26 16:40:25 -05002633
Larry Fingera619d1a2014-02-28 15:16:50 -06002634 if (rtlpriv->sec.key_len[key_index] == 0) {
2635 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2636 "delete one entry, entry_id is %d\n",
Larry Finger5c99f042014-09-26 16:40:25 -05002637 entry_id);
Larry Fingera619d1a2014-02-28 15:16:50 -06002638 if (mac->opmode == NL80211_IFTYPE_AP)
2639 rtl_cam_del_entry(hw, p_macaddr);
2640 rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
2641 } else {
2642 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2643 "add one entry\n");
2644 if (is_pairwise) {
2645 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
Colin Ian King6b9e6f62017-05-03 23:55:43 +01002646 "set Pairwise key\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06002647
2648 rtl_cam_add_one_entry(hw, macaddr, key_index,
Larry Finger5c99f042014-09-26 16:40:25 -05002649 entry_id, enc_algo,
2650 CAM_CONFIG_NO_USEDK,
2651 rtlpriv->sec.key_buf[key_index]);
Larry Fingera619d1a2014-02-28 15:16:50 -06002652 } else {
2653 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2654 "set group key\n");
2655
2656 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
2657 rtl_cam_add_one_entry(hw,
2658 rtlefuse->dev_addr,
2659 PAIRWISE_KEYIDX,
2660 CAM_PAIRWISE_KEY_POSITION,
2661 enc_algo,
2662 CAM_CONFIG_NO_USEDK,
2663 rtlpriv->sec.key_buf
2664 [entry_id]);
2665 }
Larry Finger5c99f042014-09-26 16:40:25 -05002666
Larry Fingera619d1a2014-02-28 15:16:50 -06002667 rtl_cam_add_one_entry(hw, macaddr, key_index,
Larry Finger5c99f042014-09-26 16:40:25 -05002668 entry_id, enc_algo,
2669 CAM_CONFIG_NO_USEDK,
2670 rtlpriv->sec.key_buf[entry_id]);
Larry Fingera619d1a2014-02-28 15:16:50 -06002671 }
2672 }
2673 }
2674}
2675
2676void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
2677 bool auto_load_fail, u8 *hwinfo)
2678{
2679 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Fingerc18d8f52016-03-16 13:33:34 -05002680 struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params;
Larry Fingera619d1a2014-02-28 15:16:50 -06002681 u8 value;
2682 u32 tmpu_32;
2683
2684 if (!auto_load_fail) {
2685 tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL);
2686 if (tmpu_32 & BIT(18))
2687 rtlpriv->btcoexist.btc_info.btcoexist = 1;
2688 else
2689 rtlpriv->btcoexist.btc_info.btcoexist = 0;
Larry Finger5c99f042014-09-26 16:40:25 -05002690 value = hwinfo[EEPROM_RF_BT_SETTING_8723B];
Larry Fingera619d1a2014-02-28 15:16:50 -06002691 rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2692 rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1);
Ping-Ke Shih0de9b5d2017-02-06 21:30:04 -06002693 rtlpriv->btcoexist.btc_info.single_ant_path =
2694 (value & 0x40); /*0xc3[6]*/
Larry Fingera619d1a2014-02-28 15:16:50 -06002695 } else {
2696 rtlpriv->btcoexist.btc_info.btcoexist = 0;
2697 rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2698 rtlpriv->btcoexist.btc_info.ant_num = ANT_X2;
Ping-Ke Shihdb8cb002017-02-06 21:30:03 -06002699 rtlpriv->btcoexist.btc_info.single_ant_path = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002700 }
Larry Finger5c99f042014-09-26 16:40:25 -05002701
Larry Fingerc18d8f52016-03-16 13:33:34 -05002702 /* override ant_num / ant_path */
Ping-Ke Shih0ff78ad2017-02-06 21:30:07 -06002703 if (mod_params->ant_sel) {
Larry Fingerc18d8f52016-03-16 13:33:34 -05002704 rtlpriv->btcoexist.btc_info.ant_num =
2705 (mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1);
Ping-Ke Shih0ff78ad2017-02-06 21:30:07 -06002706
2707 rtlpriv->btcoexist.btc_info.single_ant_path =
2708 (mod_params->ant_sel == 1 ? 0 : 1);
2709 }
Larry Fingera619d1a2014-02-28 15:16:50 -06002710}
2711
2712void rtl8723be_bt_reg_init(struct ieee80211_hw *hw)
2713{
2714 struct rtl_priv *rtlpriv = rtl_priv(hw);
2715
2716 /* 0:Low, 1:High, 2:From Efuse. */
2717 rtlpriv->btcoexist.reg_bt_iso = 2;
2718 /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */
2719 rtlpriv->btcoexist.reg_bt_sco = 3;
2720 /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
2721 rtlpriv->btcoexist.reg_bt_sco = 0;
2722}
2723
2724void rtl8723be_bt_hw_init(struct ieee80211_hw *hw)
2725{
2726 struct rtl_priv *rtlpriv = rtl_priv(hw);
2727
2728 if (rtlpriv->cfg->ops->get_btc_status())
2729 rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv);
Larry Finger5c99f042014-09-26 16:40:25 -05002730
Larry Fingera619d1a2014-02-28 15:16:50 -06002731}
2732
2733void rtl8723be_suspend(struct ieee80211_hw *hw)
2734{
2735}
2736
2737void rtl8723be_resume(struct ieee80211_hw *hw)
2738{
2739}