Merge tag 'powerpc-4.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[deliverable/linux.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;
a619d1ab 351 default:
5c99f04f 352 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
a619d1ab
LF
353 "switch case not process %x\n", variable);
354 break;
355 }
356}
357
5c99f04f
LF
358static void _rtl8723be_download_rsvd_page(struct ieee80211_hw *hw)
359{
360 struct rtl_priv *rtlpriv = rtl_priv(hw);
361 u8 tmp_regcr, tmp_reg422, bcnvalid_reg;
362 u8 count = 0, dlbcn_count = 0;
363 bool b_recover = false;
364
365 tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
366 rtl_write_byte(rtlpriv, REG_CR + 1,
367 (tmp_regcr | BIT(0)));
368
369 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3));
370 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0);
371
372 tmp_reg422 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
373 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422 & (~BIT(6)));
374 if (tmp_reg422 & BIT(6))
375 b_recover = true;
376
377 do {
378 bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL + 2);
379 rtl_write_byte(rtlpriv, REG_TDECTRL + 2,
380 (bcnvalid_reg | BIT(0)));
381 _rtl8723be_return_beacon_queue_skb(hw);
382
383 rtl8723be_set_fw_rsvdpagepkt(hw, 0);
384 bcnvalid_reg = rtl_read_byte(rtlpriv, REG_TDECTRL + 2);
385 count = 0;
386 while (!(bcnvalid_reg & BIT(0)) && count < 20) {
387 count++;
388 udelay(10);
389 bcnvalid_reg = rtl_read_byte(rtlpriv,
390 REG_TDECTRL + 2);
391 }
392 dlbcn_count++;
393 } while (!(bcnvalid_reg & BIT(0)) && dlbcn_count < 5);
394
395 if (bcnvalid_reg & BIT(0))
396 rtl_write_byte(rtlpriv, REG_TDECTRL + 2, BIT(0));
397
398 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
399 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4));
400
401 if (b_recover)
402 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422);
403
404 tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
405 rtl_write_byte(rtlpriv, REG_CR + 1, (tmp_regcr & ~(BIT(0))));
406}
407
a619d1ab
LF
408void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
409{
410 struct rtl_priv *rtlpriv = rtl_priv(hw);
411 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
412 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
413 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
414 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
415 u8 idx;
416
417 switch (variable) {
418 case HW_VAR_ETHER_ADDR:
419 for (idx = 0; idx < ETH_ALEN; idx++)
420 rtl_write_byte(rtlpriv, (REG_MACID + idx), val[idx]);
421 break;
5c99f04f
LF
422 case HW_VAR_BASIC_RATE:{
423 u16 b_rate_cfg = ((u16 *)val)[0];
a619d1ab 424 u8 rate_index = 0;
5c99f04f
LF
425 b_rate_cfg = b_rate_cfg & 0x15f;
426 b_rate_cfg |= 0x01;
427 rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff);
428 rtl_write_byte(rtlpriv, REG_RRSR + 1, (b_rate_cfg >> 8) & 0xff);
429 while (b_rate_cfg > 0x1) {
430 b_rate_cfg = (b_rate_cfg >> 1);
a619d1ab
LF
431 rate_index++;
432 }
433 rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, rate_index);
5c99f04f
LF
434 }
435 break;
a619d1ab
LF
436 case HW_VAR_BSSID:
437 for (idx = 0; idx < ETH_ALEN; idx++)
438 rtl_write_byte(rtlpriv, (REG_BSSID + idx), val[idx]);
5c99f04f 439
a619d1ab
LF
440 break;
441 case HW_VAR_SIFS:
442 rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]);
443 rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]);
444
445 rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]);
446 rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
447
448 if (!mac->ht_enable)
449 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, 0x0e0e);
450 else
451 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
452 *((u16 *)val));
453 break;
5c99f04f 454 case HW_VAR_SLOT_TIME:{
a619d1ab
LF
455 u8 e_aci;
456
457 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
458 "HW_VAR_SLOT_TIME %x\n", val[0]);
459
460 rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
461
462 for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
463 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
5c99f04f 464 (u8 *)(&e_aci));
a619d1ab 465 }
5c99f04f
LF
466 }
467 break;
468 case HW_VAR_ACK_PREAMBLE:{
a619d1ab 469 u8 reg_tmp;
5c99f04f 470 u8 short_preamble = (bool)(*(u8 *)val);
a619d1ab
LF
471 reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL + 2);
472 if (short_preamble) {
473 reg_tmp |= 0x02;
474 rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
475 } else {
476 reg_tmp &= 0xFD;
477 rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
478 }
5c99f04f
LF
479 }
480 break;
a619d1ab 481 case HW_VAR_WPA_CONFIG:
5c99f04f 482 rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val));
a619d1ab 483 break;
5c99f04f 484 case HW_VAR_AMPDU_MIN_SPACE:{
a619d1ab
LF
485 u8 min_spacing_to_set;
486 u8 sec_min_space;
487
5c99f04f 488 min_spacing_to_set = *((u8 *)val);
a619d1ab
LF
489 if (min_spacing_to_set <= 7) {
490 sec_min_space = 0;
491
492 if (min_spacing_to_set < sec_min_space)
493 min_spacing_to_set = sec_min_space;
494
495 mac->min_space_cfg = ((mac->min_space_cfg & 0xf8) |
496 min_spacing_to_set);
497
498 *val = min_spacing_to_set;
499
500 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
501 "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
5c99f04f 502 mac->min_space_cfg);
a619d1ab
LF
503
504 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
505 mac->min_space_cfg);
506 }
5c99f04f
LF
507 }
508 break;
509 case HW_VAR_SHORTGI_DENSITY:{
a619d1ab
LF
510 u8 density_to_set;
511
5c99f04f 512 density_to_set = *((u8 *)val);
a619d1ab
LF
513 mac->min_space_cfg |= (density_to_set << 3);
514
515 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
516 "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
5c99f04f 517 mac->min_space_cfg);
a619d1ab
LF
518
519 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
520 mac->min_space_cfg);
5c99f04f
LF
521 }
522 break;
523 case HW_VAR_AMPDU_FACTOR:{
a619d1ab
LF
524 u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9};
525 u8 factor_toset;
526 u8 *p_regtoset = NULL;
527 u8 index = 0;
528
529 p_regtoset = regtoset_normal;
530
5c99f04f 531 factor_toset = *((u8 *)val);
a619d1ab
LF
532 if (factor_toset <= 3) {
533 factor_toset = (1 << (factor_toset + 2));
534 if (factor_toset > 0xf)
535 factor_toset = 0xf;
536
537 for (index = 0; index < 4; index++) {
538 if ((p_regtoset[index] & 0xf0) >
539 (factor_toset << 4))
540 p_regtoset[index] =
541 (p_regtoset[index] & 0x0f) |
542 (factor_toset << 4);
543
544 if ((p_regtoset[index] & 0x0f) > factor_toset)
545 p_regtoset[index] =
546 (p_regtoset[index] & 0xf0) |
547 (factor_toset);
548
549 rtl_write_byte(rtlpriv,
550 (REG_AGGLEN_LMT + index),
551 p_regtoset[index]);
5c99f04f 552
a619d1ab 553 }
5c99f04f 554
a619d1ab
LF
555 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
556 "Set HW_VAR_AMPDU_FACTOR: %#x\n",
5c99f04f 557 factor_toset);
a619d1ab 558 }
5c99f04f
LF
559 }
560 break;
561 case HW_VAR_AC_PARAM:{
562 u8 e_aci = *((u8 *)val);
a619d1ab
LF
563 rtl8723_dm_init_edca_turbo(hw);
564
565 if (rtlpci->acm_method != EACMWAY2_SW)
566 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
5c99f04f
LF
567 (u8 *)(&e_aci));
568 }
569 break;
570 case HW_VAR_ACM_CTRL:{
571 u8 e_aci = *((u8 *)val);
a619d1ab
LF
572 union aci_aifsn *p_aci_aifsn =
573 (union aci_aifsn *)(&(mac->ac[0].aifs));
574 u8 acm = p_aci_aifsn->f.acm;
575 u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);
576
577 acm_ctrl =
578 acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1);
579
580 if (acm) {
581 switch (e_aci) {
582 case AC0_BE:
583 acm_ctrl |= ACMHW_BEQEN;
584 break;
585 case AC2_VI:
586 acm_ctrl |= ACMHW_VIQEN;
587 break;
588 case AC3_VO:
589 acm_ctrl |= ACMHW_VOQEN;
590 break;
591 default:
592 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
5c99f04f
LF
593 "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
594 acm);
a619d1ab
LF
595 break;
596 }
597 } else {
598 switch (e_aci) {
599 case AC0_BE:
600 acm_ctrl &= (~ACMHW_BEQEN);
601 break;
602 case AC2_VI:
603 acm_ctrl &= (~ACMHW_VIQEN);
604 break;
605 case AC3_VO:
52f57804 606 acm_ctrl &= (~ACMHW_VOQEN);
a619d1ab
LF
607 break;
608 default:
5c99f04f 609 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
a619d1ab
LF
610 "switch case not process\n");
611 break;
612 }
613 }
5c99f04f 614
a619d1ab 615 RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
5c99f04f
LF
616 "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
617 acm_ctrl);
a619d1ab 618 rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
5c99f04f
LF
619 }
620 break;
a619d1ab
LF
621 case HW_VAR_RCR:
622 rtl_write_dword(rtlpriv, REG_RCR, ((u32 *)(val))[0]);
623 rtlpci->receive_config = ((u32 *)(val))[0];
624 break;
5c99f04f
LF
625 case HW_VAR_RETRY_LIMIT:{
626 u8 retry_limit = ((u8 *)(val))[0];
a619d1ab
LF
627
628 rtl_write_word(rtlpriv, REG_RL,
629 retry_limit << RETRY_LIMIT_SHORT_SHIFT |
630 retry_limit << RETRY_LIMIT_LONG_SHIFT);
5c99f04f
LF
631 }
632 break;
a619d1ab
LF
633 case HW_VAR_DUAL_TSF_RST:
634 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
635 break;
636 case HW_VAR_EFUSE_BYTES:
637 rtlefuse->efuse_usedbytes = *((u16 *)val);
638 break;
639 case HW_VAR_EFUSE_USAGE:
5c99f04f 640 rtlefuse->efuse_usedpercentage = *((u8 *)val);
a619d1ab
LF
641 break;
642 case HW_VAR_IO_CMD:
643 rtl8723be_phy_set_io_cmd(hw, (*(enum io_type *)val));
644 break;
5c99f04f 645 case HW_VAR_SET_RPWM:{
a619d1ab
LF
646 u8 rpwm_val;
647
648 rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM);
649 udelay(1);
650
651 if (rpwm_val & BIT(7)) {
5c99f04f 652 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, (*(u8 *)val));
a619d1ab 653 } else {
5c99f04f
LF
654 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM,
655 ((*(u8 *)val) | BIT(7)));
a619d1ab 656 }
5c99f04f
LF
657 }
658 break;
a619d1ab 659 case HW_VAR_H2C_FW_PWRMODE:
5c99f04f 660 rtl8723be_set_fw_pwrmode_cmd(hw, (*(u8 *)val));
a619d1ab
LF
661 break;
662 case HW_VAR_FW_PSMODE_STATUS:
663 ppsc->fw_current_inpsmode = *((bool *)val);
664 break;
665 case HW_VAR_RESUME_CLK_ON:
666 _rtl8723be_set_fw_ps_rf_on(hw);
667 break;
5c99f04f
LF
668 case HW_VAR_FW_LPS_ACTION:{
669 bool b_enter_fwlps = *((bool *)val);
a619d1ab 670
5c99f04f 671 if (b_enter_fwlps)
a619d1ab
LF
672 _rtl8723be_fwlps_enter(hw);
673 else
674 _rtl8723be_fwlps_leave(hw);
5c99f04f
LF
675 }
676 break;
677 case HW_VAR_H2C_FW_JOINBSSRPT:{
678 u8 mstatus = (*(u8 *)val);
a619d1ab
LF
679
680 if (mstatus == RT_MEDIA_CONNECT) {
681 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL);
5c99f04f
LF
682 _rtl8723be_download_rsvd_page(hw);
683 }
684 rtl8723be_set_fw_media_status_rpt_cmd(hw, mstatus);
a619d1ab 685 }
5c99f04f 686 break;
a619d1ab 687 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
5c99f04f 688 rtl8723be_set_p2p_ps_offload_cmd(hw, (*(u8 *)val));
a619d1ab 689 break;
5c99f04f 690 case HW_VAR_AID:{
a619d1ab
LF
691 u16 u2btmp;
692 u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
693 u2btmp &= 0xC000;
694 rtl_write_word(rtlpriv, REG_BCN_PSR_RPT,
695 (u2btmp | mac->assoc_id));
5c99f04f
LF
696 }
697 break;
698 case HW_VAR_CORRECT_TSF:{
699 u8 btype_ibss = ((u8 *)(val))[0];
a619d1ab
LF
700
701 if (btype_ibss)
702 _rtl8723be_stop_tx_beacon(hw);
703
704 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3));
705
706 rtl_write_dword(rtlpriv, REG_TSFTR,
707 (u32) (mac->tsf & 0xffffffff));
708 rtl_write_dword(rtlpriv, REG_TSFTR + 4,
709 (u32) ((mac->tsf >> 32) & 0xffffffff));
710
711 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
712
713 if (btype_ibss)
714 _rtl8723be_resume_tx_beacon(hw);
5c99f04f
LF
715 }
716 break;
717 case HW_VAR_KEEP_ALIVE:{
a619d1ab
LF
718 u8 array[2];
719 array[0] = 0xff;
5c99f04f
LF
720 array[1] = *((u8 *)val);
721 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_KEEP_ALIVE_CTRL, 2, array);
722 }
723 break;
a619d1ab 724 default:
5c99f04f 725 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
a619d1ab
LF
726 "switch case not process %x\n",
727 variable);
728 break;
729 }
730}
731
732static bool _rtl8723be_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
733{
734 struct rtl_priv *rtlpriv = rtl_priv(hw);
735 bool status = true;
5c99f04f 736 long count = 0;
a619d1ab
LF
737 u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) |
738 _LLT_OP(_LLT_WRITE_ACCESS);
739
740 rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
741
742 do {
743 value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
744 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
745 break;
746
747 if (count > POLLING_LLT_THRESHOLD) {
748 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
5c99f04f
LF
749 "Failed to polling write LLT done at address %d!\n",
750 address);
a619d1ab
LF
751 status = false;
752 break;
753 }
754 } while (++count);
755
756 return status;
757}
758
759static bool _rtl8723be_llt_table_init(struct ieee80211_hw *hw)
760{
761 struct rtl_priv *rtlpriv = rtl_priv(hw);
762 unsigned short i;
763 u8 txpktbuf_bndy;
5c99f04f 764 u8 maxPage;
a619d1ab
LF
765 bool status;
766
5c99f04f 767 maxPage = 255;
a619d1ab
LF
768 txpktbuf_bndy = 245;
769
770 rtl_write_dword(rtlpriv, REG_TRXFF_BNDY,
771 (0x27FF0000 | txpktbuf_bndy));
772 rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy);
773
774 rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
775 rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
776
777 rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy);
778 rtl_write_byte(rtlpriv, REG_PBP, 0x31);
779 rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);
780
781 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
782 status = _rtl8723be_llt_write(hw, i, i + 1);
783 if (!status)
784 return status;
785 }
5c99f04f 786
a619d1ab
LF
787 status = _rtl8723be_llt_write(hw, (txpktbuf_bndy - 1), 0xFF);
788
789 if (!status)
790 return status;
791
5c99f04f 792 for (i = txpktbuf_bndy; i < maxPage; i++) {
a619d1ab
LF
793 status = _rtl8723be_llt_write(hw, i, (i + 1));
794 if (!status)
795 return status;
796 }
5c99f04f
LF
797
798 status = _rtl8723be_llt_write(hw, maxPage, txpktbuf_bndy);
a619d1ab
LF
799 if (!status)
800 return status;
801
802 rtl_write_dword(rtlpriv, REG_RQPN, 0x80e40808);
803 rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x00);
804
805 return true;
806}
807
808static void _rtl8723be_gen_refresh_led_state(struct ieee80211_hw *hw)
809{
810 struct rtl_priv *rtlpriv = rtl_priv(hw);
811 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
812 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
813 struct rtl_led *pled0 = &(pcipriv->ledctl.sw_led0);
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) {
1384 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n");
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()) {
1443 rtl8723be_phy_iq_calibrate(hw, false);
1444 rtlphy->iqk_initialized = true;
1445 }
a619d1ab
LF
1446 rtl8723be_dm_check_txpower_tracking(hw);
1447 rtl8723be_phy_lc_calibrate(hw);
1448 }
5c99f04f
LF
1449 rtl_write_byte(rtlpriv, REG_NAV_UPPER, ((30000 + 127) / 128));
1450
1451 /* Release Rx DMA. */
1452 tmp_u1b = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1453 if (tmp_u1b & BIT(2)) {
1454 /* Release Rx DMA if needed */
1455 tmp_u1b &= (~BIT(2));
1456 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, tmp_u1b);
a619d1ab 1457 }
5c99f04f
LF
1458 /* Release Tx/Rx PCIE DMA. */
1459 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0);
1460
a619d1ab
LF
1461 rtl8723be_dm_init(hw);
1462exit:
1463 local_irq_restore(flags);
1464 rtlpriv->rtlhal.being_init_adapter = false;
1465 return err;
1466}
1467
1468static enum version_8723e _rtl8723be_read_chip_version(struct ieee80211_hw *hw)
1469{
1470 struct rtl_priv *rtlpriv = rtl_priv(hw);
1471 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1472 enum version_8723e version = VERSION_UNKNOWN;
a619d1ab
LF
1473 u32 value32;
1474
a619d1ab
LF
1475 value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG1);
1476 if ((value32 & (CHIP_8723B)) != CHIP_8723B)
1477 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "unkown chip version\n");
1478 else
5c99f04f 1479 version = (enum version_8723e)CHIP_8723B;
a619d1ab 1480
5c99f04f
LF
1481 rtlphy->rf_type = RF_1T1R;
1482
1483 /* treat rtl8723be chip as MP version in default */
1484 version = (enum version_8723e)(version | NORMAL_CHIP);
1485
1486 value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG);
1487 /* cut version */
1488 version |= (enum version_8723e)(value32 & CHIP_VER_RTL_MASK);
1489 /* Manufacture */
1490 if (((value32 & EXT_VENDOR_ID) >> 18) == 0x01)
1491 version = (enum version_8723e)(version | CHIP_VENDOR_SMIC);
a619d1ab 1492
a619d1ab
LF
1493 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1494 "Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
5c99f04f 1495 "RF_2T2R" : "RF_1T1R");
a619d1ab
LF
1496
1497 return version;
1498}
1499
1500static int _rtl8723be_set_media_status(struct ieee80211_hw *hw,
1501 enum nl80211_iftype type)
1502{
1503 struct rtl_priv *rtlpriv = rtl_priv(hw);
1504 u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc;
1505 enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
5c99f04f 1506 u8 mode = MSR_NOLINK;
a619d1ab 1507
a619d1ab
LF
1508 switch (type) {
1509 case NL80211_IFTYPE_UNSPECIFIED:
5c99f04f 1510 mode = MSR_NOLINK;
a619d1ab
LF
1511 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1512 "Set Network type to NO LINK!\n");
1513 break;
1514 case NL80211_IFTYPE_ADHOC:
5c99f04f
LF
1515 case NL80211_IFTYPE_MESH_POINT:
1516 mode = MSR_ADHOC;
a619d1ab
LF
1517 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1518 "Set Network type to Ad Hoc!\n");
1519 break;
1520 case NL80211_IFTYPE_STATION:
5c99f04f 1521 mode = MSR_INFRA;
a619d1ab
LF
1522 ledaction = LED_CTL_LINK;
1523 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1524 "Set Network type to STA!\n");
1525 break;
1526 case NL80211_IFTYPE_AP:
5c99f04f
LF
1527 mode = MSR_AP;
1528 ledaction = LED_CTL_LINK;
a619d1ab
LF
1529 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1530 "Set Network type to AP!\n");
1531 break;
1532 default:
1533 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1534 "Network type %d not support!\n", type);
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:
1632 RT_ASSERT(false, "invalid aci: %d !\n", aci);
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));
2029 u16 i, usvalue;
2030 u8 hwinfo[HWSET_MAX_SIZE];
2031 u16 eeprom_id;
2032 bool is_toshiba_smid1 = false;
2033 bool is_toshiba_smid2 = false;
2034 bool is_samsung_smid = false;
2035 bool is_lenovo_smid = false;
2036 u16 toshiba_smid1[] = {
2037 0x6151, 0x6152, 0x6154, 0x6155, 0x6177, 0x6178, 0x6179, 0x6180,
2038 0x7151, 0x7152, 0x7154, 0x7155, 0x7177, 0x7178, 0x7179, 0x7180,
2039 0x8151, 0x8152, 0x8154, 0x8155, 0x8181, 0x8182, 0x8184, 0x8185,
2040 0x9151, 0x9152, 0x9154, 0x9155, 0x9181, 0x9182, 0x9184, 0x9185
2041 };
2042 u16 toshiba_smid2[] = {
2043 0x6181, 0x6184, 0x6185, 0x7181, 0x7182, 0x7184, 0x7185, 0x8181,
2044 0x8182, 0x8184, 0x8185, 0x9181, 0x9182, 0x9184, 0x9185
2045 };
2046 u16 samsung_smid[] = {
2047 0x6191, 0x6192, 0x6193, 0x7191, 0x7192, 0x7193, 0x8191, 0x8192,
2048 0x8193, 0x9191, 0x9192, 0x9193
2049 };
2050 u16 lenovo_smid[] = {
2051 0x8195, 0x9195, 0x7194, 0x8200, 0x8201, 0x8202, 0x9199, 0x9200
2052 };
2053
2054 if (pseudo_test) {
2055 /* needs to be added */
2056 return;
2057 }
2058 if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
2059 rtl_efuse_shadow_map_update(hw);
2060
2061 memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
2062 HWSET_MAX_SIZE);
2063 } else if (rtlefuse->epromtype == EEPROM_93C46) {
2064 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2065 "RTL819X Not boot from eeprom, check it !!");
2066 }
2067 RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"),
2068 hwinfo, HWSET_MAX_SIZE);
2069
2070 eeprom_id = *((u16 *)&hwinfo[0]);
2071 if (eeprom_id != RTL8723BE_EEPROM_ID) {
2072 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2073 "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
2074 rtlefuse->autoload_failflag = true;
2075 } else {
2076 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
2077 rtlefuse->autoload_failflag = false;
2078 }
5c99f04f 2079
a619d1ab
LF
2080 if (rtlefuse->autoload_failflag)
2081 return;
2082
2083 rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID];
2084 rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID];
2085 rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID];
2086 rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID];
2087 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2088 "EEPROMId = 0x%4x\n", eeprom_id);
2089 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2090 "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid);
2091 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2092 "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did);
2093 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2094 "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid);
2095 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2096 "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid);
2097
2098 for (i = 0; i < 6; i += 2) {
2099 usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i];
2100 *((u16 *)(&rtlefuse->dev_addr[i])) = usvalue;
2101 }
2102 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "dev_addr: %pM\n",
2103 rtlefuse->dev_addr);
2104
2105 /*parse xtal*/
2106 rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_8723BE];
2107 if (rtlefuse->crystalcap == 0xFF)
2108 rtlefuse->crystalcap = 0x20;
2109
2110 _rtl8723be_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag,
2111 hwinfo);
2112
2113 rtl8723be_read_bt_coexist_info_from_hwpg(hw,
2114 rtlefuse->autoload_failflag,
2115 hwinfo);
2116
9cb76aa9 2117 rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN];
a619d1ab
LF
2118 rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
2119 rtlefuse->txpwr_fromeprom = true;
9cb76aa9 2120 rtlefuse->eeprom_oemid = hwinfo[EEPROM_CUSTOMER_ID];
a619d1ab
LF
2121
2122 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2123 "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid);
2124
b23cd22d
SF
2125 /* set channel plan from efuse */
2126 rtlefuse->channel_plan = rtlefuse->eeprom_channelplan;
a619d1ab
LF
2127
2128 if (rtlhal->oem_id == RT_CID_DEFAULT) {
2129 /* Does this one have a Toshiba SMID from group 1? */
2130 for (i = 0; i < sizeof(toshiba_smid1) / sizeof(u16); i++) {
2131 if (rtlefuse->eeprom_smid == toshiba_smid1[i]) {
2132 is_toshiba_smid1 = true;
2133 break;
2134 }
2135 }
2136 /* Does this one have a Toshiba SMID from group 2? */
2137 for (i = 0; i < sizeof(toshiba_smid2) / sizeof(u16); i++) {
2138 if (rtlefuse->eeprom_smid == toshiba_smid2[i]) {
2139 is_toshiba_smid2 = true;
2140 break;
2141 }
2142 }
2143 /* Does this one have a Samsung SMID? */
2144 for (i = 0; i < sizeof(samsung_smid) / sizeof(u16); i++) {
2145 if (rtlefuse->eeprom_smid == samsung_smid[i]) {
2146 is_samsung_smid = true;
2147 break;
2148 }
2149 }
2150 /* Does this one have a Lenovo SMID? */
2151 for (i = 0; i < sizeof(lenovo_smid) / sizeof(u16); i++) {
2152 if (rtlefuse->eeprom_smid == lenovo_smid[i]) {
2153 is_lenovo_smid = true;
2154 break;
2155 }
2156 }
2157 switch (rtlefuse->eeprom_oemid) {
2158 case EEPROM_CID_DEFAULT:
2159 if (rtlefuse->eeprom_did == 0x8176) {
2160 if (rtlefuse->eeprom_svid == 0x10EC &&
2161 is_toshiba_smid1) {
2162 rtlhal->oem_id = RT_CID_TOSHIBA;
2163 } else if (rtlefuse->eeprom_svid == 0x1025) {
2164 rtlhal->oem_id = RT_CID_819X_ACER;
2165 } else if (rtlefuse->eeprom_svid == 0x10EC &&
2166 is_samsung_smid) {
2167 rtlhal->oem_id = RT_CID_819X_SAMSUNG;
2168 } else if (rtlefuse->eeprom_svid == 0x10EC &&
2169 is_lenovo_smid) {
2170 rtlhal->oem_id = RT_CID_819X_LENOVO;
2171 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
2172 rtlefuse->eeprom_smid == 0x8197) ||
2173 (rtlefuse->eeprom_svid == 0x10EC &&
2174 rtlefuse->eeprom_smid == 0x9196)) {
2175 rtlhal->oem_id = RT_CID_819X_CLEVO;
2176 } else if ((rtlefuse->eeprom_svid == 0x1028 &&
2177 rtlefuse->eeprom_smid == 0x8194) ||
2178 (rtlefuse->eeprom_svid == 0x1028 &&
2179 rtlefuse->eeprom_smid == 0x8198) ||
2180 (rtlefuse->eeprom_svid == 0x1028 &&
2181 rtlefuse->eeprom_smid == 0x9197) ||
2182 (rtlefuse->eeprom_svid == 0x1028 &&
2183 rtlefuse->eeprom_smid == 0x9198)) {
2184 rtlhal->oem_id = RT_CID_819X_DELL;
2185 } else if ((rtlefuse->eeprom_svid == 0x103C &&
2186 rtlefuse->eeprom_smid == 0x1629)) {
2187 rtlhal->oem_id = RT_CID_819X_HP;
2188 } else if ((rtlefuse->eeprom_svid == 0x1A32 &&
2189 rtlefuse->eeprom_smid == 0x2315)) {
2190 rtlhal->oem_id = RT_CID_819X_QMI;
2191 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
2192 rtlefuse->eeprom_smid == 0x8203)) {
2193 rtlhal->oem_id = RT_CID_819X_PRONETS;
2194 } else if ((rtlefuse->eeprom_svid == 0x1043 &&
2195 rtlefuse->eeprom_smid == 0x84B5)) {
2196 rtlhal->oem_id = RT_CID_819X_EDIMAX_ASUS;
2197 } else {
2198 rtlhal->oem_id = RT_CID_DEFAULT;
2199 }
2200 } else if (rtlefuse->eeprom_did == 0x8178) {
2201 if (rtlefuse->eeprom_svid == 0x10EC &&
2202 is_toshiba_smid2)
2203 rtlhal->oem_id = RT_CID_TOSHIBA;
2204 else if (rtlefuse->eeprom_svid == 0x1025)
2205 rtlhal->oem_id = RT_CID_819X_ACER;
2206 else if ((rtlefuse->eeprom_svid == 0x10EC &&
2207 rtlefuse->eeprom_smid == 0x8186))
2208 rtlhal->oem_id = RT_CID_819X_PRONETS;
2209 else if ((rtlefuse->eeprom_svid == 0x1043 &&
2210 rtlefuse->eeprom_smid == 0x84B6))
2211 rtlhal->oem_id =
2212 RT_CID_819X_EDIMAX_ASUS;
2213 else
2214 rtlhal->oem_id = RT_CID_DEFAULT;
2215 } else {
2216 rtlhal->oem_id = RT_CID_DEFAULT;
2217 }
2218 break;
2219 case EEPROM_CID_TOSHIBA:
2220 rtlhal->oem_id = RT_CID_TOSHIBA;
2221 break;
2222 case EEPROM_CID_CCX:
2223 rtlhal->oem_id = RT_CID_CCX;
2224 break;
2225 case EEPROM_CID_QMI:
2226 rtlhal->oem_id = RT_CID_819X_QMI;
2227 break;
2228 case EEPROM_CID_WHQL:
2229 break;
2230 default:
2231 rtlhal->oem_id = RT_CID_DEFAULT;
2232 break;
2233 }
2234 }
2235}
2236
2237static void _rtl8723be_hal_customized_behavior(struct ieee80211_hw *hw)
2238{
2239 struct rtl_priv *rtlpriv = rtl_priv(hw);
2240 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2241 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2242
2243 pcipriv->ledctl.led_opendrain = true;
2244 switch (rtlhal->oem_id) {
2245 case RT_CID_819X_HP:
2246 pcipriv->ledctl.led_opendrain = true;
2247 break;
2248 case RT_CID_819X_LENOVO:
2249 case RT_CID_DEFAULT:
2250 case RT_CID_TOSHIBA:
2251 case RT_CID_CCX:
2252 case RT_CID_819X_ACER:
2253 case RT_CID_WHQL:
2254 default:
2255 break;
2256 }
2257 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2258 "RT Customized ID: 0x%02X\n", rtlhal->oem_id);
2259}
2260
2261void rtl8723be_read_eeprom_info(struct ieee80211_hw *hw)
2262{
2263 struct rtl_priv *rtlpriv = rtl_priv(hw);
2264 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2265 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2266 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2267 u8 tmp_u1b;
2268
2269 rtlhal->version = _rtl8723be_read_chip_version(hw);
2270 if (get_rf_type(rtlphy) == RF_1T1R)
2271 rtlpriv->dm.rfpath_rxenable[0] = true;
2272 else
2273 rtlpriv->dm.rfpath_rxenable[0] =
2274 rtlpriv->dm.rfpath_rxenable[1] = true;
2275 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
2276 rtlhal->version);
2277 tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
2278 if (tmp_u1b & BIT(4)) {
2279 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
2280 rtlefuse->epromtype = EEPROM_93C46;
2281 } else {
2282 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
2283 rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
2284 }
2285 if (tmp_u1b & BIT(5)) {
2286 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
2287 rtlefuse->autoload_failflag = false;
2288 _rtl8723be_read_adapter_info(hw, false);
2289 } else {
2290 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n");
2291 }
2292 _rtl8723be_hal_customized_behavior(hw);
2293}
2294
a619d1ab
LF
2295static u8 _rtl8723be_mrate_idx_to_arfr_id(struct ieee80211_hw *hw,
2296 u8 rate_index)
2297{
2298 u8 ret = 0;
a619d1ab
LF
2299 switch (rate_index) {
2300 case RATR_INX_WIRELESS_NGB:
2301 ret = 1;
2302 break;
2303 case RATR_INX_WIRELESS_N:
2304 case RATR_INX_WIRELESS_NG:
2305 ret = 5;
2306 break;
2307 case RATR_INX_WIRELESS_NB:
2308 ret = 3;
2309 break;
2310 case RATR_INX_WIRELESS_GB:
2311 ret = 6;
2312 break;
2313 case RATR_INX_WIRELESS_G:
2314 ret = 7;
2315 break;
2316 case RATR_INX_WIRELESS_B:
2317 ret = 8;
2318 break;
2319 default:
2320 ret = 0;
2321 break;
2322 }
2323 return ret;
2324}
2325
2326static void rtl8723be_update_hal_rate_mask(struct ieee80211_hw *hw,
2327 struct ieee80211_sta *sta,
2328 u8 rssi_level)
2329{
2330 struct rtl_priv *rtlpriv = rtl_priv(hw);
2331 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2332 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2333 struct rtl_sta_info *sta_entry = NULL;
2334 u32 ratr_bitmap;
2335 u8 ratr_index;
2336 u8 curtxbw_40mhz = (sta->ht_cap.cap &
5c99f04f 2337 IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0;
a619d1ab 2338 u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
5c99f04f 2339 1 : 0;
a619d1ab 2340 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
5c99f04f 2341 1 : 0;
a619d1ab
LF
2342 enum wireless_mode wirelessmode = 0;
2343 bool shortgi = false;
2344 u8 rate_mask[7];
2345 u8 macid = 0;
a619d1ab
LF
2346
2347 sta_entry = (struct rtl_sta_info *)sta->drv_priv;
2348 wirelessmode = sta_entry->wireless_mode;
2349 if (mac->opmode == NL80211_IFTYPE_STATION ||
2350 mac->opmode == NL80211_IFTYPE_MESH_POINT)
2351 curtxbw_40mhz = mac->bw_40;
2352 else if (mac->opmode == NL80211_IFTYPE_AP ||
2353 mac->opmode == NL80211_IFTYPE_ADHOC)
2354 macid = sta->aid + 1;
2355
2356 ratr_bitmap = sta->supp_rates[0];
2357
2358 if (mac->opmode == NL80211_IFTYPE_ADHOC)
2359 ratr_bitmap = 0xfff;
2360
2361 ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
2362 sta->ht_cap.mcs.rx_mask[0] << 12);
2363 switch (wirelessmode) {
2364 case WIRELESS_MODE_B:
2365 ratr_index = RATR_INX_WIRELESS_B;
2366 if (ratr_bitmap & 0x0000000c)
2367 ratr_bitmap &= 0x0000000d;
2368 else
2369 ratr_bitmap &= 0x0000000f;
2370 break;
2371 case WIRELESS_MODE_G:
2372 ratr_index = RATR_INX_WIRELESS_GB;
2373
2374 if (rssi_level == 1)
2375 ratr_bitmap &= 0x00000f00;
2376 else if (rssi_level == 2)
2377 ratr_bitmap &= 0x00000ff0;
2378 else
2379 ratr_bitmap &= 0x00000ff5;
2380 break;
a619d1ab
LF
2381 case WIRELESS_MODE_N_24G:
2382 case WIRELESS_MODE_N_5G:
2383 ratr_index = RATR_INX_WIRELESS_NGB;
5c99f04f
LF
2384 if (rtlphy->rf_type == RF_1T1R) {
2385 if (curtxbw_40mhz) {
2386 if (rssi_level == 1)
2387 ratr_bitmap &= 0x000f0000;
2388 else if (rssi_level == 2)
2389 ratr_bitmap &= 0x000ff000;
2390 else
2391 ratr_bitmap &= 0x000ff015;
2392 } else {
2393 if (rssi_level == 1)
2394 ratr_bitmap &= 0x000f0000;
2395 else if (rssi_level == 2)
2396 ratr_bitmap &= 0x000ff000;
2397 else
2398 ratr_bitmap &= 0x000ff005;
2399 }
a619d1ab 2400 } else {
5c99f04f
LF
2401 if (curtxbw_40mhz) {
2402 if (rssi_level == 1)
2403 ratr_bitmap &= 0x0f8f0000;
2404 else if (rssi_level == 2)
2405 ratr_bitmap &= 0x0f8ff000;
2406 else
2407 ratr_bitmap &= 0x0f8ff015;
a619d1ab 2408 } else {
5c99f04f
LF
2409 if (rssi_level == 1)
2410 ratr_bitmap &= 0x0f8f0000;
2411 else if (rssi_level == 2)
2412 ratr_bitmap &= 0x0f8ff000;
2413 else
2414 ratr_bitmap &= 0x0f8ff005;
a619d1ab
LF
2415 }
2416 }
2417 if ((curtxbw_40mhz && curshortgi_40mhz) ||
2418 (!curtxbw_40mhz && curshortgi_20mhz)) {
2419 if (macid == 0)
2420 shortgi = true;
2421 else if (macid == 1)
2422 shortgi = false;
2423 }
2424 break;
2425 default:
2426 ratr_index = RATR_INX_WIRELESS_NGB;
2427
2428 if (rtlphy->rf_type == RF_1T2R)
2429 ratr_bitmap &= 0x000ff0ff;
2430 else
2431 ratr_bitmap &= 0x0f0ff0ff;
2432 break;
2433 }
5c99f04f 2434
a619d1ab
LF
2435 sta_entry->ratr_index = ratr_index;
2436
2437 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2438 "ratr_bitmap :%x\n", ratr_bitmap);
5c99f04f
LF
2439 *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
2440 (ratr_index << 28);
a619d1ab
LF
2441 rate_mask[0] = macid;
2442 rate_mask[1] = _rtl8723be_mrate_idx_to_arfr_id(hw, ratr_index) |
5c99f04f 2443 (shortgi ? 0x80 : 0x00);
a619d1ab 2444 rate_mask[2] = curtxbw_40mhz;
a619d1ab
LF
2445
2446 rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff);
2447 rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >> 8);
2448 rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16);
2449 rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24);
2450
2451 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2452 "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x:%x:%x\n",
2453 ratr_index, ratr_bitmap,
2454 rate_mask[0], rate_mask[1],
2455 rate_mask[2], rate_mask[3],
2456 rate_mask[4], rate_mask[5],
2457 rate_mask[6]);
5c99f04f 2458 rtl8723be_fill_h2c_cmd(hw, H2C_8723B_RA_MASK, 7, rate_mask);
a619d1ab
LF
2459 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
2460}
2461
2462void rtl8723be_update_hal_rate_tbl(struct ieee80211_hw *hw,
2463 struct ieee80211_sta *sta,
2464 u8 rssi_level)
2465{
2466 struct rtl_priv *rtlpriv = rtl_priv(hw);
2467 if (rtlpriv->dm.useramask)
2468 rtl8723be_update_hal_rate_mask(hw, sta, rssi_level);
a619d1ab
LF
2469}
2470
2471void rtl8723be_update_channel_access_setting(struct ieee80211_hw *hw)
2472{
2473 struct rtl_priv *rtlpriv = rtl_priv(hw);
2474 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2475 u16 sifs_timer;
2476
9cb76aa9 2477 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);
a619d1ab
LF
2478 if (!mac->ht_enable)
2479 sifs_timer = 0x0a0a;
2480 else
2481 sifs_timer = 0x0e0e;
2482 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
2483}
2484
2485bool rtl8723be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
2486{
2487 struct rtl_priv *rtlpriv = rtl_priv(hw);
2488 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2489 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2490 enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate;
2491 u8 u1tmp;
5c99f04f 2492 bool b_actuallyset = false;
a619d1ab
LF
2493
2494 if (rtlpriv->rtlhal.being_init_adapter)
2495 return false;
2496
2497 if (ppsc->swrf_processing)
2498 return false;
2499
2500 spin_lock(&rtlpriv->locks.rf_ps_lock);
2501 if (ppsc->rfchange_inprogress) {
2502 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2503 return false;
2504 } else {
2505 ppsc->rfchange_inprogress = true;
2506 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2507 }
5c99f04f 2508
a619d1ab
LF
2509 cur_rfstate = ppsc->rfpwr_state;
2510
2511 rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2,
2512 rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2) & ~(BIT(1)));
2513
2514 u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2);
2515
2516 if (rtlphy->polarity_ctl)
2517 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON;
2518 else
2519 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF;
2520
5c99f04f 2521 if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) {
a619d1ab
LF
2522 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2523 "GPIOChangeRF - HW Radio ON, RF ON\n");
2524
2525 e_rfpowerstate_toset = ERFON;
2526 ppsc->hwradiooff = false;
5c99f04f
LF
2527 b_actuallyset = true;
2528 } else if (!ppsc->hwradiooff && (e_rfpowerstate_toset == ERFOFF)) {
a619d1ab
LF
2529 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2530 "GPIOChangeRF - HW Radio OFF, RF OFF\n");
2531
2532 e_rfpowerstate_toset = ERFOFF;
2533 ppsc->hwradiooff = true;
5c99f04f 2534 b_actuallyset = true;
a619d1ab 2535 }
5c99f04f
LF
2536
2537 if (b_actuallyset) {
a619d1ab
LF
2538 spin_lock(&rtlpriv->locks.rf_ps_lock);
2539 ppsc->rfchange_inprogress = false;
2540 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2541 } else {
2542 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
2543 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2544
2545 spin_lock(&rtlpriv->locks.rf_ps_lock);
2546 ppsc->rfchange_inprogress = false;
2547 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2548 }
5c99f04f 2549
a619d1ab
LF
2550 *valid = 1;
2551 return !ppsc->hwradiooff;
5c99f04f 2552
a619d1ab
LF
2553}
2554
2555void rtl8723be_set_key(struct ieee80211_hw *hw, u32 key_index,
2556 u8 *p_macaddr, bool is_group, u8 enc_algo,
2557 bool is_wepkey, bool clear_all)
2558{
2559 struct rtl_priv *rtlpriv = rtl_priv(hw);
2560 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2561 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2562 u8 *macaddr = p_macaddr;
2563 u32 entry_id = 0;
2564 bool is_pairwise = false;
2565
2566 static u8 cam_const_addr[4][6] = {
2567 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
2568 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
2569 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
2570 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
2571 };
2572 static u8 cam_const_broad[] = {
2573 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2574 };
2575
2576 if (clear_all) {
2577 u8 idx = 0;
2578 u8 cam_offset = 0;
2579 u8 clear_number = 5;
2580
2581 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
2582
2583 for (idx = 0; idx < clear_number; idx++) {
2584 rtl_cam_mark_invalid(hw, cam_offset + idx);
2585 rtl_cam_empty_entry(hw, cam_offset + idx);
2586
2587 if (idx < 5) {
2588 memset(rtlpriv->sec.key_buf[idx], 0,
2589 MAX_KEY_LEN);
2590 rtlpriv->sec.key_len[idx] = 0;
2591 }
2592 }
5c99f04f 2593
a619d1ab
LF
2594 } else {
2595 switch (enc_algo) {
2596 case WEP40_ENCRYPTION:
2597 enc_algo = CAM_WEP40;
2598 break;
2599 case WEP104_ENCRYPTION:
2600 enc_algo = CAM_WEP104;
2601 break;
2602 case TKIP_ENCRYPTION:
2603 enc_algo = CAM_TKIP;
2604 break;
2605 case AESCCMP_ENCRYPTION:
2606 enc_algo = CAM_AES;
2607 break;
2608 default:
5c99f04f 2609 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
a619d1ab
LF
2610 "switch case not process\n");
2611 enc_algo = CAM_TKIP;
2612 break;
2613 }
2614
2615 if (is_wepkey || rtlpriv->sec.use_defaultkey) {
2616 macaddr = cam_const_addr[key_index];
2617 entry_id = key_index;
2618 } else {
2619 if (is_group) {
2620 macaddr = cam_const_broad;
2621 entry_id = key_index;
2622 } else {
2623 if (mac->opmode == NL80211_IFTYPE_AP) {
2624 entry_id = rtl_cam_get_free_entry(hw,
2625 p_macaddr);
2626 if (entry_id >= TOTAL_CAM_ENTRY) {
2627 RT_TRACE(rtlpriv, COMP_SEC,
2628 DBG_EMERG,
5c99f04f 2629 "Can not find free hw security cam entry\n");
a619d1ab
LF
2630 return;
2631 }
2632 } else {
2633 entry_id = CAM_PAIRWISE_KEY_POSITION;
2634 }
5c99f04f 2635
a619d1ab
LF
2636 key_index = PAIRWISE_KEYIDX;
2637 is_pairwise = true;
2638 }
2639 }
5c99f04f 2640
a619d1ab
LF
2641 if (rtlpriv->sec.key_len[key_index] == 0) {
2642 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2643 "delete one entry, entry_id is %d\n",
5c99f04f 2644 entry_id);
a619d1ab
LF
2645 if (mac->opmode == NL80211_IFTYPE_AP)
2646 rtl_cam_del_entry(hw, p_macaddr);
2647 rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
2648 } else {
2649 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2650 "add one entry\n");
2651 if (is_pairwise) {
2652 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
5c99f04f 2653 "set Pairwiase key\n");
a619d1ab
LF
2654
2655 rtl_cam_add_one_entry(hw, macaddr, key_index,
5c99f04f
LF
2656 entry_id, enc_algo,
2657 CAM_CONFIG_NO_USEDK,
2658 rtlpriv->sec.key_buf[key_index]);
a619d1ab
LF
2659 } else {
2660 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2661 "set group key\n");
2662
2663 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
2664 rtl_cam_add_one_entry(hw,
2665 rtlefuse->dev_addr,
2666 PAIRWISE_KEYIDX,
2667 CAM_PAIRWISE_KEY_POSITION,
2668 enc_algo,
2669 CAM_CONFIG_NO_USEDK,
2670 rtlpriv->sec.key_buf
2671 [entry_id]);
2672 }
5c99f04f 2673
a619d1ab 2674 rtl_cam_add_one_entry(hw, macaddr, key_index,
5c99f04f
LF
2675 entry_id, enc_algo,
2676 CAM_CONFIG_NO_USEDK,
2677 rtlpriv->sec.key_buf[entry_id]);
a619d1ab
LF
2678 }
2679 }
2680 }
2681}
2682
2683void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
2684 bool auto_load_fail, u8 *hwinfo)
2685{
2686 struct rtl_priv *rtlpriv = rtl_priv(hw);
c18d8f50 2687 struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params;
a619d1ab
LF
2688 u8 value;
2689 u32 tmpu_32;
2690
2691 if (!auto_load_fail) {
2692 tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL);
2693 if (tmpu_32 & BIT(18))
2694 rtlpriv->btcoexist.btc_info.btcoexist = 1;
2695 else
2696 rtlpriv->btcoexist.btc_info.btcoexist = 0;
5c99f04f 2697 value = hwinfo[EEPROM_RF_BT_SETTING_8723B];
a619d1ab
LF
2698 rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2699 rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1);
2700 } else {
2701 rtlpriv->btcoexist.btc_info.btcoexist = 0;
2702 rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2703 rtlpriv->btcoexist.btc_info.ant_num = ANT_X2;
2704 }
5c99f04f 2705
c18d8f50
LF
2706 /* override ant_num / ant_path */
2707 if (mod_params->ant_sel)
2708 rtlpriv->btcoexist.btc_info.ant_num =
2709 (mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1);
a619d1ab
LF
2710}
2711
2712void rtl8723be_bt_reg_init(struct ieee80211_hw *hw)
2713{
2714 struct rtl_priv *rtlpriv = rtl_priv(hw);
2715
2716 /* 0:Low, 1:High, 2:From Efuse. */
2717 rtlpriv->btcoexist.reg_bt_iso = 2;
2718 /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */
2719 rtlpriv->btcoexist.reg_bt_sco = 3;
2720 /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
2721 rtlpriv->btcoexist.reg_bt_sco = 0;
2722}
2723
2724void rtl8723be_bt_hw_init(struct ieee80211_hw *hw)
2725{
2726 struct rtl_priv *rtlpriv = rtl_priv(hw);
2727
2728 if (rtlpriv->cfg->ops->get_btc_status())
2729 rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv);
5c99f04f 2730
a619d1ab
LF
2731}
2732
2733void rtl8723be_suspend(struct ieee80211_hw *hw)
2734{
2735}
2736
2737void rtl8723be_resume(struct ieee80211_hw *hw)
2738{
2739}
This page took 0.269707 seconds and 5 git commands to generate.