]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
Merge tag 'for-linus-20170825' of git://git.infradead.org/linux-mtd
[mirror_ubuntu-artful-kernel.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"
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];
5c99f04f 54 unsigned long flags;
a619d1ab 55
5c99f04f 56 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
a619d1ab
LF
57 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 }
5c99f04f 68 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
a619d1ab
LF
69}
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
5c99f04f 80 rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlpci->reg_bcn_ctrl_val);
a619d1ab
LF
81}
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,
5c99f04f 120 bool b_need_turn_off_ckk)
a619d1ab
LF
121{
122 struct rtl_priv *rtlpriv = rtl_priv(hw);
123 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
5c99f04f 124 bool b_support_remote_wake_up;
a619d1ab 125 u32 count = 0, isr_regaddr, content;
5c99f04f 126 bool b_schedule_timer = b_need_turn_off_ckk;
a619d1ab 127 rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN,
5c99f04f 128 (u8 *)(&b_support_remote_wake_up));
a619d1ab
LF
129
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 }
5c99f04f
LF
153
154 if (IS_IN_LOW_POWER_STATE(rtlhal->fw_ps_state)) {
a619d1ab 155 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM,
5c99f04f 156 (u8 *)(&rpwm_val));
a619d1ab
LF
157 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);
5c99f04f 168 rtlhal->fw_ps_state = FW_PS_STATE_RF_ON;
a619d1ab 169 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
5c99f04f 170 "Receive CPWM INT!!! Set pHalData->FwPSState = %X\n",
a619d1ab
LF
171 rtlhal->fw_ps_state);
172 }
173 }
5c99f04f 174
a619d1ab
LF
175 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);
5c99f04f 178 if (b_schedule_timer)
a619d1ab
LF
179 mod_timer(&rtlpriv->works.fw_clockoff_timer,
180 jiffies + MSECS(10));
a619d1ab
LF
181 } 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;
5c99f04f 195 bool b_schedule_timer = false;
a619d1ab
LF
196 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)) {
5c99f04f 211 b_schedule_timer = true;
a619d1ab
LF
212 break;
213 }
214 }
5c99f04f
LF
215
216 if (b_schedule_timer) {
a619d1ab
LF
217 mod_timer(&rtlpriv->works.fw_clockoff_timer,
218 jiffies + MSECS(10));
219 return;
220 }
5c99f04f
LF
221
222 if (FW_PS_STATE(rtlhal->fw_ps_state) != FW_PS_STATE_RF_OFF_LOW_PWR) {
a619d1ab
LF
223 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,
5c99f04f 230 (u8 *)(&rpwm_val));
a619d1ab
LF
231 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 }
5c99f04f 240
a619d1ab
LF
241}
242
243static void _rtl8723be_set_fw_ps_rf_on(struct ieee80211_hw *hw)
244{
245 u8 rpwm_val = 0;
5c99f04f 246 rpwm_val |= (FW_PS_STATE_RF_OFF | FW_PS_ACK);
a619d1ab
LF
247 _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) {
5c99f04f 259 rpwm_val = (FW_PS_STATE_ALL_ON | FW_PS_ACK);/* RF on */
a619d1ab
LF
260 _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,
5c99f04f 263 (u8 *)(&fw_pwrmode));
a619d1ab
LF
264 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
265 (u8 *)(&fw_current_inps));
266 } else {
5c99f04f
LF
267 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));
a619d1ab 270 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
5c99f04f 271 (u8 *)(&fw_pwrmode));
a619d1ab
LF
272 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
273 (u8 *)(&fw_current_inps));
274 }
5c99f04f 275
a619d1ab
LF
276}
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) {
5c99f04f 287 rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR; /* RF off */
a619d1ab
LF
288 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,
5c99f04f 291 (u8 *)(&ppsc->fwctrl_psmode));
a619d1ab
LF
292 rtlhal->allow_sw_to_change_hwclc = true;
293 _rtl8723be_set_fw_clock_off(hw, rpwm_val);
a619d1ab 294 } else {
5c99f04f 295 rpwm_val = FW_PS_STATE_RF_OFF; /* RF off */
a619d1ab
LF
296 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,
5c99f04f
LF
299 (u8 *)(&ppsc->fwctrl_psmode));
300 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
301 (u8 *)(&rpwm_val));
a619d1ab 302 }
5c99f04f 303
a619d1ab
LF
304}
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;
5c99f04f
LF
319 case HW_VAR_FWLPS_RF_ON:{
320 enum rf_pwrstate rfState;
a619d1ab
LF
321 u32 val_rcr;
322
323 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE,
5c99f04f
LF
324 (u8 *)(&rfState));
325 if (rfState == ERFOFF) {
a619d1ab
LF
326 *((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 }
5c99f04f
LF
335 }
336 break;
a619d1ab
LF
337 case HW_VAR_FW_PSMODE_STATUS:
338 *((bool *)(val)) = ppsc->fw_current_inpsmode;
339 break;
5c99f04f 340 case HW_VAR_CORRECT_TSF:{
a619d1ab
LF
341 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;
5c99f04f
LF
349 }
350 break;
1cc49a5b
LF
351 case HAL_DEF_WOWLAN:
352 break;
a619d1ab 353 default:
5c99f04f 354 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
ad574889 355 "switch case %#x not processed\n", variable);
a619d1ab
LF
356 break;
357 }
358}
359
5c99f04f
LF
360static 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
a619d1ab
LF
410void 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;
5c99f04f
LF
424 case HW_VAR_BASIC_RATE:{
425 u16 b_rate_cfg = ((u16 *)val)[0];
a619d1ab 426 u8 rate_index = 0;
5c99f04f
LF
427 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);
a619d1ab
LF
433 rate_index++;
434 }
435 rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, rate_index);
5c99f04f
LF
436 }
437 break;
a619d1ab
LF
438 case HW_VAR_BSSID:
439 for (idx = 0; idx < ETH_ALEN; idx++)
440 rtl_write_byte(rtlpriv, (REG_BSSID + idx), val[idx]);
5c99f04f 441
a619d1ab
LF
442 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;
5c99f04f 456 case HW_VAR_SLOT_TIME:{
a619d1ab
LF
457 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,
5c99f04f 466 (u8 *)(&e_aci));
a619d1ab 467 }
5c99f04f
LF
468 }
469 break;
470 case HW_VAR_ACK_PREAMBLE:{
a619d1ab 471 u8 reg_tmp;
5c99f04f 472 u8 short_preamble = (bool)(*(u8 *)val);
a619d1ab
LF
473 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 }
5c99f04f
LF
481 }
482 break;
a619d1ab 483 case HW_VAR_WPA_CONFIG:
5c99f04f 484 rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val));
a619d1ab 485 break;
5c99f04f 486 case HW_VAR_AMPDU_MIN_SPACE:{
a619d1ab
LF
487 u8 min_spacing_to_set;
488 u8 sec_min_space;
489
5c99f04f 490 min_spacing_to_set = *((u8 *)val);
a619d1ab
LF
491 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",
5c99f04f 504 mac->min_space_cfg);
a619d1ab
LF
505
506 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
507 mac->min_space_cfg);
508 }
5c99f04f
LF
509 }
510 break;
511 case HW_VAR_SHORTGI_DENSITY:{
a619d1ab
LF
512 u8 density_to_set;
513
5c99f04f 514 density_to_set = *((u8 *)val);
a619d1ab
LF
515 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",
5c99f04f 519 mac->min_space_cfg);
a619d1ab
LF
520
521 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
522 mac->min_space_cfg);
5c99f04f
LF
523 }
524 break;
525 case HW_VAR_AMPDU_FACTOR:{
a619d1ab
LF
526 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
5c99f04f 533 factor_toset = *((u8 *)val);
a619d1ab
LF
534 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]);
5c99f04f 554
a619d1ab 555 }
5c99f04f 556
a619d1ab
LF
557 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
558 "Set HW_VAR_AMPDU_FACTOR: %#x\n",
5c99f04f 559 factor_toset);
a619d1ab 560 }
5c99f04f
LF
561 }
562 break;
563 case HW_VAR_AC_PARAM:{
564 u8 e_aci = *((u8 *)val);
a619d1ab
LF
565 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,
5c99f04f
LF
569 (u8 *)(&e_aci));
570 }
571 break;
572 case HW_VAR_ACM_CTRL:{
573 u8 e_aci = *((u8 *)val);
a619d1ab
LF
574 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,
5c99f04f
LF
595 "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
596 acm);
a619d1ab
LF
597 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:
52f57804 608 acm_ctrl &= (~ACMHW_VOQEN);
a619d1ab
LF
609 break;
610 default:
5c99f04f 611 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
ad574889
JP
612 "switch case %#x not processed\n",
613 e_aci);
a619d1ab
LF
614 break;
615 }
616 }
5c99f04f 617
a619d1ab 618 RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
5c99f04f
LF
619 "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
620 acm_ctrl);
a619d1ab 621 rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
5c99f04f
LF
622 }
623 break;
a619d1ab
LF
624 case HW_VAR_RCR:
625 rtl_write_dword(rtlpriv, REG_RCR, ((u32 *)(val))[0]);
626 rtlpci->receive_config = ((u32 *)(val))[0];
627 break;
5c99f04f
LF
628 case HW_VAR_RETRY_LIMIT:{
629 u8 retry_limit = ((u8 *)(val))[0];
a619d1ab
LF
630
631 rtl_write_word(rtlpriv, REG_RL,
632 retry_limit << RETRY_LIMIT_SHORT_SHIFT |
633 retry_limit << RETRY_LIMIT_LONG_SHIFT);
5c99f04f
LF
634 }
635 break;
a619d1ab
LF
636 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:
5c99f04f 643 rtlefuse->efuse_usedpercentage = *((u8 *)val);
a619d1ab
LF
644 break;
645 case HW_VAR_IO_CMD:
646 rtl8723be_phy_set_io_cmd(hw, (*(enum io_type *)val));
647 break;
5c99f04f 648 case HW_VAR_SET_RPWM:{
a619d1ab
LF
649 u8 rpwm_val;
650
651 rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM);
652 udelay(1);
653
654 if (rpwm_val & BIT(7)) {
5c99f04f 655 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, (*(u8 *)val));
a619d1ab 656 } else {
5c99f04f
LF
657 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
658 ((*(u8 *)val) | BIT(7)));
a619d1ab 659 }
5c99f04f
LF
660 }
661 break;
a619d1ab 662 case HW_VAR_H2C_FW_PWRMODE:
5c99f04f 663 rtl8723be_set_fw_pwrmode_cmd(hw, (*(u8 *)val));
a619d1ab
LF
664 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;
5c99f04f
LF
671 case HW_VAR_FW_LPS_ACTION:{
672 bool b_enter_fwlps = *((bool *)val);
a619d1ab 673
5c99f04f 674 if (b_enter_fwlps)
a619d1ab
LF
675 _rtl8723be_fwlps_enter(hw);
676 else
677 _rtl8723be_fwlps_leave(hw);
5c99f04f
LF
678 }
679 break;
680 case HW_VAR_H2C_FW_JOINBSSRPT:{
681 u8 mstatus = (*(u8 *)val);
a619d1ab
LF
682
683 if (mstatus == RT_MEDIA_CONNECT) {
684 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL);
5c99f04f
LF
685 _rtl8723be_download_rsvd_page(hw);
686 }
687 rtl8723be_set_fw_media_status_rpt_cmd(hw, mstatus);
a619d1ab 688 }
5c99f04f 689 break;
a619d1ab 690 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
5c99f04f 691 rtl8723be_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
a619d1ab 692 break;
5c99f04f 693 case HW_VAR_AID:{
a619d1ab
LF
694 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));
5c99f04f
LF
699 }
700 break;
701 case HW_VAR_CORRECT_TSF:{
702 u8 btype_ibss = ((u8 *)(val))[0];
a619d1ab
LF
703
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);
5c99f04f
LF
718 }
719 break;
720 case HW_VAR_KEEP_ALIVE:{
a619d1ab
LF
721 u8 array[2];
722 array[0] = 0xff;
5c99f04f
LF
723 array[1] = *((u8 *)val);
724 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_KEEP_ALIVE_CTRL, 2, array);
725 }
726 break;
a619d1ab 727 default:
5c99f04f 728 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
ad574889 729 "switch case %#x not processed\n", variable);
a619d1ab
LF
730 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;
5c99f04f 738 long count = 0;
a619d1ab
LF
739 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) {
4e2b4378
LF
750 pr_err("Failed to polling write LLT done at address %d!\n",
751 address);
a619d1ab
LF
752 status = false;
753 break;
754 }
755 } while (++count);
756
757 return status;
758}
759
760static bool _rtl8723be_llt_table_init(struct ieee80211_hw *hw)
761{
762 struct rtl_priv *rtlpriv = rtl_priv(hw);
763 unsigned short i;
764 u8 txpktbuf_bndy;
5c99f04f 765 u8 maxPage;
a619d1ab
LF
766 bool status;
767
5c99f04f 768 maxPage = 255;
a619d1ab
LF
769 txpktbuf_bndy = 245;
770
771 rtl_write_dword(rtlpriv, REG_TRXFF_BNDY,
772 (0x27FF0000 | txpktbuf_bndy));
773 rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy);
774
775 rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
776 rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
777
778 rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy);
779 rtl_write_byte(rtlpriv, REG_PBP, 0x31);
780 rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);
781
782 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
783 status = _rtl8723be_llt_write(hw, i, i + 1);
784 if (!status)
785 return status;
786 }
5c99f04f 787
a619d1ab
LF
788 status = _rtl8723be_llt_write(hw, (txpktbuf_bndy - 1), 0xFF);
789
790 if (!status)
791 return status;
792
5c99f04f 793 for (i = txpktbuf_bndy; i < maxPage; i++) {
a619d1ab
LF
794 status = _rtl8723be_llt_write(hw, i, (i + 1));
795 if (!status)
796 return status;
797 }
5c99f04f
LF
798
799 status = _rtl8723be_llt_write(hw, maxPage, txpktbuf_bndy);
a619d1ab
LF
800 if (!status)
801 return status;
802
803 rtl_write_dword(rtlpriv, REG_RQPN, 0x80e40808);
804 rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x00);
805
806 return true;
807}
808
809static void _rtl8723be_gen_refresh_led_state(struct ieee80211_hw *hw)
810{
811 struct rtl_priv *rtlpriv = rtl_priv(hw);
a619d1ab 812 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
d5efe153 813 struct rtl_led *pled0 = &rtlpriv->ledctl.sw_led0;
a619d1ab
LF
814
815 if (rtlpriv->rtlhal.up_first_time)
816 return;
817
818 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
819 rtl8723be_sw_led_on(hw, pled0);
820 else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT)
821 rtl8723be_sw_led_on(hw, pled0);
822 else
823 rtl8723be_sw_led_off(hw, pled0);
824}
825
826static bool _rtl8723be_init_mac(struct ieee80211_hw *hw)
827{
828 struct rtl_priv *rtlpriv = rtl_priv(hw);
829 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
5c99f04f 830 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
a619d1ab
LF
831 unsigned char bytetmp;
832 unsigned short wordtmp;
a619d1ab
LF
833
834 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
835
836 /*Auto Power Down to CHIP-off State*/
837 bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) & (~BIT(7));
838 rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp);
839
a619d1ab 840 /* HW Power on sequence */
34ed780a
LF
841 if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK,
842 PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,
843 RTL8723_NIC_ENABLE_FLOW)) {
a619d1ab
LF
844 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
845 "init MAC Fail as power on failure\n");
846 return false;
847 }
5c99f04f
LF
848
849 bytetmp = rtl_read_byte(rtlpriv, REG_MULTI_FUNC_CTRL);
850 rtl_write_byte(rtlpriv, REG_MULTI_FUNC_CTRL, bytetmp | BIT(3));
851
a619d1ab
LF
852 bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO) | BIT(4);
853 rtl_write_byte(rtlpriv, REG_APS_FSMCO, bytetmp);
854
855 bytetmp = rtl_read_byte(rtlpriv, REG_CR);
856 bytetmp = 0xff;
857 rtl_write_byte(rtlpriv, REG_CR, bytetmp);
858 mdelay(2);
859
860 bytetmp = rtl_read_byte(rtlpriv, REG_HWSEQ_CTRL);
861 bytetmp |= 0x7f;
862 rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, bytetmp);
863 mdelay(2);
864
865 bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CFG + 3);
866 if (bytetmp & BIT(0)) {
867 bytetmp = rtl_read_byte(rtlpriv, 0x7c);
5c99f04f 868 rtl_write_byte(rtlpriv, 0x7c, bytetmp | BIT(6));
a619d1ab 869 }
5c99f04f 870
a619d1ab 871 bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CLKR);
5c99f04f 872 rtl_write_byte(rtlpriv, REG_SYS_CLKR, bytetmp | BIT(3));
a619d1ab 873 bytetmp = rtl_read_byte(rtlpriv, REG_GPIO_MUXCFG + 1);
5c99f04f 874 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG + 1, bytetmp & (~BIT(4)));
a619d1ab
LF
875
876 rtl_write_word(rtlpriv, REG_CR, 0x2ff);
877
5c99f04f
LF
878 if (!rtlhal->mac_func_enable) {
879 if (_rtl8723be_llt_table_init(hw) == false)
a619d1ab
LF
880 return false;
881 }
5c99f04f 882
a619d1ab
LF
883 rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
884 rtl_write_dword(rtlpriv, REG_HISRE, 0xffffffff);
885
886 /* Enable FW Beamformer Interrupt */
887 bytetmp = rtl_read_byte(rtlpriv, REG_FWIMR + 3);
888 rtl_write_byte(rtlpriv, REG_FWIMR + 3, bytetmp | BIT(6));
889
890 wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL);
891 wordtmp &= 0xf;
892 wordtmp |= 0xF5B1;
893 rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp);
894
895 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F);
896 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
897 rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xFFFF);
898 rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config);
899
a619d1ab
LF
900 rtl_write_dword(rtlpriv, REG_BCNQ_DESA,
901 ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) &
902 DMA_BIT_MASK(32));
903 rtl_write_dword(rtlpriv, REG_MGQ_DESA,
904 (u64) rtlpci->tx_ring[MGNT_QUEUE].dma &
905 DMA_BIT_MASK(32));
906 rtl_write_dword(rtlpriv, REG_VOQ_DESA,
907 (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32));
908 rtl_write_dword(rtlpriv, REG_VIQ_DESA,
909 (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32));
910 rtl_write_dword(rtlpriv, REG_BEQ_DESA,
911 (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32));
912 rtl_write_dword(rtlpriv, REG_BKQ_DESA,
913 (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32));
914 rtl_write_dword(rtlpriv, REG_HQ_DESA,
915 (u64) rtlpci->tx_ring[HIGH_QUEUE].dma &
916 DMA_BIT_MASK(32));
917 rtl_write_dword(rtlpriv, REG_RX_DESA,
918 (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma &
919 DMA_BIT_MASK(32));
920
921 bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 3);
922 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, bytetmp | 0x77);
923
924 rtl_write_dword(rtlpriv, REG_INT_MIG, 0);
925
5c99f04f 926 rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0);
a619d1ab
LF
927
928 rtl_write_byte(rtlpriv, REG_SECONDARY_CCA_CTRL, 0x3);
929
5c99f04f
LF
930 /* <20130114, Kordan> The following setting is
931 * only for DPDT and Fixed board type.
932 * TODO: A better solution is configure it
933 * according EFUSE during the run-time.
934 */
935 rtl_set_bbreg(hw, 0x64, BIT(20), 0x0);/* 0x66[4]=0 */
936 rtl_set_bbreg(hw, 0x64, BIT(24), 0x0);/* 0x66[8]=0 */
937 rtl_set_bbreg(hw, 0x40, BIT(4), 0x0)/* 0x40[4]=0 */;
938 rtl_set_bbreg(hw, 0x40, BIT(3), 0x1)/* 0x40[3]=1 */;
939 rtl_set_bbreg(hw, 0x4C, BIT(24) | BIT(23), 0x2)/* 0x4C[24:23]=10 */;
940 rtl_set_bbreg(hw, 0x944, BIT(1) | BIT(0), 0x3)/* 0x944[1:0]=11 */;
941 rtl_set_bbreg(hw, 0x930, MASKBYTE0, 0x77)/* 0x930[7:0]=77 */;
942 rtl_set_bbreg(hw, 0x38, BIT(11), 0x1)/* 0x38[11]=1 */;
a619d1ab
LF
943
944 bytetmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
5c99f04f 945 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, bytetmp & (~BIT(2)));
a619d1ab 946
5c99f04f 947 _rtl8723be_gen_refresh_led_state(hw);
a619d1ab
LF
948 return true;
949}
950
951static void _rtl8723be_hw_configure(struct ieee80211_hw *hw)
952{
953 struct rtl_priv *rtlpriv = rtl_priv(hw);
5c99f04f
LF
954 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
955 u32 reg_rrsr;
956
957 reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
958 /* Init value for RRSR. */
959 rtl_write_dword(rtlpriv, REG_RRSR, reg_rrsr);
960
961 /* ARFB table 9 for 11ac 5G 2SS */
962 rtl_write_dword(rtlpriv, REG_ARFR0 + 4, 0xfffff000);
963
964 /* ARFB table 10 for 11ac 5G 1SS */
965 rtl_write_dword(rtlpriv, REG_ARFR1 + 4, 0x003ff000);
966
967 /* CF-End setting. */
968 rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F00);
969
970 /* 0x456 = 0x70, sugguested by Zhilin */
971 rtl_write_byte(rtlpriv, REG_AMPDU_MAX_TIME, 0x70);
972
973 /* Set retry limit */
974 rtl_write_word(rtlpriv, REG_RL, 0x0707);
975
976 /* Set Data / Response auto rate fallack retry count */
977 rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000);
978 rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504);
979 rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000);
980 rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504);
981
982 rtlpci->reg_bcn_ctrl_val = 0x1d;
983 rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val);
984
985 /* TBTT prohibit hold time. Suggested by designer TimChen. */
986 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); /* 8 ms */
987
988 rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040);
989
990 /*For Rx TP. Suggested by SD1 Richard. Added by tynli. 2010.04.12.*/
991 rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666);
a619d1ab 992
5c99f04f 993 rtl_write_byte(rtlpriv, REG_HT_SINGLE_AMPDU, 0x80);
a619d1ab 994
5c99f04f
LF
995 rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x20);
996
997 rtl_write_byte(rtlpriv, REG_MAX_AGGR_NUM, 0x1F);
998}
999
1000static u8 _rtl8723be_dbi_read(struct rtl_priv *rtlpriv, u16 addr)
1001{
1002 u16 read_addr = addr & 0xfffc;
1003 u8 ret = 0, tmp = 0, count = 0;
1004
1005 rtl_write_word(rtlpriv, REG_DBI_ADDR, read_addr);
1006 rtl_write_byte(rtlpriv, REG_DBI_FLAG, 0x2);
1007 tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1008 count = 0;
1009 while (tmp && count < 20) {
1010 udelay(10);
1011 tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1012 count++;
1013 }
1014 if (0 == tmp) {
1015 read_addr = REG_DBI_RDATA + addr % 4;
1016 ret = rtl_read_byte(rtlpriv, read_addr);
1017 }
1018
1019 return ret;
1020}
1021
1022static void _rtl8723be_dbi_write(struct rtl_priv *rtlpriv, u16 addr, u8 data)
1023{
1024 u8 tmp = 0, count = 0;
1025 u16 write_addr = 0, remainder = addr % 4;
1026
1027 /* Write DBI 1Byte Data */
1028 write_addr = REG_DBI_WDATA + remainder;
1029 rtl_write_byte(rtlpriv, write_addr, data);
1030
1031 /* Write DBI 2Byte Address & Write Enable */
1032 write_addr = (addr & 0xfffc) | (BIT(0) << (remainder + 12));
1033 rtl_write_word(rtlpriv, REG_DBI_ADDR, write_addr);
1034
1035 /* Write DBI Write Flag */
1036 rtl_write_byte(rtlpriv, REG_DBI_FLAG, 0x1);
1037
1038 tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1039 count = 0;
1040 while (tmp && count < 20) {
1041 udelay(10);
1042 tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1043 count++;
1044 }
1045}
1046
1047static u16 _rtl8723be_mdio_read(struct rtl_priv *rtlpriv, u8 addr)
1048{
1049 u16 ret = 0;
1050 u8 tmp = 0, count = 0;
1051
1052 rtl_write_byte(rtlpriv, REG_MDIO_CTL, addr | BIT(6));
1053 tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(6);
1054 count = 0;
1055 while (tmp && count < 20) {
1056 udelay(10);
1057 tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(6);
1058 count++;
1059 }
1060
1061 if (0 == tmp)
1062 ret = rtl_read_word(rtlpriv, REG_MDIO_RDATA);
1063
1064 return ret;
1065}
1066
1067static void _rtl8723be_mdio_write(struct rtl_priv *rtlpriv, u8 addr, u16 data)
1068{
1069 u8 tmp = 0, count = 0;
1070
1071 rtl_write_word(rtlpriv, REG_MDIO_WDATA, data);
1072 rtl_write_byte(rtlpriv, REG_MDIO_CTL, addr | BIT(5));
1073 tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(5);
1074 count = 0;
1075 while (tmp && count < 20) {
1076 udelay(10);
1077 tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(5);
1078 count++;
1079 }
a619d1ab
LF
1080}
1081
1082static void _rtl8723be_enable_aspm_back_door(struct ieee80211_hw *hw)
1083{
1084 struct rtl_priv *rtlpriv = rtl_priv(hw);
5c99f04f
LF
1085 u8 tmp8 = 0;
1086 u16 tmp16 = 0;
a619d1ab 1087
5c99f04f
LF
1088 /* <Roger_Notes> Overwrite following ePHY parameter for
1089 * some platform compatibility issue,
1090 * especially when CLKReq is enabled, 2012.11.09.
1091 */
1092 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x01);
1093 if (tmp16 != 0x0663)
1094 _rtl8723be_mdio_write(rtlpriv, 0x01, 0x0663);
a619d1ab 1095
5c99f04f
LF
1096 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x04);
1097 if (tmp16 != 0x7544)
1098 _rtl8723be_mdio_write(rtlpriv, 0x04, 0x7544);
1099
1100 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x06);
1101 if (tmp16 != 0xB880)
1102 _rtl8723be_mdio_write(rtlpriv, 0x06, 0xB880);
1103
1104 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x07);
1105 if (tmp16 != 0x4000)
1106 _rtl8723be_mdio_write(rtlpriv, 0x07, 0x4000);
1107
1108 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x08);
1109 if (tmp16 != 0x9003)
1110 _rtl8723be_mdio_write(rtlpriv, 0x08, 0x9003);
1111
1112 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x09);
1113 if (tmp16 != 0x0D03)
1114 _rtl8723be_mdio_write(rtlpriv, 0x09, 0x0D03);
1115
1116 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x0A);
1117 if (tmp16 != 0x4037)
1118 _rtl8723be_mdio_write(rtlpriv, 0x0A, 0x4037);
a619d1ab 1119
5c99f04f
LF
1120 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x0B);
1121 if (tmp16 != 0x0070)
1122 _rtl8723be_mdio_write(rtlpriv, 0x0B, 0x0070);
1123
1124 /* Configuration Space offset 0x70f BIT7 is used to control L0S */
1125 tmp8 = _rtl8723be_dbi_read(rtlpriv, 0x70f);
1126 _rtl8723be_dbi_write(rtlpriv, 0x70f, tmp8 | BIT(7));
1127
1128 /* Configuration Space offset 0x719 Bit3 is for L1
1129 * BIT4 is for clock request
1130 */
1131 tmp8 = _rtl8723be_dbi_read(rtlpriv, 0x719);
1132 _rtl8723be_dbi_write(rtlpriv, 0x719, tmp8 | BIT(3) | BIT(4));
a619d1ab
LF
1133}
1134
1135void rtl8723be_enable_hw_security_config(struct ieee80211_hw *hw)
1136{
1137 struct rtl_priv *rtlpriv = rtl_priv(hw);
1138 u8 sec_reg_value;
1139
1140 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1141 "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
5c99f04f
LF
1142 rtlpriv->sec.pairwise_enc_algorithm,
1143 rtlpriv->sec.group_enc_algorithm);
a619d1ab
LF
1144
1145 if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
1146 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1147 "not open hw encryption\n");
1148 return;
1149 }
5c99f04f 1150
a619d1ab
LF
1151 sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE;
1152
1153 if (rtlpriv->sec.use_defaultkey) {
1154 sec_reg_value |= SCR_TXUSEDK;
1155 sec_reg_value |= SCR_RXUSEDK;
1156 }
5c99f04f 1157
a619d1ab
LF
1158 sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
1159
1160 rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
1161
5c99f04f
LF
1162 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1163 "The SECR-value %x\n", sec_reg_value);
a619d1ab
LF
1164
1165 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
1166}
1167
5c99f04f
LF
1168static void _rtl8723be_poweroff_adapter(struct ieee80211_hw *hw)
1169{
1170 struct rtl_priv *rtlpriv = rtl_priv(hw);
1171 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1172 u8 u1b_tmp;
1173
1174 rtlhal->mac_func_enable = false;
1175 /* Combo (PCIe + USB) Card and PCIe-MF Card */
1176 /* 1. Run LPS WL RFOFF flow */
1177 rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1178 PWR_INTF_PCI_MSK, RTL8723_NIC_LPS_ENTER_FLOW);
1179
1180 /* 2. 0x1F[7:0] = 0 */
1181 /* turn off RF */
1182 /* rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); */
1183 if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) &&
1184 rtlhal->fw_ready) {
1185 rtl8723be_firmware_selfreset(hw);
1186 }
1187
1188 /* Reset MCU. Suggested by Filen. */
1189 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1190 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2))));
1191
1192 /* g. MCUFWDL 0x80[1:0]=0 */
1193 /* reset MCU ready status */
1194 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
1195
1196 /* HW card disable configuration. */
1197 rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1198 PWR_INTF_PCI_MSK, RTL8723_NIC_DISABLE_FLOW);
1199
1200 /* Reset MCU IO Wrapper */
1201 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1202 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0))));
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
1206 /* 7. RSV_CTRL 0x1C[7:0] = 0x0E */
1207 /* lock ISO/CLK/Power control register */
1208 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e);
1209}
1210
1211static bool _rtl8723be_check_pcie_dma_hang(struct rtl_priv *rtlpriv)
1212{
1213 u8 tmp;
1214
1215 /* write reg 0x350 Bit[26]=1. Enable debug port. */
1216 tmp = rtl_read_byte(rtlpriv, REG_DBI_CTRL + 3);
1217 if (!(tmp & BIT(2))) {
1218 rtl_write_byte(rtlpriv, REG_DBI_CTRL + 3, (tmp | BIT(2)));
1219 mdelay(100); /* Suggested by DD Justin_tsai. */
1220 }
1221
1222 /* read reg 0x350 Bit[25] if 1 : RX hang
1223 * read reg 0x350 Bit[24] if 1 : TX hang
1224 */
1225 tmp = rtl_read_byte(rtlpriv, REG_DBI_CTRL + 3);
1226 if ((tmp & BIT(0)) || (tmp & BIT(1))) {
1227 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1228 "CheckPcieDMAHang8723BE(): true!!\n");
1229 return true;
1230 }
1231 return false;
1232}
1233
1234static void _rtl8723be_reset_pcie_interface_dma(struct rtl_priv *rtlpriv,
1235 bool mac_power_on)
1236{
1237 u8 tmp;
1238 bool release_mac_rx_pause;
1239 u8 backup_pcie_dma_pause;
1240
1241 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1242 "ResetPcieInterfaceDMA8723BE()\n");
1243
1244 /* Revise Note: Follow the document "PCIe RX DMA Hang Reset Flow_v03"
1245 * released by SD1 Alan.
1246 * 2013.05.07, by tynli.
1247 */
1248
1249 /* 1. disable register write lock
1250 * write 0x1C bit[1:0] = 2'h0
1251 * write 0xCC bit[2] = 1'b1
1252 */
1253 tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL);
1254 tmp &= ~(BIT(1) | BIT(0));
1255 rtl_write_byte(rtlpriv, REG_RSV_CTRL, tmp);
1256 tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2);
1257 tmp |= BIT(2);
1258 rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp);
1259
1260 /* 2. Check and pause TRX DMA
1261 * write 0x284 bit[18] = 1'b1
1262 * write 0x301 = 0xFF
1263 */
1264 tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1265 if (tmp & BIT(2)) {
1266 /* Already pause before the function for another purpose. */
1267 release_mac_rx_pause = false;
1268 } else {
1269 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, (tmp | BIT(2)));
1270 release_mac_rx_pause = true;
1271 }
1272
1273 backup_pcie_dma_pause = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 1);
1274 if (backup_pcie_dma_pause != 0xFF)
1275 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xFF);
1276
1277 if (mac_power_on) {
1278 /* 3. reset TRX function
1279 * write 0x100 = 0x00
1280 */
1281 rtl_write_byte(rtlpriv, REG_CR, 0);
1282 }
1283
1284 /* 4. Reset PCIe DMA
1285 * write 0x003 bit[0] = 0
1286 */
1287 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1288 tmp &= ~(BIT(0));
1289 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp);
1290
1291 /* 5. Enable PCIe DMA
1292 * write 0x003 bit[0] = 1
1293 */
1294 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1295 tmp |= BIT(0);
1296 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp);
1297
1298 if (mac_power_on) {
1299 /* 6. enable TRX function
1300 * write 0x100 = 0xFF
1301 */
1302 rtl_write_byte(rtlpriv, REG_CR, 0xFF);
1303
1304 /* We should init LLT & RQPN and
1305 * prepare Tx/Rx descrptor address later
1306 * because MAC function is reset.
1307 */
1308 }
1309
1310 /* 7. Restore PCIe autoload down bit
1311 * write 0xF8 bit[17] = 1'b1
1312 */
1313 tmp = rtl_read_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2);
1314 tmp |= BIT(1);
1315 rtl_write_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2, tmp);
1316
1317 /* In MAC power on state, BB and RF maybe in ON state,
1318 * if we release TRx DMA here
1319 * it will cause packets to be started to Tx/Rx,
1320 * so we release Tx/Rx DMA later.
1321 */
1322 if (!mac_power_on) {
1323 /* 8. release TRX DMA
1324 * write 0x284 bit[18] = 1'b0
1325 * write 0x301 = 0x00
1326 */
1327 if (release_mac_rx_pause) {
1328 tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1329 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL,
1330 (tmp & (~BIT(2))));
1331 }
1332 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1,
1333 backup_pcie_dma_pause);
1334 }
1335
1336 /* 9. lock system register
1337 * write 0xCC bit[2] = 1'b0
1338 */
1339 tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2);
1340 tmp &= ~(BIT(2));
1341 rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp);
1342}
1343
a619d1ab
LF
1344int rtl8723be_hw_init(struct ieee80211_hw *hw)
1345{
1346 struct rtl_priv *rtlpriv = rtl_priv(hw);
1347 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1348 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1349 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1350 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1351 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1352 bool rtstatus = true;
1353 int err;
1354 u8 tmp_u1b;
1355 unsigned long flags;
1356
1357 /* reenable interrupts to not interfere with other devices */
1358 local_save_flags(flags);
1359 local_irq_enable();
1360
5c99f04f 1361 rtlhal->fw_ready = false;
a619d1ab
LF
1362 rtlpriv->rtlhal.being_init_adapter = true;
1363 rtlpriv->intf_ops->disable_aspm(hw);
5c99f04f
LF
1364
1365 tmp_u1b = rtl_read_byte(rtlpriv, REG_CR);
1366 if (tmp_u1b != 0 && tmp_u1b != 0xea) {
1367 rtlhal->mac_func_enable = true;
1368 } else {
1369 rtlhal->mac_func_enable = false;
1370 rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON;
1371 }
1372
1373 if (_rtl8723be_check_pcie_dma_hang(rtlpriv)) {
1374 _rtl8723be_reset_pcie_interface_dma(rtlpriv,
1375 rtlhal->mac_func_enable);
1376 rtlhal->mac_func_enable = false;
1377 }
1378 if (rtlhal->mac_func_enable) {
1379 _rtl8723be_poweroff_adapter(hw);
1380 rtlhal->mac_func_enable = false;
1381 }
a619d1ab
LF
1382 rtstatus = _rtl8723be_init_mac(hw);
1383 if (!rtstatus) {
4e2b4378 1384 pr_err("Init MAC failed\n");
a619d1ab
LF
1385 err = 1;
1386 goto exit;
1387 }
5c99f04f 1388
a619d1ab 1389 tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CFG);
5c99f04f 1390 rtl_write_byte(rtlpriv, REG_SYS_CFG, tmp_u1b & 0x7F);
a619d1ab 1391
5c99f04f 1392 err = rtl8723_download_fw(hw, true, FW_8723B_POLLING_TIMEOUT_COUNT);
a619d1ab
LF
1393 if (err) {
1394 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1395 "Failed to download FW. Init HW without FW now..\n");
1396 err = 1;
a619d1ab 1397 goto exit;
a619d1ab 1398 }
5c99f04f
LF
1399 rtlhal->fw_ready = true;
1400
a619d1ab
LF
1401 rtlhal->last_hmeboxnum = 0;
1402 rtl8723be_phy_mac_config(hw);
1403 /* because last function modify RCR, so we update
1404 * rcr var here, or TP will unstable for receive_config
5c99f04f 1405 * is wrong, RX RCR_ACRC32 will cause TP unstable & Rx
a619d1ab
LF
1406 * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252
1407 */
1408 rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR);
1409 rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
1410 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
1411
1412 rtl8723be_phy_bb_config(hw);
a619d1ab
LF
1413 rtl8723be_phy_rf_config(hw);
1414
1415 rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
1416 RF_CHNLBW, RFREG_OFFSET_MASK);
1417 rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1,
1418 RF_CHNLBW, RFREG_OFFSET_MASK);
1419 rtlphy->rfreg_chnlval[0] &= 0xFFF03FF;
1420 rtlphy->rfreg_chnlval[0] |= (BIT(10) | BIT(11));
1421
a619d1ab 1422 _rtl8723be_hw_configure(hw);
5c99f04f 1423 rtlhal->mac_func_enable = true;
a619d1ab
LF
1424 rtl_cam_reset_all_entry(hw);
1425 rtl8723be_enable_hw_security_config(hw);
1426
1427 ppsc->rfpwr_state = ERFON;
1428
1429 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
1430 _rtl8723be_enable_aspm_back_door(hw);
1431 rtlpriv->intf_ops->enable_aspm(hw);
1432
1433 rtl8723be_bt_hw_init(hw);
1434
a619d1ab 1435 if (ppsc->rfpwr_state == ERFON) {
5c99f04f
LF
1436 rtl8723be_phy_set_rfpath_switch(hw, 1);
1437 /* when use 1ant NIC, iqk will disturb BT music
1438 * root cause is not clear now, is something
1439 * related with 'mdelay' and Reg[0x948]
1440 */
1441 if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2 ||
1442 !rtlpriv->cfg->ops->get_btc_status()) {
a7088392
PKS
1443 rtl8723be_phy_iq_calibrate(hw,
1444 (rtlphy->iqk_initialized ?
1445 true : false));
5c99f04f
LF
1446 rtlphy->iqk_initialized = true;
1447 }
a619d1ab
LF
1448 rtl8723be_dm_check_txpower_tracking(hw);
1449 rtl8723be_phy_lc_calibrate(hw);
1450 }
5c99f04f
LF
1451 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);
a619d1ab 1459 }
5c99f04f
LF
1460 /* Release Tx/Rx PCIE DMA. */
1461 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0);
1462
a619d1ab
LF
1463 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;
a619d1ab
LF
1475 u32 value32;
1476
a619d1ab
LF
1477 value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG1);
1478 if ((value32 & (CHIP_8723B)) != CHIP_8723B)
8a190237 1479 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "unknown chip version\n");
a619d1ab 1480 else
5c99f04f 1481 version = (enum version_8723e)CHIP_8723B;
a619d1ab 1482
5c99f04f
LF
1483 rtlphy->rf_type = RF_1T1R;
1484
1485 /* 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);
a619d1ab 1494
a619d1ab
LF
1495 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1496 "Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
5c99f04f 1497 "RF_2T2R" : "RF_1T1R");
a619d1ab
LF
1498
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;
5c99f04f 1508 u8 mode = MSR_NOLINK;
a619d1ab 1509
a619d1ab
LF
1510 switch (type) {
1511 case NL80211_IFTYPE_UNSPECIFIED:
5c99f04f 1512 mode = MSR_NOLINK;
a619d1ab
LF
1513 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1514 "Set Network type to NO LINK!\n");
1515 break;
1516 case NL80211_IFTYPE_ADHOC:
5c99f04f
LF
1517 case NL80211_IFTYPE_MESH_POINT:
1518 mode = MSR_ADHOC;
a619d1ab
LF
1519 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1520 "Set Network type to Ad Hoc!\n");
1521 break;
1522 case NL80211_IFTYPE_STATION:
5c99f04f 1523 mode = MSR_INFRA;
a619d1ab
LF
1524 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:
5c99f04f
LF
1529 mode = MSR_AP;
1530 ledaction = LED_CTL_LINK;
a619d1ab
LF
1531 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1532 "Set Network type to AP!\n");
1533 break;
1534 default:
4e2b4378 1535 pr_err("Network type %d not support!\n", type);
a619d1ab
LF
1536 return 1;
1537 }
5c99f04f
LF
1538
1539 /* MSR_INFRA == Link in infrastructure network;
1540 * MSR_ADHOC == Link in ad hoc network;
1541 * Therefore, check link state is necessary.
1542 *
1543 * MSR_AP == AP mode; link state is not cared here.
1544 */
1545 if (mode != MSR_AP && rtlpriv->mac80211.link_state < MAC80211_LINKED) {
1546 mode = MSR_NOLINK;
1547 ledaction = LED_CTL_NO_LINK;
1548 }
1549
1550 if (mode == MSR_NOLINK || mode == MSR_INFRA) {
1551 _rtl8723be_stop_tx_beacon(hw);
1552 _rtl8723be_enable_bcn_sub_func(hw);
1553 } else if (mode == MSR_ADHOC || mode == MSR_AP) {
1554 _rtl8723be_resume_tx_beacon(hw);
1555 _rtl8723be_disable_bcn_sub_func(hw);
1556 } else {
1557 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1558 "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n",
1559 mode);
1560 }
1561
e480e134 1562 rtl_write_byte(rtlpriv, MSR, bt_msr | mode);
a619d1ab 1563 rtlpriv->cfg->ops->led_control(hw, ledaction);
5c99f04f 1564 if (mode == MSR_AP)
a619d1ab
LF
1565 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1566 else
1567 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
1568 return 0;
1569}
1570
1571void rtl8723be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1572{
1573 struct rtl_priv *rtlpriv = rtl_priv(hw);
1574 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1575 u32 reg_rcr = rtlpci->receive_config;
1576
1577 if (rtlpriv->psc.rfpwr_state != ERFON)
1578 return;
1579
1580 if (check_bssid) {
1581 reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1582 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1583 (u8 *)(&reg_rcr));
1584 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4));
1585 } else if (!check_bssid) {
1586 reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
1587 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0);
1588 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1589 (u8 *)(&reg_rcr));
1590 }
5c99f04f 1591
a619d1ab
LF
1592}
1593
1594int rtl8723be_set_network_type(struct ieee80211_hw *hw,
1595 enum nl80211_iftype type)
1596{
1597 struct rtl_priv *rtlpriv = rtl_priv(hw);
1598
1599 if (_rtl8723be_set_media_status(hw, type))
1600 return -EOPNOTSUPP;
1601
1602 if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
1603 if (type != NL80211_IFTYPE_AP)
1604 rtl8723be_set_check_bssid(hw, true);
1605 } else {
1606 rtl8723be_set_check_bssid(hw, false);
1607 }
5c99f04f 1608
a619d1ab
LF
1609 return 0;
1610}
1611
1612/* don't set REG_EDCA_BE_PARAM here
1613 * because mac80211 will send pkt when scan
1614 */
1615void rtl8723be_set_qos(struct ieee80211_hw *hw, int aci)
1616{
1617 struct rtl_priv *rtlpriv = rtl_priv(hw);
5c99f04f 1618
a619d1ab
LF
1619 rtl8723_dm_init_edca_turbo(hw);
1620 switch (aci) {
1621 case AC1_BK:
1622 rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f);
1623 break;
1624 case AC0_BE:
1625 break;
1626 case AC2_VI:
1627 rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322);
1628 break;
1629 case AC3_VO:
1630 rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
1631 break;
1632 default:
531940f9 1633 WARN_ONCE(true, "rtl8723be: invalid aci: %d !\n", aci);
a619d1ab
LF
1634 break;
1635 }
1636}
1637
1638void rtl8723be_enable_interrupt(struct ieee80211_hw *hw)
1639{
1640 struct rtl_priv *rtlpriv = rtl_priv(hw);
1641 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1642
1643 rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
1644 rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
1645 rtlpci->irq_enabled = true;
5c99f04f 1646
a619d1ab
LF
1647 /*enable system interrupt*/
1648 rtl_write_dword(rtlpriv, REG_HSIMR, rtlpci->sys_irq_mask & 0xFFFFFFFF);
1649}
1650
1651void rtl8723be_disable_interrupt(struct ieee80211_hw *hw)
1652{
1653 struct rtl_priv *rtlpriv = rtl_priv(hw);
1654 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1655
1656 rtl_write_dword(rtlpriv, REG_HIMR, IMR_DISABLED);
1657 rtl_write_dword(rtlpriv, REG_HIMRE, IMR_DISABLED);
1658 rtlpci->irq_enabled = false;
5c99f04f 1659 /*synchronize_irq(rtlpci->pdev->irq);*/
a619d1ab
LF
1660}
1661
1662void rtl8723be_card_disable(struct ieee80211_hw *hw)
1663{
1664 struct rtl_priv *rtlpriv = rtl_priv(hw);
1665 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1666 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1667 enum nl80211_iftype opmode;
1668
1669 mac->link_state = MAC80211_NOLINK;
1670 opmode = NL80211_IFTYPE_UNSPECIFIED;
1671 _rtl8723be_set_media_status(hw, opmode);
1672 if (rtlpriv->rtlhal.driver_is_goingto_unload ||
1673 ppsc->rfoff_reason > RF_CHANGE_BY_PS)
1674 rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
1675 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1676 _rtl8723be_poweroff_adapter(hw);
1677
1678 /* after power off we should do iqk again */
a7088392
PKS
1679 if (!rtlpriv->cfg->ops->get_btc_status())
1680 rtlpriv->phy.iqk_initialized = false;
a619d1ab
LF
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,
5c99f04f 1767 "hal_ReadPowerValueFromPROM8723BE(): PROMContent[0x%x]=0x%x\n",
a619d1ab 1768 (addr + 1), hwinfo[addr + 1]);
5c99f04f 1769 if (0xFF == hwinfo[addr + 1]) /*YJ,add,120316*/
a619d1ab
LF
1770 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 */
5c99f04f 1777 for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) {
a619d1ab
LF
1778 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 }
5c99f04f 1795
a619d1ab
LF
1796 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;
5c99f04f 1802
a619d1ab
LF
1803 }
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))
5c99f04f
LF
1819 pw2g->bw20_diff[path][cnt] |=
1820 0xF0;
a619d1ab 1821 }
5c99f04f 1822
a619d1ab
LF
1823 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 }
5c99f04f 1845
a619d1ab
LF
1846 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 }
5c99f04f
LF
1866
1867 if (hwinfo[addr] == 0xFF)
a619d1ab 1868 pw2g->cck_diff[path][cnt] = 0xFE;
5c99f04f 1869 else {
a619d1ab
LF
1870 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 }
5c99f04f 1879
a619d1ab
LF
1880 /*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 }
5c99f04f 1886
a619d1ab
LF
1887 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 }
5c99f04f
LF
1900
1901 if (hwinfo[addr] == 0xFF)
a619d1ab 1902 pw5g->ofdm_diff[path][cnt] = 0x04;
5c99f04f 1903 else {
a619d1ab
LF
1904 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 }
5c99f04f 1920
a619d1ab
LF
1921 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 }
5c99f04f 1932
a619d1ab
LF
1933 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 }
5c99f04f 1988
a619d1ab 1989 for (i = 0; i < 14; i++) {
5c99f04f
LF
1990 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1991 "RF(%d)-Ch(%d) [CCK / HT40_1S ] = [0x%x / 0x%x ]\n",
1992 rf_path, i,
a619d1ab
LF
1993 rtlefuse->txpwrlevel_cck[rf_path][i],
1994 rtlefuse->txpwrlevel_ht40_1s[rf_path][i]);
1995 }
1996 }
5c99f04f 1997
a619d1ab
LF
1998 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 }
5c99f04f 2008
a619d1ab 2009 rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
5c99f04f 2010 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
a619d1ab
LF
2011 "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 }
5c99f04f 2021 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
a619d1ab
LF
2022 "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
2023}
2024
7fe1fe75
PKS
2025static u8 _rtl8723be_read_package_type(struct ieee80211_hw *hw)
2026{
2027 u8 package_type;
2028 u8 value;
2029
2030 efuse_power_switch(hw, false, true);
2031 if (!efuse_one_byte_read(hw, 0x1FB, &value))
2032 value = 0;
2033 efuse_power_switch(hw, false, false);
2034
2035 switch (value & 0x7) {
2036 case 0x4:
2037 package_type = PACKAGE_TFBGA79;
2038 break;
2039 case 0x5:
2040 package_type = PACKAGE_TFBGA90;
2041 break;
2042 case 0x6:
2043 package_type = PACKAGE_QFN68;
2044 break;
2045 case 0x7:
2046 package_type = PACKAGE_TFBGA80;
2047 break;
2048 default:
2049 package_type = PACKAGE_DEFAULT;
2050 break;
2051 }
2052
2053 return package_type;
2054}
2055
a619d1ab
LF
2056static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw,
2057 bool pseudo_test)
2058{
2059 struct rtl_priv *rtlpriv = rtl_priv(hw);
2060 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2061 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
9e9c9c24
LF
2062 int params[] = {RTL8723BE_EEPROM_ID, EEPROM_VID, EEPROM_DID,
2063 EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR,
2064 EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID,
2065 COUNTRY_CODE_WORLD_WIDE_13};
2066 u8 *hwinfo;
2067 int i;
a619d1ab
LF
2068 bool is_toshiba_smid1 = false;
2069 bool is_toshiba_smid2 = false;
2070 bool is_samsung_smid = false;
2071 bool is_lenovo_smid = false;
2072 u16 toshiba_smid1[] = {
2073 0x6151, 0x6152, 0x6154, 0x6155, 0x6177, 0x6178, 0x6179, 0x6180,
2074 0x7151, 0x7152, 0x7154, 0x7155, 0x7177, 0x7178, 0x7179, 0x7180,
2075 0x8151, 0x8152, 0x8154, 0x8155, 0x8181, 0x8182, 0x8184, 0x8185,
2076 0x9151, 0x9152, 0x9154, 0x9155, 0x9181, 0x9182, 0x9184, 0x9185
2077 };
2078 u16 toshiba_smid2[] = {
2079 0x6181, 0x6184, 0x6185, 0x7181, 0x7182, 0x7184, 0x7185, 0x8181,
2080 0x8182, 0x8184, 0x8185, 0x9181, 0x9182, 0x9184, 0x9185
2081 };
2082 u16 samsung_smid[] = {
2083 0x6191, 0x6192, 0x6193, 0x7191, 0x7192, 0x7193, 0x8191, 0x8192,
2084 0x8193, 0x9191, 0x9192, 0x9193
2085 };
2086 u16 lenovo_smid[] = {
2087 0x8195, 0x9195, 0x7194, 0x8200, 0x8201, 0x8202, 0x9199, 0x9200
2088 };
2089
2090 if (pseudo_test) {
2091 /* needs to be added */
2092 return;
2093 }
5345ea6a 2094
9e9c9c24
LF
2095 hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL);
2096 if (!hwinfo)
a619d1ab
LF
2097 return;
2098
9e9c9c24
LF
2099 if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params))
2100 goto exit;
a619d1ab
LF
2101
2102 /*parse xtal*/
2103 rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_8723BE];
2104 if (rtlefuse->crystalcap == 0xFF)
2105 rtlefuse->crystalcap = 0x20;
2106
2107 _rtl8723be_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag,
2108 hwinfo);
2109
2110 rtl8723be_read_bt_coexist_info_from_hwpg(hw,
2111 rtlefuse->autoload_failflag,
2112 hwinfo);
2113
7fe1fe75
PKS
2114 rtlhal->package_type = _rtl8723be_read_package_type(hw);
2115
b23cd22d
SF
2116 /* set channel plan from efuse */
2117 rtlefuse->channel_plan = rtlefuse->eeprom_channelplan;
a619d1ab
LF
2118
2119 if (rtlhal->oem_id == RT_CID_DEFAULT) {
2120 /* Does this one have a Toshiba SMID from group 1? */
2121 for (i = 0; i < sizeof(toshiba_smid1) / sizeof(u16); i++) {
2122 if (rtlefuse->eeprom_smid == toshiba_smid1[i]) {
2123 is_toshiba_smid1 = true;
2124 break;
2125 }
2126 }
2127 /* Does this one have a Toshiba SMID from group 2? */
2128 for (i = 0; i < sizeof(toshiba_smid2) / sizeof(u16); i++) {
2129 if (rtlefuse->eeprom_smid == toshiba_smid2[i]) {
2130 is_toshiba_smid2 = true;
2131 break;
2132 }
2133 }
2134 /* Does this one have a Samsung SMID? */
2135 for (i = 0; i < sizeof(samsung_smid) / sizeof(u16); i++) {
2136 if (rtlefuse->eeprom_smid == samsung_smid[i]) {
2137 is_samsung_smid = true;
2138 break;
2139 }
2140 }
2141 /* Does this one have a Lenovo SMID? */
2142 for (i = 0; i < sizeof(lenovo_smid) / sizeof(u16); i++) {
2143 if (rtlefuse->eeprom_smid == lenovo_smid[i]) {
2144 is_lenovo_smid = true;
2145 break;
2146 }
2147 }
2148 switch (rtlefuse->eeprom_oemid) {
2149 case EEPROM_CID_DEFAULT:
2150 if (rtlefuse->eeprom_did == 0x8176) {
2151 if (rtlefuse->eeprom_svid == 0x10EC &&
2152 is_toshiba_smid1) {
2153 rtlhal->oem_id = RT_CID_TOSHIBA;
2154 } else if (rtlefuse->eeprom_svid == 0x1025) {
2155 rtlhal->oem_id = RT_CID_819X_ACER;
2156 } else if (rtlefuse->eeprom_svid == 0x10EC &&
2157 is_samsung_smid) {
2158 rtlhal->oem_id = RT_CID_819X_SAMSUNG;
2159 } else if (rtlefuse->eeprom_svid == 0x10EC &&
2160 is_lenovo_smid) {
2161 rtlhal->oem_id = RT_CID_819X_LENOVO;
2162 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
2163 rtlefuse->eeprom_smid == 0x8197) ||
2164 (rtlefuse->eeprom_svid == 0x10EC &&
2165 rtlefuse->eeprom_smid == 0x9196)) {
2166 rtlhal->oem_id = RT_CID_819X_CLEVO;
2167 } else if ((rtlefuse->eeprom_svid == 0x1028 &&
2168 rtlefuse->eeprom_smid == 0x8194) ||
2169 (rtlefuse->eeprom_svid == 0x1028 &&
2170 rtlefuse->eeprom_smid == 0x8198) ||
2171 (rtlefuse->eeprom_svid == 0x1028 &&
2172 rtlefuse->eeprom_smid == 0x9197) ||
2173 (rtlefuse->eeprom_svid == 0x1028 &&
2174 rtlefuse->eeprom_smid == 0x9198)) {
2175 rtlhal->oem_id = RT_CID_819X_DELL;
2176 } else if ((rtlefuse->eeprom_svid == 0x103C &&
2177 rtlefuse->eeprom_smid == 0x1629)) {
2178 rtlhal->oem_id = RT_CID_819X_HP;
2179 } else if ((rtlefuse->eeprom_svid == 0x1A32 &&
2180 rtlefuse->eeprom_smid == 0x2315)) {
2181 rtlhal->oem_id = RT_CID_819X_QMI;
2182 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
2183 rtlefuse->eeprom_smid == 0x8203)) {
2184 rtlhal->oem_id = RT_CID_819X_PRONETS;
2185 } else if ((rtlefuse->eeprom_svid == 0x1043 &&
2186 rtlefuse->eeprom_smid == 0x84B5)) {
2187 rtlhal->oem_id = RT_CID_819X_EDIMAX_ASUS;
2188 } else {
2189 rtlhal->oem_id = RT_CID_DEFAULT;
2190 }
2191 } else if (rtlefuse->eeprom_did == 0x8178) {
2192 if (rtlefuse->eeprom_svid == 0x10EC &&
2193 is_toshiba_smid2)
2194 rtlhal->oem_id = RT_CID_TOSHIBA;
2195 else if (rtlefuse->eeprom_svid == 0x1025)
2196 rtlhal->oem_id = RT_CID_819X_ACER;
2197 else if ((rtlefuse->eeprom_svid == 0x10EC &&
2198 rtlefuse->eeprom_smid == 0x8186))
2199 rtlhal->oem_id = RT_CID_819X_PRONETS;
2200 else if ((rtlefuse->eeprom_svid == 0x1043 &&
2201 rtlefuse->eeprom_smid == 0x84B6))
2202 rtlhal->oem_id =
2203 RT_CID_819X_EDIMAX_ASUS;
2204 else
2205 rtlhal->oem_id = RT_CID_DEFAULT;
2206 } else {
2207 rtlhal->oem_id = RT_CID_DEFAULT;
2208 }
2209 break;
2210 case EEPROM_CID_TOSHIBA:
2211 rtlhal->oem_id = RT_CID_TOSHIBA;
2212 break;
2213 case EEPROM_CID_CCX:
2214 rtlhal->oem_id = RT_CID_CCX;
2215 break;
2216 case EEPROM_CID_QMI:
2217 rtlhal->oem_id = RT_CID_819X_QMI;
2218 break;
2219 case EEPROM_CID_WHQL:
2220 break;
2221 default:
2222 rtlhal->oem_id = RT_CID_DEFAULT;
2223 break;
2224 }
2225 }
9e9c9c24
LF
2226exit:
2227 kfree(hwinfo);
a619d1ab
LF
2228}
2229
2230static void _rtl8723be_hal_customized_behavior(struct ieee80211_hw *hw)
2231{
2232 struct rtl_priv *rtlpriv = rtl_priv(hw);
a619d1ab
LF
2233 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2234
d5efe153 2235 rtlpriv->ledctl.led_opendrain = true;
a619d1ab
LF
2236 switch (rtlhal->oem_id) {
2237 case RT_CID_819X_HP:
d5efe153 2238 rtlpriv->ledctl.led_opendrain = true;
a619d1ab
LF
2239 break;
2240 case RT_CID_819X_LENOVO:
2241 case RT_CID_DEFAULT:
2242 case RT_CID_TOSHIBA:
2243 case RT_CID_CCX:
2244 case RT_CID_819X_ACER:
2245 case RT_CID_WHQL:
2246 default:
2247 break;
2248 }
2249 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2250 "RT Customized ID: 0x%02X\n", rtlhal->oem_id);
2251}
2252
2253void rtl8723be_read_eeprom_info(struct ieee80211_hw *hw)
2254{
2255 struct rtl_priv *rtlpriv = rtl_priv(hw);
2256 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2257 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2258 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2259 u8 tmp_u1b;
2260
2261 rtlhal->version = _rtl8723be_read_chip_version(hw);
2262 if (get_rf_type(rtlphy) == RF_1T1R)
2263 rtlpriv->dm.rfpath_rxenable[0] = true;
2264 else
2265 rtlpriv->dm.rfpath_rxenable[0] =
2266 rtlpriv->dm.rfpath_rxenable[1] = true;
2267 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
2268 rtlhal->version);
2269 tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
2270 if (tmp_u1b & BIT(4)) {
2271 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
2272 rtlefuse->epromtype = EEPROM_93C46;
2273 } else {
2274 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
2275 rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
2276 }
2277 if (tmp_u1b & BIT(5)) {
2278 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
2279 rtlefuse->autoload_failflag = false;
2280 _rtl8723be_read_adapter_info(hw, false);
2281 } else {
4e2b4378 2282 pr_err("Autoload ERR!!\n");
a619d1ab
LF
2283 }
2284 _rtl8723be_hal_customized_behavior(hw);
2285}
2286
a619d1ab
LF
2287static u8 _rtl8723be_mrate_idx_to_arfr_id(struct ieee80211_hw *hw,
2288 u8 rate_index)
2289{
2290 u8 ret = 0;
a619d1ab
LF
2291 switch (rate_index) {
2292 case RATR_INX_WIRELESS_NGB:
2293 ret = 1;
2294 break;
2295 case RATR_INX_WIRELESS_N:
2296 case RATR_INX_WIRELESS_NG:
2297 ret = 5;
2298 break;
2299 case RATR_INX_WIRELESS_NB:
2300 ret = 3;
2301 break;
2302 case RATR_INX_WIRELESS_GB:
2303 ret = 6;
2304 break;
2305 case RATR_INX_WIRELESS_G:
2306 ret = 7;
2307 break;
2308 case RATR_INX_WIRELESS_B:
2309 ret = 8;
2310 break;
2311 default:
2312 ret = 0;
2313 break;
2314 }
2315 return ret;
2316}
2317
2318static void rtl8723be_update_hal_rate_mask(struct ieee80211_hw *hw,
2319 struct ieee80211_sta *sta,
2320 u8 rssi_level)
2321{
2322 struct rtl_priv *rtlpriv = rtl_priv(hw);
2323 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2324 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2325 struct rtl_sta_info *sta_entry = NULL;
2326 u32 ratr_bitmap;
2327 u8 ratr_index;
2328 u8 curtxbw_40mhz = (sta->ht_cap.cap &
5c99f04f 2329 IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0;
a619d1ab 2330 u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
5c99f04f 2331 1 : 0;
a619d1ab 2332 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
5c99f04f 2333 1 : 0;
a619d1ab
LF
2334 enum wireless_mode wirelessmode = 0;
2335 bool shortgi = false;
2336 u8 rate_mask[7];
2337 u8 macid = 0;
a619d1ab
LF
2338
2339 sta_entry = (struct rtl_sta_info *)sta->drv_priv;
2340 wirelessmode = sta_entry->wireless_mode;
2341 if (mac->opmode == NL80211_IFTYPE_STATION ||
2342 mac->opmode == NL80211_IFTYPE_MESH_POINT)
2343 curtxbw_40mhz = mac->bw_40;
2344 else if (mac->opmode == NL80211_IFTYPE_AP ||
2345 mac->opmode == NL80211_IFTYPE_ADHOC)
2346 macid = sta->aid + 1;
2347
2348 ratr_bitmap = sta->supp_rates[0];
2349
2350 if (mac->opmode == NL80211_IFTYPE_ADHOC)
2351 ratr_bitmap = 0xfff;
2352
2353 ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
2354 sta->ht_cap.mcs.rx_mask[0] << 12);
2355 switch (wirelessmode) {
2356 case WIRELESS_MODE_B:
2357 ratr_index = RATR_INX_WIRELESS_B;
2358 if (ratr_bitmap & 0x0000000c)
2359 ratr_bitmap &= 0x0000000d;
2360 else
2361 ratr_bitmap &= 0x0000000f;
2362 break;
2363 case WIRELESS_MODE_G:
2364 ratr_index = RATR_INX_WIRELESS_GB;
2365
2366 if (rssi_level == 1)
2367 ratr_bitmap &= 0x00000f00;
2368 else if (rssi_level == 2)
2369 ratr_bitmap &= 0x00000ff0;
2370 else
2371 ratr_bitmap &= 0x00000ff5;
2372 break;
a619d1ab
LF
2373 case WIRELESS_MODE_N_24G:
2374 case WIRELESS_MODE_N_5G:
2375 ratr_index = RATR_INX_WIRELESS_NGB;
5c99f04f
LF
2376 if (rtlphy->rf_type == RF_1T1R) {
2377 if (curtxbw_40mhz) {
2378 if (rssi_level == 1)
2379 ratr_bitmap &= 0x000f0000;
2380 else if (rssi_level == 2)
2381 ratr_bitmap &= 0x000ff000;
2382 else
2383 ratr_bitmap &= 0x000ff015;
2384 } else {
2385 if (rssi_level == 1)
2386 ratr_bitmap &= 0x000f0000;
2387 else if (rssi_level == 2)
2388 ratr_bitmap &= 0x000ff000;
2389 else
2390 ratr_bitmap &= 0x000ff005;
2391 }
a619d1ab 2392 } else {
5c99f04f
LF
2393 if (curtxbw_40mhz) {
2394 if (rssi_level == 1)
2395 ratr_bitmap &= 0x0f8f0000;
2396 else if (rssi_level == 2)
2397 ratr_bitmap &= 0x0f8ff000;
2398 else
2399 ratr_bitmap &= 0x0f8ff015;
a619d1ab 2400 } else {
5c99f04f
LF
2401 if (rssi_level == 1)
2402 ratr_bitmap &= 0x0f8f0000;
2403 else if (rssi_level == 2)
2404 ratr_bitmap &= 0x0f8ff000;
2405 else
2406 ratr_bitmap &= 0x0f8ff005;
a619d1ab
LF
2407 }
2408 }
2409 if ((curtxbw_40mhz && curshortgi_40mhz) ||
2410 (!curtxbw_40mhz && curshortgi_20mhz)) {
2411 if (macid == 0)
2412 shortgi = true;
2413 else if (macid == 1)
2414 shortgi = false;
2415 }
2416 break;
2417 default:
2418 ratr_index = RATR_INX_WIRELESS_NGB;
2419
2420 if (rtlphy->rf_type == RF_1T2R)
2421 ratr_bitmap &= 0x000ff0ff;
2422 else
2423 ratr_bitmap &= 0x0f0ff0ff;
2424 break;
2425 }
5c99f04f 2426
a619d1ab
LF
2427 sta_entry->ratr_index = ratr_index;
2428
2429 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2430 "ratr_bitmap :%x\n", ratr_bitmap);
5c99f04f
LF
2431 *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
2432 (ratr_index << 28);
a619d1ab
LF
2433 rate_mask[0] = macid;
2434 rate_mask[1] = _rtl8723be_mrate_idx_to_arfr_id(hw, ratr_index) |
5c99f04f 2435 (shortgi ? 0x80 : 0x00);
a619d1ab 2436 rate_mask[2] = curtxbw_40mhz;
a619d1ab
LF
2437
2438 rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff);
2439 rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >> 8);
2440 rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16);
2441 rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24);
2442
2443 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2444 "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x:%x:%x\n",
2445 ratr_index, ratr_bitmap,
2446 rate_mask[0], rate_mask[1],
2447 rate_mask[2], rate_mask[3],
2448 rate_mask[4], rate_mask[5],
2449 rate_mask[6]);
5c99f04f 2450 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_RA_MASK, 7, rate_mask);
a619d1ab
LF
2451 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
2452}
2453
2454void rtl8723be_update_hal_rate_tbl(struct ieee80211_hw *hw,
2455 struct ieee80211_sta *sta,
2456 u8 rssi_level)
2457{
2458 struct rtl_priv *rtlpriv = rtl_priv(hw);
2459 if (rtlpriv->dm.useramask)
2460 rtl8723be_update_hal_rate_mask(hw, sta, rssi_level);
a619d1ab
LF
2461}
2462
2463void rtl8723be_update_channel_access_setting(struct ieee80211_hw *hw)
2464{
2465 struct rtl_priv *rtlpriv = rtl_priv(hw);
2466 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2467 u16 sifs_timer;
2468
9cb76aa9 2469 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);
a619d1ab
LF
2470 if (!mac->ht_enable)
2471 sifs_timer = 0x0a0a;
2472 else
2473 sifs_timer = 0x0e0e;
2474 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
2475}
2476
2477bool rtl8723be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
2478{
2479 struct rtl_priv *rtlpriv = rtl_priv(hw);
2480 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2481 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2482 enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate;
2483 u8 u1tmp;
5c99f04f 2484 bool b_actuallyset = false;
a619d1ab
LF
2485
2486 if (rtlpriv->rtlhal.being_init_adapter)
2487 return false;
2488
2489 if (ppsc->swrf_processing)
2490 return false;
2491
2492 spin_lock(&rtlpriv->locks.rf_ps_lock);
2493 if (ppsc->rfchange_inprogress) {
2494 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2495 return false;
2496 } else {
2497 ppsc->rfchange_inprogress = true;
2498 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2499 }
5c99f04f 2500
a619d1ab
LF
2501 cur_rfstate = ppsc->rfpwr_state;
2502
2503 rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2,
2504 rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2) & ~(BIT(1)));
2505
2506 u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2);
2507
2508 if (rtlphy->polarity_ctl)
2509 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON;
2510 else
2511 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF;
2512
5c99f04f 2513 if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) {
a619d1ab
LF
2514 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2515 "GPIOChangeRF - HW Radio ON, RF ON\n");
2516
2517 e_rfpowerstate_toset = ERFON;
2518 ppsc->hwradiooff = false;
5c99f04f
LF
2519 b_actuallyset = true;
2520 } else if (!ppsc->hwradiooff && (e_rfpowerstate_toset == ERFOFF)) {
a619d1ab
LF
2521 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2522 "GPIOChangeRF - HW Radio OFF, RF OFF\n");
2523
2524 e_rfpowerstate_toset = ERFOFF;
2525 ppsc->hwradiooff = true;
5c99f04f 2526 b_actuallyset = true;
a619d1ab 2527 }
5c99f04f
LF
2528
2529 if (b_actuallyset) {
a619d1ab
LF
2530 spin_lock(&rtlpriv->locks.rf_ps_lock);
2531 ppsc->rfchange_inprogress = false;
2532 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2533 } else {
2534 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
2535 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2536
2537 spin_lock(&rtlpriv->locks.rf_ps_lock);
2538 ppsc->rfchange_inprogress = false;
2539 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2540 }
5c99f04f 2541
a619d1ab
LF
2542 *valid = 1;
2543 return !ppsc->hwradiooff;
5c99f04f 2544
a619d1ab
LF
2545}
2546
2547void rtl8723be_set_key(struct ieee80211_hw *hw, u32 key_index,
2548 u8 *p_macaddr, bool is_group, u8 enc_algo,
2549 bool is_wepkey, bool clear_all)
2550{
2551 struct rtl_priv *rtlpriv = rtl_priv(hw);
2552 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2553 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2554 u8 *macaddr = p_macaddr;
2555 u32 entry_id = 0;
2556 bool is_pairwise = false;
2557
2558 static u8 cam_const_addr[4][6] = {
2559 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
2560 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
2561 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
2562 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
2563 };
2564 static u8 cam_const_broad[] = {
2565 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2566 };
2567
2568 if (clear_all) {
2569 u8 idx = 0;
2570 u8 cam_offset = 0;
2571 u8 clear_number = 5;
2572
2573 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
2574
2575 for (idx = 0; idx < clear_number; idx++) {
2576 rtl_cam_mark_invalid(hw, cam_offset + idx);
2577 rtl_cam_empty_entry(hw, cam_offset + idx);
2578
2579 if (idx < 5) {
2580 memset(rtlpriv->sec.key_buf[idx], 0,
2581 MAX_KEY_LEN);
2582 rtlpriv->sec.key_len[idx] = 0;
2583 }
2584 }
5c99f04f 2585
a619d1ab
LF
2586 } else {
2587 switch (enc_algo) {
2588 case WEP40_ENCRYPTION:
2589 enc_algo = CAM_WEP40;
2590 break;
2591 case WEP104_ENCRYPTION:
2592 enc_algo = CAM_WEP104;
2593 break;
2594 case TKIP_ENCRYPTION:
2595 enc_algo = CAM_TKIP;
2596 break;
2597 case AESCCMP_ENCRYPTION:
2598 enc_algo = CAM_AES;
2599 break;
2600 default:
5c99f04f 2601 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
ad574889 2602 "switch case %#x not processed\n", enc_algo);
a619d1ab
LF
2603 enc_algo = CAM_TKIP;
2604 break;
2605 }
2606
2607 if (is_wepkey || rtlpriv->sec.use_defaultkey) {
2608 macaddr = cam_const_addr[key_index];
2609 entry_id = key_index;
2610 } else {
2611 if (is_group) {
2612 macaddr = cam_const_broad;
2613 entry_id = key_index;
2614 } else {
2615 if (mac->opmode == NL80211_IFTYPE_AP) {
2616 entry_id = rtl_cam_get_free_entry(hw,
2617 p_macaddr);
2618 if (entry_id >= TOTAL_CAM_ENTRY) {
4e2b4378 2619 pr_err("Can not find free hw security cam entry\n");
a619d1ab
LF
2620 return;
2621 }
2622 } else {
2623 entry_id = CAM_PAIRWISE_KEY_POSITION;
2624 }
5c99f04f 2625
a619d1ab
LF
2626 key_index = PAIRWISE_KEYIDX;
2627 is_pairwise = true;
2628 }
2629 }
5c99f04f 2630
a619d1ab
LF
2631 if (rtlpriv->sec.key_len[key_index] == 0) {
2632 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2633 "delete one entry, entry_id is %d\n",
5c99f04f 2634 entry_id);
a619d1ab
LF
2635 if (mac->opmode == NL80211_IFTYPE_AP)
2636 rtl_cam_del_entry(hw, p_macaddr);
2637 rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
2638 } else {
2639 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2640 "add one entry\n");
2641 if (is_pairwise) {
2642 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
6b9e6f62 2643 "set Pairwise key\n");
a619d1ab
LF
2644
2645 rtl_cam_add_one_entry(hw, macaddr, key_index,
5c99f04f
LF
2646 entry_id, enc_algo,
2647 CAM_CONFIG_NO_USEDK,
2648 rtlpriv->sec.key_buf[key_index]);
a619d1ab
LF
2649 } else {
2650 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2651 "set group key\n");
2652
2653 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
2654 rtl_cam_add_one_entry(hw,
2655 rtlefuse->dev_addr,
2656 PAIRWISE_KEYIDX,
2657 CAM_PAIRWISE_KEY_POSITION,
2658 enc_algo,
2659 CAM_CONFIG_NO_USEDK,
2660 rtlpriv->sec.key_buf
2661 [entry_id]);
2662 }
5c99f04f 2663
a619d1ab 2664 rtl_cam_add_one_entry(hw, macaddr, key_index,
5c99f04f
LF
2665 entry_id, enc_algo,
2666 CAM_CONFIG_NO_USEDK,
2667 rtlpriv->sec.key_buf[entry_id]);
a619d1ab
LF
2668 }
2669 }
2670 }
2671}
2672
2673void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
2674 bool auto_load_fail, u8 *hwinfo)
2675{
2676 struct rtl_priv *rtlpriv = rtl_priv(hw);
c18d8f50 2677 struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params;
a619d1ab
LF
2678 u8 value;
2679 u32 tmpu_32;
2680
2681 if (!auto_load_fail) {
2682 tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL);
2683 if (tmpu_32 & BIT(18))
2684 rtlpriv->btcoexist.btc_info.btcoexist = 1;
2685 else
2686 rtlpriv->btcoexist.btc_info.btcoexist = 0;
5c99f04f 2687 value = hwinfo[EEPROM_RF_BT_SETTING_8723B];
a619d1ab
LF
2688 rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2689 rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1);
0de9b5db
PKS
2690 rtlpriv->btcoexist.btc_info.single_ant_path =
2691 (value & 0x40); /*0xc3[6]*/
a619d1ab
LF
2692 } else {
2693 rtlpriv->btcoexist.btc_info.btcoexist = 0;
2694 rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2695 rtlpriv->btcoexist.btc_info.ant_num = ANT_X2;
db8cb009 2696 rtlpriv->btcoexist.btc_info.single_ant_path = 0;
a619d1ab 2697 }
5c99f04f 2698
c18d8f50 2699 /* override ant_num / ant_path */
0ff78ade 2700 if (mod_params->ant_sel) {
c18d8f50
LF
2701 rtlpriv->btcoexist.btc_info.ant_num =
2702 (mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1);
0ff78ade
PKS
2703
2704 rtlpriv->btcoexist.btc_info.single_ant_path =
2705 (mod_params->ant_sel == 1 ? 0 : 1);
2706 }
a619d1ab
LF
2707}
2708
2709void rtl8723be_bt_reg_init(struct ieee80211_hw *hw)
2710{
2711 struct rtl_priv *rtlpriv = rtl_priv(hw);
2712
2713 /* 0:Low, 1:High, 2:From Efuse. */
2714 rtlpriv->btcoexist.reg_bt_iso = 2;
2715 /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */
2716 rtlpriv->btcoexist.reg_bt_sco = 3;
2717 /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
2718 rtlpriv->btcoexist.reg_bt_sco = 0;
2719}
2720
2721void rtl8723be_bt_hw_init(struct ieee80211_hw *hw)
2722{
2723 struct rtl_priv *rtlpriv = rtl_priv(hw);
2724
2725 if (rtlpriv->cfg->ops->get_btc_status())
2726 rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv);
5c99f04f 2727
a619d1ab
LF
2728}
2729
2730void rtl8723be_suspend(struct ieee80211_hw *hw)
2731{
2732}
2733
2734void rtl8723be_resume(struct ieee80211_hw *hw)
2735{
2736}