blob: e7bbbc95cdb1f6ef5611c93f4bf97e269624bdc3 [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"
Jérémy Lefaure53ac7932017-11-13 22:19:41 -050046#include <linux/kernel.h>
Larry Fingera619d1a2014-02-28 15:16:50 -060047
48#define LLT_CONFIG 5
49
50static void _rtl8723be_return_beacon_queue_skb(struct ieee80211_hw *hw)
51{
52 struct rtl_priv *rtlpriv = rtl_priv(hw);
53 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
54 struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
Larry Finger5c99f042014-09-26 16:40:25 -050055 unsigned long flags;
Larry Fingera619d1a2014-02-28 15:16:50 -060056
Larry Finger5c99f042014-09-26 16:40:25 -050057 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
Larry Fingera619d1a2014-02-28 15:16:50 -060058 while (skb_queue_len(&ring->queue)) {
59 struct rtl_tx_desc *entry = &ring->desc[ring->idx];
60 struct sk_buff *skb = __skb_dequeue(&ring->queue);
61
62 pci_unmap_single(rtlpci->pdev,
63 rtlpriv->cfg->ops->get_desc(
Ping-Ke Shih0c07bd72017-09-29 14:47:53 -050064 hw,
Larry Fingera619d1a2014-02-28 15:16:50 -060065 (u8 *)entry, true, HW_DESC_TXBUFF_ADDR),
66 skb->len, PCI_DMA_TODEVICE);
67 kfree_skb(skb);
68 ring->idx = (ring->idx + 1) % ring->entries;
69 }
Larry Finger5c99f042014-09-26 16:40:25 -050070 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
Larry Fingera619d1a2014-02-28 15:16:50 -060071}
72
73static void _rtl8723be_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
74 u8 set_bits, u8 clear_bits)
75{
76 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
77 struct rtl_priv *rtlpriv = rtl_priv(hw);
78
79 rtlpci->reg_bcn_ctrl_val |= set_bits;
80 rtlpci->reg_bcn_ctrl_val &= ~clear_bits;
81
Larry Finger5c99f042014-09-26 16:40:25 -050082 rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlpci->reg_bcn_ctrl_val);
Larry Fingera619d1a2014-02-28 15:16:50 -060083}
84
85static void _rtl8723be_stop_tx_beacon(struct ieee80211_hw *hw)
86{
87 struct rtl_priv *rtlpriv = rtl_priv(hw);
88 u8 tmp1byte;
89
90 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
91 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6)));
92 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64);
93 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
94 tmp1byte &= ~(BIT(0));
95 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
96}
97
98static void _rtl8723be_resume_tx_beacon(struct ieee80211_hw *hw)
99{
100 struct rtl_priv *rtlpriv = rtl_priv(hw);
101 u8 tmp1byte;
102
103 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
104 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6));
105 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
106 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
107 tmp1byte |= BIT(1);
108 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
109}
110
111static void _rtl8723be_enable_bcn_sub_func(struct ieee80211_hw *hw)
112{
113 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(1));
114}
115
116static void _rtl8723be_disable_bcn_sub_func(struct ieee80211_hw *hw)
117{
118 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(1), 0);
119}
120
121static void _rtl8723be_set_fw_clock_on(struct ieee80211_hw *hw, u8 rpwm_val,
Larry Finger5c99f042014-09-26 16:40:25 -0500122 bool b_need_turn_off_ckk)
Larry Fingera619d1a2014-02-28 15:16:50 -0600123{
124 struct rtl_priv *rtlpriv = rtl_priv(hw);
125 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
Larry Finger5c99f042014-09-26 16:40:25 -0500126 bool b_support_remote_wake_up;
Larry Fingera619d1a2014-02-28 15:16:50 -0600127 u32 count = 0, isr_regaddr, content;
Larry Finger5c99f042014-09-26 16:40:25 -0500128 bool b_schedule_timer = b_need_turn_off_ckk;
Larry Fingera619d1a2014-02-28 15:16:50 -0600129 rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN,
Larry Finger5c99f042014-09-26 16:40:25 -0500130 (u8 *)(&b_support_remote_wake_up));
Larry Fingera619d1a2014-02-28 15:16:50 -0600131
132 if (!rtlhal->fw_ready)
133 return;
134 if (!rtlpriv->psc.fw_current_inpsmode)
135 return;
136
137 while (1) {
138 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
139 if (rtlhal->fw_clk_change_in_progress) {
140 while (rtlhal->fw_clk_change_in_progress) {
141 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
142 count++;
143 udelay(100);
144 if (count > 1000)
145 return;
146 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
147 }
148 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
149 } else {
150 rtlhal->fw_clk_change_in_progress = false;
151 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
152 break;
153 }
154 }
Larry Finger5c99f042014-09-26 16:40:25 -0500155
156 if (IS_IN_LOW_POWER_STATE(rtlhal->fw_ps_state)) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600157 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM,
Larry Finger5c99f042014-09-26 16:40:25 -0500158 (u8 *)(&rpwm_val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600159 if (FW_PS_IS_ACK(rpwm_val)) {
160 isr_regaddr = REG_HISR;
161 content = rtl_read_dword(rtlpriv, isr_regaddr);
162 while (!(content & IMR_CPWM) && (count < 500)) {
163 udelay(50);
164 count++;
165 content = rtl_read_dword(rtlpriv, isr_regaddr);
166 }
167
168 if (content & IMR_CPWM) {
169 rtl_write_word(rtlpriv, isr_regaddr, 0x0100);
Larry Finger5c99f042014-09-26 16:40:25 -0500170 rtlhal->fw_ps_state = FW_PS_STATE_RF_ON;
Larry Fingera619d1a2014-02-28 15:16:50 -0600171 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
Larry Finger5c99f042014-09-26 16:40:25 -0500172 "Receive CPWM INT!!! Set pHalData->FwPSState = %X\n",
Larry Fingera619d1a2014-02-28 15:16:50 -0600173 rtlhal->fw_ps_state);
174 }
175 }
Larry Finger5c99f042014-09-26 16:40:25 -0500176
Larry Fingera619d1a2014-02-28 15:16:50 -0600177 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
178 rtlhal->fw_clk_change_in_progress = false;
179 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
Larry Finger5c99f042014-09-26 16:40:25 -0500180 if (b_schedule_timer)
Larry Fingera619d1a2014-02-28 15:16:50 -0600181 mod_timer(&rtlpriv->works.fw_clockoff_timer,
182 jiffies + MSECS(10));
Larry Fingera619d1a2014-02-28 15:16:50 -0600183 } else {
184 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
185 rtlhal->fw_clk_change_in_progress = false;
186 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
187 }
188}
189
190static void _rtl8723be_set_fw_clock_off(struct ieee80211_hw *hw, u8 rpwm_val)
191{
192 struct rtl_priv *rtlpriv = rtl_priv(hw);
193 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
194 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
195 struct rtl8192_tx_ring *ring;
196 enum rf_pwrstate rtstate;
Larry Finger5c99f042014-09-26 16:40:25 -0500197 bool b_schedule_timer = false;
Larry Fingera619d1a2014-02-28 15:16:50 -0600198 u8 queue;
199
200 if (!rtlhal->fw_ready)
201 return;
202 if (!rtlpriv->psc.fw_current_inpsmode)
203 return;
204 if (!rtlhal->allow_sw_to_change_hwclc)
205 return;
206 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, (u8 *)(&rtstate));
207 if (rtstate == ERFOFF || rtlpriv->psc.inactive_pwrstate == ERFOFF)
208 return;
209
210 for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) {
211 ring = &rtlpci->tx_ring[queue];
212 if (skb_queue_len(&ring->queue)) {
Larry Finger5c99f042014-09-26 16:40:25 -0500213 b_schedule_timer = true;
Larry Fingera619d1a2014-02-28 15:16:50 -0600214 break;
215 }
216 }
Larry Finger5c99f042014-09-26 16:40:25 -0500217
218 if (b_schedule_timer) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600219 mod_timer(&rtlpriv->works.fw_clockoff_timer,
220 jiffies + MSECS(10));
221 return;
222 }
Larry Finger5c99f042014-09-26 16:40:25 -0500223
224 if (FW_PS_STATE(rtlhal->fw_ps_state) != FW_PS_STATE_RF_OFF_LOW_PWR) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600225 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
226 if (!rtlhal->fw_clk_change_in_progress) {
227 rtlhal->fw_clk_change_in_progress = true;
228 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
229 rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val);
230 rtl_write_word(rtlpriv, REG_HISR, 0x0100);
231 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
Larry Finger5c99f042014-09-26 16:40:25 -0500232 (u8 *)(&rpwm_val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600233 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
234 rtlhal->fw_clk_change_in_progress = false;
235 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
236 } else {
237 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
238 mod_timer(&rtlpriv->works.fw_clockoff_timer,
239 jiffies + MSECS(10));
240 }
241 }
Larry Finger5c99f042014-09-26 16:40:25 -0500242
Larry Fingera619d1a2014-02-28 15:16:50 -0600243}
244
245static void _rtl8723be_set_fw_ps_rf_on(struct ieee80211_hw *hw)
246{
247 u8 rpwm_val = 0;
Larry Finger5c99f042014-09-26 16:40:25 -0500248 rpwm_val |= (FW_PS_STATE_RF_OFF | FW_PS_ACK);
Larry Fingera619d1a2014-02-28 15:16:50 -0600249 _rtl8723be_set_fw_clock_on(hw, rpwm_val, true);
250}
251
252static void _rtl8723be_fwlps_leave(struct ieee80211_hw *hw)
253{
254 struct rtl_priv *rtlpriv = rtl_priv(hw);
255 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
256 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
257 bool fw_current_inps = false;
258 u8 rpwm_val = 0, fw_pwrmode = FW_PS_ACTIVE_MODE;
259
260 if (ppsc->low_power_enable) {
Larry Finger5c99f042014-09-26 16:40:25 -0500261 rpwm_val = (FW_PS_STATE_ALL_ON | FW_PS_ACK);/* RF on */
Larry Fingera619d1a2014-02-28 15:16:50 -0600262 _rtl8723be_set_fw_clock_on(hw, rpwm_val, false);
263 rtlhal->allow_sw_to_change_hwclc = false;
264 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
Larry Finger5c99f042014-09-26 16:40:25 -0500265 (u8 *)(&fw_pwrmode));
Larry Fingera619d1a2014-02-28 15:16:50 -0600266 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
267 (u8 *)(&fw_current_inps));
268 } else {
Larry Finger5c99f042014-09-26 16:40:25 -0500269 rpwm_val = FW_PS_STATE_ALL_ON; /* RF on */
270 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
271 (u8 *)(&rpwm_val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600272 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
Larry Finger5c99f042014-09-26 16:40:25 -0500273 (u8 *)(&fw_pwrmode));
Larry Fingera619d1a2014-02-28 15:16:50 -0600274 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
275 (u8 *)(&fw_current_inps));
276 }
Larry Finger5c99f042014-09-26 16:40:25 -0500277
Larry Fingera619d1a2014-02-28 15:16:50 -0600278}
279
280static void _rtl8723be_fwlps_enter(struct ieee80211_hw *hw)
281{
282 struct rtl_priv *rtlpriv = rtl_priv(hw);
283 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
284 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
285 bool fw_current_inps = true;
286 u8 rpwm_val;
287
288 if (ppsc->low_power_enable) {
Larry Finger5c99f042014-09-26 16:40:25 -0500289 rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR; /* RF off */
Larry Fingera619d1a2014-02-28 15:16:50 -0600290 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
291 (u8 *)(&fw_current_inps));
292 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
Larry Finger5c99f042014-09-26 16:40:25 -0500293 (u8 *)(&ppsc->fwctrl_psmode));
Larry Fingera619d1a2014-02-28 15:16:50 -0600294 rtlhal->allow_sw_to_change_hwclc = true;
295 _rtl8723be_set_fw_clock_off(hw, rpwm_val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600296 } else {
Larry Finger5c99f042014-09-26 16:40:25 -0500297 rpwm_val = FW_PS_STATE_RF_OFF; /* RF off */
Larry Fingera619d1a2014-02-28 15:16:50 -0600298 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
299 (u8 *)(&fw_current_inps));
300 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
Larry Finger5c99f042014-09-26 16:40:25 -0500301 (u8 *)(&ppsc->fwctrl_psmode));
302 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
303 (u8 *)(&rpwm_val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600304 }
Larry Finger5c99f042014-09-26 16:40:25 -0500305
Larry Fingera619d1a2014-02-28 15:16:50 -0600306}
307
308void rtl8723be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
309{
310 struct rtl_priv *rtlpriv = rtl_priv(hw);
311 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
312 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
313
314 switch (variable) {
315 case HW_VAR_RCR:
316 *((u32 *)(val)) = rtlpci->receive_config;
317 break;
318 case HW_VAR_RF_STATE:
319 *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
320 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500321 case HW_VAR_FWLPS_RF_ON:{
322 enum rf_pwrstate rfState;
Larry Fingera619d1a2014-02-28 15:16:50 -0600323 u32 val_rcr;
324
325 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE,
Larry Finger5c99f042014-09-26 16:40:25 -0500326 (u8 *)(&rfState));
327 if (rfState == ERFOFF) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600328 *((bool *)(val)) = true;
329 } else {
330 val_rcr = rtl_read_dword(rtlpriv, REG_RCR);
331 val_rcr &= 0x00070000;
332 if (val_rcr)
333 *((bool *)(val)) = false;
334 else
335 *((bool *)(val)) = true;
336 }
Larry Finger5c99f042014-09-26 16:40:25 -0500337 }
338 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600339 case HW_VAR_FW_PSMODE_STATUS:
340 *((bool *)(val)) = ppsc->fw_current_inpsmode;
341 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500342 case HW_VAR_CORRECT_TSF:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600343 u64 tsf;
344 u32 *ptsf_low = (u32 *)&tsf;
345 u32 *ptsf_high = ((u32 *)&tsf) + 1;
346
347 *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4));
348 *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
349
350 *((u64 *)(val)) = tsf;
Larry Finger5c99f042014-09-26 16:40:25 -0500351 }
352 break;
Larry Finger1cc49a52016-09-24 11:57:18 -0500353 case HAL_DEF_WOWLAN:
354 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600355 default:
Larry Finger5c99f042014-09-26 16:40:25 -0500356 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -0700357 "switch case %#x not processed\n", variable);
Larry Fingera619d1a2014-02-28 15:16:50 -0600358 break;
359 }
360}
361
Larry Finger5c99f042014-09-26 16:40:25 -0500362static void _rtl8723be_download_rsvd_page(struct ieee80211_hw *hw)
363{
364 struct rtl_priv *rtlpriv = rtl_priv(hw);
365 u8 tmp_regcr, tmp_reg422, bcnvalid_reg;
366 u8 count = 0, dlbcn_count = 0;
367 bool b_recover = false;
368
369 tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
370 rtl_write_byte(rtlpriv, REG_CR + 1,
371 (tmp_regcr | BIT(0)));
372
373 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3));
374 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0);
375
376 tmp_reg422 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
377 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422 & (~BIT(6)));
378 if (tmp_reg422 & BIT(6))
379 b_recover = true;
380
381 do {
382 bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL + 2);
383 rtl_write_byte(rtlpriv, REG_TDECTRL + 2,
384 (bcnvalid_reg | BIT(0)));
385 _rtl8723be_return_beacon_queue_skb(hw);
386
387 rtl8723be_set_fw_rsvdpagepkt(hw, 0);
388 bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL + 2);
389 count = 0;
390 while (!(bcnvalid_reg & BIT(0)) && count < 20) {
391 count++;
392 udelay(10);
393 bcnvalid_reg = rtl_read_byte(rtlpriv,
394 REG_TDECTRL + 2);
395 }
396 dlbcn_count++;
397 } while (!(bcnvalid_reg & BIT(0)) && dlbcn_count < 5);
398
399 if (bcnvalid_reg & BIT(0))
400 rtl_write_byte(rtlpriv, REG_TDECTRL + 2, BIT(0));
401
402 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
403 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4));
404
405 if (b_recover)
406 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422);
407
408 tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
409 rtl_write_byte(rtlpriv, REG_CR + 1, (tmp_regcr & ~(BIT(0))));
410}
411
Larry Fingera619d1a2014-02-28 15:16:50 -0600412void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
413{
414 struct rtl_priv *rtlpriv = rtl_priv(hw);
415 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
416 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
417 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
418 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
419 u8 idx;
420
421 switch (variable) {
422 case HW_VAR_ETHER_ADDR:
423 for (idx = 0; idx < ETH_ALEN; idx++)
424 rtl_write_byte(rtlpriv, (REG_MACID + idx), val[idx]);
425 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500426 case HW_VAR_BASIC_RATE:{
427 u16 b_rate_cfg = ((u16 *)val)[0];
Larry Fingera619d1a2014-02-28 15:16:50 -0600428 u8 rate_index = 0;
Larry Finger5c99f042014-09-26 16:40:25 -0500429 b_rate_cfg = b_rate_cfg & 0x15f;
430 b_rate_cfg |= 0x01;
431 rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff);
432 rtl_write_byte(rtlpriv, REG_RRSR + 1, (b_rate_cfg >> 8) & 0xff);
433 while (b_rate_cfg > 0x1) {
434 b_rate_cfg = (b_rate_cfg >> 1);
Larry Fingera619d1a2014-02-28 15:16:50 -0600435 rate_index++;
436 }
437 rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, rate_index);
Larry Finger5c99f042014-09-26 16:40:25 -0500438 }
439 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600440 case HW_VAR_BSSID:
441 for (idx = 0; idx < ETH_ALEN; idx++)
442 rtl_write_byte(rtlpriv, (REG_BSSID + idx), val[idx]);
Larry Finger5c99f042014-09-26 16:40:25 -0500443
Larry Fingera619d1a2014-02-28 15:16:50 -0600444 break;
445 case HW_VAR_SIFS:
446 rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]);
447 rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]);
448
449 rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]);
450 rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
451
452 if (!mac->ht_enable)
453 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, 0x0e0e);
454 else
455 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
456 *((u16 *)val));
457 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500458 case HW_VAR_SLOT_TIME:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600459 u8 e_aci;
460
461 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
462 "HW_VAR_SLOT_TIME %x\n", val[0]);
463
464 rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
465
466 for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
467 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
Larry Finger5c99f042014-09-26 16:40:25 -0500468 (u8 *)(&e_aci));
Larry Fingera619d1a2014-02-28 15:16:50 -0600469 }
Larry Finger5c99f042014-09-26 16:40:25 -0500470 }
471 break;
472 case HW_VAR_ACK_PREAMBLE:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600473 u8 reg_tmp;
Larry Finger5c99f042014-09-26 16:40:25 -0500474 u8 short_preamble = (bool)(*(u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600475 reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL + 2);
476 if (short_preamble) {
477 reg_tmp |= 0x02;
478 rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
479 } else {
480 reg_tmp &= 0xFD;
481 rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
482 }
Larry Finger5c99f042014-09-26 16:40:25 -0500483 }
Larry Fingera619d1a2014-02-28 15:16:50 -0600484 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500485 case HW_VAR_WPA_CONFIG:
486 rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val));
487 break;
488 case HW_VAR_AMPDU_MIN_SPACE:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600489 u8 min_spacing_to_set;
490 u8 sec_min_space;
491
Larry Finger5c99f042014-09-26 16:40:25 -0500492 min_spacing_to_set = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600493 if (min_spacing_to_set <= 7) {
494 sec_min_space = 0;
495
496 if (min_spacing_to_set < sec_min_space)
497 min_spacing_to_set = sec_min_space;
498
499 mac->min_space_cfg = ((mac->min_space_cfg & 0xf8) |
500 min_spacing_to_set);
501
502 *val = min_spacing_to_set;
503
504 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
505 "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
Larry Finger5c99f042014-09-26 16:40:25 -0500506 mac->min_space_cfg);
Larry Fingera619d1a2014-02-28 15:16:50 -0600507
508 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
509 mac->min_space_cfg);
510 }
Larry Finger5c99f042014-09-26 16:40:25 -0500511 }
512 break;
513 case HW_VAR_SHORTGI_DENSITY:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600514 u8 density_to_set;
515
Larry Finger5c99f042014-09-26 16:40:25 -0500516 density_to_set = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600517 mac->min_space_cfg |= (density_to_set << 3);
518
519 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
520 "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
Larry Finger5c99f042014-09-26 16:40:25 -0500521 mac->min_space_cfg);
Larry Fingera619d1a2014-02-28 15:16:50 -0600522
523 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
524 mac->min_space_cfg);
Larry Finger5c99f042014-09-26 16:40:25 -0500525 }
526 break;
527 case HW_VAR_AMPDU_FACTOR:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600528 u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9};
529 u8 factor_toset;
530 u8 *p_regtoset = NULL;
531 u8 index = 0;
532
533 p_regtoset = regtoset_normal;
534
Larry Finger5c99f042014-09-26 16:40:25 -0500535 factor_toset = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600536 if (factor_toset <= 3) {
537 factor_toset = (1 << (factor_toset + 2));
538 if (factor_toset > 0xf)
539 factor_toset = 0xf;
540
541 for (index = 0; index < 4; index++) {
542 if ((p_regtoset[index] & 0xf0) >
543 (factor_toset << 4))
544 p_regtoset[index] =
545 (p_regtoset[index] & 0x0f) |
546 (factor_toset << 4);
547
548 if ((p_regtoset[index] & 0x0f) > factor_toset)
549 p_regtoset[index] =
550 (p_regtoset[index] & 0xf0) |
551 (factor_toset);
552
553 rtl_write_byte(rtlpriv,
554 (REG_AGGLEN_LMT + index),
555 p_regtoset[index]);
Larry Finger5c99f042014-09-26 16:40:25 -0500556
Larry Fingera619d1a2014-02-28 15:16:50 -0600557 }
Larry Finger5c99f042014-09-26 16:40:25 -0500558
Larry Fingera619d1a2014-02-28 15:16:50 -0600559 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
560 "Set HW_VAR_AMPDU_FACTOR: %#x\n",
Larry Finger5c99f042014-09-26 16:40:25 -0500561 factor_toset);
Larry Fingera619d1a2014-02-28 15:16:50 -0600562 }
Larry Finger5c99f042014-09-26 16:40:25 -0500563 }
564 break;
565 case HW_VAR_AC_PARAM:{
566 u8 e_aci = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600567 rtl8723_dm_init_edca_turbo(hw);
568
569 if (rtlpci->acm_method != EACMWAY2_SW)
570 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
Larry Finger5c99f042014-09-26 16:40:25 -0500571 (u8 *)(&e_aci));
572 }
573 break;
574 case HW_VAR_ACM_CTRL:{
575 u8 e_aci = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600576 union aci_aifsn *p_aci_aifsn =
577 (union aci_aifsn *)(&(mac->ac[0].aifs));
578 u8 acm = p_aci_aifsn->f.acm;
579 u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);
580
581 acm_ctrl =
582 acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1);
583
584 if (acm) {
585 switch (e_aci) {
586 case AC0_BE:
587 acm_ctrl |= ACMHW_BEQEN;
588 break;
589 case AC2_VI:
590 acm_ctrl |= ACMHW_VIQEN;
591 break;
592 case AC3_VO:
593 acm_ctrl |= ACMHW_VOQEN;
594 break;
595 default:
596 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
Larry Finger5c99f042014-09-26 16:40:25 -0500597 "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
598 acm);
Larry Fingera619d1a2014-02-28 15:16:50 -0600599 break;
600 }
601 } else {
602 switch (e_aci) {
603 case AC0_BE:
604 acm_ctrl &= (~ACMHW_BEQEN);
605 break;
606 case AC2_VI:
607 acm_ctrl &= (~ACMHW_VIQEN);
608 break;
609 case AC3_VO:
Jes Sorensen52f57802015-02-06 17:24:32 -0500610 acm_ctrl &= (~ACMHW_VOQEN);
Larry Fingera619d1a2014-02-28 15:16:50 -0600611 break;
612 default:
Larry Finger5c99f042014-09-26 16:40:25 -0500613 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -0700614 "switch case %#x not processed\n",
615 e_aci);
Larry Fingera619d1a2014-02-28 15:16:50 -0600616 break;
617 }
618 }
Larry Finger5c99f042014-09-26 16:40:25 -0500619
Larry Fingera619d1a2014-02-28 15:16:50 -0600620 RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
Larry Finger5c99f042014-09-26 16:40:25 -0500621 "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
622 acm_ctrl);
Larry Fingera619d1a2014-02-28 15:16:50 -0600623 rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
Larry Finger5c99f042014-09-26 16:40:25 -0500624 }
625 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600626 case HW_VAR_RCR:
627 rtl_write_dword(rtlpriv, REG_RCR, ((u32 *)(val))[0]);
628 rtlpci->receive_config = ((u32 *)(val))[0];
629 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500630 case HW_VAR_RETRY_LIMIT:{
631 u8 retry_limit = ((u8 *)(val))[0];
Larry Fingera619d1a2014-02-28 15:16:50 -0600632
633 rtl_write_word(rtlpriv, REG_RL,
634 retry_limit << RETRY_LIMIT_SHORT_SHIFT |
635 retry_limit << RETRY_LIMIT_LONG_SHIFT);
Larry Finger5c99f042014-09-26 16:40:25 -0500636 }
637 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600638 case HW_VAR_DUAL_TSF_RST:
639 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
640 break;
641 case HW_VAR_EFUSE_BYTES:
642 rtlefuse->efuse_usedbytes = *((u16 *)val);
643 break;
644 case HW_VAR_EFUSE_USAGE:
Larry Finger5c99f042014-09-26 16:40:25 -0500645 rtlefuse->efuse_usedpercentage = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600646 break;
647 case HW_VAR_IO_CMD:
648 rtl8723be_phy_set_io_cmd(hw, (*(enum io_type *)val));
649 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500650 case HW_VAR_SET_RPWM:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600651 u8 rpwm_val;
652
653 rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM);
654 udelay(1);
655
656 if (rpwm_val & BIT(7)) {
Larry Finger5c99f042014-09-26 16:40:25 -0500657 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, (*(u8 *)val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600658 } else {
Larry Finger5c99f042014-09-26 16:40:25 -0500659 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
660 ((*(u8 *)val) | BIT(7)));
Larry Fingera619d1a2014-02-28 15:16:50 -0600661 }
Larry Finger5c99f042014-09-26 16:40:25 -0500662 }
663 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600664 case HW_VAR_H2C_FW_PWRMODE:
Larry Finger5c99f042014-09-26 16:40:25 -0500665 rtl8723be_set_fw_pwrmode_cmd(hw, (*(u8 *)val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600666 break;
667 case HW_VAR_FW_PSMODE_STATUS:
668 ppsc->fw_current_inpsmode = *((bool *)val);
669 break;
670 case HW_VAR_RESUME_CLK_ON:
671 _rtl8723be_set_fw_ps_rf_on(hw);
672 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500673 case HW_VAR_FW_LPS_ACTION:{
674 bool b_enter_fwlps = *((bool *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600675
Larry Finger5c99f042014-09-26 16:40:25 -0500676 if (b_enter_fwlps)
Larry Fingera619d1a2014-02-28 15:16:50 -0600677 _rtl8723be_fwlps_enter(hw);
678 else
679 _rtl8723be_fwlps_leave(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500680 }
681 break;
682 case HW_VAR_H2C_FW_JOINBSSRPT:{
683 u8 mstatus = (*(u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600684
685 if (mstatus == RT_MEDIA_CONNECT) {
686 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL);
Larry Finger5c99f042014-09-26 16:40:25 -0500687 _rtl8723be_download_rsvd_page(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -0600688 }
Larry Finger5c99f042014-09-26 16:40:25 -0500689 rtl8723be_set_fw_media_status_rpt_cmd(hw, mstatus);
690 }
Larry Fingera619d1a2014-02-28 15:16:50 -0600691 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500692 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
693 rtl8723be_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
694 break;
695 case HW_VAR_AID:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600696 u16 u2btmp;
697 u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
698 u2btmp &= 0xC000;
699 rtl_write_word(rtlpriv, REG_BCN_PSR_RPT,
700 (u2btmp | mac->assoc_id));
Larry Finger5c99f042014-09-26 16:40:25 -0500701 }
702 break;
703 case HW_VAR_CORRECT_TSF:{
704 u8 btype_ibss = ((u8 *)(val))[0];
Larry Fingera619d1a2014-02-28 15:16:50 -0600705
706 if (btype_ibss)
707 _rtl8723be_stop_tx_beacon(hw);
708
709 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3));
710
711 rtl_write_dword(rtlpriv, REG_TSFTR,
712 (u32) (mac->tsf & 0xffffffff));
713 rtl_write_dword(rtlpriv, REG_TSFTR + 4,
714 (u32) ((mac->tsf >> 32) & 0xffffffff));
715
716 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
717
718 if (btype_ibss)
719 _rtl8723be_resume_tx_beacon(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500720 }
721 break;
722 case HW_VAR_KEEP_ALIVE:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600723 u8 array[2];
724 array[0] = 0xff;
Larry Finger5c99f042014-09-26 16:40:25 -0500725 array[1] = *((u8 *)val);
726 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_KEEP_ALIVE_CTRL, 2, array);
727 }
728 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600729 default:
Larry Finger5c99f042014-09-26 16:40:25 -0500730 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -0700731 "switch case %#x not processed\n", variable);
Larry Fingera619d1a2014-02-28 15:16:50 -0600732 break;
733 }
734}
735
736static bool _rtl8723be_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
737{
738 struct rtl_priv *rtlpriv = rtl_priv(hw);
739 bool status = true;
Larry Finger5c99f042014-09-26 16:40:25 -0500740 long count = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -0600741 u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) |
742 _LLT_OP(_LLT_WRITE_ACCESS);
743
744 rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
745
746 do {
747 value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
748 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
749 break;
750
751 if (count > POLLING_LLT_THRESHOLD) {
Larry Finger4e2b4372016-12-15 12:23:00 -0600752 pr_err("Failed to polling write LLT done at address %d!\n",
753 address);
Larry Fingera619d1a2014-02-28 15:16:50 -0600754 status = false;
755 break;
756 }
757 } while (++count);
758
759 return status;
760}
761
762static bool _rtl8723be_llt_table_init(struct ieee80211_hw *hw)
763{
764 struct rtl_priv *rtlpriv = rtl_priv(hw);
765 unsigned short i;
766 u8 txpktbuf_bndy;
Larry Finger5c99f042014-09-26 16:40:25 -0500767 u8 maxPage;
Larry Fingera619d1a2014-02-28 15:16:50 -0600768 bool status;
769
Larry Finger5c99f042014-09-26 16:40:25 -0500770 maxPage = 255;
Larry Fingera619d1a2014-02-28 15:16:50 -0600771 txpktbuf_bndy = 245;
772
773 rtl_write_dword(rtlpriv, REG_TRXFF_BNDY,
774 (0x27FF0000 | txpktbuf_bndy));
775 rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy);
776
777 rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
778 rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
779
780 rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy);
781 rtl_write_byte(rtlpriv, REG_PBP, 0x31);
782 rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);
783
784 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
785 status = _rtl8723be_llt_write(hw, i, i + 1);
786 if (!status)
787 return status;
788 }
Larry Finger5c99f042014-09-26 16:40:25 -0500789
Larry Fingera619d1a2014-02-28 15:16:50 -0600790 status = _rtl8723be_llt_write(hw, (txpktbuf_bndy - 1), 0xFF);
791
792 if (!status)
793 return status;
794
Larry Finger5c99f042014-09-26 16:40:25 -0500795 for (i = txpktbuf_bndy; i < maxPage; i++) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600796 status = _rtl8723be_llt_write(hw, i, (i + 1));
797 if (!status)
798 return status;
799 }
Larry Finger5c99f042014-09-26 16:40:25 -0500800
801 status = _rtl8723be_llt_write(hw, maxPage, txpktbuf_bndy);
Larry Fingera619d1a2014-02-28 15:16:50 -0600802 if (!status)
803 return status;
804
805 rtl_write_dword(rtlpriv, REG_RQPN, 0x80e40808);
806 rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x00);
807
808 return true;
809}
810
811static void _rtl8723be_gen_refresh_led_state(struct ieee80211_hw *hw)
812{
813 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -0600814 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
Larry Fingerd5efe152017-02-07 09:14:21 -0600815 struct rtl_led *pled0 = &rtlpriv->ledctl.sw_led0;
Larry Fingera619d1a2014-02-28 15:16:50 -0600816
817 if (rtlpriv->rtlhal.up_first_time)
818 return;
819
820 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
821 rtl8723be_sw_led_on(hw, pled0);
822 else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT)
823 rtl8723be_sw_led_on(hw, pled0);
824 else
825 rtl8723be_sw_led_off(hw, pled0);
826}
827
828static bool _rtl8723be_init_mac(struct ieee80211_hw *hw)
829{
830 struct rtl_priv *rtlpriv = rtl_priv(hw);
831 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
Larry Finger5c99f042014-09-26 16:40:25 -0500832 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
Larry Fingera619d1a2014-02-28 15:16:50 -0600833 unsigned char bytetmp;
834 unsigned short wordtmp;
Larry Fingera619d1a2014-02-28 15:16:50 -0600835
836 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
837
838 /*Auto Power Down to CHIP-off State*/
839 bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) & (~BIT(7));
840 rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp);
841
Larry Fingera619d1a2014-02-28 15:16:50 -0600842 /* HW Power on sequence */
Larry Finger34ed7802014-09-22 09:39:27 -0500843 if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK,
844 PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,
845 RTL8723_NIC_ENABLE_FLOW)) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600846 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
847 "init MAC Fail as power on failure\n");
848 return false;
849 }
Larry Finger5c99f042014-09-26 16:40:25 -0500850
851 bytetmp = rtl_read_byte(rtlpriv, REG_MULTI_FUNC_CTRL);
852 rtl_write_byte(rtlpriv, REG_MULTI_FUNC_CTRL, bytetmp | BIT(3));
853
Larry Fingera619d1a2014-02-28 15:16:50 -0600854 bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO) | BIT(4);
855 rtl_write_byte(rtlpriv, REG_APS_FSMCO, bytetmp);
856
857 bytetmp = rtl_read_byte(rtlpriv, REG_CR);
858 bytetmp = 0xff;
859 rtl_write_byte(rtlpriv, REG_CR, bytetmp);
860 mdelay(2);
861
862 bytetmp = rtl_read_byte(rtlpriv, REG_HWSEQ_CTRL);
863 bytetmp |= 0x7f;
864 rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, bytetmp);
865 mdelay(2);
866
867 bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CFG + 3);
868 if (bytetmp & BIT(0)) {
869 bytetmp = rtl_read_byte(rtlpriv, 0x7c);
Larry Finger5c99f042014-09-26 16:40:25 -0500870 rtl_write_byte(rtlpriv, 0x7c, bytetmp | BIT(6));
Larry Fingera619d1a2014-02-28 15:16:50 -0600871 }
Larry Fingera619d1a2014-02-28 15:16:50 -0600872
Larry Finger5c99f042014-09-26 16:40:25 -0500873 bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CLKR);
874 rtl_write_byte(rtlpriv, REG_SYS_CLKR, bytetmp | BIT(3));
875 bytetmp = rtl_read_byte(rtlpriv, REG_GPIO_MUXCFG + 1);
876 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG + 1, bytetmp & (~BIT(4)));
Larry Fingera619d1a2014-02-28 15:16:50 -0600877
878 rtl_write_word(rtlpriv, REG_CR, 0x2ff);
879
Larry Finger5c99f042014-09-26 16:40:25 -0500880 if (!rtlhal->mac_func_enable) {
881 if (_rtl8723be_llt_table_init(hw) == false)
Larry Fingera619d1a2014-02-28 15:16:50 -0600882 return false;
883 }
Larry Finger5c99f042014-09-26 16:40:25 -0500884
Larry Fingera619d1a2014-02-28 15:16:50 -0600885 rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
886 rtl_write_dword(rtlpriv, REG_HISRE, 0xffffffff);
887
888 /* Enable FW Beamformer Interrupt */
889 bytetmp = rtl_read_byte(rtlpriv, REG_FWIMR + 3);
890 rtl_write_byte(rtlpriv, REG_FWIMR + 3, bytetmp | BIT(6));
891
892 wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL);
893 wordtmp &= 0xf;
894 wordtmp |= 0xF5B1;
895 rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp);
896
897 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F);
898 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
899 rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xFFFF);
900 rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config);
901
Larry Fingera619d1a2014-02-28 15:16:50 -0600902 rtl_write_dword(rtlpriv, REG_BCNQ_DESA,
903 ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) &
904 DMA_BIT_MASK(32));
905 rtl_write_dword(rtlpriv, REG_MGQ_DESA,
906 (u64) rtlpci->tx_ring[MGNT_QUEUE].dma &
907 DMA_BIT_MASK(32));
908 rtl_write_dword(rtlpriv, REG_VOQ_DESA,
909 (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32));
910 rtl_write_dword(rtlpriv, REG_VIQ_DESA,
911 (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32));
912 rtl_write_dword(rtlpriv, REG_BEQ_DESA,
913 (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32));
914 rtl_write_dword(rtlpriv, REG_BKQ_DESA,
915 (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32));
916 rtl_write_dword(rtlpriv, REG_HQ_DESA,
917 (u64) rtlpci->tx_ring[HIGH_QUEUE].dma &
918 DMA_BIT_MASK(32));
919 rtl_write_dword(rtlpriv, REG_RX_DESA,
920 (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma &
921 DMA_BIT_MASK(32));
922
923 bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 3);
924 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, bytetmp | 0x77);
925
926 rtl_write_dword(rtlpriv, REG_INT_MIG, 0);
927
Larry Finger5c99f042014-09-26 16:40:25 -0500928 rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0);
Larry Fingera619d1a2014-02-28 15:16:50 -0600929
930 rtl_write_byte(rtlpriv, REG_SECONDARY_CCA_CTRL, 0x3);
931
Larry Finger5c99f042014-09-26 16:40:25 -0500932 /* <20130114, Kordan> The following setting is
933 * only for DPDT and Fixed board type.
934 * TODO: A better solution is configure it
935 * according EFUSE during the run-time.
936 */
937 rtl_set_bbreg(hw, 0x64, BIT(20), 0x0);/* 0x66[4]=0 */
938 rtl_set_bbreg(hw, 0x64, BIT(24), 0x0);/* 0x66[8]=0 */
939 rtl_set_bbreg(hw, 0x40, BIT(4), 0x0)/* 0x40[4]=0 */;
940 rtl_set_bbreg(hw, 0x40, BIT(3), 0x1)/* 0x40[3]=1 */;
941 rtl_set_bbreg(hw, 0x4C, BIT(24) | BIT(23), 0x2)/* 0x4C[24:23]=10 */;
942 rtl_set_bbreg(hw, 0x944, BIT(1) | BIT(0), 0x3)/* 0x944[1:0]=11 */;
943 rtl_set_bbreg(hw, 0x930, MASKBYTE0, 0x77)/* 0x930[7:0]=77 */;
944 rtl_set_bbreg(hw, 0x38, BIT(11), 0x1)/* 0x38[11]=1 */;
Larry Fingera619d1a2014-02-28 15:16:50 -0600945
946 bytetmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
Larry Finger5c99f042014-09-26 16:40:25 -0500947 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, bytetmp & (~BIT(2)));
Larry Fingera619d1a2014-02-28 15:16:50 -0600948
Larry Finger5c99f042014-09-26 16:40:25 -0500949 _rtl8723be_gen_refresh_led_state(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -0600950 return true;
951}
952
953static void _rtl8723be_hw_configure(struct ieee80211_hw *hw)
954{
955 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500956 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
957 u32 reg_rrsr;
Larry Fingera619d1a2014-02-28 15:16:50 -0600958
Larry Finger5c99f042014-09-26 16:40:25 -0500959 reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
960 /* Init value for RRSR. */
961 rtl_write_dword(rtlpriv, REG_RRSR, reg_rrsr);
Larry Fingera619d1a2014-02-28 15:16:50 -0600962
Larry Finger5c99f042014-09-26 16:40:25 -0500963 /* ARFB table 9 for 11ac 5G 2SS */
964 rtl_write_dword(rtlpriv, REG_ARFR0 + 4, 0xfffff000);
965
966 /* ARFB table 10 for 11ac 5G 1SS */
967 rtl_write_dword(rtlpriv, REG_ARFR1 + 4, 0x003ff000);
968
969 /* CF-End setting. */
970 rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F00);
971
972 /* 0x456 = 0x70, sugguested by Zhilin */
973 rtl_write_byte(rtlpriv, REG_AMPDU_MAX_TIME, 0x70);
974
975 /* Set retry limit */
976 rtl_write_word(rtlpriv, REG_RL, 0x0707);
977
978 /* Set Data / Response auto rate fallack retry count */
979 rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000);
980 rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504);
981 rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000);
982 rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504);
983
984 rtlpci->reg_bcn_ctrl_val = 0x1d;
985 rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val);
986
987 /* TBTT prohibit hold time. Suggested by designer TimChen. */
988 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); /* 8 ms */
989
990 rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040);
991
992 /*For Rx TP. Suggested by SD1 Richard. Added by tynli. 2010.04.12.*/
993 rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666);
994
995 rtl_write_byte(rtlpriv, REG_HT_SINGLE_AMPDU, 0x80);
996
997 rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x20);
998
999 rtl_write_byte(rtlpriv, REG_MAX_AGGR_NUM, 0x1F);
1000}
1001
1002static u8 _rtl8723be_dbi_read(struct rtl_priv *rtlpriv, u16 addr)
1003{
1004 u16 read_addr = addr & 0xfffc;
1005 u8 ret = 0, tmp = 0, count = 0;
1006
1007 rtl_write_word(rtlpriv, REG_DBI_ADDR, read_addr);
1008 rtl_write_byte(rtlpriv, REG_DBI_FLAG, 0x2);
1009 tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1010 count = 0;
1011 while (tmp && count < 20) {
1012 udelay(10);
1013 tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1014 count++;
1015 }
1016 if (0 == tmp) {
1017 read_addr = REG_DBI_RDATA + addr % 4;
1018 ret = rtl_read_byte(rtlpriv, read_addr);
1019 }
1020
1021 return ret;
1022}
1023
1024static void _rtl8723be_dbi_write(struct rtl_priv *rtlpriv, u16 addr, u8 data)
1025{
1026 u8 tmp = 0, count = 0;
1027 u16 write_addr = 0, remainder = addr % 4;
1028
1029 /* Write DBI 1Byte Data */
1030 write_addr = REG_DBI_WDATA + remainder;
1031 rtl_write_byte(rtlpriv, write_addr, data);
1032
1033 /* Write DBI 2Byte Address & Write Enable */
1034 write_addr = (addr & 0xfffc) | (BIT(0) << (remainder + 12));
1035 rtl_write_word(rtlpriv, REG_DBI_ADDR, write_addr);
1036
1037 /* Write DBI Write Flag */
1038 rtl_write_byte(rtlpriv, REG_DBI_FLAG, 0x1);
1039
1040 tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1041 count = 0;
1042 while (tmp && count < 20) {
1043 udelay(10);
1044 tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1045 count++;
1046 }
1047}
1048
1049static u16 _rtl8723be_mdio_read(struct rtl_priv *rtlpriv, u8 addr)
1050{
1051 u16 ret = 0;
1052 u8 tmp = 0, count = 0;
1053
1054 rtl_write_byte(rtlpriv, REG_MDIO_CTL, addr | BIT(6));
1055 tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(6);
1056 count = 0;
1057 while (tmp && count < 20) {
1058 udelay(10);
1059 tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(6);
1060 count++;
1061 }
1062
1063 if (0 == tmp)
1064 ret = rtl_read_word(rtlpriv, REG_MDIO_RDATA);
1065
1066 return ret;
1067}
1068
1069static void _rtl8723be_mdio_write(struct rtl_priv *rtlpriv, u8 addr, u16 data)
1070{
1071 u8 tmp = 0, count = 0;
1072
1073 rtl_write_word(rtlpriv, REG_MDIO_WDATA, data);
1074 rtl_write_byte(rtlpriv, REG_MDIO_CTL, addr | BIT(5));
1075 tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(5);
1076 count = 0;
1077 while (tmp && count < 20) {
1078 udelay(10);
1079 tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(5);
1080 count++;
1081 }
Larry Fingera619d1a2014-02-28 15:16:50 -06001082}
1083
1084static void _rtl8723be_enable_aspm_back_door(struct ieee80211_hw *hw)
1085{
1086 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -05001087 u8 tmp8 = 0;
1088 u16 tmp16 = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06001089
Larry Finger5c99f042014-09-26 16:40:25 -05001090 /* <Roger_Notes> Overwrite following ePHY parameter for
1091 * some platform compatibility issue,
1092 * especially when CLKReq is enabled, 2012.11.09.
1093 */
1094 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x01);
1095 if (tmp16 != 0x0663)
1096 _rtl8723be_mdio_write(rtlpriv, 0x01, 0x0663);
Larry Fingera619d1a2014-02-28 15:16:50 -06001097
Larry Finger5c99f042014-09-26 16:40:25 -05001098 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x04);
1099 if (tmp16 != 0x7544)
1100 _rtl8723be_mdio_write(rtlpriv, 0x04, 0x7544);
Larry Fingera619d1a2014-02-28 15:16:50 -06001101
Larry Finger5c99f042014-09-26 16:40:25 -05001102 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x06);
1103 if (tmp16 != 0xB880)
1104 _rtl8723be_mdio_write(rtlpriv, 0x06, 0xB880);
1105
1106 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x07);
1107 if (tmp16 != 0x4000)
1108 _rtl8723be_mdio_write(rtlpriv, 0x07, 0x4000);
1109
1110 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x08);
1111 if (tmp16 != 0x9003)
1112 _rtl8723be_mdio_write(rtlpriv, 0x08, 0x9003);
1113
1114 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x09);
1115 if (tmp16 != 0x0D03)
1116 _rtl8723be_mdio_write(rtlpriv, 0x09, 0x0D03);
1117
1118 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x0A);
1119 if (tmp16 != 0x4037)
1120 _rtl8723be_mdio_write(rtlpriv, 0x0A, 0x4037);
1121
1122 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x0B);
1123 if (tmp16 != 0x0070)
1124 _rtl8723be_mdio_write(rtlpriv, 0x0B, 0x0070);
1125
1126 /* Configuration Space offset 0x70f BIT7 is used to control L0S */
1127 tmp8 = _rtl8723be_dbi_read(rtlpriv, 0x70f);
Larry Finger78dc8972018-02-22 14:28:59 -06001128 _rtl8723be_dbi_write(rtlpriv, 0x70f, tmp8 | BIT(7) |
1129 ASPM_L1_LATENCY << 3);
Larry Finger5c99f042014-09-26 16:40:25 -05001130
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,
Larry Finger78aa6012017-11-12 14:06:45 -06001687 struct rtl_int *intvec)
Larry Fingera619d1a2014-02-28 15:16:50 -06001688{
1689 struct rtl_priv *rtlpriv = rtl_priv(hw);
1690 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1691
Larry Finger78aa6012017-11-12 14:06:45 -06001692 intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0];
1693 rtl_write_dword(rtlpriv, ISR, intvec->inta);
Larry Fingera619d1a2014-02-28 15:16:50 -06001694
Larry Finger78aa6012017-11-12 14:06:45 -06001695 intvec->intb = rtl_read_dword(rtlpriv, REG_HISRE) &
1696 rtlpci->irq_mask[1];
1697 rtl_write_dword(rtlpriv, REG_HISRE, intvec->intb);
Larry Fingera619d1a2014-02-28 15:16:50 -06001698}
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 Shih881d53a2017-07-02 13:12:32 -05002117 if (rtlpriv->btcoexist.btc_info.btcoexist == 1)
2118 rtlefuse->board_type |= BIT(2); /* ODM_BOARD_BT */
2119
2120 rtlhal->board_type = rtlefuse->board_type;
2121 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2122 "board_type = 0x%x\n", rtlefuse->board_type);
2123
Ping-Ke Shih7fe1fe752017-02-06 21:30:05 -06002124 rtlhal->package_type = _rtl8723be_read_package_type(hw);
2125
Shao Fub23cd222015-05-15 16:33:02 -05002126 /* set channel plan from efuse */
2127 rtlefuse->channel_plan = rtlefuse->eeprom_channelplan;
Larry Fingera619d1a2014-02-28 15:16:50 -06002128
2129 if (rtlhal->oem_id == RT_CID_DEFAULT) {
2130 /* Does this one have a Toshiba SMID from group 1? */
Jérémy Lefaure53ac7932017-11-13 22:19:41 -05002131 for (i = 0; i < ARRAY_SIZE(toshiba_smid1); i++) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002132 if (rtlefuse->eeprom_smid == toshiba_smid1[i]) {
2133 is_toshiba_smid1 = true;
2134 break;
2135 }
2136 }
2137 /* Does this one have a Toshiba SMID from group 2? */
Jérémy Lefaure53ac7932017-11-13 22:19:41 -05002138 for (i = 0; i < ARRAY_SIZE(toshiba_smid2); i++) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002139 if (rtlefuse->eeprom_smid == toshiba_smid2[i]) {
2140 is_toshiba_smid2 = true;
2141 break;
2142 }
2143 }
2144 /* Does this one have a Samsung SMID? */
Jérémy Lefaure53ac7932017-11-13 22:19:41 -05002145 for (i = 0; i < ARRAY_SIZE(samsung_smid); i++) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002146 if (rtlefuse->eeprom_smid == samsung_smid[i]) {
2147 is_samsung_smid = true;
2148 break;
2149 }
2150 }
2151 /* Does this one have a Lenovo SMID? */
Jérémy Lefaure53ac7932017-11-13 22:19:41 -05002152 for (i = 0; i < ARRAY_SIZE(lenovo_smid); i++) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002153 if (rtlefuse->eeprom_smid == lenovo_smid[i]) {
2154 is_lenovo_smid = true;
2155 break;
2156 }
2157 }
2158 switch (rtlefuse->eeprom_oemid) {
2159 case EEPROM_CID_DEFAULT:
2160 if (rtlefuse->eeprom_did == 0x8176) {
2161 if (rtlefuse->eeprom_svid == 0x10EC &&
2162 is_toshiba_smid1) {
2163 rtlhal->oem_id = RT_CID_TOSHIBA;
2164 } else if (rtlefuse->eeprom_svid == 0x1025) {
2165 rtlhal->oem_id = RT_CID_819X_ACER;
2166 } else if (rtlefuse->eeprom_svid == 0x10EC &&
2167 is_samsung_smid) {
2168 rtlhal->oem_id = RT_CID_819X_SAMSUNG;
2169 } else if (rtlefuse->eeprom_svid == 0x10EC &&
2170 is_lenovo_smid) {
2171 rtlhal->oem_id = RT_CID_819X_LENOVO;
2172 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
2173 rtlefuse->eeprom_smid == 0x8197) ||
2174 (rtlefuse->eeprom_svid == 0x10EC &&
2175 rtlefuse->eeprom_smid == 0x9196)) {
2176 rtlhal->oem_id = RT_CID_819X_CLEVO;
2177 } else if ((rtlefuse->eeprom_svid == 0x1028 &&
2178 rtlefuse->eeprom_smid == 0x8194) ||
2179 (rtlefuse->eeprom_svid == 0x1028 &&
2180 rtlefuse->eeprom_smid == 0x8198) ||
2181 (rtlefuse->eeprom_svid == 0x1028 &&
2182 rtlefuse->eeprom_smid == 0x9197) ||
2183 (rtlefuse->eeprom_svid == 0x1028 &&
2184 rtlefuse->eeprom_smid == 0x9198)) {
2185 rtlhal->oem_id = RT_CID_819X_DELL;
2186 } else if ((rtlefuse->eeprom_svid == 0x103C &&
2187 rtlefuse->eeprom_smid == 0x1629)) {
2188 rtlhal->oem_id = RT_CID_819X_HP;
2189 } else if ((rtlefuse->eeprom_svid == 0x1A32 &&
2190 rtlefuse->eeprom_smid == 0x2315)) {
2191 rtlhal->oem_id = RT_CID_819X_QMI;
2192 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
2193 rtlefuse->eeprom_smid == 0x8203)) {
2194 rtlhal->oem_id = RT_CID_819X_PRONETS;
2195 } else if ((rtlefuse->eeprom_svid == 0x1043 &&
2196 rtlefuse->eeprom_smid == 0x84B5)) {
2197 rtlhal->oem_id = RT_CID_819X_EDIMAX_ASUS;
2198 } else {
2199 rtlhal->oem_id = RT_CID_DEFAULT;
2200 }
2201 } else if (rtlefuse->eeprom_did == 0x8178) {
2202 if (rtlefuse->eeprom_svid == 0x10EC &&
2203 is_toshiba_smid2)
2204 rtlhal->oem_id = RT_CID_TOSHIBA;
2205 else if (rtlefuse->eeprom_svid == 0x1025)
2206 rtlhal->oem_id = RT_CID_819X_ACER;
2207 else if ((rtlefuse->eeprom_svid == 0x10EC &&
2208 rtlefuse->eeprom_smid == 0x8186))
2209 rtlhal->oem_id = RT_CID_819X_PRONETS;
2210 else if ((rtlefuse->eeprom_svid == 0x1043 &&
2211 rtlefuse->eeprom_smid == 0x84B6))
2212 rtlhal->oem_id =
2213 RT_CID_819X_EDIMAX_ASUS;
2214 else
2215 rtlhal->oem_id = RT_CID_DEFAULT;
2216 } else {
2217 rtlhal->oem_id = RT_CID_DEFAULT;
2218 }
2219 break;
2220 case EEPROM_CID_TOSHIBA:
2221 rtlhal->oem_id = RT_CID_TOSHIBA;
2222 break;
2223 case EEPROM_CID_CCX:
2224 rtlhal->oem_id = RT_CID_CCX;
2225 break;
2226 case EEPROM_CID_QMI:
2227 rtlhal->oem_id = RT_CID_819X_QMI;
2228 break;
2229 case EEPROM_CID_WHQL:
2230 break;
2231 default:
2232 rtlhal->oem_id = RT_CID_DEFAULT;
2233 break;
2234 }
2235 }
Larry Finger9e9c9c22016-07-05 10:08:12 -05002236exit:
2237 kfree(hwinfo);
Larry Fingera619d1a2014-02-28 15:16:50 -06002238}
2239
2240static void _rtl8723be_hal_customized_behavior(struct ieee80211_hw *hw)
2241{
2242 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -06002243 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2244
Larry Fingerd5efe152017-02-07 09:14:21 -06002245 rtlpriv->ledctl.led_opendrain = true;
Larry Fingera619d1a2014-02-28 15:16:50 -06002246 switch (rtlhal->oem_id) {
2247 case RT_CID_819X_HP:
Larry Fingerd5efe152017-02-07 09:14:21 -06002248 rtlpriv->ledctl.led_opendrain = true;
Larry Fingera619d1a2014-02-28 15:16:50 -06002249 break;
2250 case RT_CID_819X_LENOVO:
2251 case RT_CID_DEFAULT:
2252 case RT_CID_TOSHIBA:
2253 case RT_CID_CCX:
2254 case RT_CID_819X_ACER:
2255 case RT_CID_WHQL:
2256 default:
2257 break;
2258 }
2259 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2260 "RT Customized ID: 0x%02X\n", rtlhal->oem_id);
2261}
2262
2263void rtl8723be_read_eeprom_info(struct ieee80211_hw *hw)
2264{
2265 struct rtl_priv *rtlpriv = rtl_priv(hw);
2266 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2267 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2268 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2269 u8 tmp_u1b;
2270
2271 rtlhal->version = _rtl8723be_read_chip_version(hw);
2272 if (get_rf_type(rtlphy) == RF_1T1R)
2273 rtlpriv->dm.rfpath_rxenable[0] = true;
2274 else
2275 rtlpriv->dm.rfpath_rxenable[0] =
2276 rtlpriv->dm.rfpath_rxenable[1] = true;
2277 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
2278 rtlhal->version);
2279 tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
2280 if (tmp_u1b & BIT(4)) {
2281 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
2282 rtlefuse->epromtype = EEPROM_93C46;
2283 } else {
2284 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
2285 rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
2286 }
2287 if (tmp_u1b & BIT(5)) {
2288 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
2289 rtlefuse->autoload_failflag = false;
2290 _rtl8723be_read_adapter_info(hw, false);
2291 } else {
Larry Finger4e2b4372016-12-15 12:23:00 -06002292 pr_err("Autoload ERR!!\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06002293 }
2294 _rtl8723be_hal_customized_behavior(hw);
2295}
2296
Larry Fingera619d1a2014-02-28 15:16:50 -06002297static u8 _rtl8723be_mrate_idx_to_arfr_id(struct ieee80211_hw *hw,
2298 u8 rate_index)
2299{
2300 u8 ret = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002301 switch (rate_index) {
2302 case RATR_INX_WIRELESS_NGB:
2303 ret = 1;
2304 break;
2305 case RATR_INX_WIRELESS_N:
2306 case RATR_INX_WIRELESS_NG:
2307 ret = 5;
2308 break;
2309 case RATR_INX_WIRELESS_NB:
2310 ret = 3;
2311 break;
2312 case RATR_INX_WIRELESS_GB:
2313 ret = 6;
2314 break;
2315 case RATR_INX_WIRELESS_G:
2316 ret = 7;
2317 break;
2318 case RATR_INX_WIRELESS_B:
2319 ret = 8;
2320 break;
2321 default:
2322 ret = 0;
2323 break;
2324 }
2325 return ret;
2326}
2327
2328static void rtl8723be_update_hal_rate_mask(struct ieee80211_hw *hw,
2329 struct ieee80211_sta *sta,
Ping-Ke Shih1d22b172017-09-29 14:47:59 -05002330 u8 rssi_level, bool update_bw)
Larry Fingera619d1a2014-02-28 15:16:50 -06002331{
2332 struct rtl_priv *rtlpriv = rtl_priv(hw);
2333 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2334 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2335 struct rtl_sta_info *sta_entry = NULL;
2336 u32 ratr_bitmap;
2337 u8 ratr_index;
2338 u8 curtxbw_40mhz = (sta->ht_cap.cap &
Larry Finger5c99f042014-09-26 16:40:25 -05002339 IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002340 u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
Larry Finger5c99f042014-09-26 16:40:25 -05002341 1 : 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002342 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
Larry Finger5c99f042014-09-26 16:40:25 -05002343 1 : 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002344 enum wireless_mode wirelessmode = 0;
2345 bool shortgi = false;
2346 u8 rate_mask[7];
2347 u8 macid = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002348
2349 sta_entry = (struct rtl_sta_info *)sta->drv_priv;
2350 wirelessmode = sta_entry->wireless_mode;
2351 if (mac->opmode == NL80211_IFTYPE_STATION ||
2352 mac->opmode == NL80211_IFTYPE_MESH_POINT)
2353 curtxbw_40mhz = mac->bw_40;
2354 else if (mac->opmode == NL80211_IFTYPE_AP ||
2355 mac->opmode == NL80211_IFTYPE_ADHOC)
2356 macid = sta->aid + 1;
2357
2358 ratr_bitmap = sta->supp_rates[0];
2359
2360 if (mac->opmode == NL80211_IFTYPE_ADHOC)
2361 ratr_bitmap = 0xfff;
2362
2363 ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
2364 sta->ht_cap.mcs.rx_mask[0] << 12);
2365 switch (wirelessmode) {
2366 case WIRELESS_MODE_B:
2367 ratr_index = RATR_INX_WIRELESS_B;
2368 if (ratr_bitmap & 0x0000000c)
2369 ratr_bitmap &= 0x0000000d;
2370 else
2371 ratr_bitmap &= 0x0000000f;
2372 break;
2373 case WIRELESS_MODE_G:
2374 ratr_index = RATR_INX_WIRELESS_GB;
2375
2376 if (rssi_level == 1)
2377 ratr_bitmap &= 0x00000f00;
2378 else if (rssi_level == 2)
2379 ratr_bitmap &= 0x00000ff0;
2380 else
2381 ratr_bitmap &= 0x00000ff5;
2382 break;
Larry Fingera619d1a2014-02-28 15:16:50 -06002383 case WIRELESS_MODE_N_24G:
2384 case WIRELESS_MODE_N_5G:
2385 ratr_index = RATR_INX_WIRELESS_NGB;
Larry Finger5c99f042014-09-26 16:40:25 -05002386 if (rtlphy->rf_type == RF_1T1R) {
2387 if (curtxbw_40mhz) {
2388 if (rssi_level == 1)
2389 ratr_bitmap &= 0x000f0000;
2390 else if (rssi_level == 2)
2391 ratr_bitmap &= 0x000ff000;
2392 else
2393 ratr_bitmap &= 0x000ff015;
Larry Fingera619d1a2014-02-28 15:16:50 -06002394 } else {
Larry Finger5c99f042014-09-26 16:40:25 -05002395 if (rssi_level == 1)
2396 ratr_bitmap &= 0x000f0000;
2397 else if (rssi_level == 2)
2398 ratr_bitmap &= 0x000ff000;
2399 else
2400 ratr_bitmap &= 0x000ff005;
2401 }
2402 } else {
2403 if (curtxbw_40mhz) {
2404 if (rssi_level == 1)
2405 ratr_bitmap &= 0x0f8f0000;
2406 else if (rssi_level == 2)
2407 ratr_bitmap &= 0x0f8ff000;
2408 else
2409 ratr_bitmap &= 0x0f8ff015;
2410 } else {
2411 if (rssi_level == 1)
2412 ratr_bitmap &= 0x0f8f0000;
2413 else if (rssi_level == 2)
2414 ratr_bitmap &= 0x0f8ff000;
2415 else
2416 ratr_bitmap &= 0x0f8ff005;
Larry Fingera619d1a2014-02-28 15:16:50 -06002417 }
2418 }
2419 if ((curtxbw_40mhz && curshortgi_40mhz) ||
2420 (!curtxbw_40mhz && curshortgi_20mhz)) {
2421 if (macid == 0)
2422 shortgi = true;
2423 else if (macid == 1)
2424 shortgi = false;
2425 }
2426 break;
2427 default:
2428 ratr_index = RATR_INX_WIRELESS_NGB;
2429
2430 if (rtlphy->rf_type == RF_1T2R)
2431 ratr_bitmap &= 0x000ff0ff;
2432 else
2433 ratr_bitmap &= 0x0f0ff0ff;
2434 break;
2435 }
Larry Finger5c99f042014-09-26 16:40:25 -05002436
Larry Fingera619d1a2014-02-28 15:16:50 -06002437 sta_entry->ratr_index = ratr_index;
2438
2439 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2440 "ratr_bitmap :%x\n", ratr_bitmap);
Larry Finger5c99f042014-09-26 16:40:25 -05002441 *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
2442 (ratr_index << 28);
Larry Fingera619d1a2014-02-28 15:16:50 -06002443 rate_mask[0] = macid;
2444 rate_mask[1] = _rtl8723be_mrate_idx_to_arfr_id(hw, ratr_index) |
Larry Finger5c99f042014-09-26 16:40:25 -05002445 (shortgi ? 0x80 : 0x00);
Ping-Ke Shih1d22b172017-09-29 14:47:59 -05002446 rate_mask[2] = curtxbw_40mhz | ((!update_bw) << 3);
Larry Fingera619d1a2014-02-28 15:16:50 -06002447
2448 rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff);
2449 rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >> 8);
2450 rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16);
2451 rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24);
2452
2453 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2454 "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x:%x:%x\n",
2455 ratr_index, ratr_bitmap,
2456 rate_mask[0], rate_mask[1],
2457 rate_mask[2], rate_mask[3],
2458 rate_mask[4], rate_mask[5],
2459 rate_mask[6]);
Larry Finger5c99f042014-09-26 16:40:25 -05002460 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_RA_MASK, 7, rate_mask);
Larry Fingera619d1a2014-02-28 15:16:50 -06002461 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
2462}
2463
2464void rtl8723be_update_hal_rate_tbl(struct ieee80211_hw *hw,
2465 struct ieee80211_sta *sta,
Ping-Ke Shih1d22b172017-09-29 14:47:59 -05002466 u8 rssi_level, bool update_bw)
Larry Fingera619d1a2014-02-28 15:16:50 -06002467{
2468 struct rtl_priv *rtlpriv = rtl_priv(hw);
2469 if (rtlpriv->dm.useramask)
Ping-Ke Shih1d22b172017-09-29 14:47:59 -05002470 rtl8723be_update_hal_rate_mask(hw, sta, rssi_level, update_bw);
Larry Fingera619d1a2014-02-28 15:16:50 -06002471}
2472
2473void rtl8723be_update_channel_access_setting(struct ieee80211_hw *hw)
2474{
2475 struct rtl_priv *rtlpriv = rtl_priv(hw);
2476 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2477 u16 sifs_timer;
2478
Joe Perches9cb76aa2014-03-24 10:46:20 -07002479 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);
Larry Fingera619d1a2014-02-28 15:16:50 -06002480 if (!mac->ht_enable)
2481 sifs_timer = 0x0a0a;
2482 else
2483 sifs_timer = 0x0e0e;
2484 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
2485}
2486
2487bool rtl8723be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
2488{
2489 struct rtl_priv *rtlpriv = rtl_priv(hw);
2490 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2491 struct rtl_phy *rtlphy = &(rtlpriv->phy);
Christos Gkekas76d7b122017-10-11 22:15:15 +01002492 enum rf_pwrstate e_rfpowerstate_toset;
Larry Fingera619d1a2014-02-28 15:16:50 -06002493 u8 u1tmp;
Larry Finger5c99f042014-09-26 16:40:25 -05002494 bool b_actuallyset = false;
Larry Fingera619d1a2014-02-28 15:16:50 -06002495
2496 if (rtlpriv->rtlhal.being_init_adapter)
2497 return false;
2498
2499 if (ppsc->swrf_processing)
2500 return false;
2501
2502 spin_lock(&rtlpriv->locks.rf_ps_lock);
2503 if (ppsc->rfchange_inprogress) {
2504 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2505 return false;
2506 } else {
2507 ppsc->rfchange_inprogress = true;
2508 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2509 }
Larry Finger5c99f042014-09-26 16:40:25 -05002510
Larry Fingera619d1a2014-02-28 15:16:50 -06002511 rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2,
2512 rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2) & ~(BIT(1)));
2513
2514 u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2);
2515
2516 if (rtlphy->polarity_ctl)
2517 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON;
2518 else
2519 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF;
2520
Larry Finger5c99f042014-09-26 16:40:25 -05002521 if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002522 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2523 "GPIOChangeRF - HW Radio ON, RF ON\n");
2524
2525 e_rfpowerstate_toset = ERFON;
2526 ppsc->hwradiooff = false;
Larry Finger5c99f042014-09-26 16:40:25 -05002527 b_actuallyset = true;
2528 } else if (!ppsc->hwradiooff && (e_rfpowerstate_toset == ERFOFF)) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002529 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2530 "GPIOChangeRF - HW Radio OFF, RF OFF\n");
2531
2532 e_rfpowerstate_toset = ERFOFF;
2533 ppsc->hwradiooff = true;
Larry Finger5c99f042014-09-26 16:40:25 -05002534 b_actuallyset = true;
Larry Fingera619d1a2014-02-28 15:16:50 -06002535 }
Larry Finger5c99f042014-09-26 16:40:25 -05002536
2537 if (b_actuallyset) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002538 spin_lock(&rtlpriv->locks.rf_ps_lock);
2539 ppsc->rfchange_inprogress = false;
2540 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2541 } else {
2542 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
2543 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2544
2545 spin_lock(&rtlpriv->locks.rf_ps_lock);
2546 ppsc->rfchange_inprogress = false;
2547 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2548 }
Larry Finger5c99f042014-09-26 16:40:25 -05002549
Larry Fingera619d1a2014-02-28 15:16:50 -06002550 *valid = 1;
2551 return !ppsc->hwradiooff;
Larry Finger5c99f042014-09-26 16:40:25 -05002552
Larry Fingera619d1a2014-02-28 15:16:50 -06002553}
2554
2555void rtl8723be_set_key(struct ieee80211_hw *hw, u32 key_index,
2556 u8 *p_macaddr, bool is_group, u8 enc_algo,
2557 bool is_wepkey, bool clear_all)
2558{
2559 struct rtl_priv *rtlpriv = rtl_priv(hw);
2560 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2561 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2562 u8 *macaddr = p_macaddr;
2563 u32 entry_id = 0;
2564 bool is_pairwise = false;
2565
2566 static u8 cam_const_addr[4][6] = {
2567 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
2568 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
2569 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
2570 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
2571 };
2572 static u8 cam_const_broad[] = {
2573 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2574 };
2575
2576 if (clear_all) {
2577 u8 idx = 0;
2578 u8 cam_offset = 0;
2579 u8 clear_number = 5;
2580
2581 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
2582
2583 for (idx = 0; idx < clear_number; idx++) {
2584 rtl_cam_mark_invalid(hw, cam_offset + idx);
2585 rtl_cam_empty_entry(hw, cam_offset + idx);
2586
2587 if (idx < 5) {
2588 memset(rtlpriv->sec.key_buf[idx], 0,
2589 MAX_KEY_LEN);
2590 rtlpriv->sec.key_len[idx] = 0;
2591 }
2592 }
Larry Finger5c99f042014-09-26 16:40:25 -05002593
Larry Fingera619d1a2014-02-28 15:16:50 -06002594 } else {
2595 switch (enc_algo) {
2596 case WEP40_ENCRYPTION:
2597 enc_algo = CAM_WEP40;
2598 break;
2599 case WEP104_ENCRYPTION:
2600 enc_algo = CAM_WEP104;
2601 break;
2602 case TKIP_ENCRYPTION:
2603 enc_algo = CAM_TKIP;
2604 break;
2605 case AESCCMP_ENCRYPTION:
2606 enc_algo = CAM_AES;
2607 break;
2608 default:
Larry Finger5c99f042014-09-26 16:40:25 -05002609 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -07002610 "switch case %#x not processed\n", enc_algo);
Larry Fingera619d1a2014-02-28 15:16:50 -06002611 enc_algo = CAM_TKIP;
2612 break;
2613 }
2614
2615 if (is_wepkey || rtlpriv->sec.use_defaultkey) {
2616 macaddr = cam_const_addr[key_index];
2617 entry_id = key_index;
2618 } else {
2619 if (is_group) {
2620 macaddr = cam_const_broad;
2621 entry_id = key_index;
2622 } else {
2623 if (mac->opmode == NL80211_IFTYPE_AP) {
2624 entry_id = rtl_cam_get_free_entry(hw,
2625 p_macaddr);
2626 if (entry_id >= TOTAL_CAM_ENTRY) {
Larry Finger4e2b4372016-12-15 12:23:00 -06002627 pr_err("Can not find free hw security cam entry\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06002628 return;
2629 }
2630 } else {
2631 entry_id = CAM_PAIRWISE_KEY_POSITION;
2632 }
Larry Finger5c99f042014-09-26 16:40:25 -05002633
Larry Fingera619d1a2014-02-28 15:16:50 -06002634 key_index = PAIRWISE_KEYIDX;
2635 is_pairwise = true;
2636 }
2637 }
Larry Finger5c99f042014-09-26 16:40:25 -05002638
Larry Fingera619d1a2014-02-28 15:16:50 -06002639 if (rtlpriv->sec.key_len[key_index] == 0) {
2640 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2641 "delete one entry, entry_id is %d\n",
Larry Finger5c99f042014-09-26 16:40:25 -05002642 entry_id);
Larry Fingera619d1a2014-02-28 15:16:50 -06002643 if (mac->opmode == NL80211_IFTYPE_AP)
2644 rtl_cam_del_entry(hw, p_macaddr);
2645 rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
2646 } else {
2647 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2648 "add one entry\n");
2649 if (is_pairwise) {
2650 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
Colin Ian King6b9e6f62017-05-03 23:55:43 +01002651 "set Pairwise key\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06002652
2653 rtl_cam_add_one_entry(hw, macaddr, key_index,
Larry Finger5c99f042014-09-26 16:40:25 -05002654 entry_id, enc_algo,
2655 CAM_CONFIG_NO_USEDK,
2656 rtlpriv->sec.key_buf[key_index]);
Larry Fingera619d1a2014-02-28 15:16:50 -06002657 } else {
2658 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2659 "set group key\n");
2660
2661 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
2662 rtl_cam_add_one_entry(hw,
2663 rtlefuse->dev_addr,
2664 PAIRWISE_KEYIDX,
2665 CAM_PAIRWISE_KEY_POSITION,
2666 enc_algo,
2667 CAM_CONFIG_NO_USEDK,
2668 rtlpriv->sec.key_buf
2669 [entry_id]);
2670 }
Larry Finger5c99f042014-09-26 16:40:25 -05002671
Larry Fingera619d1a2014-02-28 15:16:50 -06002672 rtl_cam_add_one_entry(hw, macaddr, key_index,
Larry Finger5c99f042014-09-26 16:40:25 -05002673 entry_id, enc_algo,
2674 CAM_CONFIG_NO_USEDK,
2675 rtlpriv->sec.key_buf[entry_id]);
Larry Fingera619d1a2014-02-28 15:16:50 -06002676 }
2677 }
2678 }
2679}
2680
2681void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
2682 bool auto_load_fail, u8 *hwinfo)
2683{
2684 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Fingerc18d8f52016-03-16 13:33:34 -05002685 struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params;
Larry Fingera619d1a2014-02-28 15:16:50 -06002686 u8 value;
2687 u32 tmpu_32;
2688
2689 if (!auto_load_fail) {
2690 tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL);
2691 if (tmpu_32 & BIT(18))
2692 rtlpriv->btcoexist.btc_info.btcoexist = 1;
2693 else
2694 rtlpriv->btcoexist.btc_info.btcoexist = 0;
Larry Finger5c99f042014-09-26 16:40:25 -05002695 value = hwinfo[EEPROM_RF_BT_SETTING_8723B];
Larry Fingera619d1a2014-02-28 15:16:50 -06002696 rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2697 rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1);
Ping-Ke Shih0de9b5d2017-02-06 21:30:04 -06002698 rtlpriv->btcoexist.btc_info.single_ant_path =
2699 (value & 0x40); /*0xc3[6]*/
Larry Fingera619d1a2014-02-28 15:16:50 -06002700 } else {
2701 rtlpriv->btcoexist.btc_info.btcoexist = 0;
2702 rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2703 rtlpriv->btcoexist.btc_info.ant_num = ANT_X2;
Ping-Ke Shihdb8cb002017-02-06 21:30:03 -06002704 rtlpriv->btcoexist.btc_info.single_ant_path = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002705 }
Larry Finger5c99f042014-09-26 16:40:25 -05002706
Larry Fingerc18d8f52016-03-16 13:33:34 -05002707 /* override ant_num / ant_path */
Ping-Ke Shih0ff78ad2017-02-06 21:30:07 -06002708 if (mod_params->ant_sel) {
Larry Fingerc18d8f52016-03-16 13:33:34 -05002709 rtlpriv->btcoexist.btc_info.ant_num =
2710 (mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1);
Ping-Ke Shih0ff78ad2017-02-06 21:30:07 -06002711
2712 rtlpriv->btcoexist.btc_info.single_ant_path =
2713 (mod_params->ant_sel == 1 ? 0 : 1);
2714 }
Larry Fingera619d1a2014-02-28 15:16:50 -06002715}
2716
2717void rtl8723be_bt_reg_init(struct ieee80211_hw *hw)
2718{
2719 struct rtl_priv *rtlpriv = rtl_priv(hw);
2720
2721 /* 0:Low, 1:High, 2:From Efuse. */
2722 rtlpriv->btcoexist.reg_bt_iso = 2;
2723 /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */
2724 rtlpriv->btcoexist.reg_bt_sco = 3;
2725 /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
2726 rtlpriv->btcoexist.reg_bt_sco = 0;
2727}
2728
2729void rtl8723be_bt_hw_init(struct ieee80211_hw *hw)
2730{
2731 struct rtl_priv *rtlpriv = rtl_priv(hw);
2732
2733 if (rtlpriv->cfg->ops->get_btc_status())
2734 rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv);
Larry Finger5c99f042014-09-26 16:40:25 -05002735
Larry Fingera619d1a2014-02-28 15:16:50 -06002736}
2737
2738void rtl8723be_suspend(struct ieee80211_hw *hw)
2739{
2740}
2741
2742void rtl8723be_resume(struct ieee80211_hw *hw)
2743{
2744}