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