]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
rtlwifi: rtl8723be: btcoexist: Add single_ant_path
[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);
812 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
813 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
814 struct rtl_led *pled0 = &(pcipriv->ledctl.sw_led0);
815
816 if (rtlpriv->rtlhal.up_first_time)
817 return;
818
819 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
820 rtl8723be_sw_led_on(hw, pled0);
821 else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT)
822 rtl8723be_sw_led_on(hw, pled0);
823 else
824 rtl8723be_sw_led_off(hw, pled0);
825}
826
827static bool _rtl8723be_init_mac(struct ieee80211_hw *hw)
828{
829 struct rtl_priv *rtlpriv = rtl_priv(hw);
830 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
5c99f04f 831 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
a619d1ab
LF
832 unsigned char bytetmp;
833 unsigned short wordtmp;
a619d1ab
LF
834
835 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
836
837 /*Auto Power Down to CHIP-off State*/
838 bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) & (~BIT(7));
839 rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp);
840
a619d1ab 841 /* HW Power on sequence */
34ed780a
LF
842 if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK,
843 PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,
844 RTL8723_NIC_ENABLE_FLOW)) {
a619d1ab
LF
845 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
846 "init MAC Fail as power on failure\n");
847 return false;
848 }
5c99f04f
LF
849
850 bytetmp = rtl_read_byte(rtlpriv, REG_MULTI_FUNC_CTRL);
851 rtl_write_byte(rtlpriv, REG_MULTI_FUNC_CTRL, bytetmp | BIT(3));
852
a619d1ab
LF
853 bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO) | BIT(4);
854 rtl_write_byte(rtlpriv, REG_APS_FSMCO, bytetmp);
855
856 bytetmp = rtl_read_byte(rtlpriv, REG_CR);
857 bytetmp = 0xff;
858 rtl_write_byte(rtlpriv, REG_CR, bytetmp);
859 mdelay(2);
860
861 bytetmp = rtl_read_byte(rtlpriv, REG_HWSEQ_CTRL);
862 bytetmp |= 0x7f;
863 rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, bytetmp);
864 mdelay(2);
865
866 bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CFG + 3);
867 if (bytetmp & BIT(0)) {
868 bytetmp = rtl_read_byte(rtlpriv, 0x7c);
5c99f04f 869 rtl_write_byte(rtlpriv, 0x7c, bytetmp | BIT(6));
a619d1ab 870 }
5c99f04f 871
a619d1ab 872 bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CLKR);
5c99f04f 873 rtl_write_byte(rtlpriv, REG_SYS_CLKR, bytetmp | BIT(3));
a619d1ab 874 bytetmp = rtl_read_byte(rtlpriv, REG_GPIO_MUXCFG + 1);
5c99f04f 875 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG + 1, bytetmp & (~BIT(4)));
a619d1ab
LF
876
877 rtl_write_word(rtlpriv, REG_CR, 0x2ff);
878
5c99f04f
LF
879 if (!rtlhal->mac_func_enable) {
880 if (_rtl8723be_llt_table_init(hw) == false)
a619d1ab
LF
881 return false;
882 }
5c99f04f 883
a619d1ab
LF
884 rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
885 rtl_write_dword(rtlpriv, REG_HISRE, 0xffffffff);
886
887 /* Enable FW Beamformer Interrupt */
888 bytetmp = rtl_read_byte(rtlpriv, REG_FWIMR + 3);
889 rtl_write_byte(rtlpriv, REG_FWIMR + 3, bytetmp | BIT(6));
890
891 wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL);
892 wordtmp &= 0xf;
893 wordtmp |= 0xF5B1;
894 rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp);
895
896 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F);
897 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
898 rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xFFFF);
899 rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config);
900
a619d1ab
LF
901 rtl_write_dword(rtlpriv, REG_BCNQ_DESA,
902 ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) &
903 DMA_BIT_MASK(32));
904 rtl_write_dword(rtlpriv, REG_MGQ_DESA,
905 (u64) rtlpci->tx_ring[MGNT_QUEUE].dma &
906 DMA_BIT_MASK(32));
907 rtl_write_dword(rtlpriv, REG_VOQ_DESA,
908 (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32));
909 rtl_write_dword(rtlpriv, REG_VIQ_DESA,
910 (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32));
911 rtl_write_dword(rtlpriv, REG_BEQ_DESA,
912 (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32));
913 rtl_write_dword(rtlpriv, REG_BKQ_DESA,
914 (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32));
915 rtl_write_dword(rtlpriv, REG_HQ_DESA,
916 (u64) rtlpci->tx_ring[HIGH_QUEUE].dma &
917 DMA_BIT_MASK(32));
918 rtl_write_dword(rtlpriv, REG_RX_DESA,
919 (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma &
920 DMA_BIT_MASK(32));
921
922 bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 3);
923 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, bytetmp | 0x77);
924
925 rtl_write_dword(rtlpriv, REG_INT_MIG, 0);
926
5c99f04f 927 rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0);
a619d1ab
LF
928
929 rtl_write_byte(rtlpriv, REG_SECONDARY_CCA_CTRL, 0x3);
930
5c99f04f
LF
931 /* <20130114, Kordan> The following setting is
932 * only for DPDT and Fixed board type.
933 * TODO: A better solution is configure it
934 * according EFUSE during the run-time.
935 */
936 rtl_set_bbreg(hw, 0x64, BIT(20), 0x0);/* 0x66[4]=0 */
937 rtl_set_bbreg(hw, 0x64, BIT(24), 0x0);/* 0x66[8]=0 */
938 rtl_set_bbreg(hw, 0x40, BIT(4), 0x0)/* 0x40[4]=0 */;
939 rtl_set_bbreg(hw, 0x40, BIT(3), 0x1)/* 0x40[3]=1 */;
940 rtl_set_bbreg(hw, 0x4C, BIT(24) | BIT(23), 0x2)/* 0x4C[24:23]=10 */;
941 rtl_set_bbreg(hw, 0x944, BIT(1) | BIT(0), 0x3)/* 0x944[1:0]=11 */;
942 rtl_set_bbreg(hw, 0x930, MASKBYTE0, 0x77)/* 0x930[7:0]=77 */;
943 rtl_set_bbreg(hw, 0x38, BIT(11), 0x1)/* 0x38[11]=1 */;
a619d1ab
LF
944
945 bytetmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
5c99f04f 946 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, bytetmp & (~BIT(2)));
a619d1ab 947
5c99f04f 948 _rtl8723be_gen_refresh_led_state(hw);
a619d1ab
LF
949 return true;
950}
951
952static void _rtl8723be_hw_configure(struct ieee80211_hw *hw)
953{
954 struct rtl_priv *rtlpriv = rtl_priv(hw);
5c99f04f
LF
955 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
956 u32 reg_rrsr;
957
958 reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
959 /* Init value for RRSR. */
960 rtl_write_dword(rtlpriv, REG_RRSR, reg_rrsr);
961
962 /* ARFB table 9 for 11ac 5G 2SS */
963 rtl_write_dword(rtlpriv, REG_ARFR0 + 4, 0xfffff000);
964
965 /* ARFB table 10 for 11ac 5G 1SS */
966 rtl_write_dword(rtlpriv, REG_ARFR1 + 4, 0x003ff000);
967
968 /* CF-End setting. */
969 rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F00);
970
971 /* 0x456 = 0x70, sugguested by Zhilin */
972 rtl_write_byte(rtlpriv, REG_AMPDU_MAX_TIME, 0x70);
973
974 /* Set retry limit */
975 rtl_write_word(rtlpriv, REG_RL, 0x0707);
976
977 /* Set Data / Response auto rate fallack retry count */
978 rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000);
979 rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504);
980 rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000);
981 rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504);
982
983 rtlpci->reg_bcn_ctrl_val = 0x1d;
984 rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val);
985
986 /* TBTT prohibit hold time. Suggested by designer TimChen. */
987 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); /* 8 ms */
988
989 rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040);
990
991 /*For Rx TP. Suggested by SD1 Richard. Added by tynli. 2010.04.12.*/
992 rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666);
a619d1ab 993
5c99f04f 994 rtl_write_byte(rtlpriv, REG_HT_SINGLE_AMPDU, 0x80);
a619d1ab 995
5c99f04f
LF
996 rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x20);
997
998 rtl_write_byte(rtlpriv, REG_MAX_AGGR_NUM, 0x1F);
999}
1000
1001static u8 _rtl8723be_dbi_read(struct rtl_priv *rtlpriv, u16 addr)
1002{
1003 u16 read_addr = addr & 0xfffc;
1004 u8 ret = 0, tmp = 0, count = 0;
1005
1006 rtl_write_word(rtlpriv, REG_DBI_ADDR, read_addr);
1007 rtl_write_byte(rtlpriv, REG_DBI_FLAG, 0x2);
1008 tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1009 count = 0;
1010 while (tmp && count < 20) {
1011 udelay(10);
1012 tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1013 count++;
1014 }
1015 if (0 == tmp) {
1016 read_addr = REG_DBI_RDATA + addr % 4;
1017 ret = rtl_read_byte(rtlpriv, read_addr);
1018 }
1019
1020 return ret;
1021}
1022
1023static void _rtl8723be_dbi_write(struct rtl_priv *rtlpriv, u16 addr, u8 data)
1024{
1025 u8 tmp = 0, count = 0;
1026 u16 write_addr = 0, remainder = addr % 4;
1027
1028 /* Write DBI 1Byte Data */
1029 write_addr = REG_DBI_WDATA + remainder;
1030 rtl_write_byte(rtlpriv, write_addr, data);
1031
1032 /* Write DBI 2Byte Address & Write Enable */
1033 write_addr = (addr & 0xfffc) | (BIT(0) << (remainder + 12));
1034 rtl_write_word(rtlpriv, REG_DBI_ADDR, write_addr);
1035
1036 /* Write DBI Write Flag */
1037 rtl_write_byte(rtlpriv, REG_DBI_FLAG, 0x1);
1038
1039 tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1040 count = 0;
1041 while (tmp && count < 20) {
1042 udelay(10);
1043 tmp = rtl_read_byte(rtlpriv, REG_DBI_FLAG);
1044 count++;
1045 }
1046}
1047
1048static u16 _rtl8723be_mdio_read(struct rtl_priv *rtlpriv, u8 addr)
1049{
1050 u16 ret = 0;
1051 u8 tmp = 0, count = 0;
1052
1053 rtl_write_byte(rtlpriv, REG_MDIO_CTL, addr | BIT(6));
1054 tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(6);
1055 count = 0;
1056 while (tmp && count < 20) {
1057 udelay(10);
1058 tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(6);
1059 count++;
1060 }
1061
1062 if (0 == tmp)
1063 ret = rtl_read_word(rtlpriv, REG_MDIO_RDATA);
1064
1065 return ret;
1066}
1067
1068static void _rtl8723be_mdio_write(struct rtl_priv *rtlpriv, u8 addr, u16 data)
1069{
1070 u8 tmp = 0, count = 0;
1071
1072 rtl_write_word(rtlpriv, REG_MDIO_WDATA, data);
1073 rtl_write_byte(rtlpriv, REG_MDIO_CTL, addr | BIT(5));
1074 tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(5);
1075 count = 0;
1076 while (tmp && count < 20) {
1077 udelay(10);
1078 tmp = rtl_read_byte(rtlpriv, REG_MDIO_CTL) & BIT(5);
1079 count++;
1080 }
a619d1ab
LF
1081}
1082
1083static void _rtl8723be_enable_aspm_back_door(struct ieee80211_hw *hw)
1084{
1085 struct rtl_priv *rtlpriv = rtl_priv(hw);
5c99f04f
LF
1086 u8 tmp8 = 0;
1087 u16 tmp16 = 0;
a619d1ab 1088
5c99f04f
LF
1089 /* <Roger_Notes> Overwrite following ePHY parameter for
1090 * some platform compatibility issue,
1091 * especially when CLKReq is enabled, 2012.11.09.
1092 */
1093 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x01);
1094 if (tmp16 != 0x0663)
1095 _rtl8723be_mdio_write(rtlpriv, 0x01, 0x0663);
a619d1ab 1096
5c99f04f
LF
1097 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x04);
1098 if (tmp16 != 0x7544)
1099 _rtl8723be_mdio_write(rtlpriv, 0x04, 0x7544);
1100
1101 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x06);
1102 if (tmp16 != 0xB880)
1103 _rtl8723be_mdio_write(rtlpriv, 0x06, 0xB880);
1104
1105 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x07);
1106 if (tmp16 != 0x4000)
1107 _rtl8723be_mdio_write(rtlpriv, 0x07, 0x4000);
1108
1109 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x08);
1110 if (tmp16 != 0x9003)
1111 _rtl8723be_mdio_write(rtlpriv, 0x08, 0x9003);
1112
1113 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x09);
1114 if (tmp16 != 0x0D03)
1115 _rtl8723be_mdio_write(rtlpriv, 0x09, 0x0D03);
1116
1117 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x0A);
1118 if (tmp16 != 0x4037)
1119 _rtl8723be_mdio_write(rtlpriv, 0x0A, 0x4037);
a619d1ab 1120
5c99f04f
LF
1121 tmp16 = _rtl8723be_mdio_read(rtlpriv, 0x0B);
1122 if (tmp16 != 0x0070)
1123 _rtl8723be_mdio_write(rtlpriv, 0x0B, 0x0070);
1124
1125 /* Configuration Space offset 0x70f BIT7 is used to control L0S */
1126 tmp8 = _rtl8723be_dbi_read(rtlpriv, 0x70f);
1127 _rtl8723be_dbi_write(rtlpriv, 0x70f, tmp8 | BIT(7));
1128
1129 /* Configuration Space offset 0x719 Bit3 is for L1
1130 * BIT4 is for clock request
1131 */
1132 tmp8 = _rtl8723be_dbi_read(rtlpriv, 0x719);
1133 _rtl8723be_dbi_write(rtlpriv, 0x719, tmp8 | BIT(3) | BIT(4));
a619d1ab
LF
1134}
1135
1136void rtl8723be_enable_hw_security_config(struct ieee80211_hw *hw)
1137{
1138 struct rtl_priv *rtlpriv = rtl_priv(hw);
1139 u8 sec_reg_value;
1140
1141 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1142 "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
5c99f04f
LF
1143 rtlpriv->sec.pairwise_enc_algorithm,
1144 rtlpriv->sec.group_enc_algorithm);
a619d1ab
LF
1145
1146 if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
1147 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1148 "not open hw encryption\n");
1149 return;
1150 }
5c99f04f 1151
a619d1ab
LF
1152 sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE;
1153
1154 if (rtlpriv->sec.use_defaultkey) {
1155 sec_reg_value |= SCR_TXUSEDK;
1156 sec_reg_value |= SCR_RXUSEDK;
1157 }
5c99f04f 1158
a619d1ab
LF
1159 sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
1160
1161 rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
1162
5c99f04f
LF
1163 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
1164 "The SECR-value %x\n", sec_reg_value);
a619d1ab
LF
1165
1166 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
1167}
1168
5c99f04f
LF
1169static void _rtl8723be_poweroff_adapter(struct ieee80211_hw *hw)
1170{
1171 struct rtl_priv *rtlpriv = rtl_priv(hw);
1172 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1173 u8 u1b_tmp;
1174
1175 rtlhal->mac_func_enable = false;
1176 /* Combo (PCIe + USB) Card and PCIe-MF Card */
1177 /* 1. Run LPS WL RFOFF flow */
1178 rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1179 PWR_INTF_PCI_MSK, RTL8723_NIC_LPS_ENTER_FLOW);
1180
1181 /* 2. 0x1F[7:0] = 0 */
1182 /* turn off RF */
1183 /* rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); */
1184 if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) &&
1185 rtlhal->fw_ready) {
1186 rtl8723be_firmware_selfreset(hw);
1187 }
1188
1189 /* Reset MCU. Suggested by Filen. */
1190 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1191 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2))));
1192
1193 /* g. MCUFWDL 0x80[1:0]=0 */
1194 /* reset MCU ready status */
1195 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
1196
1197 /* HW card disable configuration. */
1198 rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1199 PWR_INTF_PCI_MSK, RTL8723_NIC_DISABLE_FLOW);
1200
1201 /* Reset MCU IO Wrapper */
1202 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1203 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0))));
1204 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1205 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1b_tmp | BIT(0));
1206
1207 /* 7. RSV_CTRL 0x1C[7:0] = 0x0E */
1208 /* lock ISO/CLK/Power control register */
1209 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e);
1210}
1211
1212static bool _rtl8723be_check_pcie_dma_hang(struct rtl_priv *rtlpriv)
1213{
1214 u8 tmp;
1215
1216 /* write reg 0x350 Bit[26]=1. Enable debug port. */
1217 tmp = rtl_read_byte(rtlpriv, REG_DBI_CTRL + 3);
1218 if (!(tmp & BIT(2))) {
1219 rtl_write_byte(rtlpriv, REG_DBI_CTRL + 3, (tmp | BIT(2)));
1220 mdelay(100); /* Suggested by DD Justin_tsai. */
1221 }
1222
1223 /* read reg 0x350 Bit[25] if 1 : RX hang
1224 * read reg 0x350 Bit[24] if 1 : TX hang
1225 */
1226 tmp = rtl_read_byte(rtlpriv, REG_DBI_CTRL + 3);
1227 if ((tmp & BIT(0)) || (tmp & BIT(1))) {
1228 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1229 "CheckPcieDMAHang8723BE(): true!!\n");
1230 return true;
1231 }
1232 return false;
1233}
1234
1235static void _rtl8723be_reset_pcie_interface_dma(struct rtl_priv *rtlpriv,
1236 bool mac_power_on)
1237{
1238 u8 tmp;
1239 bool release_mac_rx_pause;
1240 u8 backup_pcie_dma_pause;
1241
1242 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1243 "ResetPcieInterfaceDMA8723BE()\n");
1244
1245 /* Revise Note: Follow the document "PCIe RX DMA Hang Reset Flow_v03"
1246 * released by SD1 Alan.
1247 * 2013.05.07, by tynli.
1248 */
1249
1250 /* 1. disable register write lock
1251 * write 0x1C bit[1:0] = 2'h0
1252 * write 0xCC bit[2] = 1'b1
1253 */
1254 tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL);
1255 tmp &= ~(BIT(1) | BIT(0));
1256 rtl_write_byte(rtlpriv, REG_RSV_CTRL, tmp);
1257 tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2);
1258 tmp |= BIT(2);
1259 rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp);
1260
1261 /* 2. Check and pause TRX DMA
1262 * write 0x284 bit[18] = 1'b1
1263 * write 0x301 = 0xFF
1264 */
1265 tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1266 if (tmp & BIT(2)) {
1267 /* Already pause before the function for another purpose. */
1268 release_mac_rx_pause = false;
1269 } else {
1270 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, (tmp | BIT(2)));
1271 release_mac_rx_pause = true;
1272 }
1273
1274 backup_pcie_dma_pause = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 1);
1275 if (backup_pcie_dma_pause != 0xFF)
1276 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xFF);
1277
1278 if (mac_power_on) {
1279 /* 3. reset TRX function
1280 * write 0x100 = 0x00
1281 */
1282 rtl_write_byte(rtlpriv, REG_CR, 0);
1283 }
1284
1285 /* 4. Reset PCIe DMA
1286 * write 0x003 bit[0] = 0
1287 */
1288 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1289 tmp &= ~(BIT(0));
1290 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp);
1291
1292 /* 5. Enable PCIe DMA
1293 * write 0x003 bit[0] = 1
1294 */
1295 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1296 tmp |= BIT(0);
1297 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp);
1298
1299 if (mac_power_on) {
1300 /* 6. enable TRX function
1301 * write 0x100 = 0xFF
1302 */
1303 rtl_write_byte(rtlpriv, REG_CR, 0xFF);
1304
1305 /* We should init LLT & RQPN and
1306 * prepare Tx/Rx descrptor address later
1307 * because MAC function is reset.
1308 */
1309 }
1310
1311 /* 7. Restore PCIe autoload down bit
1312 * write 0xF8 bit[17] = 1'b1
1313 */
1314 tmp = rtl_read_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2);
1315 tmp |= BIT(1);
1316 rtl_write_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2, tmp);
1317
1318 /* In MAC power on state, BB and RF maybe in ON state,
1319 * if we release TRx DMA here
1320 * it will cause packets to be started to Tx/Rx,
1321 * so we release Tx/Rx DMA later.
1322 */
1323 if (!mac_power_on) {
1324 /* 8. release TRX DMA
1325 * write 0x284 bit[18] = 1'b0
1326 * write 0x301 = 0x00
1327 */
1328 if (release_mac_rx_pause) {
1329 tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1330 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL,
1331 (tmp & (~BIT(2))));
1332 }
1333 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1,
1334 backup_pcie_dma_pause);
1335 }
1336
1337 /* 9. lock system register
1338 * write 0xCC bit[2] = 1'b0
1339 */
1340 tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2);
1341 tmp &= ~(BIT(2));
1342 rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp);
1343}
1344
a619d1ab
LF
1345int rtl8723be_hw_init(struct ieee80211_hw *hw)
1346{
1347 struct rtl_priv *rtlpriv = rtl_priv(hw);
1348 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1349 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1350 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1351 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1352 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1353 bool rtstatus = true;
1354 int err;
1355 u8 tmp_u1b;
1356 unsigned long flags;
1357
1358 /* reenable interrupts to not interfere with other devices */
1359 local_save_flags(flags);
1360 local_irq_enable();
1361
5c99f04f 1362 rtlhal->fw_ready = false;
a619d1ab
LF
1363 rtlpriv->rtlhal.being_init_adapter = true;
1364 rtlpriv->intf_ops->disable_aspm(hw);
5c99f04f
LF
1365
1366 tmp_u1b = rtl_read_byte(rtlpriv, REG_CR);
1367 if (tmp_u1b != 0 && tmp_u1b != 0xea) {
1368 rtlhal->mac_func_enable = true;
1369 } else {
1370 rtlhal->mac_func_enable = false;
1371 rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON;
1372 }
1373
1374 if (_rtl8723be_check_pcie_dma_hang(rtlpriv)) {
1375 _rtl8723be_reset_pcie_interface_dma(rtlpriv,
1376 rtlhal->mac_func_enable);
1377 rtlhal->mac_func_enable = false;
1378 }
1379 if (rtlhal->mac_func_enable) {
1380 _rtl8723be_poweroff_adapter(hw);
1381 rtlhal->mac_func_enable = false;
1382 }
a619d1ab
LF
1383 rtstatus = _rtl8723be_init_mac(hw);
1384 if (!rtstatus) {
4e2b4378 1385 pr_err("Init MAC failed\n");
a619d1ab
LF
1386 err = 1;
1387 goto exit;
1388 }
5c99f04f 1389
a619d1ab 1390 tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CFG);
5c99f04f 1391 rtl_write_byte(rtlpriv, REG_SYS_CFG, tmp_u1b & 0x7F);
a619d1ab 1392
5c99f04f 1393 err = rtl8723_download_fw(hw, true, FW_8723B_POLLING_TIMEOUT_COUNT);
a619d1ab
LF
1394 if (err) {
1395 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1396 "Failed to download FW. Init HW without FW now..\n");
1397 err = 1;
a619d1ab 1398 goto exit;
a619d1ab 1399 }
5c99f04f
LF
1400 rtlhal->fw_ready = true;
1401
a619d1ab
LF
1402 rtlhal->last_hmeboxnum = 0;
1403 rtl8723be_phy_mac_config(hw);
1404 /* because last function modify RCR, so we update
1405 * rcr var here, or TP will unstable for receive_config
5c99f04f 1406 * is wrong, RX RCR_ACRC32 will cause TP unstable & Rx
a619d1ab
LF
1407 * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252
1408 */
1409 rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR);
1410 rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
1411 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
1412
1413 rtl8723be_phy_bb_config(hw);
a619d1ab
LF
1414 rtl8723be_phy_rf_config(hw);
1415
1416 rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
1417 RF_CHNLBW, RFREG_OFFSET_MASK);
1418 rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1,
1419 RF_CHNLBW, RFREG_OFFSET_MASK);
1420 rtlphy->rfreg_chnlval[0] &= 0xFFF03FF;
1421 rtlphy->rfreg_chnlval[0] |= (BIT(10) | BIT(11));
1422
a619d1ab 1423 _rtl8723be_hw_configure(hw);
5c99f04f 1424 rtlhal->mac_func_enable = true;
a619d1ab
LF
1425 rtl_cam_reset_all_entry(hw);
1426 rtl8723be_enable_hw_security_config(hw);
1427
1428 ppsc->rfpwr_state = ERFON;
1429
1430 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
1431 _rtl8723be_enable_aspm_back_door(hw);
1432 rtlpriv->intf_ops->enable_aspm(hw);
1433
1434 rtl8723be_bt_hw_init(hw);
1435
a619d1ab 1436 if (ppsc->rfpwr_state == ERFON) {
5c99f04f
LF
1437 rtl8723be_phy_set_rfpath_switch(hw, 1);
1438 /* when use 1ant NIC, iqk will disturb BT music
1439 * root cause is not clear now, is something
1440 * related with 'mdelay' and Reg[0x948]
1441 */
1442 if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2 ||
1443 !rtlpriv->cfg->ops->get_btc_status()) {
1444 rtl8723be_phy_iq_calibrate(hw, false);
1445 rtlphy->iqk_initialized = true;
1446 }
a619d1ab
LF
1447 rtl8723be_dm_check_txpower_tracking(hw);
1448 rtl8723be_phy_lc_calibrate(hw);
1449 }
5c99f04f
LF
1450 rtl_write_byte(rtlpriv, REG_NAV_UPPER, ((30000 + 127) / 128));
1451
1452 /* Release Rx DMA. */
1453 tmp_u1b = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1454 if (tmp_u1b & BIT(2)) {
1455 /* Release Rx DMA if needed */
1456 tmp_u1b &= (~BIT(2));
1457 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, tmp_u1b);
a619d1ab 1458 }
5c99f04f
LF
1459 /* Release Tx/Rx PCIE DMA. */
1460 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0);
1461
a619d1ab
LF
1462 rtl8723be_dm_init(hw);
1463exit:
1464 local_irq_restore(flags);
1465 rtlpriv->rtlhal.being_init_adapter = false;
1466 return err;
1467}
1468
1469static enum version_8723e _rtl8723be_read_chip_version(struct ieee80211_hw *hw)
1470{
1471 struct rtl_priv *rtlpriv = rtl_priv(hw);
1472 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1473 enum version_8723e version = VERSION_UNKNOWN;
a619d1ab
LF
1474 u32 value32;
1475
a619d1ab
LF
1476 value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG1);
1477 if ((value32 & (CHIP_8723B)) != CHIP_8723B)
8a190237 1478 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "unknown chip version\n");
a619d1ab 1479 else
5c99f04f 1480 version = (enum version_8723e)CHIP_8723B;
a619d1ab 1481
5c99f04f
LF
1482 rtlphy->rf_type = RF_1T1R;
1483
1484 /* treat rtl8723be chip as MP version in default */
1485 version = (enum version_8723e)(version | NORMAL_CHIP);
1486
1487 value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
1488 /* cut version */
1489 version |= (enum version_8723e)(value32 & CHIP_VER_RTL_MASK);
1490 /* Manufacture */
1491 if (((value32 & EXT_VENDOR_ID) >> 18) == 0x01)
1492 version = (enum version_8723e)(version | CHIP_VENDOR_SMIC);
a619d1ab 1493
a619d1ab
LF
1494 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1495 "Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
5c99f04f 1496 "RF_2T2R" : "RF_1T1R");
a619d1ab
LF
1497
1498 return version;
1499}
1500
1501static int _rtl8723be_set_media_status(struct ieee80211_hw *hw,
1502 enum nl80211_iftype type)
1503{
1504 struct rtl_priv *rtlpriv = rtl_priv(hw);
1505 u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc;
1506 enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
5c99f04f 1507 u8 mode = MSR_NOLINK;
a619d1ab 1508
a619d1ab
LF
1509 switch (type) {
1510 case NL80211_IFTYPE_UNSPECIFIED:
5c99f04f 1511 mode = MSR_NOLINK;
a619d1ab
LF
1512 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1513 "Set Network type to NO LINK!\n");
1514 break;
1515 case NL80211_IFTYPE_ADHOC:
5c99f04f
LF
1516 case NL80211_IFTYPE_MESH_POINT:
1517 mode = MSR_ADHOC;
a619d1ab
LF
1518 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1519 "Set Network type to Ad Hoc!\n");
1520 break;
1521 case NL80211_IFTYPE_STATION:
5c99f04f 1522 mode = MSR_INFRA;
a619d1ab
LF
1523 ledaction = LED_CTL_LINK;
1524 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1525 "Set Network type to STA!\n");
1526 break;
1527 case NL80211_IFTYPE_AP:
5c99f04f
LF
1528 mode = MSR_AP;
1529 ledaction = LED_CTL_LINK;
a619d1ab
LF
1530 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1531 "Set Network type to AP!\n");
1532 break;
1533 default:
4e2b4378 1534 pr_err("Network type %d not support!\n", type);
a619d1ab
LF
1535 return 1;
1536 }
5c99f04f
LF
1537
1538 /* MSR_INFRA == Link in infrastructure network;
1539 * MSR_ADHOC == Link in ad hoc network;
1540 * Therefore, check link state is necessary.
1541 *
1542 * MSR_AP == AP mode; link state is not cared here.
1543 */
1544 if (mode != MSR_AP && rtlpriv->mac80211.link_state < MAC80211_LINKED) {
1545 mode = MSR_NOLINK;
1546 ledaction = LED_CTL_NO_LINK;
1547 }
1548
1549 if (mode == MSR_NOLINK || mode == MSR_INFRA) {
1550 _rtl8723be_stop_tx_beacon(hw);
1551 _rtl8723be_enable_bcn_sub_func(hw);
1552 } else if (mode == MSR_ADHOC || mode == MSR_AP) {
1553 _rtl8723be_resume_tx_beacon(hw);
1554 _rtl8723be_disable_bcn_sub_func(hw);
1555 } else {
1556 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1557 "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n",
1558 mode);
1559 }
1560
e480e134 1561 rtl_write_byte(rtlpriv, MSR, bt_msr | mode);
a619d1ab 1562 rtlpriv->cfg->ops->led_control(hw, ledaction);
5c99f04f 1563 if (mode == MSR_AP)
a619d1ab
LF
1564 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1565 else
1566 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
1567 return 0;
1568}
1569
1570void rtl8723be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1571{
1572 struct rtl_priv *rtlpriv = rtl_priv(hw);
1573 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1574 u32 reg_rcr = rtlpci->receive_config;
1575
1576 if (rtlpriv->psc.rfpwr_state != ERFON)
1577 return;
1578
1579 if (check_bssid) {
1580 reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1581 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1582 (u8 *)(&reg_rcr));
1583 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4));
1584 } else if (!check_bssid) {
1585 reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
1586 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0);
1587 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1588 (u8 *)(&reg_rcr));
1589 }
5c99f04f 1590
a619d1ab
LF
1591}
1592
1593int rtl8723be_set_network_type(struct ieee80211_hw *hw,
1594 enum nl80211_iftype type)
1595{
1596 struct rtl_priv *rtlpriv = rtl_priv(hw);
1597
1598 if (_rtl8723be_set_media_status(hw, type))
1599 return -EOPNOTSUPP;
1600
1601 if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
1602 if (type != NL80211_IFTYPE_AP)
1603 rtl8723be_set_check_bssid(hw, true);
1604 } else {
1605 rtl8723be_set_check_bssid(hw, false);
1606 }
5c99f04f 1607
a619d1ab
LF
1608 return 0;
1609}
1610
1611/* don't set REG_EDCA_BE_PARAM here
1612 * because mac80211 will send pkt when scan
1613 */
1614void rtl8723be_set_qos(struct ieee80211_hw *hw, int aci)
1615{
1616 struct rtl_priv *rtlpriv = rtl_priv(hw);
5c99f04f 1617
a619d1ab
LF
1618 rtl8723_dm_init_edca_turbo(hw);
1619 switch (aci) {
1620 case AC1_BK:
1621 rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f);
1622 break;
1623 case AC0_BE:
1624 break;
1625 case AC2_VI:
1626 rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322);
1627 break;
1628 case AC3_VO:
1629 rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
1630 break;
1631 default:
531940f9 1632 WARN_ONCE(true, "rtl8723be: invalid aci: %d !\n", aci);
a619d1ab
LF
1633 break;
1634 }
1635}
1636
1637void rtl8723be_enable_interrupt(struct ieee80211_hw *hw)
1638{
1639 struct rtl_priv *rtlpriv = rtl_priv(hw);
1640 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1641
1642 rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
1643 rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
1644 rtlpci->irq_enabled = true;
5c99f04f 1645
a619d1ab
LF
1646 /*enable system interrupt*/
1647 rtl_write_dword(rtlpriv, REG_HSIMR, rtlpci->sys_irq_mask & 0xFFFFFFFF);
1648}
1649
1650void rtl8723be_disable_interrupt(struct ieee80211_hw *hw)
1651{
1652 struct rtl_priv *rtlpriv = rtl_priv(hw);
1653 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1654
1655 rtl_write_dword(rtlpriv, REG_HIMR, IMR_DISABLED);
1656 rtl_write_dword(rtlpriv, REG_HIMRE, IMR_DISABLED);
1657 rtlpci->irq_enabled = false;
5c99f04f 1658 /*synchronize_irq(rtlpci->pdev->irq);*/
a619d1ab
LF
1659}
1660
1661void rtl8723be_card_disable(struct ieee80211_hw *hw)
1662{
1663 struct rtl_priv *rtlpriv = rtl_priv(hw);
1664 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1665 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1666 enum nl80211_iftype opmode;
1667
1668 mac->link_state = MAC80211_NOLINK;
1669 opmode = NL80211_IFTYPE_UNSPECIFIED;
1670 _rtl8723be_set_media_status(hw, opmode);
1671 if (rtlpriv->rtlhal.driver_is_goingto_unload ||
1672 ppsc->rfoff_reason > RF_CHANGE_BY_PS)
1673 rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
1674 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1675 _rtl8723be_poweroff_adapter(hw);
1676
1677 /* after power off we should do iqk again */
1678 rtlpriv->phy.iqk_initialized = false;
1679}
1680
1681void rtl8723be_interrupt_recognized(struct ieee80211_hw *hw,
1682 u32 *p_inta, u32 *p_intb)
1683{
1684 struct rtl_priv *rtlpriv = rtl_priv(hw);
1685 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1686
1687 *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0];
1688 rtl_write_dword(rtlpriv, ISR, *p_inta);
1689
1690 *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) &
1691 rtlpci->irq_mask[1];
1692 rtl_write_dword(rtlpriv, REG_HISRE, *p_intb);
1693}
1694
1695void rtl8723be_set_beacon_related_registers(struct ieee80211_hw *hw)
1696{
1697 struct rtl_priv *rtlpriv = rtl_priv(hw);
1698 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1699 u16 bcn_interval, atim_window;
1700
1701 bcn_interval = mac->beacon_interval;
1702 atim_window = 2; /*FIX MERGE */
1703 rtl8723be_disable_interrupt(hw);
1704 rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
1705 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1706 rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
1707 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18);
1708 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18);
1709 rtl_write_byte(rtlpriv, 0x606, 0x30);
1710 rtl8723be_enable_interrupt(hw);
1711}
1712
1713void rtl8723be_set_beacon_interval(struct ieee80211_hw *hw)
1714{
1715 struct rtl_priv *rtlpriv = rtl_priv(hw);
1716 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1717 u16 bcn_interval = mac->beacon_interval;
1718
1719 RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
1720 "beacon_interval:%d\n", bcn_interval);
1721 rtl8723be_disable_interrupt(hw);
1722 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1723 rtl8723be_enable_interrupt(hw);
1724}
1725
1726void rtl8723be_update_interrupt_mask(struct ieee80211_hw *hw,
1727 u32 add_msr, u32 rm_msr)
1728{
1729 struct rtl_priv *rtlpriv = rtl_priv(hw);
1730 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1731
1732 RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
1733 "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr);
1734
1735 if (add_msr)
1736 rtlpci->irq_mask[0] |= add_msr;
1737 if (rm_msr)
1738 rtlpci->irq_mask[0] &= (~rm_msr);
1739 rtl8723be_disable_interrupt(hw);
1740 rtl8723be_enable_interrupt(hw);
1741}
1742
1743static u8 _rtl8723be_get_chnl_group(u8 chnl)
1744{
1745 u8 group;
1746
1747 if (chnl < 3)
1748 group = 0;
1749 else if (chnl < 9)
1750 group = 1;
1751 else
1752 group = 2;
1753 return group;
1754}
1755
1756static void _rtl8723be_read_power_value_fromprom(struct ieee80211_hw *hw,
1757 struct txpower_info_2g *pw2g,
1758 struct txpower_info_5g *pw5g,
1759 bool autoload_fail, u8 *hwinfo)
1760{
1761 struct rtl_priv *rtlpriv = rtl_priv(hw);
1762 u32 path, addr = EEPROM_TX_PWR_INX, group, cnt = 0;
1763
1764 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
5c99f04f 1765 "hal_ReadPowerValueFromPROM8723BE(): PROMContent[0x%x]=0x%x\n",
a619d1ab 1766 (addr + 1), hwinfo[addr + 1]);
5c99f04f 1767 if (0xFF == hwinfo[addr + 1]) /*YJ,add,120316*/
a619d1ab
LF
1768 autoload_fail = true;
1769
1770 if (autoload_fail) {
1771 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1772 "auto load fail : Use Default value!\n");
1773 for (path = 0; path < MAX_RF_PATH; path++) {
1774 /* 2.4G default value */
5c99f04f 1775 for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) {
a619d1ab
LF
1776 pw2g->index_cck_base[path][group] = 0x2D;
1777 pw2g->index_bw40_base[path][group] = 0x2D;
1778 }
1779 for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1780 if (cnt == 0) {
1781 pw2g->bw20_diff[path][0] = 0x02;
1782 pw2g->ofdm_diff[path][0] = 0x04;
1783 } else {
1784 pw2g->bw20_diff[path][cnt] = 0xFE;
1785 pw2g->bw40_diff[path][cnt] = 0xFE;
1786 pw2g->cck_diff[path][cnt] = 0xFE;
1787 pw2g->ofdm_diff[path][cnt] = 0xFE;
1788 }
1789 }
1790 }
1791 return;
1792 }
5c99f04f 1793
a619d1ab
LF
1794 for (path = 0; path < MAX_RF_PATH; path++) {
1795 /*2.4G default value*/
1796 for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
1797 pw2g->index_cck_base[path][group] = hwinfo[addr++];
1798 if (pw2g->index_cck_base[path][group] == 0xFF)
1799 pw2g->index_cck_base[path][group] = 0x2D;
5c99f04f 1800
a619d1ab
LF
1801 }
1802 for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) {
1803 pw2g->index_bw40_base[path][group] = hwinfo[addr++];
1804 if (pw2g->index_bw40_base[path][group] == 0xFF)
1805 pw2g->index_bw40_base[path][group] = 0x2D;
1806 }
1807 for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1808 if (cnt == 0) {
1809 pw2g->bw40_diff[path][cnt] = 0;
1810 if (hwinfo[addr] == 0xFF) {
1811 pw2g->bw20_diff[path][cnt] = 0x02;
1812 } else {
1813 pw2g->bw20_diff[path][cnt] =
1814 (hwinfo[addr] & 0xf0) >> 4;
1815 /*bit sign number to 8 bit sign number*/
1816 if (pw2g->bw20_diff[path][cnt] & BIT(3))
5c99f04f
LF
1817 pw2g->bw20_diff[path][cnt] |=
1818 0xF0;
a619d1ab 1819 }
5c99f04f 1820
a619d1ab
LF
1821 if (hwinfo[addr] == 0xFF) {
1822 pw2g->ofdm_diff[path][cnt] = 0x04;
1823 } else {
1824 pw2g->ofdm_diff[path][cnt] =
1825 (hwinfo[addr] & 0x0f);
1826 /*bit sign number to 8 bit sign number*/
1827 if (pw2g->ofdm_diff[path][cnt] & BIT(3))
1828 pw2g->ofdm_diff[path][cnt] |=
1829 0xF0;
1830 }
1831 pw2g->cck_diff[path][cnt] = 0;
1832 addr++;
1833 } else {
1834 if (hwinfo[addr] == 0xFF) {
1835 pw2g->bw40_diff[path][cnt] = 0xFE;
1836 } else {
1837 pw2g->bw40_diff[path][cnt] =
1838 (hwinfo[addr] & 0xf0) >> 4;
1839 if (pw2g->bw40_diff[path][cnt] & BIT(3))
1840 pw2g->bw40_diff[path][cnt] |=
1841 0xF0;
1842 }
5c99f04f 1843
a619d1ab
LF
1844 if (hwinfo[addr] == 0xFF) {
1845 pw2g->bw20_diff[path][cnt] = 0xFE;
1846 } else {
1847 pw2g->bw20_diff[path][cnt] =
1848 (hwinfo[addr] & 0x0f);
1849 if (pw2g->bw20_diff[path][cnt] & BIT(3))
1850 pw2g->bw20_diff[path][cnt] |=
1851 0xF0;
1852 }
1853 addr++;
1854
1855 if (hwinfo[addr] == 0xFF) {
1856 pw2g->ofdm_diff[path][cnt] = 0xFE;
1857 } else {
1858 pw2g->ofdm_diff[path][cnt] =
1859 (hwinfo[addr] & 0xf0) >> 4;
1860 if (pw2g->ofdm_diff[path][cnt] & BIT(3))
1861 pw2g->ofdm_diff[path][cnt] |=
1862 0xF0;
1863 }
5c99f04f
LF
1864
1865 if (hwinfo[addr] == 0xFF)
a619d1ab 1866 pw2g->cck_diff[path][cnt] = 0xFE;
5c99f04f 1867 else {
a619d1ab
LF
1868 pw2g->cck_diff[path][cnt] =
1869 (hwinfo[addr] & 0x0f);
1870 if (pw2g->cck_diff[path][cnt] & BIT(3))
1871 pw2g->cck_diff[path][cnt] |=
1872 0xF0;
1873 }
1874 addr++;
1875 }
1876 }
5c99f04f 1877
a619d1ab
LF
1878 /*5G default value*/
1879 for (group = 0; group < MAX_CHNL_GROUP_5G; group++) {
1880 pw5g->index_bw40_base[path][group] = hwinfo[addr++];
1881 if (pw5g->index_bw40_base[path][group] == 0xFF)
1882 pw5g->index_bw40_base[path][group] = 0xFE;
1883 }
5c99f04f 1884
a619d1ab
LF
1885 for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1886 if (cnt == 0) {
1887 pw5g->bw40_diff[path][cnt] = 0;
1888
1889 if (hwinfo[addr] == 0xFF) {
1890 pw5g->bw20_diff[path][cnt] = 0;
1891 } else {
1892 pw5g->bw20_diff[path][0] =
1893 (hwinfo[addr] & 0xf0) >> 4;
1894 if (pw5g->bw20_diff[path][cnt] & BIT(3))
1895 pw5g->bw20_diff[path][cnt] |=
1896 0xF0;
1897 }
5c99f04f
LF
1898
1899 if (hwinfo[addr] == 0xFF)
a619d1ab 1900 pw5g->ofdm_diff[path][cnt] = 0x04;
5c99f04f 1901 else {
a619d1ab
LF
1902 pw5g->ofdm_diff[path][0] =
1903 (hwinfo[addr] & 0x0f);
1904 if (pw5g->ofdm_diff[path][cnt] & BIT(3))
1905 pw5g->ofdm_diff[path][cnt] |=
1906 0xF0;
1907 }
1908 addr++;
1909 } else {
1910 if (hwinfo[addr] == 0xFF) {
1911 pw5g->bw40_diff[path][cnt] = 0xFE;
1912 } else {
1913 pw5g->bw40_diff[path][cnt] =
1914 (hwinfo[addr] & 0xf0) >> 4;
1915 if (pw5g->bw40_diff[path][cnt] & BIT(3))
1916 pw5g->bw40_diff[path][cnt] |= 0xF0;
1917 }
5c99f04f 1918
a619d1ab
LF
1919 if (hwinfo[addr] == 0xFF) {
1920 pw5g->bw20_diff[path][cnt] = 0xFE;
1921 } else {
1922 pw5g->bw20_diff[path][cnt] =
1923 (hwinfo[addr] & 0x0f);
1924 if (pw5g->bw20_diff[path][cnt] & BIT(3))
1925 pw5g->bw20_diff[path][cnt] |= 0xF0;
1926 }
1927 addr++;
1928 }
1929 }
5c99f04f 1930
a619d1ab
LF
1931 if (hwinfo[addr] == 0xFF) {
1932 pw5g->ofdm_diff[path][1] = 0xFE;
1933 pw5g->ofdm_diff[path][2] = 0xFE;
1934 } else {
1935 pw5g->ofdm_diff[path][1] = (hwinfo[addr] & 0xf0) >> 4;
1936 pw5g->ofdm_diff[path][2] = (hwinfo[addr] & 0x0f);
1937 }
1938 addr++;
1939
1940 if (hwinfo[addr] == 0xFF)
1941 pw5g->ofdm_diff[path][3] = 0xFE;
1942 else
1943 pw5g->ofdm_diff[path][3] = (hwinfo[addr] & 0x0f);
1944 addr++;
1945
1946 for (cnt = 1; cnt < MAX_TX_COUNT; cnt++) {
1947 if (pw5g->ofdm_diff[path][cnt] == 0xFF)
1948 pw5g->ofdm_diff[path][cnt] = 0xFE;
1949 else if (pw5g->ofdm_diff[path][cnt] & BIT(3))
1950 pw5g->ofdm_diff[path][cnt] |= 0xF0;
1951 }
1952 }
1953}
1954
1955static void _rtl8723be_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1956 bool autoload_fail,
1957 u8 *hwinfo)
1958{
1959 struct rtl_priv *rtlpriv = rtl_priv(hw);
1960 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1961 struct txpower_info_2g pw2g;
1962 struct txpower_info_5g pw5g;
1963 u8 rf_path, index;
1964 u8 i;
1965
1966 _rtl8723be_read_power_value_fromprom(hw, &pw2g, &pw5g, autoload_fail,
1967 hwinfo);
1968
1969 for (rf_path = 0; rf_path < 2; rf_path++) {
1970 for (i = 0; i < 14; i++) {
1971 index = _rtl8723be_get_chnl_group(i+1);
1972
1973 rtlefuse->txpwrlevel_cck[rf_path][i] =
1974 pw2g.index_cck_base[rf_path][index];
1975 rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
1976 pw2g.index_bw40_base[rf_path][index];
1977 }
1978 for (i = 0; i < MAX_TX_COUNT; i++) {
1979 rtlefuse->txpwr_ht20diff[rf_path][i] =
1980 pw2g.bw20_diff[rf_path][i];
1981 rtlefuse->txpwr_ht40diff[rf_path][i] =
1982 pw2g.bw40_diff[rf_path][i];
1983 rtlefuse->txpwr_legacyhtdiff[rf_path][i] =
1984 pw2g.ofdm_diff[rf_path][i];
1985 }
5c99f04f 1986
a619d1ab 1987 for (i = 0; i < 14; i++) {
5c99f04f
LF
1988 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1989 "RF(%d)-Ch(%d) [CCK / HT40_1S ] = [0x%x / 0x%x ]\n",
1990 rf_path, i,
a619d1ab
LF
1991 rtlefuse->txpwrlevel_cck[rf_path][i],
1992 rtlefuse->txpwrlevel_ht40_1s[rf_path][i]);
1993 }
1994 }
5c99f04f 1995
a619d1ab
LF
1996 if (!autoload_fail)
1997 rtlefuse->eeprom_thermalmeter =
1998 hwinfo[EEPROM_THERMAL_METER_88E];
1999 else
2000 rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
2001
2002 if (rtlefuse->eeprom_thermalmeter == 0xff || autoload_fail) {
2003 rtlefuse->apk_thermalmeterignore = true;
2004 rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
2005 }
5c99f04f 2006
a619d1ab 2007 rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
5c99f04f 2008 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
a619d1ab
LF
2009 "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
2010
2011 if (!autoload_fail) {
2012 rtlefuse->eeprom_regulatory =
2013 hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0x07;/*bit0~2*/
2014 if (hwinfo[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
2015 rtlefuse->eeprom_regulatory = 0;
2016 } else {
2017 rtlefuse->eeprom_regulatory = 0;
2018 }
5c99f04f 2019 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
a619d1ab
LF
2020 "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
2021}
2022
2023static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw,
2024 bool pseudo_test)
2025{
2026 struct rtl_priv *rtlpriv = rtl_priv(hw);
2027 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2028 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
9e9c9c24
LF
2029 int params[] = {RTL8723BE_EEPROM_ID, EEPROM_VID, EEPROM_DID,
2030 EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR,
2031 EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID,
2032 COUNTRY_CODE_WORLD_WIDE_13};
2033 u8 *hwinfo;
2034 int i;
a619d1ab
LF
2035 bool is_toshiba_smid1 = false;
2036 bool is_toshiba_smid2 = false;
2037 bool is_samsung_smid = false;
2038 bool is_lenovo_smid = false;
2039 u16 toshiba_smid1[] = {
2040 0x6151, 0x6152, 0x6154, 0x6155, 0x6177, 0x6178, 0x6179, 0x6180,
2041 0x7151, 0x7152, 0x7154, 0x7155, 0x7177, 0x7178, 0x7179, 0x7180,
2042 0x8151, 0x8152, 0x8154, 0x8155, 0x8181, 0x8182, 0x8184, 0x8185,
2043 0x9151, 0x9152, 0x9154, 0x9155, 0x9181, 0x9182, 0x9184, 0x9185
2044 };
2045 u16 toshiba_smid2[] = {
2046 0x6181, 0x6184, 0x6185, 0x7181, 0x7182, 0x7184, 0x7185, 0x8181,
2047 0x8182, 0x8184, 0x8185, 0x9181, 0x9182, 0x9184, 0x9185
2048 };
2049 u16 samsung_smid[] = {
2050 0x6191, 0x6192, 0x6193, 0x7191, 0x7192, 0x7193, 0x8191, 0x8192,
2051 0x8193, 0x9191, 0x9192, 0x9193
2052 };
2053 u16 lenovo_smid[] = {
2054 0x8195, 0x9195, 0x7194, 0x8200, 0x8201, 0x8202, 0x9199, 0x9200
2055 };
2056
2057 if (pseudo_test) {
2058 /* needs to be added */
2059 return;
2060 }
5345ea6a 2061
9e9c9c24
LF
2062 hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL);
2063 if (!hwinfo)
a619d1ab
LF
2064 return;
2065
9e9c9c24
LF
2066 if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params))
2067 goto exit;
a619d1ab
LF
2068
2069 /*parse xtal*/
2070 rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_8723BE];
2071 if (rtlefuse->crystalcap == 0xFF)
2072 rtlefuse->crystalcap = 0x20;
2073
2074 _rtl8723be_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag,
2075 hwinfo);
2076
2077 rtl8723be_read_bt_coexist_info_from_hwpg(hw,
2078 rtlefuse->autoload_failflag,
2079 hwinfo);
2080
b23cd22d
SF
2081 /* set channel plan from efuse */
2082 rtlefuse->channel_plan = rtlefuse->eeprom_channelplan;
a619d1ab
LF
2083
2084 if (rtlhal->oem_id == RT_CID_DEFAULT) {
2085 /* Does this one have a Toshiba SMID from group 1? */
2086 for (i = 0; i < sizeof(toshiba_smid1) / sizeof(u16); i++) {
2087 if (rtlefuse->eeprom_smid == toshiba_smid1[i]) {
2088 is_toshiba_smid1 = true;
2089 break;
2090 }
2091 }
2092 /* Does this one have a Toshiba SMID from group 2? */
2093 for (i = 0; i < sizeof(toshiba_smid2) / sizeof(u16); i++) {
2094 if (rtlefuse->eeprom_smid == toshiba_smid2[i]) {
2095 is_toshiba_smid2 = true;
2096 break;
2097 }
2098 }
2099 /* Does this one have a Samsung SMID? */
2100 for (i = 0; i < sizeof(samsung_smid) / sizeof(u16); i++) {
2101 if (rtlefuse->eeprom_smid == samsung_smid[i]) {
2102 is_samsung_smid = true;
2103 break;
2104 }
2105 }
2106 /* Does this one have a Lenovo SMID? */
2107 for (i = 0; i < sizeof(lenovo_smid) / sizeof(u16); i++) {
2108 if (rtlefuse->eeprom_smid == lenovo_smid[i]) {
2109 is_lenovo_smid = true;
2110 break;
2111 }
2112 }
2113 switch (rtlefuse->eeprom_oemid) {
2114 case EEPROM_CID_DEFAULT:
2115 if (rtlefuse->eeprom_did == 0x8176) {
2116 if (rtlefuse->eeprom_svid == 0x10EC &&
2117 is_toshiba_smid1) {
2118 rtlhal->oem_id = RT_CID_TOSHIBA;
2119 } else if (rtlefuse->eeprom_svid == 0x1025) {
2120 rtlhal->oem_id = RT_CID_819X_ACER;
2121 } else if (rtlefuse->eeprom_svid == 0x10EC &&
2122 is_samsung_smid) {
2123 rtlhal->oem_id = RT_CID_819X_SAMSUNG;
2124 } else if (rtlefuse->eeprom_svid == 0x10EC &&
2125 is_lenovo_smid) {
2126 rtlhal->oem_id = RT_CID_819X_LENOVO;
2127 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
2128 rtlefuse->eeprom_smid == 0x8197) ||
2129 (rtlefuse->eeprom_svid == 0x10EC &&
2130 rtlefuse->eeprom_smid == 0x9196)) {
2131 rtlhal->oem_id = RT_CID_819X_CLEVO;
2132 } else if ((rtlefuse->eeprom_svid == 0x1028 &&
2133 rtlefuse->eeprom_smid == 0x8194) ||
2134 (rtlefuse->eeprom_svid == 0x1028 &&
2135 rtlefuse->eeprom_smid == 0x8198) ||
2136 (rtlefuse->eeprom_svid == 0x1028 &&
2137 rtlefuse->eeprom_smid == 0x9197) ||
2138 (rtlefuse->eeprom_svid == 0x1028 &&
2139 rtlefuse->eeprom_smid == 0x9198)) {
2140 rtlhal->oem_id = RT_CID_819X_DELL;
2141 } else if ((rtlefuse->eeprom_svid == 0x103C &&
2142 rtlefuse->eeprom_smid == 0x1629)) {
2143 rtlhal->oem_id = RT_CID_819X_HP;
2144 } else if ((rtlefuse->eeprom_svid == 0x1A32 &&
2145 rtlefuse->eeprom_smid == 0x2315)) {
2146 rtlhal->oem_id = RT_CID_819X_QMI;
2147 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
2148 rtlefuse->eeprom_smid == 0x8203)) {
2149 rtlhal->oem_id = RT_CID_819X_PRONETS;
2150 } else if ((rtlefuse->eeprom_svid == 0x1043 &&
2151 rtlefuse->eeprom_smid == 0x84B5)) {
2152 rtlhal->oem_id = RT_CID_819X_EDIMAX_ASUS;
2153 } else {
2154 rtlhal->oem_id = RT_CID_DEFAULT;
2155 }
2156 } else if (rtlefuse->eeprom_did == 0x8178) {
2157 if (rtlefuse->eeprom_svid == 0x10EC &&
2158 is_toshiba_smid2)
2159 rtlhal->oem_id = RT_CID_TOSHIBA;
2160 else if (rtlefuse->eeprom_svid == 0x1025)
2161 rtlhal->oem_id = RT_CID_819X_ACER;
2162 else if ((rtlefuse->eeprom_svid == 0x10EC &&
2163 rtlefuse->eeprom_smid == 0x8186))
2164 rtlhal->oem_id = RT_CID_819X_PRONETS;
2165 else if ((rtlefuse->eeprom_svid == 0x1043 &&
2166 rtlefuse->eeprom_smid == 0x84B6))
2167 rtlhal->oem_id =
2168 RT_CID_819X_EDIMAX_ASUS;
2169 else
2170 rtlhal->oem_id = RT_CID_DEFAULT;
2171 } else {
2172 rtlhal->oem_id = RT_CID_DEFAULT;
2173 }
2174 break;
2175 case EEPROM_CID_TOSHIBA:
2176 rtlhal->oem_id = RT_CID_TOSHIBA;
2177 break;
2178 case EEPROM_CID_CCX:
2179 rtlhal->oem_id = RT_CID_CCX;
2180 break;
2181 case EEPROM_CID_QMI:
2182 rtlhal->oem_id = RT_CID_819X_QMI;
2183 break;
2184 case EEPROM_CID_WHQL:
2185 break;
2186 default:
2187 rtlhal->oem_id = RT_CID_DEFAULT;
2188 break;
2189 }
2190 }
9e9c9c24
LF
2191exit:
2192 kfree(hwinfo);
a619d1ab
LF
2193}
2194
2195static void _rtl8723be_hal_customized_behavior(struct ieee80211_hw *hw)
2196{
2197 struct rtl_priv *rtlpriv = rtl_priv(hw);
2198 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2199 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2200
2201 pcipriv->ledctl.led_opendrain = true;
2202 switch (rtlhal->oem_id) {
2203 case RT_CID_819X_HP:
2204 pcipriv->ledctl.led_opendrain = true;
2205 break;
2206 case RT_CID_819X_LENOVO:
2207 case RT_CID_DEFAULT:
2208 case RT_CID_TOSHIBA:
2209 case RT_CID_CCX:
2210 case RT_CID_819X_ACER:
2211 case RT_CID_WHQL:
2212 default:
2213 break;
2214 }
2215 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2216 "RT Customized ID: 0x%02X\n", rtlhal->oem_id);
2217}
2218
2219void rtl8723be_read_eeprom_info(struct ieee80211_hw *hw)
2220{
2221 struct rtl_priv *rtlpriv = rtl_priv(hw);
2222 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2223 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2224 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2225 u8 tmp_u1b;
2226
2227 rtlhal->version = _rtl8723be_read_chip_version(hw);
2228 if (get_rf_type(rtlphy) == RF_1T1R)
2229 rtlpriv->dm.rfpath_rxenable[0] = true;
2230 else
2231 rtlpriv->dm.rfpath_rxenable[0] =
2232 rtlpriv->dm.rfpath_rxenable[1] = true;
2233 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
2234 rtlhal->version);
2235 tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
2236 if (tmp_u1b & BIT(4)) {
2237 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
2238 rtlefuse->epromtype = EEPROM_93C46;
2239 } else {
2240 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
2241 rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
2242 }
2243 if (tmp_u1b & BIT(5)) {
2244 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
2245 rtlefuse->autoload_failflag = false;
2246 _rtl8723be_read_adapter_info(hw, false);
2247 } else {
4e2b4378 2248 pr_err("Autoload ERR!!\n");
a619d1ab
LF
2249 }
2250 _rtl8723be_hal_customized_behavior(hw);
2251}
2252
a619d1ab
LF
2253static u8 _rtl8723be_mrate_idx_to_arfr_id(struct ieee80211_hw *hw,
2254 u8 rate_index)
2255{
2256 u8 ret = 0;
a619d1ab
LF
2257 switch (rate_index) {
2258 case RATR_INX_WIRELESS_NGB:
2259 ret = 1;
2260 break;
2261 case RATR_INX_WIRELESS_N:
2262 case RATR_INX_WIRELESS_NG:
2263 ret = 5;
2264 break;
2265 case RATR_INX_WIRELESS_NB:
2266 ret = 3;
2267 break;
2268 case RATR_INX_WIRELESS_GB:
2269 ret = 6;
2270 break;
2271 case RATR_INX_WIRELESS_G:
2272 ret = 7;
2273 break;
2274 case RATR_INX_WIRELESS_B:
2275 ret = 8;
2276 break;
2277 default:
2278 ret = 0;
2279 break;
2280 }
2281 return ret;
2282}
2283
2284static void rtl8723be_update_hal_rate_mask(struct ieee80211_hw *hw,
2285 struct ieee80211_sta *sta,
2286 u8 rssi_level)
2287{
2288 struct rtl_priv *rtlpriv = rtl_priv(hw);
2289 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2290 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2291 struct rtl_sta_info *sta_entry = NULL;
2292 u32 ratr_bitmap;
2293 u8 ratr_index;
2294 u8 curtxbw_40mhz = (sta->ht_cap.cap &
5c99f04f 2295 IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0;
a619d1ab 2296 u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
5c99f04f 2297 1 : 0;
a619d1ab 2298 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
5c99f04f 2299 1 : 0;
a619d1ab
LF
2300 enum wireless_mode wirelessmode = 0;
2301 bool shortgi = false;
2302 u8 rate_mask[7];
2303 u8 macid = 0;
a619d1ab
LF
2304
2305 sta_entry = (struct rtl_sta_info *)sta->drv_priv;
2306 wirelessmode = sta_entry->wireless_mode;
2307 if (mac->opmode == NL80211_IFTYPE_STATION ||
2308 mac->opmode == NL80211_IFTYPE_MESH_POINT)
2309 curtxbw_40mhz = mac->bw_40;
2310 else if (mac->opmode == NL80211_IFTYPE_AP ||
2311 mac->opmode == NL80211_IFTYPE_ADHOC)
2312 macid = sta->aid + 1;
2313
2314 ratr_bitmap = sta->supp_rates[0];
2315
2316 if (mac->opmode == NL80211_IFTYPE_ADHOC)
2317 ratr_bitmap = 0xfff;
2318
2319 ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
2320 sta->ht_cap.mcs.rx_mask[0] << 12);
2321 switch (wirelessmode) {
2322 case WIRELESS_MODE_B:
2323 ratr_index = RATR_INX_WIRELESS_B;
2324 if (ratr_bitmap & 0x0000000c)
2325 ratr_bitmap &= 0x0000000d;
2326 else
2327 ratr_bitmap &= 0x0000000f;
2328 break;
2329 case WIRELESS_MODE_G:
2330 ratr_index = RATR_INX_WIRELESS_GB;
2331
2332 if (rssi_level == 1)
2333 ratr_bitmap &= 0x00000f00;
2334 else if (rssi_level == 2)
2335 ratr_bitmap &= 0x00000ff0;
2336 else
2337 ratr_bitmap &= 0x00000ff5;
2338 break;
a619d1ab
LF
2339 case WIRELESS_MODE_N_24G:
2340 case WIRELESS_MODE_N_5G:
2341 ratr_index = RATR_INX_WIRELESS_NGB;
5c99f04f
LF
2342 if (rtlphy->rf_type == RF_1T1R) {
2343 if (curtxbw_40mhz) {
2344 if (rssi_level == 1)
2345 ratr_bitmap &= 0x000f0000;
2346 else if (rssi_level == 2)
2347 ratr_bitmap &= 0x000ff000;
2348 else
2349 ratr_bitmap &= 0x000ff015;
2350 } else {
2351 if (rssi_level == 1)
2352 ratr_bitmap &= 0x000f0000;
2353 else if (rssi_level == 2)
2354 ratr_bitmap &= 0x000ff000;
2355 else
2356 ratr_bitmap &= 0x000ff005;
2357 }
a619d1ab 2358 } else {
5c99f04f
LF
2359 if (curtxbw_40mhz) {
2360 if (rssi_level == 1)
2361 ratr_bitmap &= 0x0f8f0000;
2362 else if (rssi_level == 2)
2363 ratr_bitmap &= 0x0f8ff000;
2364 else
2365 ratr_bitmap &= 0x0f8ff015;
a619d1ab 2366 } else {
5c99f04f
LF
2367 if (rssi_level == 1)
2368 ratr_bitmap &= 0x0f8f0000;
2369 else if (rssi_level == 2)
2370 ratr_bitmap &= 0x0f8ff000;
2371 else
2372 ratr_bitmap &= 0x0f8ff005;
a619d1ab
LF
2373 }
2374 }
2375 if ((curtxbw_40mhz && curshortgi_40mhz) ||
2376 (!curtxbw_40mhz && curshortgi_20mhz)) {
2377 if (macid == 0)
2378 shortgi = true;
2379 else if (macid == 1)
2380 shortgi = false;
2381 }
2382 break;
2383 default:
2384 ratr_index = RATR_INX_WIRELESS_NGB;
2385
2386 if (rtlphy->rf_type == RF_1T2R)
2387 ratr_bitmap &= 0x000ff0ff;
2388 else
2389 ratr_bitmap &= 0x0f0ff0ff;
2390 break;
2391 }
5c99f04f 2392
a619d1ab
LF
2393 sta_entry->ratr_index = ratr_index;
2394
2395 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2396 "ratr_bitmap :%x\n", ratr_bitmap);
5c99f04f
LF
2397 *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
2398 (ratr_index << 28);
a619d1ab
LF
2399 rate_mask[0] = macid;
2400 rate_mask[1] = _rtl8723be_mrate_idx_to_arfr_id(hw, ratr_index) |
5c99f04f 2401 (shortgi ? 0x80 : 0x00);
a619d1ab 2402 rate_mask[2] = curtxbw_40mhz;
a619d1ab
LF
2403
2404 rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff);
2405 rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >> 8);
2406 rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16);
2407 rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24);
2408
2409 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2410 "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x:%x:%x\n",
2411 ratr_index, ratr_bitmap,
2412 rate_mask[0], rate_mask[1],
2413 rate_mask[2], rate_mask[3],
2414 rate_mask[4], rate_mask[5],
2415 rate_mask[6]);
5c99f04f 2416 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_RA_MASK, 7, rate_mask);
a619d1ab
LF
2417 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
2418}
2419
2420void rtl8723be_update_hal_rate_tbl(struct ieee80211_hw *hw,
2421 struct ieee80211_sta *sta,
2422 u8 rssi_level)
2423{
2424 struct rtl_priv *rtlpriv = rtl_priv(hw);
2425 if (rtlpriv->dm.useramask)
2426 rtl8723be_update_hal_rate_mask(hw, sta, rssi_level);
a619d1ab
LF
2427}
2428
2429void rtl8723be_update_channel_access_setting(struct ieee80211_hw *hw)
2430{
2431 struct rtl_priv *rtlpriv = rtl_priv(hw);
2432 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2433 u16 sifs_timer;
2434
9cb76aa9 2435 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);
a619d1ab
LF
2436 if (!mac->ht_enable)
2437 sifs_timer = 0x0a0a;
2438 else
2439 sifs_timer = 0x0e0e;
2440 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
2441}
2442
2443bool rtl8723be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
2444{
2445 struct rtl_priv *rtlpriv = rtl_priv(hw);
2446 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2447 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2448 enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate;
2449 u8 u1tmp;
5c99f04f 2450 bool b_actuallyset = false;
a619d1ab
LF
2451
2452 if (rtlpriv->rtlhal.being_init_adapter)
2453 return false;
2454
2455 if (ppsc->swrf_processing)
2456 return false;
2457
2458 spin_lock(&rtlpriv->locks.rf_ps_lock);
2459 if (ppsc->rfchange_inprogress) {
2460 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2461 return false;
2462 } else {
2463 ppsc->rfchange_inprogress = true;
2464 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2465 }
5c99f04f 2466
a619d1ab
LF
2467 cur_rfstate = ppsc->rfpwr_state;
2468
2469 rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2,
2470 rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2) & ~(BIT(1)));
2471
2472 u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2);
2473
2474 if (rtlphy->polarity_ctl)
2475 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON;
2476 else
2477 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF;
2478
5c99f04f 2479 if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) {
a619d1ab
LF
2480 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2481 "GPIOChangeRF - HW Radio ON, RF ON\n");
2482
2483 e_rfpowerstate_toset = ERFON;
2484 ppsc->hwradiooff = false;
5c99f04f
LF
2485 b_actuallyset = true;
2486 } else if (!ppsc->hwradiooff && (e_rfpowerstate_toset == ERFOFF)) {
a619d1ab
LF
2487 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2488 "GPIOChangeRF - HW Radio OFF, RF OFF\n");
2489
2490 e_rfpowerstate_toset = ERFOFF;
2491 ppsc->hwradiooff = true;
5c99f04f 2492 b_actuallyset = true;
a619d1ab 2493 }
5c99f04f
LF
2494
2495 if (b_actuallyset) {
a619d1ab
LF
2496 spin_lock(&rtlpriv->locks.rf_ps_lock);
2497 ppsc->rfchange_inprogress = false;
2498 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2499 } else {
2500 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
2501 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2502
2503 spin_lock(&rtlpriv->locks.rf_ps_lock);
2504 ppsc->rfchange_inprogress = false;
2505 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2506 }
5c99f04f 2507
a619d1ab
LF
2508 *valid = 1;
2509 return !ppsc->hwradiooff;
5c99f04f 2510
a619d1ab
LF
2511}
2512
2513void rtl8723be_set_key(struct ieee80211_hw *hw, u32 key_index,
2514 u8 *p_macaddr, bool is_group, u8 enc_algo,
2515 bool is_wepkey, bool clear_all)
2516{
2517 struct rtl_priv *rtlpriv = rtl_priv(hw);
2518 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2519 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2520 u8 *macaddr = p_macaddr;
2521 u32 entry_id = 0;
2522 bool is_pairwise = false;
2523
2524 static u8 cam_const_addr[4][6] = {
2525 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
2526 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
2527 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
2528 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
2529 };
2530 static u8 cam_const_broad[] = {
2531 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2532 };
2533
2534 if (clear_all) {
2535 u8 idx = 0;
2536 u8 cam_offset = 0;
2537 u8 clear_number = 5;
2538
2539 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
2540
2541 for (idx = 0; idx < clear_number; idx++) {
2542 rtl_cam_mark_invalid(hw, cam_offset + idx);
2543 rtl_cam_empty_entry(hw, cam_offset + idx);
2544
2545 if (idx < 5) {
2546 memset(rtlpriv->sec.key_buf[idx], 0,
2547 MAX_KEY_LEN);
2548 rtlpriv->sec.key_len[idx] = 0;
2549 }
2550 }
5c99f04f 2551
a619d1ab
LF
2552 } else {
2553 switch (enc_algo) {
2554 case WEP40_ENCRYPTION:
2555 enc_algo = CAM_WEP40;
2556 break;
2557 case WEP104_ENCRYPTION:
2558 enc_algo = CAM_WEP104;
2559 break;
2560 case TKIP_ENCRYPTION:
2561 enc_algo = CAM_TKIP;
2562 break;
2563 case AESCCMP_ENCRYPTION:
2564 enc_algo = CAM_AES;
2565 break;
2566 default:
5c99f04f 2567 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
ad574889 2568 "switch case %#x not processed\n", enc_algo);
a619d1ab
LF
2569 enc_algo = CAM_TKIP;
2570 break;
2571 }
2572
2573 if (is_wepkey || rtlpriv->sec.use_defaultkey) {
2574 macaddr = cam_const_addr[key_index];
2575 entry_id = key_index;
2576 } else {
2577 if (is_group) {
2578 macaddr = cam_const_broad;
2579 entry_id = key_index;
2580 } else {
2581 if (mac->opmode == NL80211_IFTYPE_AP) {
2582 entry_id = rtl_cam_get_free_entry(hw,
2583 p_macaddr);
2584 if (entry_id >= TOTAL_CAM_ENTRY) {
4e2b4378 2585 pr_err("Can not find free hw security cam entry\n");
a619d1ab
LF
2586 return;
2587 }
2588 } else {
2589 entry_id = CAM_PAIRWISE_KEY_POSITION;
2590 }
5c99f04f 2591
a619d1ab
LF
2592 key_index = PAIRWISE_KEYIDX;
2593 is_pairwise = true;
2594 }
2595 }
5c99f04f 2596
a619d1ab
LF
2597 if (rtlpriv->sec.key_len[key_index] == 0) {
2598 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2599 "delete one entry, entry_id is %d\n",
5c99f04f 2600 entry_id);
a619d1ab
LF
2601 if (mac->opmode == NL80211_IFTYPE_AP)
2602 rtl_cam_del_entry(hw, p_macaddr);
2603 rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
2604 } else {
2605 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2606 "add one entry\n");
2607 if (is_pairwise) {
2608 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
5c99f04f 2609 "set Pairwiase key\n");
a619d1ab
LF
2610
2611 rtl_cam_add_one_entry(hw, macaddr, key_index,
5c99f04f
LF
2612 entry_id, enc_algo,
2613 CAM_CONFIG_NO_USEDK,
2614 rtlpriv->sec.key_buf[key_index]);
a619d1ab
LF
2615 } else {
2616 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2617 "set group key\n");
2618
2619 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
2620 rtl_cam_add_one_entry(hw,
2621 rtlefuse->dev_addr,
2622 PAIRWISE_KEYIDX,
2623 CAM_PAIRWISE_KEY_POSITION,
2624 enc_algo,
2625 CAM_CONFIG_NO_USEDK,
2626 rtlpriv->sec.key_buf
2627 [entry_id]);
2628 }
5c99f04f 2629
a619d1ab 2630 rtl_cam_add_one_entry(hw, macaddr, key_index,
5c99f04f
LF
2631 entry_id, enc_algo,
2632 CAM_CONFIG_NO_USEDK,
2633 rtlpriv->sec.key_buf[entry_id]);
a619d1ab
LF
2634 }
2635 }
2636 }
2637}
2638
2639void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
2640 bool auto_load_fail, u8 *hwinfo)
2641{
2642 struct rtl_priv *rtlpriv = rtl_priv(hw);
c18d8f50 2643 struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params;
a619d1ab
LF
2644 u8 value;
2645 u32 tmpu_32;
2646
2647 if (!auto_load_fail) {
2648 tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL);
2649 if (tmpu_32 & BIT(18))
2650 rtlpriv->btcoexist.btc_info.btcoexist = 1;
2651 else
2652 rtlpriv->btcoexist.btc_info.btcoexist = 0;
5c99f04f 2653 value = hwinfo[EEPROM_RF_BT_SETTING_8723B];
a619d1ab
LF
2654 rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2655 rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1);
2656 } else {
2657 rtlpriv->btcoexist.btc_info.btcoexist = 0;
2658 rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2659 rtlpriv->btcoexist.btc_info.ant_num = ANT_X2;
db8cb009 2660 rtlpriv->btcoexist.btc_info.single_ant_path = 0;
a619d1ab 2661 }
5c99f04f 2662
c18d8f50
LF
2663 /* override ant_num / ant_path */
2664 if (mod_params->ant_sel)
2665 rtlpriv->btcoexist.btc_info.ant_num =
2666 (mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1);
a619d1ab
LF
2667}
2668
2669void rtl8723be_bt_reg_init(struct ieee80211_hw *hw)
2670{
2671 struct rtl_priv *rtlpriv = rtl_priv(hw);
2672
2673 /* 0:Low, 1:High, 2:From Efuse. */
2674 rtlpriv->btcoexist.reg_bt_iso = 2;
2675 /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */
2676 rtlpriv->btcoexist.reg_bt_sco = 3;
2677 /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
2678 rtlpriv->btcoexist.reg_bt_sco = 0;
2679}
2680
2681void rtl8723be_bt_hw_init(struct ieee80211_hw *hw)
2682{
2683 struct rtl_priv *rtlpriv = rtl_priv(hw);
2684
2685 if (rtlpriv->cfg->ops->get_btc_status())
2686 rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv);
5c99f04f 2687
a619d1ab
LF
2688}
2689
2690void rtl8723be_suspend(struct ieee80211_hw *hw)
2691{
2692}
2693
2694void rtl8723be_resume(struct ieee80211_hw *hw)
2695{
2696}