blob: aba60c3145c5f6f60b5e34cdbc7885d3042ae2f8 [file] [log] [blame]
Larry Fingera619d1a2014-02-28 15:16:50 -06001/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../efuse.h"
28#include "../base.h"
29#include "../regd.h"
30#include "../cam.h"
31#include "../ps.h"
32#include "../pci.h"
33#include "reg.h"
34#include "def.h"
35#include "phy.h"
Larry Finger5c99f042014-09-26 16:40:25 -050036#include "../rtl8723com/phy_common.h"
Larry Fingera619d1a2014-02-28 15:16:50 -060037#include "dm.h"
38#include "../rtl8723com/dm_common.h"
39#include "fw.h"
40#include "../rtl8723com/fw_common.h"
41#include "led.h"
42#include "hw.h"
Larry Finger34ed7802014-09-22 09:39:27 -050043#include "../pwrseqcmd.h"
Larry Fingera619d1a2014-02-28 15:16:50 -060044#include "pwrseq.h"
45#include "../btcoexist/rtl_btc.h"
46
47#define LLT_CONFIG 5
48
49static void _rtl8723be_return_beacon_queue_skb(struct ieee80211_hw *hw)
50{
51 struct rtl_priv *rtlpriv = rtl_priv(hw);
52 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
53 struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
Larry Finger5c99f042014-09-26 16:40:25 -050054 unsigned long flags;
Larry Fingera619d1a2014-02-28 15:16:50 -060055
Larry Finger5c99f042014-09-26 16:40:25 -050056 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
Larry Fingera619d1a2014-02-28 15:16:50 -060057 while (skb_queue_len(&ring->queue)) {
58 struct rtl_tx_desc *entry = &ring->desc[ring->idx];
59 struct sk_buff *skb = __skb_dequeue(&ring->queue);
60
61 pci_unmap_single(rtlpci->pdev,
62 rtlpriv->cfg->ops->get_desc(
63 (u8 *)entry, true, HW_DESC_TXBUFF_ADDR),
64 skb->len, PCI_DMA_TODEVICE);
65 kfree_skb(skb);
66 ring->idx = (ring->idx + 1) % ring->entries;
67 }
Larry Finger5c99f042014-09-26 16:40:25 -050068 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
Larry Fingera619d1a2014-02-28 15:16:50 -060069}
70
71static void _rtl8723be_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
72 u8 set_bits, u8 clear_bits)
73{
74 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
75 struct rtl_priv *rtlpriv = rtl_priv(hw);
76
77 rtlpci->reg_bcn_ctrl_val |= set_bits;
78 rtlpci->reg_bcn_ctrl_val &= ~clear_bits;
79
Larry Finger5c99f042014-09-26 16:40:25 -050080 rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlpci->reg_bcn_ctrl_val);
Larry Fingera619d1a2014-02-28 15:16:50 -060081}
82
83static void _rtl8723be_stop_tx_beacon(struct ieee80211_hw *hw)
84{
85 struct rtl_priv *rtlpriv = rtl_priv(hw);
86 u8 tmp1byte;
87
88 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
89 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6)));
90 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64);
91 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
92 tmp1byte &= ~(BIT(0));
93 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
94}
95
96static void _rtl8723be_resume_tx_beacon(struct ieee80211_hw *hw)
97{
98 struct rtl_priv *rtlpriv = rtl_priv(hw);
99 u8 tmp1byte;
100
101 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
102 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6));
103 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
104 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
105 tmp1byte |= BIT(1);
106 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
107}
108
109static void _rtl8723be_enable_bcn_sub_func(struct ieee80211_hw *hw)
110{
111 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(1));
112}
113
114static void _rtl8723be_disable_bcn_sub_func(struct ieee80211_hw *hw)
115{
116 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(1), 0);
117}
118
119static void _rtl8723be_set_fw_clock_on(struct ieee80211_hw *hw, u8 rpwm_val,
Larry Finger5c99f042014-09-26 16:40:25 -0500120 bool b_need_turn_off_ckk)
Larry Fingera619d1a2014-02-28 15:16:50 -0600121{
122 struct rtl_priv *rtlpriv = rtl_priv(hw);
123 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
Larry Finger5c99f042014-09-26 16:40:25 -0500124 bool b_support_remote_wake_up;
Larry Fingera619d1a2014-02-28 15:16:50 -0600125 u32 count = 0, isr_regaddr, content;
Larry Finger5c99f042014-09-26 16:40:25 -0500126 bool b_schedule_timer = b_need_turn_off_ckk;
Larry Fingera619d1a2014-02-28 15:16:50 -0600127 rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN,
Larry Finger5c99f042014-09-26 16:40:25 -0500128 (u8 *)(&b_support_remote_wake_up));
Larry Fingera619d1a2014-02-28 15:16:50 -0600129
130 if (!rtlhal->fw_ready)
131 return;
132 if (!rtlpriv->psc.fw_current_inpsmode)
133 return;
134
135 while (1) {
136 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
137 if (rtlhal->fw_clk_change_in_progress) {
138 while (rtlhal->fw_clk_change_in_progress) {
139 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
140 count++;
141 udelay(100);
142 if (count > 1000)
143 return;
144 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
145 }
146 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
147 } else {
148 rtlhal->fw_clk_change_in_progress = false;
149 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
150 break;
151 }
152 }
Larry Finger5c99f042014-09-26 16:40:25 -0500153
154 if (IS_IN_LOW_POWER_STATE(rtlhal->fw_ps_state)) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600155 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM,
Larry Finger5c99f042014-09-26 16:40:25 -0500156 (u8 *)(&rpwm_val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600157 if (FW_PS_IS_ACK(rpwm_val)) {
158 isr_regaddr = REG_HISR;
159 content = rtl_read_dword(rtlpriv, isr_regaddr);
160 while (!(content & IMR_CPWM) && (count < 500)) {
161 udelay(50);
162 count++;
163 content = rtl_read_dword(rtlpriv, isr_regaddr);
164 }
165
166 if (content & IMR_CPWM) {
167 rtl_write_word(rtlpriv, isr_regaddr, 0x0100);
Larry Finger5c99f042014-09-26 16:40:25 -0500168 rtlhal->fw_ps_state = FW_PS_STATE_RF_ON;
Larry Fingera619d1a2014-02-28 15:16:50 -0600169 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
Larry Finger5c99f042014-09-26 16:40:25 -0500170 "Receive CPWM INT!!! Set pHalData->FwPSState = %X\n",
Larry Fingera619d1a2014-02-28 15:16:50 -0600171 rtlhal->fw_ps_state);
172 }
173 }
Larry Finger5c99f042014-09-26 16:40:25 -0500174
Larry Fingera619d1a2014-02-28 15:16:50 -0600175 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
176 rtlhal->fw_clk_change_in_progress = false;
177 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
Larry Finger5c99f042014-09-26 16:40:25 -0500178 if (b_schedule_timer)
Larry Fingera619d1a2014-02-28 15:16:50 -0600179 mod_timer(&rtlpriv->works.fw_clockoff_timer,
180 jiffies + MSECS(10));
Larry Fingera619d1a2014-02-28 15:16:50 -0600181 } else {
182 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
183 rtlhal->fw_clk_change_in_progress = false;
184 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
185 }
186}
187
188static void _rtl8723be_set_fw_clock_off(struct ieee80211_hw *hw, u8 rpwm_val)
189{
190 struct rtl_priv *rtlpriv = rtl_priv(hw);
191 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
192 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
193 struct rtl8192_tx_ring *ring;
194 enum rf_pwrstate rtstate;
Larry Finger5c99f042014-09-26 16:40:25 -0500195 bool b_schedule_timer = false;
Larry Fingera619d1a2014-02-28 15:16:50 -0600196 u8 queue;
197
198 if (!rtlhal->fw_ready)
199 return;
200 if (!rtlpriv->psc.fw_current_inpsmode)
201 return;
202 if (!rtlhal->allow_sw_to_change_hwclc)
203 return;
204 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, (u8 *)(&rtstate));
205 if (rtstate == ERFOFF || rtlpriv->psc.inactive_pwrstate == ERFOFF)
206 return;
207
208 for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) {
209 ring = &rtlpci->tx_ring[queue];
210 if (skb_queue_len(&ring->queue)) {
Larry Finger5c99f042014-09-26 16:40:25 -0500211 b_schedule_timer = true;
Larry Fingera619d1a2014-02-28 15:16:50 -0600212 break;
213 }
214 }
Larry Finger5c99f042014-09-26 16:40:25 -0500215
216 if (b_schedule_timer) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600217 mod_timer(&rtlpriv->works.fw_clockoff_timer,
218 jiffies + MSECS(10));
219 return;
220 }
Larry Finger5c99f042014-09-26 16:40:25 -0500221
222 if (FW_PS_STATE(rtlhal->fw_ps_state) != FW_PS_STATE_RF_OFF_LOW_PWR) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600223 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
224 if (!rtlhal->fw_clk_change_in_progress) {
225 rtlhal->fw_clk_change_in_progress = true;
226 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
227 rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val);
228 rtl_write_word(rtlpriv, REG_HISR, 0x0100);
229 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
Larry Finger5c99f042014-09-26 16:40:25 -0500230 (u8 *)(&rpwm_val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600231 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
232 rtlhal->fw_clk_change_in_progress = false;
233 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
234 } else {
235 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
236 mod_timer(&rtlpriv->works.fw_clockoff_timer,
237 jiffies + MSECS(10));
238 }
239 }
Larry Finger5c99f042014-09-26 16:40:25 -0500240
Larry Fingera619d1a2014-02-28 15:16:50 -0600241}
242
243static void _rtl8723be_set_fw_ps_rf_on(struct ieee80211_hw *hw)
244{
245 u8 rpwm_val = 0;
Larry Finger5c99f042014-09-26 16:40:25 -0500246 rpwm_val |= (FW_PS_STATE_RF_OFF | FW_PS_ACK);
Larry Fingera619d1a2014-02-28 15:16:50 -0600247 _rtl8723be_set_fw_clock_on(hw, rpwm_val, true);
248}
249
250static void _rtl8723be_fwlps_leave(struct ieee80211_hw *hw)
251{
252 struct rtl_priv *rtlpriv = rtl_priv(hw);
253 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
254 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
255 bool fw_current_inps = false;
256 u8 rpwm_val = 0, fw_pwrmode = FW_PS_ACTIVE_MODE;
257
258 if (ppsc->low_power_enable) {
Larry Finger5c99f042014-09-26 16:40:25 -0500259 rpwm_val = (FW_PS_STATE_ALL_ON | FW_PS_ACK);/* RF on */
Larry Fingera619d1a2014-02-28 15:16:50 -0600260 _rtl8723be_set_fw_clock_on(hw, rpwm_val, false);
261 rtlhal->allow_sw_to_change_hwclc = false;
262 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
Larry Finger5c99f042014-09-26 16:40:25 -0500263 (u8 *)(&fw_pwrmode));
Larry Fingera619d1a2014-02-28 15:16:50 -0600264 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
265 (u8 *)(&fw_current_inps));
266 } else {
Larry Finger5c99f042014-09-26 16:40:25 -0500267 rpwm_val = FW_PS_STATE_ALL_ON; /* RF on */
268 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
269 (u8 *)(&rpwm_val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600270 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
Larry Finger5c99f042014-09-26 16:40:25 -0500271 (u8 *)(&fw_pwrmode));
Larry Fingera619d1a2014-02-28 15:16:50 -0600272 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
273 (u8 *)(&fw_current_inps));
274 }
Larry Finger5c99f042014-09-26 16:40:25 -0500275
Larry Fingera619d1a2014-02-28 15:16:50 -0600276}
277
278static void _rtl8723be_fwlps_enter(struct ieee80211_hw *hw)
279{
280 struct rtl_priv *rtlpriv = rtl_priv(hw);
281 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
282 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
283 bool fw_current_inps = true;
284 u8 rpwm_val;
285
286 if (ppsc->low_power_enable) {
Larry Finger5c99f042014-09-26 16:40:25 -0500287 rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR; /* RF off */
Larry Fingera619d1a2014-02-28 15:16:50 -0600288 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
289 (u8 *)(&fw_current_inps));
290 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
Larry Finger5c99f042014-09-26 16:40:25 -0500291 (u8 *)(&ppsc->fwctrl_psmode));
Larry Fingera619d1a2014-02-28 15:16:50 -0600292 rtlhal->allow_sw_to_change_hwclc = true;
293 _rtl8723be_set_fw_clock_off(hw, rpwm_val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600294 } else {
Larry Finger5c99f042014-09-26 16:40:25 -0500295 rpwm_val = FW_PS_STATE_RF_OFF; /* RF off */
Larry Fingera619d1a2014-02-28 15:16:50 -0600296 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
297 (u8 *)(&fw_current_inps));
298 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
Larry Finger5c99f042014-09-26 16:40:25 -0500299 (u8 *)(&ppsc->fwctrl_psmode));
300 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
301 (u8 *)(&rpwm_val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600302 }
Larry Finger5c99f042014-09-26 16:40:25 -0500303
Larry Fingera619d1a2014-02-28 15:16:50 -0600304}
305
306void rtl8723be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
307{
308 struct rtl_priv *rtlpriv = rtl_priv(hw);
309 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
310 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
311
312 switch (variable) {
313 case HW_VAR_RCR:
314 *((u32 *)(val)) = rtlpci->receive_config;
315 break;
316 case HW_VAR_RF_STATE:
317 *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
318 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500319 case HW_VAR_FWLPS_RF_ON:{
320 enum rf_pwrstate rfState;
Larry Fingera619d1a2014-02-28 15:16:50 -0600321 u32 val_rcr;
322
323 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE,
Larry Finger5c99f042014-09-26 16:40:25 -0500324 (u8 *)(&rfState));
325 if (rfState == ERFOFF) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600326 *((bool *)(val)) = true;
327 } else {
328 val_rcr = rtl_read_dword(rtlpriv, REG_RCR);
329 val_rcr &= 0x00070000;
330 if (val_rcr)
331 *((bool *)(val)) = false;
332 else
333 *((bool *)(val)) = true;
334 }
Larry Finger5c99f042014-09-26 16:40:25 -0500335 }
336 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600337 case HW_VAR_FW_PSMODE_STATUS:
338 *((bool *)(val)) = ppsc->fw_current_inpsmode;
339 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500340 case HW_VAR_CORRECT_TSF:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600341 u64 tsf;
342 u32 *ptsf_low = (u32 *)&tsf;
343 u32 *ptsf_high = ((u32 *)&tsf) + 1;
344
345 *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4));
346 *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
347
348 *((u64 *)(val)) = tsf;
Larry Finger5c99f042014-09-26 16:40:25 -0500349 }
350 break;
Larry Finger1cc49a52016-09-24 11:57:18 -0500351 case HAL_DEF_WOWLAN:
352 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600353 default:
Larry Finger5c99f042014-09-26 16:40:25 -0500354 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -0700355 "switch case %#x not processed\n", variable);
Larry Fingera619d1a2014-02-28 15:16:50 -0600356 break;
357 }
358}
359
Larry Finger5c99f042014-09-26 16:40:25 -0500360static void _rtl8723be_download_rsvd_page(struct ieee80211_hw *hw)
361{
362 struct rtl_priv *rtlpriv = rtl_priv(hw);
363 u8 tmp_regcr, tmp_reg422, bcnvalid_reg;
364 u8 count = 0, dlbcn_count = 0;
365 bool b_recover = false;
366
367 tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
368 rtl_write_byte(rtlpriv, REG_CR + 1,
369 (tmp_regcr | BIT(0)));
370
371 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3));
372 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0);
373
374 tmp_reg422 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
375 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422 & (~BIT(6)));
376 if (tmp_reg422 & BIT(6))
377 b_recover = true;
378
379 do {
380 bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL + 2);
381 rtl_write_byte(rtlpriv, REG_TDECTRL + 2,
382 (bcnvalid_reg | BIT(0)));
383 _rtl8723be_return_beacon_queue_skb(hw);
384
385 rtl8723be_set_fw_rsvdpagepkt(hw, 0);
386 bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL + 2);
387 count = 0;
388 while (!(bcnvalid_reg & BIT(0)) && count < 20) {
389 count++;
390 udelay(10);
391 bcnvalid_reg = rtl_read_byte(rtlpriv,
392 REG_TDECTRL + 2);
393 }
394 dlbcn_count++;
395 } while (!(bcnvalid_reg & BIT(0)) && dlbcn_count < 5);
396
397 if (bcnvalid_reg & BIT(0))
398 rtl_write_byte(rtlpriv, REG_TDECTRL + 2, BIT(0));
399
400 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
401 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4));
402
403 if (b_recover)
404 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422);
405
406 tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
407 rtl_write_byte(rtlpriv, REG_CR + 1, (tmp_regcr & ~(BIT(0))));
408}
409
Larry Fingera619d1a2014-02-28 15:16:50 -0600410void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
411{
412 struct rtl_priv *rtlpriv = rtl_priv(hw);
413 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
414 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
415 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
416 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
417 u8 idx;
418
419 switch (variable) {
420 case HW_VAR_ETHER_ADDR:
421 for (idx = 0; idx < ETH_ALEN; idx++)
422 rtl_write_byte(rtlpriv, (REG_MACID + idx), val[idx]);
423 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500424 case HW_VAR_BASIC_RATE:{
425 u16 b_rate_cfg = ((u16 *)val)[0];
Larry Fingera619d1a2014-02-28 15:16:50 -0600426 u8 rate_index = 0;
Larry Finger5c99f042014-09-26 16:40:25 -0500427 b_rate_cfg = b_rate_cfg & 0x15f;
428 b_rate_cfg |= 0x01;
429 rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff);
430 rtl_write_byte(rtlpriv, REG_RRSR + 1, (b_rate_cfg >> 8) & 0xff);
431 while (b_rate_cfg > 0x1) {
432 b_rate_cfg = (b_rate_cfg >> 1);
Larry Fingera619d1a2014-02-28 15:16:50 -0600433 rate_index++;
434 }
435 rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, rate_index);
Larry Finger5c99f042014-09-26 16:40:25 -0500436 }
437 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600438 case HW_VAR_BSSID:
439 for (idx = 0; idx < ETH_ALEN; idx++)
440 rtl_write_byte(rtlpriv, (REG_BSSID + idx), val[idx]);
Larry Finger5c99f042014-09-26 16:40:25 -0500441
Larry Fingera619d1a2014-02-28 15:16:50 -0600442 break;
443 case HW_VAR_SIFS:
444 rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]);
445 rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]);
446
447 rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]);
448 rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
449
450 if (!mac->ht_enable)
451 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, 0x0e0e);
452 else
453 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
454 *((u16 *)val));
455 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500456 case HW_VAR_SLOT_TIME:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600457 u8 e_aci;
458
459 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
460 "HW_VAR_SLOT_TIME %x\n", val[0]);
461
462 rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
463
464 for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
465 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
Larry Finger5c99f042014-09-26 16:40:25 -0500466 (u8 *)(&e_aci));
Larry Fingera619d1a2014-02-28 15:16:50 -0600467 }
Larry Finger5c99f042014-09-26 16:40:25 -0500468 }
469 break;
470 case HW_VAR_ACK_PREAMBLE:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600471 u8 reg_tmp;
Larry Finger5c99f042014-09-26 16:40:25 -0500472 u8 short_preamble = (bool)(*(u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600473 reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL + 2);
474 if (short_preamble) {
475 reg_tmp |= 0x02;
476 rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
477 } else {
478 reg_tmp &= 0xFD;
479 rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
480 }
Larry Finger5c99f042014-09-26 16:40:25 -0500481 }
Larry Fingera619d1a2014-02-28 15:16:50 -0600482 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500483 case HW_VAR_WPA_CONFIG:
484 rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val));
485 break;
486 case HW_VAR_AMPDU_MIN_SPACE:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600487 u8 min_spacing_to_set;
488 u8 sec_min_space;
489
Larry Finger5c99f042014-09-26 16:40:25 -0500490 min_spacing_to_set = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600491 if (min_spacing_to_set <= 7) {
492 sec_min_space = 0;
493
494 if (min_spacing_to_set < sec_min_space)
495 min_spacing_to_set = sec_min_space;
496
497 mac->min_space_cfg = ((mac->min_space_cfg & 0xf8) |
498 min_spacing_to_set);
499
500 *val = min_spacing_to_set;
501
502 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
503 "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
Larry Finger5c99f042014-09-26 16:40:25 -0500504 mac->min_space_cfg);
Larry Fingera619d1a2014-02-28 15:16:50 -0600505
506 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
507 mac->min_space_cfg);
508 }
Larry Finger5c99f042014-09-26 16:40:25 -0500509 }
510 break;
511 case HW_VAR_SHORTGI_DENSITY:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600512 u8 density_to_set;
513
Larry Finger5c99f042014-09-26 16:40:25 -0500514 density_to_set = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600515 mac->min_space_cfg |= (density_to_set << 3);
516
517 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
518 "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
Larry Finger5c99f042014-09-26 16:40:25 -0500519 mac->min_space_cfg);
Larry Fingera619d1a2014-02-28 15:16:50 -0600520
521 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
522 mac->min_space_cfg);
Larry Finger5c99f042014-09-26 16:40:25 -0500523 }
524 break;
525 case HW_VAR_AMPDU_FACTOR:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600526 u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9};
527 u8 factor_toset;
528 u8 *p_regtoset = NULL;
529 u8 index = 0;
530
531 p_regtoset = regtoset_normal;
532
Larry Finger5c99f042014-09-26 16:40:25 -0500533 factor_toset = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600534 if (factor_toset <= 3) {
535 factor_toset = (1 << (factor_toset + 2));
536 if (factor_toset > 0xf)
537 factor_toset = 0xf;
538
539 for (index = 0; index < 4; index++) {
540 if ((p_regtoset[index] & 0xf0) >
541 (factor_toset << 4))
542 p_regtoset[index] =
543 (p_regtoset[index] & 0x0f) |
544 (factor_toset << 4);
545
546 if ((p_regtoset[index] & 0x0f) > factor_toset)
547 p_regtoset[index] =
548 (p_regtoset[index] & 0xf0) |
549 (factor_toset);
550
551 rtl_write_byte(rtlpriv,
552 (REG_AGGLEN_LMT + index),
553 p_regtoset[index]);
Larry Finger5c99f042014-09-26 16:40:25 -0500554
Larry Fingera619d1a2014-02-28 15:16:50 -0600555 }
Larry Finger5c99f042014-09-26 16:40:25 -0500556
Larry Fingera619d1a2014-02-28 15:16:50 -0600557 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
558 "Set HW_VAR_AMPDU_FACTOR: %#x\n",
Larry Finger5c99f042014-09-26 16:40:25 -0500559 factor_toset);
Larry Fingera619d1a2014-02-28 15:16:50 -0600560 }
Larry Finger5c99f042014-09-26 16:40:25 -0500561 }
562 break;
563 case HW_VAR_AC_PARAM:{
564 u8 e_aci = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600565 rtl8723_dm_init_edca_turbo(hw);
566
567 if (rtlpci->acm_method != EACMWAY2_SW)
568 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
Larry Finger5c99f042014-09-26 16:40:25 -0500569 (u8 *)(&e_aci));
570 }
571 break;
572 case HW_VAR_ACM_CTRL:{
573 u8 e_aci = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600574 union aci_aifsn *p_aci_aifsn =
575 (union aci_aifsn *)(&(mac->ac[0].aifs));
576 u8 acm = p_aci_aifsn->f.acm;
577 u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);
578
579 acm_ctrl =
580 acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1);
581
582 if (acm) {
583 switch (e_aci) {
584 case AC0_BE:
585 acm_ctrl |= ACMHW_BEQEN;
586 break;
587 case AC2_VI:
588 acm_ctrl |= ACMHW_VIQEN;
589 break;
590 case AC3_VO:
591 acm_ctrl |= ACMHW_VOQEN;
592 break;
593 default:
594 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
Larry Finger5c99f042014-09-26 16:40:25 -0500595 "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
596 acm);
Larry Fingera619d1a2014-02-28 15:16:50 -0600597 break;
598 }
599 } else {
600 switch (e_aci) {
601 case AC0_BE:
602 acm_ctrl &= (~ACMHW_BEQEN);
603 break;
604 case AC2_VI:
605 acm_ctrl &= (~ACMHW_VIQEN);
606 break;
607 case AC3_VO:
Jes Sorensen52f57802015-02-06 17:24:32 -0500608 acm_ctrl &= (~ACMHW_VOQEN);
Larry Fingera619d1a2014-02-28 15:16:50 -0600609 break;
610 default:
Larry Finger5c99f042014-09-26 16:40:25 -0500611 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -0700612 "switch case %#x not processed\n",
613 e_aci);
Larry Fingera619d1a2014-02-28 15:16:50 -0600614 break;
615 }
616 }
Larry Finger5c99f042014-09-26 16:40:25 -0500617
Larry Fingera619d1a2014-02-28 15:16:50 -0600618 RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
Larry Finger5c99f042014-09-26 16:40:25 -0500619 "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
620 acm_ctrl);
Larry Fingera619d1a2014-02-28 15:16:50 -0600621 rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
Larry Finger5c99f042014-09-26 16:40:25 -0500622 }
623 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600624 case HW_VAR_RCR:
625 rtl_write_dword(rtlpriv, REG_RCR, ((u32 *)(val))[0]);
626 rtlpci->receive_config = ((u32 *)(val))[0];
627 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500628 case HW_VAR_RETRY_LIMIT:{
629 u8 retry_limit = ((u8 *)(val))[0];
Larry Fingera619d1a2014-02-28 15:16:50 -0600630
631 rtl_write_word(rtlpriv, REG_RL,
632 retry_limit << RETRY_LIMIT_SHORT_SHIFT |
633 retry_limit << RETRY_LIMIT_LONG_SHIFT);
Larry Finger5c99f042014-09-26 16:40:25 -0500634 }
635 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600636 case HW_VAR_DUAL_TSF_RST:
637 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
638 break;
639 case HW_VAR_EFUSE_BYTES:
640 rtlefuse->efuse_usedbytes = *((u16 *)val);
641 break;
642 case HW_VAR_EFUSE_USAGE:
Larry Finger5c99f042014-09-26 16:40:25 -0500643 rtlefuse->efuse_usedpercentage = *((u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600644 break;
645 case HW_VAR_IO_CMD:
646 rtl8723be_phy_set_io_cmd(hw, (*(enum io_type *)val));
647 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500648 case HW_VAR_SET_RPWM:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600649 u8 rpwm_val;
650
651 rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM);
652 udelay(1);
653
654 if (rpwm_val & BIT(7)) {
Larry Finger5c99f042014-09-26 16:40:25 -0500655 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, (*(u8 *)val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600656 } else {
Larry Finger5c99f042014-09-26 16:40:25 -0500657 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
658 ((*(u8 *)val) | BIT(7)));
Larry Fingera619d1a2014-02-28 15:16:50 -0600659 }
Larry Finger5c99f042014-09-26 16:40:25 -0500660 }
661 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600662 case HW_VAR_H2C_FW_PWRMODE:
Larry Finger5c99f042014-09-26 16:40:25 -0500663 rtl8723be_set_fw_pwrmode_cmd(hw, (*(u8 *)val));
Larry Fingera619d1a2014-02-28 15:16:50 -0600664 break;
665 case HW_VAR_FW_PSMODE_STATUS:
666 ppsc->fw_current_inpsmode = *((bool *)val);
667 break;
668 case HW_VAR_RESUME_CLK_ON:
669 _rtl8723be_set_fw_ps_rf_on(hw);
670 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500671 case HW_VAR_FW_LPS_ACTION:{
672 bool b_enter_fwlps = *((bool *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600673
Larry Finger5c99f042014-09-26 16:40:25 -0500674 if (b_enter_fwlps)
Larry Fingera619d1a2014-02-28 15:16:50 -0600675 _rtl8723be_fwlps_enter(hw);
676 else
677 _rtl8723be_fwlps_leave(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500678 }
679 break;
680 case HW_VAR_H2C_FW_JOINBSSRPT:{
681 u8 mstatus = (*(u8 *)val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600682
683 if (mstatus == RT_MEDIA_CONNECT) {
684 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL);
Larry Finger5c99f042014-09-26 16:40:25 -0500685 _rtl8723be_download_rsvd_page(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -0600686 }
Larry Finger5c99f042014-09-26 16:40:25 -0500687 rtl8723be_set_fw_media_status_rpt_cmd(hw, mstatus);
688 }
Larry Fingera619d1a2014-02-28 15:16:50 -0600689 break;
Larry Finger5c99f042014-09-26 16:40:25 -0500690 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
691 rtl8723be_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
692 break;
693 case HW_VAR_AID:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600694 u16 u2btmp;
695 u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
696 u2btmp &= 0xC000;
697 rtl_write_word(rtlpriv, REG_BCN_PSR_RPT,
698 (u2btmp | mac->assoc_id));
Larry Finger5c99f042014-09-26 16:40:25 -0500699 }
700 break;
701 case HW_VAR_CORRECT_TSF:{
702 u8 btype_ibss = ((u8 *)(val))[0];
Larry Fingera619d1a2014-02-28 15:16:50 -0600703
704 if (btype_ibss)
705 _rtl8723be_stop_tx_beacon(hw);
706
707 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3));
708
709 rtl_write_dword(rtlpriv, REG_TSFTR,
710 (u32) (mac->tsf & 0xffffffff));
711 rtl_write_dword(rtlpriv, REG_TSFTR + 4,
712 (u32) ((mac->tsf >> 32) & 0xffffffff));
713
714 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
715
716 if (btype_ibss)
717 _rtl8723be_resume_tx_beacon(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500718 }
719 break;
720 case HW_VAR_KEEP_ALIVE:{
Larry Fingera619d1a2014-02-28 15:16:50 -0600721 u8 array[2];
722 array[0] = 0xff;
Larry Finger5c99f042014-09-26 16:40:25 -0500723 array[1] = *((u8 *)val);
724 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_KEEP_ALIVE_CTRL, 2, array);
725 }
726 break;
Larry Fingera619d1a2014-02-28 15:16:50 -0600727 default:
Larry Finger5c99f042014-09-26 16:40:25 -0500728 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -0700729 "switch case %#x not processed\n", variable);
Larry Fingera619d1a2014-02-28 15:16:50 -0600730 break;
731 }
732}
733
734static bool _rtl8723be_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
735{
736 struct rtl_priv *rtlpriv = rtl_priv(hw);
737 bool status = true;
Larry Finger5c99f042014-09-26 16:40:25 -0500738 long count = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -0600739 u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) |
740 _LLT_OP(_LLT_WRITE_ACCESS);
741
742 rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
743
744 do {
745 value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
746 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
747 break;
748
749 if (count > POLLING_LLT_THRESHOLD) {
750 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
Larry Finger5c99f042014-09-26 16:40:25 -0500751 "Failed to polling write LLT done at address %d!\n",
752 address);
Larry Fingera619d1a2014-02-28 15:16:50 -0600753 status = false;
754 break;
755 }
756 } while (++count);
757
758 return status;
759}
760
761static bool _rtl8723be_llt_table_init(struct ieee80211_hw *hw)
762{
763 struct rtl_priv *rtlpriv = rtl_priv(hw);
764 unsigned short i;
765 u8 txpktbuf_bndy;
Larry Finger5c99f042014-09-26 16:40:25 -0500766 u8 maxPage;
Larry Fingera619d1a2014-02-28 15:16:50 -0600767 bool status;
768
Larry Finger5c99f042014-09-26 16:40:25 -0500769 maxPage = 255;
Larry Fingera619d1a2014-02-28 15:16:50 -0600770 txpktbuf_bndy = 245;
771
772 rtl_write_dword(rtlpriv, REG_TRXFF_BNDY,
773 (0x27FF0000 | txpktbuf_bndy));
774 rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy);
775
776 rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
777 rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
778
779 rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy);
780 rtl_write_byte(rtlpriv, REG_PBP, 0x31);
781 rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);
782
783 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
784 status = _rtl8723be_llt_write(hw, i, i + 1);
785 if (!status)
786 return status;
787 }
Larry Finger5c99f042014-09-26 16:40:25 -0500788
Larry Fingera619d1a2014-02-28 15:16:50 -0600789 status = _rtl8723be_llt_write(hw, (txpktbuf_bndy - 1), 0xFF);
790
791 if (!status)
792 return status;
793
Larry Finger5c99f042014-09-26 16:40:25 -0500794 for (i = txpktbuf_bndy; i < maxPage; i++) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600795 status = _rtl8723be_llt_write(hw, i, (i + 1));
796 if (!status)
797 return status;
798 }
Larry Finger5c99f042014-09-26 16:40:25 -0500799
800 status = _rtl8723be_llt_write(hw, maxPage, txpktbuf_bndy);
Larry Fingera619d1a2014-02-28 15:16:50 -0600801 if (!status)
802 return status;
803
804 rtl_write_dword(rtlpriv, REG_RQPN, 0x80e40808);
805 rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x00);
806
807 return true;
808}
809
810static void _rtl8723be_gen_refresh_led_state(struct ieee80211_hw *hw)
811{
812 struct rtl_priv *rtlpriv = rtl_priv(hw);
813 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
814 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
815 struct rtl_led *pled0 = &(pcipriv->ledctl.sw_led0);
816
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);
1128 _rtl8723be_dbi_write(rtlpriv, 0x70f, tmp8 | BIT(7));
1129
1130 /* Configuration Space offset 0x719 Bit3 is for L1
1131 * BIT4 is for clock request
1132 */
1133 tmp8 = _rtl8723be_dbi_read(rtlpriv, 0x719);
1134 _rtl8723be_dbi_write(rtlpriv, 0x719, tmp8 | BIT(3) | BIT(4));
Larry Fingera619d1a2014-02-28 15:16:50 -06001135}
1136
1137void rtl8723be_enable_hw_security_config(struct ieee80211_hw *hw)
1138{
1139 struct rtl_priv *rtlpriv = rtl_priv(hw);
1140 u8 sec_reg_value;
1141
1142 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1143 "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
Larry Finger5c99f042014-09-26 16:40:25 -05001144 rtlpriv->sec.pairwise_enc_algorithm,
1145 rtlpriv->sec.group_enc_algorithm);
Larry Fingera619d1a2014-02-28 15:16:50 -06001146
1147 if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
1148 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1149 "not open hw encryption\n");
1150 return;
1151 }
Larry Finger5c99f042014-09-26 16:40:25 -05001152
Larry Fingera619d1a2014-02-28 15:16:50 -06001153 sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE;
1154
1155 if (rtlpriv->sec.use_defaultkey) {
1156 sec_reg_value |= SCR_TXUSEDK;
1157 sec_reg_value |= SCR_RXUSEDK;
1158 }
Larry Finger5c99f042014-09-26 16:40:25 -05001159
Larry Fingera619d1a2014-02-28 15:16:50 -06001160 sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
1161
1162 rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
1163
Larry Finger5c99f042014-09-26 16:40:25 -05001164 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1165 "The SECR-value %x\n", sec_reg_value);
Larry Fingera619d1a2014-02-28 15:16:50 -06001166
1167 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
1168}
1169
Larry Finger5c99f042014-09-26 16:40:25 -05001170static void _rtl8723be_poweroff_adapter(struct ieee80211_hw *hw)
1171{
1172 struct rtl_priv *rtlpriv = rtl_priv(hw);
1173 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1174 u8 u1b_tmp;
1175
1176 rtlhal->mac_func_enable = false;
1177 /* Combo (PCIe + USB) Card and PCIe-MF Card */
1178 /* 1. Run LPS WL RFOFF flow */
1179 rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1180 PWR_INTF_PCI_MSK, RTL8723_NIC_LPS_ENTER_FLOW);
1181
1182 /* 2. 0x1F[7:0] = 0 */
1183 /* turn off RF */
1184 /* rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); */
1185 if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) &&
1186 rtlhal->fw_ready) {
1187 rtl8723be_firmware_selfreset(hw);
1188 }
1189
1190 /* Reset MCU. Suggested by Filen. */
1191 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1192 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2))));
1193
1194 /* g. MCUFWDL 0x80[1:0]=0 */
1195 /* reset MCU ready status */
1196 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
1197
1198 /* HW card disable configuration. */
1199 rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1200 PWR_INTF_PCI_MSK, RTL8723_NIC_DISABLE_FLOW);
1201
1202 /* Reset MCU IO Wrapper */
1203 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1204 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0))));
1205 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1206 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1b_tmp | BIT(0));
1207
1208 /* 7. RSV_CTRL 0x1C[7:0] = 0x0E */
1209 /* lock ISO/CLK/Power control register */
1210 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e);
1211}
1212
1213static bool _rtl8723be_check_pcie_dma_hang(struct rtl_priv *rtlpriv)
1214{
1215 u8 tmp;
1216
1217 /* write reg 0x350 Bit[26]=1. Enable debug port. */
1218 tmp = rtl_read_byte(rtlpriv, REG_DBI_CTRL + 3);
1219 if (!(tmp & BIT(2))) {
1220 rtl_write_byte(rtlpriv, REG_DBI_CTRL + 3, (tmp | BIT(2)));
1221 mdelay(100); /* Suggested by DD Justin_tsai. */
1222 }
1223
1224 /* read reg 0x350 Bit[25] if 1 : RX hang
1225 * read reg 0x350 Bit[24] if 1 : TX hang
1226 */
1227 tmp = rtl_read_byte(rtlpriv, REG_DBI_CTRL + 3);
1228 if ((tmp & BIT(0)) || (tmp & BIT(1))) {
1229 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1230 "CheckPcieDMAHang8723BE(): true!!\n");
1231 return true;
1232 }
1233 return false;
1234}
1235
1236static void _rtl8723be_reset_pcie_interface_dma(struct rtl_priv *rtlpriv,
1237 bool mac_power_on)
1238{
1239 u8 tmp;
1240 bool release_mac_rx_pause;
1241 u8 backup_pcie_dma_pause;
1242
1243 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1244 "ResetPcieInterfaceDMA8723BE()\n");
1245
1246 /* Revise Note: Follow the document "PCIe RX DMA Hang Reset Flow_v03"
1247 * released by SD1 Alan.
1248 * 2013.05.07, by tynli.
1249 */
1250
1251 /* 1. disable register write lock
1252 * write 0x1C bit[1:0] = 2'h0
1253 * write 0xCC bit[2] = 1'b1
1254 */
1255 tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL);
1256 tmp &= ~(BIT(1) | BIT(0));
1257 rtl_write_byte(rtlpriv, REG_RSV_CTRL, tmp);
1258 tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2);
1259 tmp |= BIT(2);
1260 rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp);
1261
1262 /* 2. Check and pause TRX DMA
1263 * write 0x284 bit[18] = 1'b1
1264 * write 0x301 = 0xFF
1265 */
1266 tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1267 if (tmp & BIT(2)) {
1268 /* Already pause before the function for another purpose. */
1269 release_mac_rx_pause = false;
1270 } else {
1271 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, (tmp | BIT(2)));
1272 release_mac_rx_pause = true;
1273 }
1274
1275 backup_pcie_dma_pause = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 1);
1276 if (backup_pcie_dma_pause != 0xFF)
1277 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xFF);
1278
1279 if (mac_power_on) {
1280 /* 3. reset TRX function
1281 * write 0x100 = 0x00
1282 */
1283 rtl_write_byte(rtlpriv, REG_CR, 0);
1284 }
1285
1286 /* 4. Reset PCIe DMA
1287 * write 0x003 bit[0] = 0
1288 */
1289 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1290 tmp &= ~(BIT(0));
1291 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp);
1292
1293 /* 5. Enable PCIe DMA
1294 * write 0x003 bit[0] = 1
1295 */
1296 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1297 tmp |= BIT(0);
1298 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp);
1299
1300 if (mac_power_on) {
1301 /* 6. enable TRX function
1302 * write 0x100 = 0xFF
1303 */
1304 rtl_write_byte(rtlpriv, REG_CR, 0xFF);
1305
1306 /* We should init LLT & RQPN and
1307 * prepare Tx/Rx descrptor address later
1308 * because MAC function is reset.
1309 */
1310 }
1311
1312 /* 7. Restore PCIe autoload down bit
1313 * write 0xF8 bit[17] = 1'b1
1314 */
1315 tmp = rtl_read_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2);
1316 tmp |= BIT(1);
1317 rtl_write_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2, tmp);
1318
1319 /* In MAC power on state, BB and RF maybe in ON state,
1320 * if we release TRx DMA here
1321 * it will cause packets to be started to Tx/Rx,
1322 * so we release Tx/Rx DMA later.
1323 */
1324 if (!mac_power_on) {
1325 /* 8. release TRX DMA
1326 * write 0x284 bit[18] = 1'b0
1327 * write 0x301 = 0x00
1328 */
1329 if (release_mac_rx_pause) {
1330 tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1331 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL,
1332 (tmp & (~BIT(2))));
1333 }
1334 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1,
1335 backup_pcie_dma_pause);
1336 }
1337
1338 /* 9. lock system register
1339 * write 0xCC bit[2] = 1'b0
1340 */
1341 tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2);
1342 tmp &= ~(BIT(2));
1343 rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp);
1344}
1345
Larry Fingera619d1a2014-02-28 15:16:50 -06001346int rtl8723be_hw_init(struct ieee80211_hw *hw)
1347{
1348 struct rtl_priv *rtlpriv = rtl_priv(hw);
1349 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1350 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1351 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1352 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1353 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1354 bool rtstatus = true;
1355 int err;
1356 u8 tmp_u1b;
1357 unsigned long flags;
1358
1359 /* reenable interrupts to not interfere with other devices */
1360 local_save_flags(flags);
1361 local_irq_enable();
1362
Larry Finger5c99f042014-09-26 16:40:25 -05001363 rtlhal->fw_ready = false;
Larry Fingera619d1a2014-02-28 15:16:50 -06001364 rtlpriv->rtlhal.being_init_adapter = true;
1365 rtlpriv->intf_ops->disable_aspm(hw);
Larry Finger5c99f042014-09-26 16:40:25 -05001366
1367 tmp_u1b = rtl_read_byte(rtlpriv, REG_CR);
1368 if (tmp_u1b != 0 && tmp_u1b != 0xea) {
1369 rtlhal->mac_func_enable = true;
1370 } else {
1371 rtlhal->mac_func_enable = false;
1372 rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON;
1373 }
1374
1375 if (_rtl8723be_check_pcie_dma_hang(rtlpriv)) {
1376 _rtl8723be_reset_pcie_interface_dma(rtlpriv,
1377 rtlhal->mac_func_enable);
1378 rtlhal->mac_func_enable = false;
1379 }
1380 if (rtlhal->mac_func_enable) {
1381 _rtl8723be_poweroff_adapter(hw);
1382 rtlhal->mac_func_enable = false;
1383 }
Larry Fingera619d1a2014-02-28 15:16:50 -06001384 rtstatus = _rtl8723be_init_mac(hw);
1385 if (!rtstatus) {
1386 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n");
1387 err = 1;
1388 goto exit;
1389 }
Larry Fingera619d1a2014-02-28 15:16:50 -06001390
Larry Finger5c99f042014-09-26 16:40:25 -05001391 tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CFG);
1392 rtl_write_byte(rtlpriv, REG_SYS_CFG, tmp_u1b & 0x7F);
1393
1394 err = rtl8723_download_fw(hw, true, FW_8723B_POLLING_TIMEOUT_COUNT);
Larry Fingera619d1a2014-02-28 15:16:50 -06001395 if (err) {
1396 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1397 "Failed to download FW. Init HW without FW now..\n");
1398 err = 1;
Larry Fingera619d1a2014-02-28 15:16:50 -06001399 goto exit;
Larry Fingera619d1a2014-02-28 15:16:50 -06001400 }
Larry Finger5c99f042014-09-26 16:40:25 -05001401 rtlhal->fw_ready = true;
1402
Larry Fingera619d1a2014-02-28 15:16:50 -06001403 rtlhal->last_hmeboxnum = 0;
1404 rtl8723be_phy_mac_config(hw);
1405 /* because last function modify RCR, so we update
1406 * rcr var here, or TP will unstable for receive_config
Larry Finger5c99f042014-09-26 16:40:25 -05001407 * is wrong, RX RCR_ACRC32 will cause TP unstable & Rx
Larry Fingera619d1a2014-02-28 15:16:50 -06001408 * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252
1409 */
1410 rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR);
1411 rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
1412 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
1413
1414 rtl8723be_phy_bb_config(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -06001415 rtl8723be_phy_rf_config(hw);
1416
1417 rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
1418 RF_CHNLBW, RFREG_OFFSET_MASK);
1419 rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1,
1420 RF_CHNLBW, RFREG_OFFSET_MASK);
1421 rtlphy->rfreg_chnlval[0] &= 0xFFF03FF;
1422 rtlphy->rfreg_chnlval[0] |= (BIT(10) | BIT(11));
1423
Larry Fingera619d1a2014-02-28 15:16:50 -06001424 _rtl8723be_hw_configure(hw);
Larry Finger5c99f042014-09-26 16:40:25 -05001425 rtlhal->mac_func_enable = true;
Larry Fingera619d1a2014-02-28 15:16:50 -06001426 rtl_cam_reset_all_entry(hw);
1427 rtl8723be_enable_hw_security_config(hw);
1428
1429 ppsc->rfpwr_state = ERFON;
1430
1431 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
1432 _rtl8723be_enable_aspm_back_door(hw);
1433 rtlpriv->intf_ops->enable_aspm(hw);
1434
1435 rtl8723be_bt_hw_init(hw);
1436
Larry Fingera619d1a2014-02-28 15:16:50 -06001437 if (ppsc->rfpwr_state == ERFON) {
Larry Finger5c99f042014-09-26 16:40:25 -05001438 rtl8723be_phy_set_rfpath_switch(hw, 1);
1439 /* when use 1ant NIC, iqk will disturb BT music
1440 * root cause is not clear now, is something
1441 * related with 'mdelay' and Reg[0x948]
1442 */
1443 if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2 ||
1444 !rtlpriv->cfg->ops->get_btc_status()) {
1445 rtl8723be_phy_iq_calibrate(hw, false);
1446 rtlphy->iqk_initialized = true;
1447 }
Larry Fingera619d1a2014-02-28 15:16:50 -06001448 rtl8723be_dm_check_txpower_tracking(hw);
1449 rtl8723be_phy_lc_calibrate(hw);
1450 }
Larry Finger5c99f042014-09-26 16:40:25 -05001451 rtl_write_byte(rtlpriv, REG_NAV_UPPER, ((30000 + 127) / 128));
1452
1453 /* Release Rx DMA. */
1454 tmp_u1b = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1455 if (tmp_u1b & BIT(2)) {
1456 /* Release Rx DMA if needed */
1457 tmp_u1b &= (~BIT(2));
1458 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, tmp_u1b);
Larry Fingera619d1a2014-02-28 15:16:50 -06001459 }
Larry Finger5c99f042014-09-26 16:40:25 -05001460 /* Release Tx/Rx PCIE DMA. */
1461 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0);
1462
Larry Fingera619d1a2014-02-28 15:16:50 -06001463 rtl8723be_dm_init(hw);
1464exit:
1465 local_irq_restore(flags);
1466 rtlpriv->rtlhal.being_init_adapter = false;
1467 return err;
1468}
1469
1470static enum version_8723e _rtl8723be_read_chip_version(struct ieee80211_hw *hw)
1471{
1472 struct rtl_priv *rtlpriv = rtl_priv(hw);
1473 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1474 enum version_8723e version = VERSION_UNKNOWN;
Larry Fingera619d1a2014-02-28 15:16:50 -06001475 u32 value32;
1476
Larry Fingera619d1a2014-02-28 15:16:50 -06001477 value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG1);
1478 if ((value32 & (CHIP_8723B)) != CHIP_8723B)
Masanari Iida8a190232016-06-29 12:37:19 +09001479 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "unknown chip version\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06001480 else
Larry Finger5c99f042014-09-26 16:40:25 -05001481 version = (enum version_8723e)CHIP_8723B;
Larry Fingera619d1a2014-02-28 15:16:50 -06001482
Larry Finger5c99f042014-09-26 16:40:25 -05001483 rtlphy->rf_type = RF_1T1R;
Larry Fingera619d1a2014-02-28 15:16:50 -06001484
Larry Finger5c99f042014-09-26 16:40:25 -05001485 /* treat rtl8723be chip as MP version in default */
1486 version = (enum version_8723e)(version | NORMAL_CHIP);
1487
1488 value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
1489 /* cut version */
1490 version |= (enum version_8723e)(value32 & CHIP_VER_RTL_MASK);
1491 /* Manufacture */
1492 if (((value32 & EXT_VENDOR_ID) >> 18) == 0x01)
1493 version = (enum version_8723e)(version | CHIP_VENDOR_SMIC);
1494
Larry Fingera619d1a2014-02-28 15:16:50 -06001495 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1496 "Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
Larry Finger5c99f042014-09-26 16:40:25 -05001497 "RF_2T2R" : "RF_1T1R");
Larry Fingera619d1a2014-02-28 15:16:50 -06001498
1499 return version;
1500}
1501
1502static int _rtl8723be_set_media_status(struct ieee80211_hw *hw,
1503 enum nl80211_iftype type)
1504{
1505 struct rtl_priv *rtlpriv = rtl_priv(hw);
1506 u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc;
1507 enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
Larry Finger5c99f042014-09-26 16:40:25 -05001508 u8 mode = MSR_NOLINK;
Larry Fingera619d1a2014-02-28 15:16:50 -06001509
Larry Fingera619d1a2014-02-28 15:16:50 -06001510 switch (type) {
1511 case NL80211_IFTYPE_UNSPECIFIED:
Larry Finger5c99f042014-09-26 16:40:25 -05001512 mode = MSR_NOLINK;
Larry Fingera619d1a2014-02-28 15:16:50 -06001513 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1514 "Set Network type to NO LINK!\n");
1515 break;
1516 case NL80211_IFTYPE_ADHOC:
Larry Finger5c99f042014-09-26 16:40:25 -05001517 case NL80211_IFTYPE_MESH_POINT:
1518 mode = MSR_ADHOC;
Larry Fingera619d1a2014-02-28 15:16:50 -06001519 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1520 "Set Network type to Ad Hoc!\n");
1521 break;
1522 case NL80211_IFTYPE_STATION:
Larry Finger5c99f042014-09-26 16:40:25 -05001523 mode = MSR_INFRA;
Larry Fingera619d1a2014-02-28 15:16:50 -06001524 ledaction = LED_CTL_LINK;
1525 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1526 "Set Network type to STA!\n");
1527 break;
1528 case NL80211_IFTYPE_AP:
Larry Finger5c99f042014-09-26 16:40:25 -05001529 mode = MSR_AP;
1530 ledaction = LED_CTL_LINK;
Larry Fingera619d1a2014-02-28 15:16:50 -06001531 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1532 "Set Network type to AP!\n");
1533 break;
1534 default:
1535 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1536 "Network type %d not support!\n", type);
1537 return 1;
1538 }
Larry Finger5c99f042014-09-26 16:40:25 -05001539
1540 /* MSR_INFRA == Link in infrastructure network;
1541 * MSR_ADHOC == Link in ad hoc network;
1542 * Therefore, check link state is necessary.
1543 *
1544 * MSR_AP == AP mode; link state is not cared here.
1545 */
1546 if (mode != MSR_AP && rtlpriv->mac80211.link_state < MAC80211_LINKED) {
1547 mode = MSR_NOLINK;
1548 ledaction = LED_CTL_NO_LINK;
1549 }
1550
1551 if (mode == MSR_NOLINK || mode == MSR_INFRA) {
1552 _rtl8723be_stop_tx_beacon(hw);
1553 _rtl8723be_enable_bcn_sub_func(hw);
1554 } else if (mode == MSR_ADHOC || mode == MSR_AP) {
1555 _rtl8723be_resume_tx_beacon(hw);
1556 _rtl8723be_disable_bcn_sub_func(hw);
1557 } else {
1558 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1559 "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n",
1560 mode);
1561 }
1562
Taehee Yooe480e132015-03-20 19:31:33 +09001563 rtl_write_byte(rtlpriv, MSR, bt_msr | mode);
Larry Fingera619d1a2014-02-28 15:16:50 -06001564 rtlpriv->cfg->ops->led_control(hw, ledaction);
Larry Finger5c99f042014-09-26 16:40:25 -05001565 if (mode == MSR_AP)
Larry Fingera619d1a2014-02-28 15:16:50 -06001566 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1567 else
1568 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
1569 return 0;
1570}
1571
1572void rtl8723be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1573{
1574 struct rtl_priv *rtlpriv = rtl_priv(hw);
1575 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1576 u32 reg_rcr = rtlpci->receive_config;
1577
1578 if (rtlpriv->psc.rfpwr_state != ERFON)
1579 return;
1580
1581 if (check_bssid) {
1582 reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1583 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1584 (u8 *)(&reg_rcr));
1585 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4));
1586 } else if (!check_bssid) {
1587 reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
1588 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0);
1589 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1590 (u8 *)(&reg_rcr));
1591 }
Larry Finger5c99f042014-09-26 16:40:25 -05001592
Larry Fingera619d1a2014-02-28 15:16:50 -06001593}
1594
1595int rtl8723be_set_network_type(struct ieee80211_hw *hw,
1596 enum nl80211_iftype type)
1597{
1598 struct rtl_priv *rtlpriv = rtl_priv(hw);
1599
1600 if (_rtl8723be_set_media_status(hw, type))
1601 return -EOPNOTSUPP;
1602
1603 if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
1604 if (type != NL80211_IFTYPE_AP)
1605 rtl8723be_set_check_bssid(hw, true);
1606 } else {
1607 rtl8723be_set_check_bssid(hw, false);
1608 }
Larry Finger5c99f042014-09-26 16:40:25 -05001609
Larry Fingera619d1a2014-02-28 15:16:50 -06001610 return 0;
1611}
1612
1613/* don't set REG_EDCA_BE_PARAM here
1614 * because mac80211 will send pkt when scan
1615 */
1616void rtl8723be_set_qos(struct ieee80211_hw *hw, int aci)
1617{
1618 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -05001619
Larry Fingera619d1a2014-02-28 15:16:50 -06001620 rtl8723_dm_init_edca_turbo(hw);
1621 switch (aci) {
1622 case AC1_BK:
1623 rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f);
1624 break;
1625 case AC0_BE:
1626 break;
1627 case AC2_VI:
1628 rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322);
1629 break;
1630 case AC3_VO:
1631 rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
1632 break;
1633 default:
1634 RT_ASSERT(false, "invalid aci: %d !\n", aci);
1635 break;
1636 }
1637}
1638
1639void rtl8723be_enable_interrupt(struct ieee80211_hw *hw)
1640{
1641 struct rtl_priv *rtlpriv = rtl_priv(hw);
1642 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1643
1644 rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
1645 rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
1646 rtlpci->irq_enabled = true;
Larry Finger5c99f042014-09-26 16:40:25 -05001647
Larry Fingera619d1a2014-02-28 15:16:50 -06001648 /*enable system interrupt*/
1649 rtl_write_dword(rtlpriv, REG_HSIMR, rtlpci->sys_irq_mask & 0xFFFFFFFF);
1650}
1651
1652void rtl8723be_disable_interrupt(struct ieee80211_hw *hw)
1653{
1654 struct rtl_priv *rtlpriv = rtl_priv(hw);
1655 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1656
1657 rtl_write_dword(rtlpriv, REG_HIMR, IMR_DISABLED);
1658 rtl_write_dword(rtlpriv, REG_HIMRE, IMR_DISABLED);
1659 rtlpci->irq_enabled = false;
Larry Finger5c99f042014-09-26 16:40:25 -05001660 /*synchronize_irq(rtlpci->pdev->irq);*/
Larry Fingera619d1a2014-02-28 15:16:50 -06001661}
1662
1663void rtl8723be_card_disable(struct ieee80211_hw *hw)
1664{
1665 struct rtl_priv *rtlpriv = rtl_priv(hw);
1666 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1667 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1668 enum nl80211_iftype opmode;
1669
1670 mac->link_state = MAC80211_NOLINK;
1671 opmode = NL80211_IFTYPE_UNSPECIFIED;
1672 _rtl8723be_set_media_status(hw, opmode);
1673 if (rtlpriv->rtlhal.driver_is_goingto_unload ||
1674 ppsc->rfoff_reason > RF_CHANGE_BY_PS)
1675 rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
1676 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1677 _rtl8723be_poweroff_adapter(hw);
1678
1679 /* after power off we should do iqk again */
1680 rtlpriv->phy.iqk_initialized = false;
1681}
1682
1683void rtl8723be_interrupt_recognized(struct ieee80211_hw *hw,
1684 u32 *p_inta, u32 *p_intb)
1685{
1686 struct rtl_priv *rtlpriv = rtl_priv(hw);
1687 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1688
1689 *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0];
1690 rtl_write_dword(rtlpriv, ISR, *p_inta);
1691
1692 *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) &
1693 rtlpci->irq_mask[1];
1694 rtl_write_dword(rtlpriv, REG_HISRE, *p_intb);
1695}
1696
1697void rtl8723be_set_beacon_related_registers(struct ieee80211_hw *hw)
1698{
1699 struct rtl_priv *rtlpriv = rtl_priv(hw);
1700 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1701 u16 bcn_interval, atim_window;
1702
1703 bcn_interval = mac->beacon_interval;
1704 atim_window = 2; /*FIX MERGE */
1705 rtl8723be_disable_interrupt(hw);
1706 rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
1707 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1708 rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
1709 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18);
1710 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18);
1711 rtl_write_byte(rtlpriv, 0x606, 0x30);
1712 rtl8723be_enable_interrupt(hw);
1713}
1714
1715void rtl8723be_set_beacon_interval(struct ieee80211_hw *hw)
1716{
1717 struct rtl_priv *rtlpriv = rtl_priv(hw);
1718 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1719 u16 bcn_interval = mac->beacon_interval;
1720
1721 RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
1722 "beacon_interval:%d\n", bcn_interval);
1723 rtl8723be_disable_interrupt(hw);
1724 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1725 rtl8723be_enable_interrupt(hw);
1726}
1727
1728void rtl8723be_update_interrupt_mask(struct ieee80211_hw *hw,
1729 u32 add_msr, u32 rm_msr)
1730{
1731 struct rtl_priv *rtlpriv = rtl_priv(hw);
1732 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1733
1734 RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
1735 "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr);
1736
1737 if (add_msr)
1738 rtlpci->irq_mask[0] |= add_msr;
1739 if (rm_msr)
1740 rtlpci->irq_mask[0] &= (~rm_msr);
1741 rtl8723be_disable_interrupt(hw);
1742 rtl8723be_enable_interrupt(hw);
1743}
1744
1745static u8 _rtl8723be_get_chnl_group(u8 chnl)
1746{
1747 u8 group;
1748
1749 if (chnl < 3)
1750 group = 0;
1751 else if (chnl < 9)
1752 group = 1;
1753 else
1754 group = 2;
1755 return group;
1756}
1757
1758static void _rtl8723be_read_power_value_fromprom(struct ieee80211_hw *hw,
1759 struct txpower_info_2g *pw2g,
1760 struct txpower_info_5g *pw5g,
1761 bool autoload_fail, u8 *hwinfo)
1762{
1763 struct rtl_priv *rtlpriv = rtl_priv(hw);
1764 u32 path, addr = EEPROM_TX_PWR_INX, group, cnt = 0;
1765
1766 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
Larry Finger5c99f042014-09-26 16:40:25 -05001767 "hal_ReadPowerValueFromPROM8723BE(): PROMContent[0x%x]=0x%x\n",
Larry Fingera619d1a2014-02-28 15:16:50 -06001768 (addr + 1), hwinfo[addr + 1]);
Larry Finger5c99f042014-09-26 16:40:25 -05001769 if (0xFF == hwinfo[addr + 1]) /*YJ,add,120316*/
Larry Fingera619d1a2014-02-28 15:16:50 -06001770 autoload_fail = true;
1771
1772 if (autoload_fail) {
1773 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1774 "auto load fail : Use Default value!\n");
1775 for (path = 0; path < MAX_RF_PATH; path++) {
1776 /* 2.4G default value */
Larry Finger5c99f042014-09-26 16:40:25 -05001777 for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) {
Larry Fingera619d1a2014-02-28 15:16:50 -06001778 pw2g->index_cck_base[path][group] = 0x2D;
1779 pw2g->index_bw40_base[path][group] = 0x2D;
1780 }
1781 for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1782 if (cnt == 0) {
1783 pw2g->bw20_diff[path][0] = 0x02;
1784 pw2g->ofdm_diff[path][0] = 0x04;
1785 } else {
1786 pw2g->bw20_diff[path][cnt] = 0xFE;
1787 pw2g->bw40_diff[path][cnt] = 0xFE;
1788 pw2g->cck_diff[path][cnt] = 0xFE;
1789 pw2g->ofdm_diff[path][cnt] = 0xFE;
1790 }
1791 }
1792 }
1793 return;
1794 }
Larry Finger5c99f042014-09-26 16:40:25 -05001795
Larry Fingera619d1a2014-02-28 15:16:50 -06001796 for (path = 0; path < MAX_RF_PATH; path++) {
1797 /*2.4G default value*/
1798 for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
1799 pw2g->index_cck_base[path][group] = hwinfo[addr++];
1800 if (pw2g->index_cck_base[path][group] == 0xFF)
1801 pw2g->index_cck_base[path][group] = 0x2D;
Larry Finger5c99f042014-09-26 16:40:25 -05001802
Larry Fingera619d1a2014-02-28 15:16:50 -06001803 }
1804 for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) {
1805 pw2g->index_bw40_base[path][group] = hwinfo[addr++];
1806 if (pw2g->index_bw40_base[path][group] == 0xFF)
1807 pw2g->index_bw40_base[path][group] = 0x2D;
1808 }
1809 for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1810 if (cnt == 0) {
1811 pw2g->bw40_diff[path][cnt] = 0;
1812 if (hwinfo[addr] == 0xFF) {
1813 pw2g->bw20_diff[path][cnt] = 0x02;
1814 } else {
1815 pw2g->bw20_diff[path][cnt] =
1816 (hwinfo[addr] & 0xf0) >> 4;
1817 /*bit sign number to 8 bit sign number*/
1818 if (pw2g->bw20_diff[path][cnt] & BIT(3))
Larry Finger5c99f042014-09-26 16:40:25 -05001819 pw2g->bw20_diff[path][cnt] |=
1820 0xF0;
Larry Fingera619d1a2014-02-28 15:16:50 -06001821 }
Larry Finger5c99f042014-09-26 16:40:25 -05001822
Larry Fingera619d1a2014-02-28 15:16:50 -06001823 if (hwinfo[addr] == 0xFF) {
1824 pw2g->ofdm_diff[path][cnt] = 0x04;
1825 } else {
1826 pw2g->ofdm_diff[path][cnt] =
1827 (hwinfo[addr] & 0x0f);
1828 /*bit sign number to 8 bit sign number*/
1829 if (pw2g->ofdm_diff[path][cnt] & BIT(3))
1830 pw2g->ofdm_diff[path][cnt] |=
1831 0xF0;
1832 }
1833 pw2g->cck_diff[path][cnt] = 0;
1834 addr++;
1835 } else {
1836 if (hwinfo[addr] == 0xFF) {
1837 pw2g->bw40_diff[path][cnt] = 0xFE;
1838 } else {
1839 pw2g->bw40_diff[path][cnt] =
1840 (hwinfo[addr] & 0xf0) >> 4;
1841 if (pw2g->bw40_diff[path][cnt] & BIT(3))
1842 pw2g->bw40_diff[path][cnt] |=
1843 0xF0;
1844 }
Larry Finger5c99f042014-09-26 16:40:25 -05001845
Larry Fingera619d1a2014-02-28 15:16:50 -06001846 if (hwinfo[addr] == 0xFF) {
1847 pw2g->bw20_diff[path][cnt] = 0xFE;
1848 } else {
1849 pw2g->bw20_diff[path][cnt] =
1850 (hwinfo[addr] & 0x0f);
1851 if (pw2g->bw20_diff[path][cnt] & BIT(3))
1852 pw2g->bw20_diff[path][cnt] |=
1853 0xF0;
1854 }
1855 addr++;
1856
1857 if (hwinfo[addr] == 0xFF) {
1858 pw2g->ofdm_diff[path][cnt] = 0xFE;
1859 } else {
1860 pw2g->ofdm_diff[path][cnt] =
1861 (hwinfo[addr] & 0xf0) >> 4;
1862 if (pw2g->ofdm_diff[path][cnt] & BIT(3))
1863 pw2g->ofdm_diff[path][cnt] |=
1864 0xF0;
1865 }
Larry Finger5c99f042014-09-26 16:40:25 -05001866
1867 if (hwinfo[addr] == 0xFF)
Larry Fingera619d1a2014-02-28 15:16:50 -06001868 pw2g->cck_diff[path][cnt] = 0xFE;
Larry Finger5c99f042014-09-26 16:40:25 -05001869 else {
Larry Fingera619d1a2014-02-28 15:16:50 -06001870 pw2g->cck_diff[path][cnt] =
1871 (hwinfo[addr] & 0x0f);
1872 if (pw2g->cck_diff[path][cnt] & BIT(3))
1873 pw2g->cck_diff[path][cnt] |=
1874 0xF0;
1875 }
1876 addr++;
1877 }
1878 }
Larry Finger5c99f042014-09-26 16:40:25 -05001879
Larry Fingera619d1a2014-02-28 15:16:50 -06001880 /*5G default value*/
1881 for (group = 0; group < MAX_CHNL_GROUP_5G; group++) {
1882 pw5g->index_bw40_base[path][group] = hwinfo[addr++];
1883 if (pw5g->index_bw40_base[path][group] == 0xFF)
1884 pw5g->index_bw40_base[path][group] = 0xFE;
1885 }
Larry Finger5c99f042014-09-26 16:40:25 -05001886
Larry Fingera619d1a2014-02-28 15:16:50 -06001887 for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1888 if (cnt == 0) {
1889 pw5g->bw40_diff[path][cnt] = 0;
1890
1891 if (hwinfo[addr] == 0xFF) {
1892 pw5g->bw20_diff[path][cnt] = 0;
1893 } else {
1894 pw5g->bw20_diff[path][0] =
1895 (hwinfo[addr] & 0xf0) >> 4;
1896 if (pw5g->bw20_diff[path][cnt] & BIT(3))
1897 pw5g->bw20_diff[path][cnt] |=
1898 0xF0;
1899 }
Larry Finger5c99f042014-09-26 16:40:25 -05001900
1901 if (hwinfo[addr] == 0xFF)
Larry Fingera619d1a2014-02-28 15:16:50 -06001902 pw5g->ofdm_diff[path][cnt] = 0x04;
Larry Finger5c99f042014-09-26 16:40:25 -05001903 else {
Larry Fingera619d1a2014-02-28 15:16:50 -06001904 pw5g->ofdm_diff[path][0] =
1905 (hwinfo[addr] & 0x0f);
1906 if (pw5g->ofdm_diff[path][cnt] & BIT(3))
1907 pw5g->ofdm_diff[path][cnt] |=
1908 0xF0;
1909 }
1910 addr++;
1911 } else {
1912 if (hwinfo[addr] == 0xFF) {
1913 pw5g->bw40_diff[path][cnt] = 0xFE;
1914 } else {
1915 pw5g->bw40_diff[path][cnt] =
1916 (hwinfo[addr] & 0xf0) >> 4;
1917 if (pw5g->bw40_diff[path][cnt] & BIT(3))
1918 pw5g->bw40_diff[path][cnt] |= 0xF0;
1919 }
Larry Finger5c99f042014-09-26 16:40:25 -05001920
Larry Fingera619d1a2014-02-28 15:16:50 -06001921 if (hwinfo[addr] == 0xFF) {
1922 pw5g->bw20_diff[path][cnt] = 0xFE;
1923 } else {
1924 pw5g->bw20_diff[path][cnt] =
1925 (hwinfo[addr] & 0x0f);
1926 if (pw5g->bw20_diff[path][cnt] & BIT(3))
1927 pw5g->bw20_diff[path][cnt] |= 0xF0;
1928 }
1929 addr++;
1930 }
1931 }
Larry Finger5c99f042014-09-26 16:40:25 -05001932
Larry Fingera619d1a2014-02-28 15:16:50 -06001933 if (hwinfo[addr] == 0xFF) {
1934 pw5g->ofdm_diff[path][1] = 0xFE;
1935 pw5g->ofdm_diff[path][2] = 0xFE;
1936 } else {
1937 pw5g->ofdm_diff[path][1] = (hwinfo[addr] & 0xf0) >> 4;
1938 pw5g->ofdm_diff[path][2] = (hwinfo[addr] & 0x0f);
1939 }
1940 addr++;
1941
1942 if (hwinfo[addr] == 0xFF)
1943 pw5g->ofdm_diff[path][3] = 0xFE;
1944 else
1945 pw5g->ofdm_diff[path][3] = (hwinfo[addr] & 0x0f);
1946 addr++;
1947
1948 for (cnt = 1; cnt < MAX_TX_COUNT; cnt++) {
1949 if (pw5g->ofdm_diff[path][cnt] == 0xFF)
1950 pw5g->ofdm_diff[path][cnt] = 0xFE;
1951 else if (pw5g->ofdm_diff[path][cnt] & BIT(3))
1952 pw5g->ofdm_diff[path][cnt] |= 0xF0;
1953 }
1954 }
1955}
1956
1957static void _rtl8723be_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1958 bool autoload_fail,
1959 u8 *hwinfo)
1960{
1961 struct rtl_priv *rtlpriv = rtl_priv(hw);
1962 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1963 struct txpower_info_2g pw2g;
1964 struct txpower_info_5g pw5g;
1965 u8 rf_path, index;
1966 u8 i;
1967
1968 _rtl8723be_read_power_value_fromprom(hw, &pw2g, &pw5g, autoload_fail,
1969 hwinfo);
1970
1971 for (rf_path = 0; rf_path < 2; rf_path++) {
1972 for (i = 0; i < 14; i++) {
1973 index = _rtl8723be_get_chnl_group(i+1);
1974
1975 rtlefuse->txpwrlevel_cck[rf_path][i] =
1976 pw2g.index_cck_base[rf_path][index];
1977 rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
1978 pw2g.index_bw40_base[rf_path][index];
1979 }
1980 for (i = 0; i < MAX_TX_COUNT; i++) {
1981 rtlefuse->txpwr_ht20diff[rf_path][i] =
1982 pw2g.bw20_diff[rf_path][i];
1983 rtlefuse->txpwr_ht40diff[rf_path][i] =
1984 pw2g.bw40_diff[rf_path][i];
1985 rtlefuse->txpwr_legacyhtdiff[rf_path][i] =
1986 pw2g.ofdm_diff[rf_path][i];
1987 }
Larry Finger5c99f042014-09-26 16:40:25 -05001988
Larry Fingera619d1a2014-02-28 15:16:50 -06001989 for (i = 0; i < 14; i++) {
Larry Finger5c99f042014-09-26 16:40:25 -05001990 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1991 "RF(%d)-Ch(%d) [CCK / HT40_1S ] = [0x%x / 0x%x ]\n",
1992 rf_path, i,
Larry Fingera619d1a2014-02-28 15:16:50 -06001993 rtlefuse->txpwrlevel_cck[rf_path][i],
1994 rtlefuse->txpwrlevel_ht40_1s[rf_path][i]);
1995 }
1996 }
Larry Finger5c99f042014-09-26 16:40:25 -05001997
Larry Fingera619d1a2014-02-28 15:16:50 -06001998 if (!autoload_fail)
1999 rtlefuse->eeprom_thermalmeter =
2000 hwinfo[EEPROM_THERMAL_METER_88E];
2001 else
2002 rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
2003
2004 if (rtlefuse->eeprom_thermalmeter == 0xff || autoload_fail) {
2005 rtlefuse->apk_thermalmeterignore = true;
2006 rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
2007 }
Larry Finger5c99f042014-09-26 16:40:25 -05002008
Larry Fingera619d1a2014-02-28 15:16:50 -06002009 rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
Larry Finger5c99f042014-09-26 16:40:25 -05002010 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
Larry Fingera619d1a2014-02-28 15:16:50 -06002011 "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
2012
2013 if (!autoload_fail) {
2014 rtlefuse->eeprom_regulatory =
2015 hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0x07;/*bit0~2*/
2016 if (hwinfo[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
2017 rtlefuse->eeprom_regulatory = 0;
2018 } else {
2019 rtlefuse->eeprom_regulatory = 0;
2020 }
Larry Finger5c99f042014-09-26 16:40:25 -05002021 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
Larry Fingera619d1a2014-02-28 15:16:50 -06002022 "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
2023}
2024
2025static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw,
2026 bool pseudo_test)
2027{
2028 struct rtl_priv *rtlpriv = rtl_priv(hw);
2029 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2030 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
Larry Finger9e9c9c22016-07-05 10:08:12 -05002031 int params[] = {RTL8723BE_EEPROM_ID, EEPROM_VID, EEPROM_DID,
2032 EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR,
2033 EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID,
2034 COUNTRY_CODE_WORLD_WIDE_13};
2035 u8 *hwinfo;
2036 int i;
Larry Fingera619d1a2014-02-28 15:16:50 -06002037 bool is_toshiba_smid1 = false;
2038 bool is_toshiba_smid2 = false;
2039 bool is_samsung_smid = false;
2040 bool is_lenovo_smid = false;
2041 u16 toshiba_smid1[] = {
2042 0x6151, 0x6152, 0x6154, 0x6155, 0x6177, 0x6178, 0x6179, 0x6180,
2043 0x7151, 0x7152, 0x7154, 0x7155, 0x7177, 0x7178, 0x7179, 0x7180,
2044 0x8151, 0x8152, 0x8154, 0x8155, 0x8181, 0x8182, 0x8184, 0x8185,
2045 0x9151, 0x9152, 0x9154, 0x9155, 0x9181, 0x9182, 0x9184, 0x9185
2046 };
2047 u16 toshiba_smid2[] = {
2048 0x6181, 0x6184, 0x6185, 0x7181, 0x7182, 0x7184, 0x7185, 0x8181,
2049 0x8182, 0x8184, 0x8185, 0x9181, 0x9182, 0x9184, 0x9185
2050 };
2051 u16 samsung_smid[] = {
2052 0x6191, 0x6192, 0x6193, 0x7191, 0x7192, 0x7193, 0x8191, 0x8192,
2053 0x8193, 0x9191, 0x9192, 0x9193
2054 };
2055 u16 lenovo_smid[] = {
2056 0x8195, 0x9195, 0x7194, 0x8200, 0x8201, 0x8202, 0x9199, 0x9200
2057 };
2058
2059 if (pseudo_test) {
2060 /* needs to be added */
2061 return;
2062 }
Larry Fingera619d1a2014-02-28 15:16:50 -06002063
Larry Finger9e9c9c22016-07-05 10:08:12 -05002064 hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL);
2065 if (!hwinfo)
Arnd Bergmann5345ea62016-05-30 17:26:16 +02002066 return;
2067
Larry Finger9e9c9c22016-07-05 10:08:12 -05002068 if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params))
2069 goto exit;
Larry Fingera619d1a2014-02-28 15:16:50 -06002070
2071 /*parse xtal*/
2072 rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_8723BE];
2073 if (rtlefuse->crystalcap == 0xFF)
2074 rtlefuse->crystalcap = 0x20;
2075
2076 _rtl8723be_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag,
2077 hwinfo);
2078
2079 rtl8723be_read_bt_coexist_info_from_hwpg(hw,
2080 rtlefuse->autoload_failflag,
2081 hwinfo);
2082
Shao Fub23cd222015-05-15 16:33:02 -05002083 /* set channel plan from efuse */
2084 rtlefuse->channel_plan = rtlefuse->eeprom_channelplan;
Larry Fingera619d1a2014-02-28 15:16:50 -06002085
2086 if (rtlhal->oem_id == RT_CID_DEFAULT) {
2087 /* Does this one have a Toshiba SMID from group 1? */
2088 for (i = 0; i < sizeof(toshiba_smid1) / sizeof(u16); i++) {
2089 if (rtlefuse->eeprom_smid == toshiba_smid1[i]) {
2090 is_toshiba_smid1 = true;
2091 break;
2092 }
2093 }
2094 /* Does this one have a Toshiba SMID from group 2? */
2095 for (i = 0; i < sizeof(toshiba_smid2) / sizeof(u16); i++) {
2096 if (rtlefuse->eeprom_smid == toshiba_smid2[i]) {
2097 is_toshiba_smid2 = true;
2098 break;
2099 }
2100 }
2101 /* Does this one have a Samsung SMID? */
2102 for (i = 0; i < sizeof(samsung_smid) / sizeof(u16); i++) {
2103 if (rtlefuse->eeprom_smid == samsung_smid[i]) {
2104 is_samsung_smid = true;
2105 break;
2106 }
2107 }
2108 /* Does this one have a Lenovo SMID? */
2109 for (i = 0; i < sizeof(lenovo_smid) / sizeof(u16); i++) {
2110 if (rtlefuse->eeprom_smid == lenovo_smid[i]) {
2111 is_lenovo_smid = true;
2112 break;
2113 }
2114 }
2115 switch (rtlefuse->eeprom_oemid) {
2116 case EEPROM_CID_DEFAULT:
2117 if (rtlefuse->eeprom_did == 0x8176) {
2118 if (rtlefuse->eeprom_svid == 0x10EC &&
2119 is_toshiba_smid1) {
2120 rtlhal->oem_id = RT_CID_TOSHIBA;
2121 } else if (rtlefuse->eeprom_svid == 0x1025) {
2122 rtlhal->oem_id = RT_CID_819X_ACER;
2123 } else if (rtlefuse->eeprom_svid == 0x10EC &&
2124 is_samsung_smid) {
2125 rtlhal->oem_id = RT_CID_819X_SAMSUNG;
2126 } else if (rtlefuse->eeprom_svid == 0x10EC &&
2127 is_lenovo_smid) {
2128 rtlhal->oem_id = RT_CID_819X_LENOVO;
2129 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
2130 rtlefuse->eeprom_smid == 0x8197) ||
2131 (rtlefuse->eeprom_svid == 0x10EC &&
2132 rtlefuse->eeprom_smid == 0x9196)) {
2133 rtlhal->oem_id = RT_CID_819X_CLEVO;
2134 } else if ((rtlefuse->eeprom_svid == 0x1028 &&
2135 rtlefuse->eeprom_smid == 0x8194) ||
2136 (rtlefuse->eeprom_svid == 0x1028 &&
2137 rtlefuse->eeprom_smid == 0x8198) ||
2138 (rtlefuse->eeprom_svid == 0x1028 &&
2139 rtlefuse->eeprom_smid == 0x9197) ||
2140 (rtlefuse->eeprom_svid == 0x1028 &&
2141 rtlefuse->eeprom_smid == 0x9198)) {
2142 rtlhal->oem_id = RT_CID_819X_DELL;
2143 } else if ((rtlefuse->eeprom_svid == 0x103C &&
2144 rtlefuse->eeprom_smid == 0x1629)) {
2145 rtlhal->oem_id = RT_CID_819X_HP;
2146 } else if ((rtlefuse->eeprom_svid == 0x1A32 &&
2147 rtlefuse->eeprom_smid == 0x2315)) {
2148 rtlhal->oem_id = RT_CID_819X_QMI;
2149 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
2150 rtlefuse->eeprom_smid == 0x8203)) {
2151 rtlhal->oem_id = RT_CID_819X_PRONETS;
2152 } else if ((rtlefuse->eeprom_svid == 0x1043 &&
2153 rtlefuse->eeprom_smid == 0x84B5)) {
2154 rtlhal->oem_id = RT_CID_819X_EDIMAX_ASUS;
2155 } else {
2156 rtlhal->oem_id = RT_CID_DEFAULT;
2157 }
2158 } else if (rtlefuse->eeprom_did == 0x8178) {
2159 if (rtlefuse->eeprom_svid == 0x10EC &&
2160 is_toshiba_smid2)
2161 rtlhal->oem_id = RT_CID_TOSHIBA;
2162 else if (rtlefuse->eeprom_svid == 0x1025)
2163 rtlhal->oem_id = RT_CID_819X_ACER;
2164 else if ((rtlefuse->eeprom_svid == 0x10EC &&
2165 rtlefuse->eeprom_smid == 0x8186))
2166 rtlhal->oem_id = RT_CID_819X_PRONETS;
2167 else if ((rtlefuse->eeprom_svid == 0x1043 &&
2168 rtlefuse->eeprom_smid == 0x84B6))
2169 rtlhal->oem_id =
2170 RT_CID_819X_EDIMAX_ASUS;
2171 else
2172 rtlhal->oem_id = RT_CID_DEFAULT;
2173 } else {
2174 rtlhal->oem_id = RT_CID_DEFAULT;
2175 }
2176 break;
2177 case EEPROM_CID_TOSHIBA:
2178 rtlhal->oem_id = RT_CID_TOSHIBA;
2179 break;
2180 case EEPROM_CID_CCX:
2181 rtlhal->oem_id = RT_CID_CCX;
2182 break;
2183 case EEPROM_CID_QMI:
2184 rtlhal->oem_id = RT_CID_819X_QMI;
2185 break;
2186 case EEPROM_CID_WHQL:
2187 break;
2188 default:
2189 rtlhal->oem_id = RT_CID_DEFAULT;
2190 break;
2191 }
2192 }
Larry Finger9e9c9c22016-07-05 10:08:12 -05002193exit:
2194 kfree(hwinfo);
Larry Fingera619d1a2014-02-28 15:16:50 -06002195}
2196
2197static void _rtl8723be_hal_customized_behavior(struct ieee80211_hw *hw)
2198{
2199 struct rtl_priv *rtlpriv = rtl_priv(hw);
2200 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2201 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2202
2203 pcipriv->ledctl.led_opendrain = true;
2204 switch (rtlhal->oem_id) {
2205 case RT_CID_819X_HP:
2206 pcipriv->ledctl.led_opendrain = true;
2207 break;
2208 case RT_CID_819X_LENOVO:
2209 case RT_CID_DEFAULT:
2210 case RT_CID_TOSHIBA:
2211 case RT_CID_CCX:
2212 case RT_CID_819X_ACER:
2213 case RT_CID_WHQL:
2214 default:
2215 break;
2216 }
2217 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2218 "RT Customized ID: 0x%02X\n", rtlhal->oem_id);
2219}
2220
2221void rtl8723be_read_eeprom_info(struct ieee80211_hw *hw)
2222{
2223 struct rtl_priv *rtlpriv = rtl_priv(hw);
2224 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2225 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2226 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2227 u8 tmp_u1b;
2228
2229 rtlhal->version = _rtl8723be_read_chip_version(hw);
2230 if (get_rf_type(rtlphy) == RF_1T1R)
2231 rtlpriv->dm.rfpath_rxenable[0] = true;
2232 else
2233 rtlpriv->dm.rfpath_rxenable[0] =
2234 rtlpriv->dm.rfpath_rxenable[1] = true;
2235 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
2236 rtlhal->version);
2237 tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
2238 if (tmp_u1b & BIT(4)) {
2239 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
2240 rtlefuse->epromtype = EEPROM_93C46;
2241 } else {
2242 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
2243 rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
2244 }
2245 if (tmp_u1b & BIT(5)) {
2246 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
2247 rtlefuse->autoload_failflag = false;
2248 _rtl8723be_read_adapter_info(hw, false);
2249 } else {
2250 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n");
2251 }
2252 _rtl8723be_hal_customized_behavior(hw);
2253}
2254
Larry Fingera619d1a2014-02-28 15:16:50 -06002255static u8 _rtl8723be_mrate_idx_to_arfr_id(struct ieee80211_hw *hw,
2256 u8 rate_index)
2257{
2258 u8 ret = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002259 switch (rate_index) {
2260 case RATR_INX_WIRELESS_NGB:
2261 ret = 1;
2262 break;
2263 case RATR_INX_WIRELESS_N:
2264 case RATR_INX_WIRELESS_NG:
2265 ret = 5;
2266 break;
2267 case RATR_INX_WIRELESS_NB:
2268 ret = 3;
2269 break;
2270 case RATR_INX_WIRELESS_GB:
2271 ret = 6;
2272 break;
2273 case RATR_INX_WIRELESS_G:
2274 ret = 7;
2275 break;
2276 case RATR_INX_WIRELESS_B:
2277 ret = 8;
2278 break;
2279 default:
2280 ret = 0;
2281 break;
2282 }
2283 return ret;
2284}
2285
2286static void rtl8723be_update_hal_rate_mask(struct ieee80211_hw *hw,
2287 struct ieee80211_sta *sta,
2288 u8 rssi_level)
2289{
2290 struct rtl_priv *rtlpriv = rtl_priv(hw);
2291 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2292 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2293 struct rtl_sta_info *sta_entry = NULL;
2294 u32 ratr_bitmap;
2295 u8 ratr_index;
2296 u8 curtxbw_40mhz = (sta->ht_cap.cap &
Larry Finger5c99f042014-09-26 16:40:25 -05002297 IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002298 u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
Larry Finger5c99f042014-09-26 16:40:25 -05002299 1 : 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002300 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
Larry Finger5c99f042014-09-26 16:40:25 -05002301 1 : 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002302 enum wireless_mode wirelessmode = 0;
2303 bool shortgi = false;
2304 u8 rate_mask[7];
2305 u8 macid = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06002306
2307 sta_entry = (struct rtl_sta_info *)sta->drv_priv;
2308 wirelessmode = sta_entry->wireless_mode;
2309 if (mac->opmode == NL80211_IFTYPE_STATION ||
2310 mac->opmode == NL80211_IFTYPE_MESH_POINT)
2311 curtxbw_40mhz = mac->bw_40;
2312 else if (mac->opmode == NL80211_IFTYPE_AP ||
2313 mac->opmode == NL80211_IFTYPE_ADHOC)
2314 macid = sta->aid + 1;
2315
2316 ratr_bitmap = sta->supp_rates[0];
2317
2318 if (mac->opmode == NL80211_IFTYPE_ADHOC)
2319 ratr_bitmap = 0xfff;
2320
2321 ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
2322 sta->ht_cap.mcs.rx_mask[0] << 12);
2323 switch (wirelessmode) {
2324 case WIRELESS_MODE_B:
2325 ratr_index = RATR_INX_WIRELESS_B;
2326 if (ratr_bitmap & 0x0000000c)
2327 ratr_bitmap &= 0x0000000d;
2328 else
2329 ratr_bitmap &= 0x0000000f;
2330 break;
2331 case WIRELESS_MODE_G:
2332 ratr_index = RATR_INX_WIRELESS_GB;
2333
2334 if (rssi_level == 1)
2335 ratr_bitmap &= 0x00000f00;
2336 else if (rssi_level == 2)
2337 ratr_bitmap &= 0x00000ff0;
2338 else
2339 ratr_bitmap &= 0x00000ff5;
2340 break;
Larry Fingera619d1a2014-02-28 15:16:50 -06002341 case WIRELESS_MODE_N_24G:
2342 case WIRELESS_MODE_N_5G:
2343 ratr_index = RATR_INX_WIRELESS_NGB;
Larry Finger5c99f042014-09-26 16:40:25 -05002344 if (rtlphy->rf_type == RF_1T1R) {
2345 if (curtxbw_40mhz) {
2346 if (rssi_level == 1)
2347 ratr_bitmap &= 0x000f0000;
2348 else if (rssi_level == 2)
2349 ratr_bitmap &= 0x000ff000;
2350 else
2351 ratr_bitmap &= 0x000ff015;
Larry Fingera619d1a2014-02-28 15:16:50 -06002352 } else {
Larry Finger5c99f042014-09-26 16:40:25 -05002353 if (rssi_level == 1)
2354 ratr_bitmap &= 0x000f0000;
2355 else if (rssi_level == 2)
2356 ratr_bitmap &= 0x000ff000;
2357 else
2358 ratr_bitmap &= 0x000ff005;
2359 }
2360 } else {
2361 if (curtxbw_40mhz) {
2362 if (rssi_level == 1)
2363 ratr_bitmap &= 0x0f8f0000;
2364 else if (rssi_level == 2)
2365 ratr_bitmap &= 0x0f8ff000;
2366 else
2367 ratr_bitmap &= 0x0f8ff015;
2368 } else {
2369 if (rssi_level == 1)
2370 ratr_bitmap &= 0x0f8f0000;
2371 else if (rssi_level == 2)
2372 ratr_bitmap &= 0x0f8ff000;
2373 else
2374 ratr_bitmap &= 0x0f8ff005;
Larry Fingera619d1a2014-02-28 15:16:50 -06002375 }
2376 }
2377 if ((curtxbw_40mhz && curshortgi_40mhz) ||
2378 (!curtxbw_40mhz && curshortgi_20mhz)) {
2379 if (macid == 0)
2380 shortgi = true;
2381 else if (macid == 1)
2382 shortgi = false;
2383 }
2384 break;
2385 default:
2386 ratr_index = RATR_INX_WIRELESS_NGB;
2387
2388 if (rtlphy->rf_type == RF_1T2R)
2389 ratr_bitmap &= 0x000ff0ff;
2390 else
2391 ratr_bitmap &= 0x0f0ff0ff;
2392 break;
2393 }
Larry Finger5c99f042014-09-26 16:40:25 -05002394
Larry Fingera619d1a2014-02-28 15:16:50 -06002395 sta_entry->ratr_index = ratr_index;
2396
2397 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2398 "ratr_bitmap :%x\n", ratr_bitmap);
Larry Finger5c99f042014-09-26 16:40:25 -05002399 *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
2400 (ratr_index << 28);
Larry Fingera619d1a2014-02-28 15:16:50 -06002401 rate_mask[0] = macid;
2402 rate_mask[1] = _rtl8723be_mrate_idx_to_arfr_id(hw, ratr_index) |
Larry Finger5c99f042014-09-26 16:40:25 -05002403 (shortgi ? 0x80 : 0x00);
Larry Fingera619d1a2014-02-28 15:16:50 -06002404 rate_mask[2] = curtxbw_40mhz;
Larry Fingera619d1a2014-02-28 15:16:50 -06002405
2406 rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff);
2407 rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >> 8);
2408 rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16);
2409 rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24);
2410
2411 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2412 "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x:%x:%x\n",
2413 ratr_index, ratr_bitmap,
2414 rate_mask[0], rate_mask[1],
2415 rate_mask[2], rate_mask[3],
2416 rate_mask[4], rate_mask[5],
2417 rate_mask[6]);
Larry Finger5c99f042014-09-26 16:40:25 -05002418 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_RA_MASK, 7, rate_mask);
Larry Fingera619d1a2014-02-28 15:16:50 -06002419 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
2420}
2421
2422void rtl8723be_update_hal_rate_tbl(struct ieee80211_hw *hw,
2423 struct ieee80211_sta *sta,
2424 u8 rssi_level)
2425{
2426 struct rtl_priv *rtlpriv = rtl_priv(hw);
2427 if (rtlpriv->dm.useramask)
2428 rtl8723be_update_hal_rate_mask(hw, sta, rssi_level);
Larry Fingera619d1a2014-02-28 15:16:50 -06002429}
2430
2431void rtl8723be_update_channel_access_setting(struct ieee80211_hw *hw)
2432{
2433 struct rtl_priv *rtlpriv = rtl_priv(hw);
2434 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2435 u16 sifs_timer;
2436
Joe Perches9cb76aa2014-03-24 10:46:20 -07002437 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);
Larry Fingera619d1a2014-02-28 15:16:50 -06002438 if (!mac->ht_enable)
2439 sifs_timer = 0x0a0a;
2440 else
2441 sifs_timer = 0x0e0e;
2442 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
2443}
2444
2445bool rtl8723be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
2446{
2447 struct rtl_priv *rtlpriv = rtl_priv(hw);
2448 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2449 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2450 enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate;
2451 u8 u1tmp;
Larry Finger5c99f042014-09-26 16:40:25 -05002452 bool b_actuallyset = false;
Larry Fingera619d1a2014-02-28 15:16:50 -06002453
2454 if (rtlpriv->rtlhal.being_init_adapter)
2455 return false;
2456
2457 if (ppsc->swrf_processing)
2458 return false;
2459
2460 spin_lock(&rtlpriv->locks.rf_ps_lock);
2461 if (ppsc->rfchange_inprogress) {
2462 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2463 return false;
2464 } else {
2465 ppsc->rfchange_inprogress = true;
2466 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2467 }
Larry Finger5c99f042014-09-26 16:40:25 -05002468
Larry Fingera619d1a2014-02-28 15:16:50 -06002469 cur_rfstate = ppsc->rfpwr_state;
2470
2471 rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2,
2472 rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2) & ~(BIT(1)));
2473
2474 u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2);
2475
2476 if (rtlphy->polarity_ctl)
2477 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON;
2478 else
2479 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF;
2480
Larry Finger5c99f042014-09-26 16:40:25 -05002481 if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002482 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2483 "GPIOChangeRF - HW Radio ON, RF ON\n");
2484
2485 e_rfpowerstate_toset = ERFON;
2486 ppsc->hwradiooff = false;
Larry Finger5c99f042014-09-26 16:40:25 -05002487 b_actuallyset = true;
2488 } else if (!ppsc->hwradiooff && (e_rfpowerstate_toset == ERFOFF)) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002489 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2490 "GPIOChangeRF - HW Radio OFF, RF OFF\n");
2491
2492 e_rfpowerstate_toset = ERFOFF;
2493 ppsc->hwradiooff = true;
Larry Finger5c99f042014-09-26 16:40:25 -05002494 b_actuallyset = true;
Larry Fingera619d1a2014-02-28 15:16:50 -06002495 }
Larry Finger5c99f042014-09-26 16:40:25 -05002496
2497 if (b_actuallyset) {
Larry Fingera619d1a2014-02-28 15:16:50 -06002498 spin_lock(&rtlpriv->locks.rf_ps_lock);
2499 ppsc->rfchange_inprogress = false;
2500 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2501 } else {
2502 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
2503 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2504
2505 spin_lock(&rtlpriv->locks.rf_ps_lock);
2506 ppsc->rfchange_inprogress = false;
2507 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2508 }
Larry Finger5c99f042014-09-26 16:40:25 -05002509
Larry Fingera619d1a2014-02-28 15:16:50 -06002510 *valid = 1;
2511 return !ppsc->hwradiooff;
Larry Finger5c99f042014-09-26 16:40:25 -05002512
Larry Fingera619d1a2014-02-28 15:16:50 -06002513}
2514
2515void rtl8723be_set_key(struct ieee80211_hw *hw, u32 key_index,
2516 u8 *p_macaddr, bool is_group, u8 enc_algo,
2517 bool is_wepkey, bool clear_all)
2518{
2519 struct rtl_priv *rtlpriv = rtl_priv(hw);
2520 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2521 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2522 u8 *macaddr = p_macaddr;
2523 u32 entry_id = 0;
2524 bool is_pairwise = false;
2525
2526 static u8 cam_const_addr[4][6] = {
2527 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
2528 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
2529 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
2530 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
2531 };
2532 static u8 cam_const_broad[] = {
2533 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2534 };
2535
2536 if (clear_all) {
2537 u8 idx = 0;
2538 u8 cam_offset = 0;
2539 u8 clear_number = 5;
2540
2541 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
2542
2543 for (idx = 0; idx < clear_number; idx++) {
2544 rtl_cam_mark_invalid(hw, cam_offset + idx);
2545 rtl_cam_empty_entry(hw, cam_offset + idx);
2546
2547 if (idx < 5) {
2548 memset(rtlpriv->sec.key_buf[idx], 0,
2549 MAX_KEY_LEN);
2550 rtlpriv->sec.key_len[idx] = 0;
2551 }
2552 }
Larry Finger5c99f042014-09-26 16:40:25 -05002553
Larry Fingera619d1a2014-02-28 15:16:50 -06002554 } else {
2555 switch (enc_algo) {
2556 case WEP40_ENCRYPTION:
2557 enc_algo = CAM_WEP40;
2558 break;
2559 case WEP104_ENCRYPTION:
2560 enc_algo = CAM_WEP104;
2561 break;
2562 case TKIP_ENCRYPTION:
2563 enc_algo = CAM_TKIP;
2564 break;
2565 case AESCCMP_ENCRYPTION:
2566 enc_algo = CAM_AES;
2567 break;
2568 default:
Larry Finger5c99f042014-09-26 16:40:25 -05002569 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
Joe Perchesad574882016-09-23 11:27:19 -07002570 "switch case %#x not processed\n", enc_algo);
Larry Fingera619d1a2014-02-28 15:16:50 -06002571 enc_algo = CAM_TKIP;
2572 break;
2573 }
2574
2575 if (is_wepkey || rtlpriv->sec.use_defaultkey) {
2576 macaddr = cam_const_addr[key_index];
2577 entry_id = key_index;
2578 } else {
2579 if (is_group) {
2580 macaddr = cam_const_broad;
2581 entry_id = key_index;
2582 } else {
2583 if (mac->opmode == NL80211_IFTYPE_AP) {
2584 entry_id = rtl_cam_get_free_entry(hw,
2585 p_macaddr);
2586 if (entry_id >= TOTAL_CAM_ENTRY) {
2587 RT_TRACE(rtlpriv, COMP_SEC,
2588 DBG_EMERG,
Larry Finger5c99f042014-09-26 16:40:25 -05002589 "Can not find free hw security cam entry\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06002590 return;
2591 }
2592 } else {
2593 entry_id = CAM_PAIRWISE_KEY_POSITION;
2594 }
Larry Finger5c99f042014-09-26 16:40:25 -05002595
Larry Fingera619d1a2014-02-28 15:16:50 -06002596 key_index = PAIRWISE_KEYIDX;
2597 is_pairwise = true;
2598 }
2599 }
Larry Finger5c99f042014-09-26 16:40:25 -05002600
Larry Fingera619d1a2014-02-28 15:16:50 -06002601 if (rtlpriv->sec.key_len[key_index] == 0) {
2602 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2603 "delete one entry, entry_id is %d\n",
Larry Finger5c99f042014-09-26 16:40:25 -05002604 entry_id);
Larry Fingera619d1a2014-02-28 15:16:50 -06002605 if (mac->opmode == NL80211_IFTYPE_AP)
2606 rtl_cam_del_entry(hw, p_macaddr);
2607 rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
2608 } else {
2609 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2610 "add one entry\n");
2611 if (is_pairwise) {
2612 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
Larry Finger5c99f042014-09-26 16:40:25 -05002613 "set Pairwiase key\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06002614
2615 rtl_cam_add_one_entry(hw, macaddr, key_index,
Larry Finger5c99f042014-09-26 16:40:25 -05002616 entry_id, enc_algo,
2617 CAM_CONFIG_NO_USEDK,
2618 rtlpriv->sec.key_buf[key_index]);
Larry Fingera619d1a2014-02-28 15:16:50 -06002619 } else {
2620 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2621 "set group key\n");
2622
2623 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
2624 rtl_cam_add_one_entry(hw,
2625 rtlefuse->dev_addr,
2626 PAIRWISE_KEYIDX,
2627 CAM_PAIRWISE_KEY_POSITION,
2628 enc_algo,
2629 CAM_CONFIG_NO_USEDK,
2630 rtlpriv->sec.key_buf
2631 [entry_id]);
2632 }
Larry Finger5c99f042014-09-26 16:40:25 -05002633
Larry Fingera619d1a2014-02-28 15:16:50 -06002634 rtl_cam_add_one_entry(hw, macaddr, key_index,
Larry Finger5c99f042014-09-26 16:40:25 -05002635 entry_id, enc_algo,
2636 CAM_CONFIG_NO_USEDK,
2637 rtlpriv->sec.key_buf[entry_id]);
Larry Fingera619d1a2014-02-28 15:16:50 -06002638 }
2639 }
2640 }
2641}
2642
2643void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
2644 bool auto_load_fail, u8 *hwinfo)
2645{
2646 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Fingerc18d8f52016-03-16 13:33:34 -05002647 struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params;
Larry Fingera619d1a2014-02-28 15:16:50 -06002648 u8 value;
2649 u32 tmpu_32;
2650
2651 if (!auto_load_fail) {
2652 tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL);
2653 if (tmpu_32 & BIT(18))
2654 rtlpriv->btcoexist.btc_info.btcoexist = 1;
2655 else
2656 rtlpriv->btcoexist.btc_info.btcoexist = 0;
Larry Finger5c99f042014-09-26 16:40:25 -05002657 value = hwinfo[EEPROM_RF_BT_SETTING_8723B];
Larry Fingera619d1a2014-02-28 15:16:50 -06002658 rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2659 rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1);
2660 } else {
2661 rtlpriv->btcoexist.btc_info.btcoexist = 0;
2662 rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2663 rtlpriv->btcoexist.btc_info.ant_num = ANT_X2;
2664 }
Larry Finger5c99f042014-09-26 16:40:25 -05002665
Larry Fingerc18d8f52016-03-16 13:33:34 -05002666 /* override ant_num / ant_path */
2667 if (mod_params->ant_sel)
2668 rtlpriv->btcoexist.btc_info.ant_num =
2669 (mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1);
Larry Fingera619d1a2014-02-28 15:16:50 -06002670}
2671
2672void rtl8723be_bt_reg_init(struct ieee80211_hw *hw)
2673{
2674 struct rtl_priv *rtlpriv = rtl_priv(hw);
2675
2676 /* 0:Low, 1:High, 2:From Efuse. */
2677 rtlpriv->btcoexist.reg_bt_iso = 2;
2678 /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */
2679 rtlpriv->btcoexist.reg_bt_sco = 3;
2680 /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
2681 rtlpriv->btcoexist.reg_bt_sco = 0;
2682}
2683
2684void rtl8723be_bt_hw_init(struct ieee80211_hw *hw)
2685{
2686 struct rtl_priv *rtlpriv = rtl_priv(hw);
2687
2688 if (rtlpriv->cfg->ops->get_btc_status())
2689 rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv);
Larry Finger5c99f042014-09-26 16:40:25 -05002690
Larry Fingera619d1a2014-02-28 15:16:50 -06002691}
2692
2693void rtl8723be_suspend(struct ieee80211_hw *hw)
2694{
2695}
2696
2697void rtl8723be_resume(struct ieee80211_hw *hw)
2698{
2699}