blob: 0fdf0909321f234c827107a13fd0a839c7c86be8 [file] [log] [blame]
Larry Fingera619d1a2014-02-28 15:16:50 -06001/******************************************************************************
2 *
3 * Copyright(c) 2009-2014 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26#include "../wifi.h"
27#include "../efuse.h"
28#include "../base.h"
29#include "../regd.h"
30#include "../cam.h"
31#include "../ps.h"
32#include "../pci.h"
33#include "reg.h"
34#include "def.h"
35#include "phy.h"
36#include "dm.h"
37#include "../rtl8723com/dm_common.h"
38#include "fw.h"
39#include "../rtl8723com/fw_common.h"
40#include "led.h"
41#include "hw.h"
Larry Fingera619d1a2014-02-28 15:16:50 -060042#include "pwrseq.h"
43#include "../btcoexist/rtl_btc.h"
44
45#define LLT_CONFIG 5
46
47static void _rtl8723be_return_beacon_queue_skb(struct ieee80211_hw *hw)
48{
49 struct rtl_priv *rtlpriv = rtl_priv(hw);
50 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
51 struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
52
53 while (skb_queue_len(&ring->queue)) {
54 struct rtl_tx_desc *entry = &ring->desc[ring->idx];
55 struct sk_buff *skb = __skb_dequeue(&ring->queue);
56
57 pci_unmap_single(rtlpci->pdev,
58 rtlpriv->cfg->ops->get_desc(
59 (u8 *)entry, true, HW_DESC_TXBUFF_ADDR),
60 skb->len, PCI_DMA_TODEVICE);
61 kfree_skb(skb);
62 ring->idx = (ring->idx + 1) % ring->entries;
63 }
64}
65
66static void _rtl8723be_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
67 u8 set_bits, u8 clear_bits)
68{
69 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
70 struct rtl_priv *rtlpriv = rtl_priv(hw);
71
72 rtlpci->reg_bcn_ctrl_val |= set_bits;
73 rtlpci->reg_bcn_ctrl_val &= ~clear_bits;
74
75 rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val);
76}
77
78static void _rtl8723be_stop_tx_beacon(struct ieee80211_hw *hw)
79{
80 struct rtl_priv *rtlpriv = rtl_priv(hw);
81 u8 tmp1byte;
82
83 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
84 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6)));
85 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64);
86 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
87 tmp1byte &= ~(BIT(0));
88 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
89}
90
91static void _rtl8723be_resume_tx_beacon(struct ieee80211_hw *hw)
92{
93 struct rtl_priv *rtlpriv = rtl_priv(hw);
94 u8 tmp1byte;
95
96 tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
97 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6));
98 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
99 tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
100 tmp1byte |= BIT(1);
101 rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
102}
103
104static void _rtl8723be_enable_bcn_sub_func(struct ieee80211_hw *hw)
105{
106 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(1));
107}
108
109static void _rtl8723be_disable_bcn_sub_func(struct ieee80211_hw *hw)
110{
111 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(1), 0);
112}
113
114static void _rtl8723be_set_fw_clock_on(struct ieee80211_hw *hw, u8 rpwm_val,
115 bool need_turn_off_ckk)
116{
117 struct rtl_priv *rtlpriv = rtl_priv(hw);
118 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
119 bool support_remote_wake_up;
120 u32 count = 0, isr_regaddr, content;
121 bool schedule_timer = need_turn_off_ckk;
122 rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN,
123 (u8 *)(&support_remote_wake_up));
124
125 if (!rtlhal->fw_ready)
126 return;
127 if (!rtlpriv->psc.fw_current_inpsmode)
128 return;
129
130 while (1) {
131 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
132 if (rtlhal->fw_clk_change_in_progress) {
133 while (rtlhal->fw_clk_change_in_progress) {
134 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
135 count++;
136 udelay(100);
137 if (count > 1000)
138 return;
139 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
140 }
141 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
142 } else {
143 rtlhal->fw_clk_change_in_progress = false;
144 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
145 break;
146 }
147 }
148 if (IS_IN_LOW_POWER_STATE_88E(rtlhal->fw_ps_state)) {
149 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM,
Joe Perches1851cb42014-03-24 13:15:40 -0700150 &rpwm_val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600151 if (FW_PS_IS_ACK(rpwm_val)) {
152 isr_regaddr = REG_HISR;
153 content = rtl_read_dword(rtlpriv, isr_regaddr);
154 while (!(content & IMR_CPWM) && (count < 500)) {
155 udelay(50);
156 count++;
157 content = rtl_read_dword(rtlpriv, isr_regaddr);
158 }
159
160 if (content & IMR_CPWM) {
161 rtl_write_word(rtlpriv, isr_regaddr, 0x0100);
162 rtlhal->fw_ps_state = FW_PS_STATE_RF_ON_88E;
163 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
164 "Receive CPWM INT!!! Set "
165 "pHalData->FwPSState = %X\n",
166 rtlhal->fw_ps_state);
167 }
168 }
169 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
170 rtlhal->fw_clk_change_in_progress = false;
171 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
172 if (schedule_timer) {
173 mod_timer(&rtlpriv->works.fw_clockoff_timer,
174 jiffies + MSECS(10));
175 }
176 } else {
177 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
178 rtlhal->fw_clk_change_in_progress = false;
179 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
180 }
181}
182
183static void _rtl8723be_set_fw_clock_off(struct ieee80211_hw *hw, u8 rpwm_val)
184{
185 struct rtl_priv *rtlpriv = rtl_priv(hw);
186 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
187 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
188 struct rtl8192_tx_ring *ring;
189 enum rf_pwrstate rtstate;
190 bool schedule_timer = false;
191 u8 queue;
192
193 if (!rtlhal->fw_ready)
194 return;
195 if (!rtlpriv->psc.fw_current_inpsmode)
196 return;
197 if (!rtlhal->allow_sw_to_change_hwclc)
198 return;
199 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, (u8 *)(&rtstate));
200 if (rtstate == ERFOFF || rtlpriv->psc.inactive_pwrstate == ERFOFF)
201 return;
202
203 for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) {
204 ring = &rtlpci->tx_ring[queue];
205 if (skb_queue_len(&ring->queue)) {
206 schedule_timer = true;
207 break;
208 }
209 }
210 if (schedule_timer) {
211 mod_timer(&rtlpriv->works.fw_clockoff_timer,
212 jiffies + MSECS(10));
213 return;
214 }
215 if (FW_PS_STATE(rtlhal->fw_ps_state) !=
216 FW_PS_STATE_RF_OFF_LOW_PWR_88E) {
217 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
218 if (!rtlhal->fw_clk_change_in_progress) {
219 rtlhal->fw_clk_change_in_progress = true;
220 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
221 rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val);
222 rtl_write_word(rtlpriv, REG_HISR, 0x0100);
223 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
Joe Perches1851cb42014-03-24 13:15:40 -0700224 &rpwm_val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600225 spin_lock_bh(&rtlpriv->locks.fw_ps_lock);
226 rtlhal->fw_clk_change_in_progress = false;
227 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
228 } else {
229 spin_unlock_bh(&rtlpriv->locks.fw_ps_lock);
230 mod_timer(&rtlpriv->works.fw_clockoff_timer,
231 jiffies + MSECS(10));
232 }
233 }
234}
235
236static void _rtl8723be_set_fw_ps_rf_on(struct ieee80211_hw *hw)
237{
238 u8 rpwm_val = 0;
239 rpwm_val |= (FW_PS_STATE_RF_OFF_88E | FW_PS_ACK);
240 _rtl8723be_set_fw_clock_on(hw, rpwm_val, true);
241}
242
243static void _rtl8723be_fwlps_leave(struct ieee80211_hw *hw)
244{
245 struct rtl_priv *rtlpriv = rtl_priv(hw);
246 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
247 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
248 bool fw_current_inps = false;
249 u8 rpwm_val = 0, fw_pwrmode = FW_PS_ACTIVE_MODE;
250
251 if (ppsc->low_power_enable) {
252 rpwm_val = (FW_PS_STATE_ALL_ON_88E | FW_PS_ACK);/* RF on */
253 _rtl8723be_set_fw_clock_on(hw, rpwm_val, false);
254 rtlhal->allow_sw_to_change_hwclc = false;
255 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
Joe Perches1851cb42014-03-24 13:15:40 -0700256 &fw_pwrmode);
Larry Fingera619d1a2014-02-28 15:16:50 -0600257 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
258 (u8 *)(&fw_current_inps));
259 } else {
260 rpwm_val = FW_PS_STATE_ALL_ON_88E; /* RF on */
Joe Perches1851cb42014-03-24 13:15:40 -0700261 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600262 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
Joe Perches1851cb42014-03-24 13:15:40 -0700263 &fw_pwrmode);
Larry Fingera619d1a2014-02-28 15:16:50 -0600264 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
265 (u8 *)(&fw_current_inps));
266 }
267}
268
269static void _rtl8723be_fwlps_enter(struct ieee80211_hw *hw)
270{
271 struct rtl_priv *rtlpriv = rtl_priv(hw);
272 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
273 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
274 bool fw_current_inps = true;
275 u8 rpwm_val;
276
277 if (ppsc->low_power_enable) {
278 rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR_88E; /* RF off */
279 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
280 (u8 *)(&fw_current_inps));
281 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
Joe Perches1851cb42014-03-24 13:15:40 -0700282 &ppsc->fwctrl_psmode);
Larry Fingera619d1a2014-02-28 15:16:50 -0600283 rtlhal->allow_sw_to_change_hwclc = true;
284 _rtl8723be_set_fw_clock_off(hw, rpwm_val);
285
286 } else {
287 rpwm_val = FW_PS_STATE_RF_OFF_88E; /* RF off */
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,
Joe Perches1851cb42014-03-24 13:15:40 -0700291 &ppsc->fwctrl_psmode);
292 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, &rpwm_val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600293 }
294}
295
296void rtl8723be_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
297{
298 struct rtl_priv *rtlpriv = rtl_priv(hw);
299 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
300 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
301
302 switch (variable) {
303 case HW_VAR_RCR:
304 *((u32 *)(val)) = rtlpci->receive_config;
305 break;
306 case HW_VAR_RF_STATE:
307 *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
308 break;
309 case HW_VAR_FWLPS_RF_ON: {
310 enum rf_pwrstate rfstate;
311 u32 val_rcr;
312
313 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE,
314 (u8 *)(&rfstate));
315 if (rfstate == ERFOFF) {
316 *((bool *)(val)) = true;
317 } else {
318 val_rcr = rtl_read_dword(rtlpriv, REG_RCR);
319 val_rcr &= 0x00070000;
320 if (val_rcr)
321 *((bool *)(val)) = false;
322 else
323 *((bool *)(val)) = true;
324 }
325 break; }
326 case HW_VAR_FW_PSMODE_STATUS:
327 *((bool *)(val)) = ppsc->fw_current_inpsmode;
328 break;
329 case HW_VAR_CORRECT_TSF: {
330 u64 tsf;
331 u32 *ptsf_low = (u32 *)&tsf;
332 u32 *ptsf_high = ((u32 *)&tsf) + 1;
333
334 *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4));
335 *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
336
337 *((u64 *)(val)) = tsf;
338
339 break; }
340 default:
341 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
342 "switch case not process %x\n", variable);
343 break;
344 }
345}
346
347void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
348{
349 struct rtl_priv *rtlpriv = rtl_priv(hw);
350 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
351 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
352 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
353 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
354 u8 idx;
355
356 switch (variable) {
357 case HW_VAR_ETHER_ADDR:
358 for (idx = 0; idx < ETH_ALEN; idx++)
359 rtl_write_byte(rtlpriv, (REG_MACID + idx), val[idx]);
360 break;
361 case HW_VAR_BASIC_RATE: {
362 u16 rate_cfg = ((u16 *)val)[0];
363 u8 rate_index = 0;
364 rate_cfg = rate_cfg & 0x15f;
365 rate_cfg |= 0x01;
366 rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff);
367 rtl_write_byte(rtlpriv, REG_RRSR + 1, (rate_cfg >> 8) & 0xff);
368 while (rate_cfg > 0x1) {
369 rate_cfg = (rate_cfg >> 1);
370 rate_index++;
371 }
372 rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, rate_index);
373 break; }
374 case HW_VAR_BSSID:
375 for (idx = 0; idx < ETH_ALEN; idx++)
376 rtl_write_byte(rtlpriv, (REG_BSSID + idx), val[idx]);
377 break;
378 case HW_VAR_SIFS:
379 rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]);
380 rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]);
381
382 rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]);
383 rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
384
385 if (!mac->ht_enable)
386 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, 0x0e0e);
387 else
388 rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM,
389 *((u16 *)val));
390 break;
391 case HW_VAR_SLOT_TIME: {
392 u8 e_aci;
393
394 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
395 "HW_VAR_SLOT_TIME %x\n", val[0]);
396
397 rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
398
399 for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
400 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
Joe Perches1851cb42014-03-24 13:15:40 -0700401 &e_aci);
Larry Fingera619d1a2014-02-28 15:16:50 -0600402 }
403 break; }
404 case HW_VAR_ACK_PREAMBLE: {
405 u8 reg_tmp;
Joe Perches1851cb42014-03-24 13:15:40 -0700406 u8 short_preamble = (bool)*val;
Larry Fingera619d1a2014-02-28 15:16:50 -0600407 reg_tmp = rtl_read_byte(rtlpriv, REG_TRXPTCL_CTL + 2);
408 if (short_preamble) {
409 reg_tmp |= 0x02;
410 rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
411 } else {
412 reg_tmp &= 0xFD;
413 rtl_write_byte(rtlpriv, REG_TRXPTCL_CTL + 2, reg_tmp);
414 }
415 break; }
416 case HW_VAR_WPA_CONFIG:
Joe Perches1851cb42014-03-24 13:15:40 -0700417 rtl_write_byte(rtlpriv, REG_SECCFG, *val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600418 break;
419 case HW_VAR_AMPDU_MIN_SPACE: {
420 u8 min_spacing_to_set;
421 u8 sec_min_space;
422
Joe Perches1851cb42014-03-24 13:15:40 -0700423 min_spacing_to_set = *val;
Larry Fingera619d1a2014-02-28 15:16:50 -0600424 if (min_spacing_to_set <= 7) {
425 sec_min_space = 0;
426
427 if (min_spacing_to_set < sec_min_space)
428 min_spacing_to_set = sec_min_space;
429
430 mac->min_space_cfg = ((mac->min_space_cfg & 0xf8) |
431 min_spacing_to_set);
432
433 *val = min_spacing_to_set;
434
435 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
436 "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
437 mac->min_space_cfg);
438
439 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
440 mac->min_space_cfg);
441 }
442 break; }
443 case HW_VAR_SHORTGI_DENSITY: {
444 u8 density_to_set;
445
Joe Perches1851cb42014-03-24 13:15:40 -0700446 density_to_set = *val;
Larry Fingera619d1a2014-02-28 15:16:50 -0600447 mac->min_space_cfg |= (density_to_set << 3);
448
449 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
450 "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
451 mac->min_space_cfg);
452
453 rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
454 mac->min_space_cfg);
455 break; }
456 case HW_VAR_AMPDU_FACTOR: {
457 u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9};
458 u8 factor_toset;
459 u8 *p_regtoset = NULL;
460 u8 index = 0;
461
462 p_regtoset = regtoset_normal;
463
Joe Perches1851cb42014-03-24 13:15:40 -0700464 factor_toset = *val;
Larry Fingera619d1a2014-02-28 15:16:50 -0600465 if (factor_toset <= 3) {
466 factor_toset = (1 << (factor_toset + 2));
467 if (factor_toset > 0xf)
468 factor_toset = 0xf;
469
470 for (index = 0; index < 4; index++) {
471 if ((p_regtoset[index] & 0xf0) >
472 (factor_toset << 4))
473 p_regtoset[index] =
474 (p_regtoset[index] & 0x0f) |
475 (factor_toset << 4);
476
477 if ((p_regtoset[index] & 0x0f) > factor_toset)
478 p_regtoset[index] =
479 (p_regtoset[index] & 0xf0) |
480 (factor_toset);
481
482 rtl_write_byte(rtlpriv,
483 (REG_AGGLEN_LMT + index),
484 p_regtoset[index]);
485 }
486 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
487 "Set HW_VAR_AMPDU_FACTOR: %#x\n",
488 factor_toset);
489 }
490 break; }
491 case HW_VAR_AC_PARAM: {
Joe Perches1851cb42014-03-24 13:15:40 -0700492 u8 e_aci = *val;
Larry Fingera619d1a2014-02-28 15:16:50 -0600493 rtl8723_dm_init_edca_turbo(hw);
494
495 if (rtlpci->acm_method != EACMWAY2_SW)
496 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL,
Joe Perches1851cb42014-03-24 13:15:40 -0700497 &e_aci);
Larry Fingera619d1a2014-02-28 15:16:50 -0600498 break; }
499 case HW_VAR_ACM_CTRL: {
Joe Perches1851cb42014-03-24 13:15:40 -0700500 u8 e_aci = *val;
Larry Fingera619d1a2014-02-28 15:16:50 -0600501 union aci_aifsn *p_aci_aifsn =
502 (union aci_aifsn *)(&(mac->ac[0].aifs));
503 u8 acm = p_aci_aifsn->f.acm;
504 u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);
505
506 acm_ctrl =
507 acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1);
508
509 if (acm) {
510 switch (e_aci) {
511 case AC0_BE:
512 acm_ctrl |= ACMHW_BEQEN;
513 break;
514 case AC2_VI:
515 acm_ctrl |= ACMHW_VIQEN;
516 break;
517 case AC3_VO:
518 acm_ctrl |= ACMHW_VOQEN;
519 break;
520 default:
521 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
522 "HW_VAR_ACM_CTRL acm set "
523 "failed: eACI is %d\n", acm);
524 break;
525 }
526 } else {
527 switch (e_aci) {
528 case AC0_BE:
529 acm_ctrl &= (~ACMHW_BEQEN);
530 break;
531 case AC2_VI:
532 acm_ctrl &= (~ACMHW_VIQEN);
533 break;
534 case AC3_VO:
535 acm_ctrl &= (~ACMHW_BEQEN);
536 break;
537 default:
538 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
539 "switch case not process\n");
540 break;
541 }
542 }
543 RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
544 "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] "
545 "Write 0x%X\n", acm_ctrl);
546 rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
547 break; }
548 case HW_VAR_RCR:
549 rtl_write_dword(rtlpriv, REG_RCR, ((u32 *)(val))[0]);
550 rtlpci->receive_config = ((u32 *)(val))[0];
551 break;
552 case HW_VAR_RETRY_LIMIT: {
Joe Perches1851cb42014-03-24 13:15:40 -0700553 u8 retry_limit = *val;
Larry Fingera619d1a2014-02-28 15:16:50 -0600554
555 rtl_write_word(rtlpriv, REG_RL,
556 retry_limit << RETRY_LIMIT_SHORT_SHIFT |
557 retry_limit << RETRY_LIMIT_LONG_SHIFT);
558 break; }
559 case HW_VAR_DUAL_TSF_RST:
560 rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
561 break;
562 case HW_VAR_EFUSE_BYTES:
563 rtlefuse->efuse_usedbytes = *((u16 *)val);
564 break;
565 case HW_VAR_EFUSE_USAGE:
Joe Perches1851cb42014-03-24 13:15:40 -0700566 rtlefuse->efuse_usedpercentage = *val;
Larry Fingera619d1a2014-02-28 15:16:50 -0600567 break;
568 case HW_VAR_IO_CMD:
569 rtl8723be_phy_set_io_cmd(hw, (*(enum io_type *)val));
570 break;
571 case HW_VAR_SET_RPWM: {
572 u8 rpwm_val;
573
574 rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM);
575 udelay(1);
576
577 if (rpwm_val & BIT(7)) {
Joe Perches1851cb42014-03-24 13:15:40 -0700578 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600579 } else {
Joe Perches1851cb42014-03-24 13:15:40 -0700580 rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, *val | BIT(7));
Larry Fingera619d1a2014-02-28 15:16:50 -0600581 }
582 break; }
583 case HW_VAR_H2C_FW_PWRMODE:
Joe Perches1851cb42014-03-24 13:15:40 -0700584 rtl8723be_set_fw_pwrmode_cmd(hw, *val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600585 break;
586 case HW_VAR_FW_PSMODE_STATUS:
587 ppsc->fw_current_inpsmode = *((bool *)val);
588 break;
589 case HW_VAR_RESUME_CLK_ON:
590 _rtl8723be_set_fw_ps_rf_on(hw);
591 break;
592 case HW_VAR_FW_LPS_ACTION: {
593 bool enter_fwlps = *((bool *)val);
594
595 if (enter_fwlps)
596 _rtl8723be_fwlps_enter(hw);
597 else
598 _rtl8723be_fwlps_leave(hw);
599
600 break; }
601 case HW_VAR_H2C_FW_JOINBSSRPT: {
Joe Perches1851cb42014-03-24 13:15:40 -0700602 u8 mstatus = *val;
Larry Fingera619d1a2014-02-28 15:16:50 -0600603 u8 tmp_regcr, tmp_reg422, bcnvalid_reg;
604 u8 count = 0, dlbcn_count = 0;
605 bool recover = false;
606
607 if (mstatus == RT_MEDIA_CONNECT) {
608 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL);
609
610 tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1);
611 rtl_write_byte(rtlpriv, REG_CR + 1,
612 (tmp_regcr | BIT(0)));
613
614 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3));
615 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0);
616
617 tmp_reg422 = rtl_read_byte(rtlpriv,
618 REG_FWHW_TXQ_CTRL + 2);
619 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
620 tmp_reg422 & (~BIT(6)));
621 if (tmp_reg422 & BIT(6))
622 recover = true;
623
624 do {
625 bcnvalid_reg = rtl_read_byte(rtlpriv,
626 REG_TDECTRL + 2);
627 rtl_write_byte(rtlpriv, REG_TDECTRL + 2,
628 (bcnvalid_reg | BIT(0)));
629 _rtl8723be_return_beacon_queue_skb(hw);
630
631 rtl8723be_set_fw_rsvdpagepkt(hw, 0);
632 bcnvalid_reg = rtl_read_byte(rtlpriv,
633 REG_TDECTRL + 2);
634 count = 0;
635 while (!(bcnvalid_reg & BIT(0)) && count < 20) {
636 count++;
637 udelay(10);
638 bcnvalid_reg = rtl_read_byte(rtlpriv,
639 REG_TDECTRL + 2);
640 }
641 dlbcn_count++;
642 } while (!(bcnvalid_reg & BIT(0)) && dlbcn_count < 5);
643
644 if (bcnvalid_reg & BIT(0))
645 rtl_write_byte(rtlpriv, REG_TDECTRL+2, BIT(0));
646
647 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
648 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4));
649
650 if (recover) {
651 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
652 tmp_reg422);
653 }
654 rtl_write_byte(rtlpriv, REG_CR + 1,
655 (tmp_regcr & ~(BIT(0))));
656 }
Joe Perches1851cb42014-03-24 13:15:40 -0700657 rtl8723be_set_fw_joinbss_report_cmd(hw, *val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600658 break; }
659 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
Joe Perches1851cb42014-03-24 13:15:40 -0700660 rtl8723be_set_p2p_ps_offload_cmd(hw, *val);
Larry Fingera619d1a2014-02-28 15:16:50 -0600661 break;
662 case HW_VAR_AID: {
663 u16 u2btmp;
664 u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
665 u2btmp &= 0xC000;
666 rtl_write_word(rtlpriv, REG_BCN_PSR_RPT,
667 (u2btmp | mac->assoc_id));
668 break; }
669 case HW_VAR_CORRECT_TSF: {
Joe Perches1851cb42014-03-24 13:15:40 -0700670 u8 btype_ibss = *val;
Larry Fingera619d1a2014-02-28 15:16:50 -0600671
672 if (btype_ibss)
673 _rtl8723be_stop_tx_beacon(hw);
674
675 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(3));
676
677 rtl_write_dword(rtlpriv, REG_TSFTR,
678 (u32) (mac->tsf & 0xffffffff));
679 rtl_write_dword(rtlpriv, REG_TSFTR + 4,
680 (u32) ((mac->tsf >> 32) & 0xffffffff));
681
682 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
683
684 if (btype_ibss)
685 _rtl8723be_resume_tx_beacon(hw);
686 break; }
687 case HW_VAR_KEEP_ALIVE: {
688 u8 array[2];
689 array[0] = 0xff;
Joe Perches1851cb42014-03-24 13:15:40 -0700690 array[1] = *val;
Larry Fingera619d1a2014-02-28 15:16:50 -0600691 rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_KEEP_ALIVE_CTRL,
692 2, array);
693 break; }
694 default:
695 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
696 "switch case not process %x\n",
697 variable);
698 break;
699 }
700}
701
702static bool _rtl8723be_llt_write(struct ieee80211_hw *hw, u32 address, u32 data)
703{
704 struct rtl_priv *rtlpriv = rtl_priv(hw);
705 bool status = true;
706 int count = 0;
707 u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) |
708 _LLT_OP(_LLT_WRITE_ACCESS);
709
710 rtl_write_dword(rtlpriv, REG_LLT_INIT, value);
711
712 do {
713 value = rtl_read_dword(rtlpriv, REG_LLT_INIT);
714 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value))
715 break;
716
717 if (count > POLLING_LLT_THRESHOLD) {
718 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
719 "Failed to polling write LLT done at "
720 "address %d!\n", address);
721 status = false;
722 break;
723 }
724 } while (++count);
725
726 return status;
727}
728
729static bool _rtl8723be_llt_table_init(struct ieee80211_hw *hw)
730{
731 struct rtl_priv *rtlpriv = rtl_priv(hw);
732 unsigned short i;
733 u8 txpktbuf_bndy;
734 u8 maxpage;
735 bool status;
736
737 maxpage = 255;
738 txpktbuf_bndy = 245;
739
740 rtl_write_dword(rtlpriv, REG_TRXFF_BNDY,
741 (0x27FF0000 | txpktbuf_bndy));
742 rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy);
743
744 rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
745 rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
746
747 rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy);
748 rtl_write_byte(rtlpriv, REG_PBP, 0x31);
749 rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4);
750
751 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
752 status = _rtl8723be_llt_write(hw, i, i + 1);
753 if (!status)
754 return status;
755 }
756 status = _rtl8723be_llt_write(hw, (txpktbuf_bndy - 1), 0xFF);
757
758 if (!status)
759 return status;
760
761 for (i = txpktbuf_bndy; i < maxpage; i++) {
762 status = _rtl8723be_llt_write(hw, i, (i + 1));
763 if (!status)
764 return status;
765 }
766 status = _rtl8723be_llt_write(hw, maxpage, txpktbuf_bndy);
767 if (!status)
768 return status;
769
770 rtl_write_dword(rtlpriv, REG_RQPN, 0x80e40808);
771 rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x00);
772
773 return true;
774}
775
776static void _rtl8723be_gen_refresh_led_state(struct ieee80211_hw *hw)
777{
778 struct rtl_priv *rtlpriv = rtl_priv(hw);
779 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
780 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
781 struct rtl_led *pled0 = &(pcipriv->ledctl.sw_led0);
782
783 if (rtlpriv->rtlhal.up_first_time)
784 return;
785
786 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
787 rtl8723be_sw_led_on(hw, pled0);
788 else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT)
789 rtl8723be_sw_led_on(hw, pled0);
790 else
791 rtl8723be_sw_led_off(hw, pled0);
792}
793
794static bool _rtl8723be_init_mac(struct ieee80211_hw *hw)
795{
796 struct rtl_priv *rtlpriv = rtl_priv(hw);
797 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
798
799 unsigned char bytetmp;
800 unsigned short wordtmp;
801 u16 retry = 0;
802 bool mac_func_enable;
803
804 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
805
806 /*Auto Power Down to CHIP-off State*/
807 bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) & (~BIT(7));
808 rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp);
809
810 bytetmp = rtl_read_byte(rtlpriv, REG_CR);
811 if (bytetmp == 0xFF)
812 mac_func_enable = true;
813 else
814 mac_func_enable = false;
815
816 /* HW Power on sequence */
Larry Finger25b13db2014-03-04 16:53:48 -0600817 if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK,
818 PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,
819 RTL8723_NIC_ENABLE_FLOW)) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600820 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
821 "init MAC Fail as power on failure\n");
822 return false;
823 }
824 bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO) | BIT(4);
825 rtl_write_byte(rtlpriv, REG_APS_FSMCO, bytetmp);
826
827 bytetmp = rtl_read_byte(rtlpriv, REG_CR);
828 bytetmp = 0xff;
829 rtl_write_byte(rtlpriv, REG_CR, bytetmp);
830 mdelay(2);
831
832 bytetmp = rtl_read_byte(rtlpriv, REG_HWSEQ_CTRL);
833 bytetmp |= 0x7f;
834 rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, bytetmp);
835 mdelay(2);
836
837 bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CFG + 3);
838 if (bytetmp & BIT(0)) {
839 bytetmp = rtl_read_byte(rtlpriv, 0x7c);
840 bytetmp |= BIT(6);
841 rtl_write_byte(rtlpriv, 0x7c, bytetmp);
842 }
843 bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CLKR);
844 bytetmp |= BIT(3);
845 rtl_write_byte(rtlpriv, REG_SYS_CLKR, bytetmp);
846 bytetmp = rtl_read_byte(rtlpriv, REG_GPIO_MUXCFG + 1);
847 bytetmp &= ~BIT(4);
848 rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG + 1, bytetmp);
849
850 bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG+3);
851 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+3, bytetmp | 0x77);
852
853 rtl_write_word(rtlpriv, REG_CR, 0x2ff);
854
855 if (!mac_func_enable) {
856 if (!_rtl8723be_llt_table_init(hw))
857 return false;
858 }
859 rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
860 rtl_write_dword(rtlpriv, REG_HISRE, 0xffffffff);
861
862 /* Enable FW Beamformer Interrupt */
863 bytetmp = rtl_read_byte(rtlpriv, REG_FWIMR + 3);
864 rtl_write_byte(rtlpriv, REG_FWIMR + 3, bytetmp | BIT(6));
865
866 wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL);
867 wordtmp &= 0xf;
868 wordtmp |= 0xF5B1;
869 rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp);
870
871 rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F);
872 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
873 rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xFFFF);
874 rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config);
875
876 rtl_write_byte(rtlpriv, 0x4d0, 0x0);
877
878 rtl_write_dword(rtlpriv, REG_BCNQ_DESA,
879 ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) &
880 DMA_BIT_MASK(32));
881 rtl_write_dword(rtlpriv, REG_MGQ_DESA,
882 (u64) rtlpci->tx_ring[MGNT_QUEUE].dma &
883 DMA_BIT_MASK(32));
884 rtl_write_dword(rtlpriv, REG_VOQ_DESA,
885 (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32));
886 rtl_write_dword(rtlpriv, REG_VIQ_DESA,
887 (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32));
888 rtl_write_dword(rtlpriv, REG_BEQ_DESA,
889 (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32));
890 rtl_write_dword(rtlpriv, REG_BKQ_DESA,
891 (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32));
892 rtl_write_dword(rtlpriv, REG_HQ_DESA,
893 (u64) rtlpci->tx_ring[HIGH_QUEUE].dma &
894 DMA_BIT_MASK(32));
895 rtl_write_dword(rtlpriv, REG_RX_DESA,
896 (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma &
897 DMA_BIT_MASK(32));
898
899 bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 3);
900 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, bytetmp | 0x77);
901
902 rtl_write_dword(rtlpriv, REG_INT_MIG, 0);
903
904 bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL);
905 rtl_write_byte(rtlpriv, REG_APSD_CTRL, bytetmp & ~BIT(6));
906
907 rtl_write_byte(rtlpriv, REG_SECONDARY_CCA_CTRL, 0x3);
908
909 do {
910 retry++;
911 bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL);
912 } while ((retry < 200) && (bytetmp & BIT(7)));
913
914 _rtl8723be_gen_refresh_led_state(hw);
915
916 rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0);
917
918 bytetmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
919 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, bytetmp & ~BIT(2));
920
921 return true;
922}
923
924static void _rtl8723be_hw_configure(struct ieee80211_hw *hw)
925{
926 struct rtl_priv *rtlpriv = rtl_priv(hw);
927 u8 reg_bw_opmode;
928 u32 reg_ratr, reg_prsr;
929
930 reg_bw_opmode = BW_OPMODE_20MHZ;
931 reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG |
932 RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS;
933 reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
934
935 rtl_write_dword(rtlpriv, REG_RRSR, reg_prsr);
936 rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF);
937}
938
939static void _rtl8723be_enable_aspm_back_door(struct ieee80211_hw *hw)
940{
941 struct rtl_priv *rtlpriv = rtl_priv(hw);
942 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
943
944 rtl_write_byte(rtlpriv, 0x34b, 0x93);
945 rtl_write_word(rtlpriv, 0x350, 0x870c);
946 rtl_write_byte(rtlpriv, 0x352, 0x1);
947
948 if (ppsc->support_backdoor)
949 rtl_write_byte(rtlpriv, 0x349, 0x1b);
950 else
951 rtl_write_byte(rtlpriv, 0x349, 0x03);
952
953 rtl_write_word(rtlpriv, 0x350, 0x2718);
954 rtl_write_byte(rtlpriv, 0x352, 0x1);
955}
956
957void rtl8723be_enable_hw_security_config(struct ieee80211_hw *hw)
958{
959 struct rtl_priv *rtlpriv = rtl_priv(hw);
960 u8 sec_reg_value;
961
962 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
963 "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
964 rtlpriv->sec.pairwise_enc_algorithm,
965 rtlpriv->sec.group_enc_algorithm);
966
967 if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
968 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
969 "not open hw encryption\n");
970 return;
971 }
972 sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE;
973
974 if (rtlpriv->sec.use_defaultkey) {
975 sec_reg_value |= SCR_TXUSEDK;
976 sec_reg_value |= SCR_RXUSEDK;
977 }
978 sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
979
980 rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
981
982 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "The SECR-value %x\n",
983 sec_reg_value);
984
985 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
986}
987
988int rtl8723be_hw_init(struct ieee80211_hw *hw)
989{
990 struct rtl_priv *rtlpriv = rtl_priv(hw);
991 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
992 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
993 struct rtl_phy *rtlphy = &(rtlpriv->phy);
994 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
995 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
996 bool rtstatus = true;
997 int err;
998 u8 tmp_u1b;
999 unsigned long flags;
1000
1001 /* reenable interrupts to not interfere with other devices */
1002 local_save_flags(flags);
1003 local_irq_enable();
1004
1005 rtlpriv->rtlhal.being_init_adapter = true;
1006 rtlpriv->intf_ops->disable_aspm(hw);
1007 rtstatus = _rtl8723be_init_mac(hw);
1008 if (!rtstatus) {
1009 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n");
1010 err = 1;
1011 goto exit;
1012 }
1013 tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CFG);
1014 tmp_u1b &= 0x7F;
1015 rtl_write_byte(rtlpriv, REG_SYS_CFG, tmp_u1b);
1016
1017 err = rtl8723_download_fw(hw, true);
1018 if (err) {
1019 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1020 "Failed to download FW. Init HW without FW now..\n");
1021 err = 1;
1022 rtlhal->fw_ready = false;
1023 goto exit;
1024 } else {
1025 rtlhal->fw_ready = true;
1026 }
1027 rtlhal->last_hmeboxnum = 0;
1028 rtl8723be_phy_mac_config(hw);
1029 /* because last function modify RCR, so we update
1030 * rcr var here, or TP will unstable for receive_config
1031 * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx
1032 * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252
1033 */
1034 rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR);
1035 rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
1036 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
1037
1038 rtl8723be_phy_bb_config(hw);
1039 rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
1040 rtl8723be_phy_rf_config(hw);
1041
1042 rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
1043 RF_CHNLBW, RFREG_OFFSET_MASK);
1044 rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1,
1045 RF_CHNLBW, RFREG_OFFSET_MASK);
1046 rtlphy->rfreg_chnlval[0] &= 0xFFF03FF;
1047 rtlphy->rfreg_chnlval[0] |= (BIT(10) | BIT(11));
1048
1049 rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
1050 rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
1051 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
1052 _rtl8723be_hw_configure(hw);
1053 rtl_cam_reset_all_entry(hw);
1054 rtl8723be_enable_hw_security_config(hw);
1055
1056 ppsc->rfpwr_state = ERFON;
1057
1058 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
1059 _rtl8723be_enable_aspm_back_door(hw);
1060 rtlpriv->intf_ops->enable_aspm(hw);
1061
1062 rtl8723be_bt_hw_init(hw);
1063
1064 rtl_set_bbreg(hw, 0x64, BIT(20), 0);
1065 rtl_set_bbreg(hw, 0x64, BIT(24), 0);
1066
1067 rtl_set_bbreg(hw, 0x40, BIT(4), 0);
1068 rtl_set_bbreg(hw, 0x40, BIT(3), 1);
1069
1070 rtl_set_bbreg(hw, 0x944, BIT(0)|BIT(1), 0x3);
1071 rtl_set_bbreg(hw, 0x930, 0xff, 0x77);
1072
1073 rtl_set_bbreg(hw, 0x38, BIT(11), 0x1);
1074
1075 rtl_set_bbreg(hw, 0xb2c, 0xffffffff, 0x80000000);
1076
1077 if (ppsc->rfpwr_state == ERFON) {
1078 rtl8723be_dm_check_txpower_tracking(hw);
1079 rtl8723be_phy_lc_calibrate(hw);
1080 }
1081 tmp_u1b = efuse_read_1byte(hw, 0x1FA);
1082 if (!(tmp_u1b & BIT(0))) {
1083 rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05);
1084 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path A\n");
1085 }
1086 if (!(tmp_u1b & BIT(4))) {
1087 tmp_u1b = rtl_read_byte(rtlpriv, 0x16);
1088 tmp_u1b &= 0x0F;
1089 rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80);
1090 udelay(10);
1091 rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90);
1092 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n");
1093 }
1094 rtl8723be_dm_init(hw);
1095exit:
1096 local_irq_restore(flags);
1097 rtlpriv->rtlhal.being_init_adapter = false;
1098 return err;
1099}
1100
1101static enum version_8723e _rtl8723be_read_chip_version(struct ieee80211_hw *hw)
1102{
1103 struct rtl_priv *rtlpriv = rtl_priv(hw);
1104 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1105 enum version_8723e version = VERSION_UNKNOWN;
1106 u8 count = 0;
1107 u8 value8;
1108 u32 value32;
1109
1110 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0);
1111
1112 value8 = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 2);
1113 rtl_write_byte(rtlpriv, REG_APS_FSMCO + 2, value8 | BIT(0));
1114
1115 value8 = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1);
1116 rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, value8 | BIT(0));
1117
1118 value8 = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1);
1119 while (((value8 & BIT(0))) && (count++ < 100)) {
1120 udelay(10);
1121 value8 = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1);
1122 }
1123 count = 0;
1124 value8 = rtl_read_byte(rtlpriv, REG_ROM_VERSION);
1125 while ((value8 == 0) && (count++ < 50)) {
1126 value8 = rtl_read_byte(rtlpriv, REG_ROM_VERSION);
1127 mdelay(1);
1128 }
1129 value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG1);
1130 if ((value32 & (CHIP_8723B)) != CHIP_8723B)
1131 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "unkown chip version\n");
1132 else
1133 version = (enum version_8723e) VERSION_TEST_CHIP_1T1R_8723B;
1134
1135 rtlphy->rf_type = RF_1T1R;
1136
1137 value8 = rtl_read_byte(rtlpriv, REG_ROM_VERSION);
1138 if (value8 >= 0x02)
1139 version |= BIT(3);
1140 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1141 "Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ?
1142 "RF_2T2R" : "RF_1T1R");
1143
1144 return version;
1145}
1146
1147static int _rtl8723be_set_media_status(struct ieee80211_hw *hw,
1148 enum nl80211_iftype type)
1149{
1150 struct rtl_priv *rtlpriv = rtl_priv(hw);
1151 u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc;
1152 enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
1153
1154 rtl_write_dword(rtlpriv, REG_BCN_CTRL, 0);
1155 RT_TRACE(rtlpriv, COMP_BEACON, DBG_LOUD,
1156 "clear 0x550 when set HW_VAR_MEDIA_STATUS\n");
1157
1158 if (type == NL80211_IFTYPE_UNSPECIFIED ||
1159 type == NL80211_IFTYPE_STATION) {
1160 _rtl8723be_stop_tx_beacon(hw);
1161 _rtl8723be_enable_bcn_sub_func(hw);
1162 } else if (type == NL80211_IFTYPE_ADHOC || type == NL80211_IFTYPE_AP) {
1163 _rtl8723be_resume_tx_beacon(hw);
1164 _rtl8723be_disable_bcn_sub_func(hw);
1165 } else {
1166 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1167 "Set HW_VAR_MEDIA_STATUS: "
1168 "No such media status(%x).\n", type);
1169 }
1170 switch (type) {
1171 case NL80211_IFTYPE_UNSPECIFIED:
1172 bt_msr |= MSR_NOLINK;
1173 ledaction = LED_CTL_LINK;
1174 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1175 "Set Network type to NO LINK!\n");
1176 break;
1177 case NL80211_IFTYPE_ADHOC:
1178 bt_msr |= MSR_ADHOC;
1179 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1180 "Set Network type to Ad Hoc!\n");
1181 break;
1182 case NL80211_IFTYPE_STATION:
1183 bt_msr |= MSR_INFRA;
1184 ledaction = LED_CTL_LINK;
1185 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1186 "Set Network type to STA!\n");
1187 break;
1188 case NL80211_IFTYPE_AP:
1189 bt_msr |= MSR_AP;
1190 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1191 "Set Network type to AP!\n");
1192 break;
1193 default:
1194 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1195 "Network type %d not support!\n", type);
1196 return 1;
1197 }
1198 rtl_write_byte(rtlpriv, (MSR), bt_msr);
1199 rtlpriv->cfg->ops->led_control(hw, ledaction);
1200 if ((bt_msr & 0x03) == MSR_AP)
1201 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1202 else
1203 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
1204 return 0;
1205}
1206
1207void rtl8723be_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1208{
1209 struct rtl_priv *rtlpriv = rtl_priv(hw);
1210 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1211 u32 reg_rcr = rtlpci->receive_config;
1212
1213 if (rtlpriv->psc.rfpwr_state != ERFON)
1214 return;
1215
1216 if (check_bssid) {
1217 reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1218 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1219 (u8 *)(&reg_rcr));
1220 _rtl8723be_set_bcn_ctrl_reg(hw, 0, BIT(4));
1221 } else if (!check_bssid) {
1222 reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
1223 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(4), 0);
1224 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1225 (u8 *)(&reg_rcr));
1226 }
1227}
1228
1229int rtl8723be_set_network_type(struct ieee80211_hw *hw,
1230 enum nl80211_iftype type)
1231{
1232 struct rtl_priv *rtlpriv = rtl_priv(hw);
1233
1234 if (_rtl8723be_set_media_status(hw, type))
1235 return -EOPNOTSUPP;
1236
1237 if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
1238 if (type != NL80211_IFTYPE_AP)
1239 rtl8723be_set_check_bssid(hw, true);
1240 } else {
1241 rtl8723be_set_check_bssid(hw, false);
1242 }
1243 return 0;
1244}
1245
1246/* don't set REG_EDCA_BE_PARAM here
1247 * because mac80211 will send pkt when scan
1248 */
1249void rtl8723be_set_qos(struct ieee80211_hw *hw, int aci)
1250{
1251 struct rtl_priv *rtlpriv = rtl_priv(hw);
1252 rtl8723_dm_init_edca_turbo(hw);
1253 switch (aci) {
1254 case AC1_BK:
1255 rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f);
1256 break;
1257 case AC0_BE:
1258 break;
1259 case AC2_VI:
1260 rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322);
1261 break;
1262 case AC3_VO:
1263 rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
1264 break;
1265 default:
1266 RT_ASSERT(false, "invalid aci: %d !\n", aci);
1267 break;
1268 }
1269}
1270
1271void rtl8723be_enable_interrupt(struct ieee80211_hw *hw)
1272{
1273 struct rtl_priv *rtlpriv = rtl_priv(hw);
1274 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1275
1276 rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF);
1277 rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF);
1278 rtlpci->irq_enabled = true;
1279 /* there are some C2H CMDs have been sent
1280 * before system interrupt is enabled, e.g., C2H, CPWM.
1281 * So we need to clear all C2H events that FW has notified,
1282 * otherwise FW won't schedule any commands anymore.
1283 */
1284 rtl_write_byte(rtlpriv, REG_C2HEVT_CLEAR, 0);
1285 /*enable system interrupt*/
1286 rtl_write_dword(rtlpriv, REG_HSIMR, rtlpci->sys_irq_mask & 0xFFFFFFFF);
1287}
1288
1289void rtl8723be_disable_interrupt(struct ieee80211_hw *hw)
1290{
1291 struct rtl_priv *rtlpriv = rtl_priv(hw);
1292 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1293
1294 rtl_write_dword(rtlpriv, REG_HIMR, IMR_DISABLED);
1295 rtl_write_dword(rtlpriv, REG_HIMRE, IMR_DISABLED);
1296 rtlpci->irq_enabled = false;
1297 synchronize_irq(rtlpci->pdev->irq);
1298}
1299
1300static void _rtl8723be_poweroff_adapter(struct ieee80211_hw *hw)
1301{
1302 struct rtl_priv *rtlpriv = rtl_priv(hw);
1303 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1304 u8 u1b_tmp;
1305
1306 /* Combo (PCIe + USB) Card and PCIe-MF Card */
1307 /* 1. Run LPS WL RFOFF flow */
Larry Finger25b13db2014-03-04 16:53:48 -06001308 rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1309 PWR_INTF_PCI_MSK, RTL8723_NIC_LPS_ENTER_FLOW);
Larry Fingera619d1a2014-02-28 15:16:50 -06001310
1311 /* 2. 0x1F[7:0] = 0 */
1312 /* turn off RF */
1313 rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00);
1314 if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) &&
1315 rtlhal->fw_ready)
1316 rtl8723be_firmware_selfreset(hw);
1317
1318 /* Reset MCU. Suggested by Filen. */
1319 u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1320 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2))));
1321
1322 /* g. MCUFWDL 0x80[1:0]= 0 */
1323 /* reset MCU ready status */
1324 rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
1325
1326 /* HW card disable configuration. */
Larry Finger25b13db2014-03-04 16:53:48 -06001327 rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1328 PWR_INTF_PCI_MSK, RTL8723_NIC_DISABLE_FLOW);
Larry Fingera619d1a2014-02-28 15:16:50 -06001329
1330 /* Reset MCU IO Wrapper */
1331 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1332 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0))));
1333 u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1);
1334 rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1b_tmp | BIT(0));
1335
1336 /* 7. RSV_CTRL 0x1C[7:0] = 0x0E */
1337 /* lock ISO/CLK/Power control register */
1338 rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e);
1339}
1340
1341void rtl8723be_card_disable(struct ieee80211_hw *hw)
1342{
1343 struct rtl_priv *rtlpriv = rtl_priv(hw);
1344 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1345 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1346 enum nl80211_iftype opmode;
1347
1348 mac->link_state = MAC80211_NOLINK;
1349 opmode = NL80211_IFTYPE_UNSPECIFIED;
1350 _rtl8723be_set_media_status(hw, opmode);
1351 if (rtlpriv->rtlhal.driver_is_goingto_unload ||
1352 ppsc->rfoff_reason > RF_CHANGE_BY_PS)
1353 rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
1354 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1355 _rtl8723be_poweroff_adapter(hw);
1356
1357 /* after power off we should do iqk again */
1358 rtlpriv->phy.iqk_initialized = false;
1359}
1360
1361void rtl8723be_interrupt_recognized(struct ieee80211_hw *hw,
1362 u32 *p_inta, u32 *p_intb)
1363{
1364 struct rtl_priv *rtlpriv = rtl_priv(hw);
1365 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1366
1367 *p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0];
1368 rtl_write_dword(rtlpriv, ISR, *p_inta);
1369
1370 *p_intb = rtl_read_dword(rtlpriv, REG_HISRE) &
1371 rtlpci->irq_mask[1];
1372 rtl_write_dword(rtlpriv, REG_HISRE, *p_intb);
1373}
1374
1375void rtl8723be_set_beacon_related_registers(struct ieee80211_hw *hw)
1376{
1377 struct rtl_priv *rtlpriv = rtl_priv(hw);
1378 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1379 u16 bcn_interval, atim_window;
1380
1381 bcn_interval = mac->beacon_interval;
1382 atim_window = 2; /*FIX MERGE */
1383 rtl8723be_disable_interrupt(hw);
1384 rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
1385 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1386 rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f);
1387 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18);
1388 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18);
1389 rtl_write_byte(rtlpriv, 0x606, 0x30);
1390 rtl8723be_enable_interrupt(hw);
1391}
1392
1393void rtl8723be_set_beacon_interval(struct ieee80211_hw *hw)
1394{
1395 struct rtl_priv *rtlpriv = rtl_priv(hw);
1396 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1397 u16 bcn_interval = mac->beacon_interval;
1398
1399 RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG,
1400 "beacon_interval:%d\n", bcn_interval);
1401 rtl8723be_disable_interrupt(hw);
1402 rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1403 rtl8723be_enable_interrupt(hw);
1404}
1405
1406void rtl8723be_update_interrupt_mask(struct ieee80211_hw *hw,
1407 u32 add_msr, u32 rm_msr)
1408{
1409 struct rtl_priv *rtlpriv = rtl_priv(hw);
1410 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1411
1412 RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
1413 "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr);
1414
1415 if (add_msr)
1416 rtlpci->irq_mask[0] |= add_msr;
1417 if (rm_msr)
1418 rtlpci->irq_mask[0] &= (~rm_msr);
1419 rtl8723be_disable_interrupt(hw);
1420 rtl8723be_enable_interrupt(hw);
1421}
1422
1423static u8 _rtl8723be_get_chnl_group(u8 chnl)
1424{
1425 u8 group;
1426
1427 if (chnl < 3)
1428 group = 0;
1429 else if (chnl < 9)
1430 group = 1;
1431 else
1432 group = 2;
1433 return group;
1434}
1435
1436static void _rtl8723be_read_power_value_fromprom(struct ieee80211_hw *hw,
1437 struct txpower_info_2g *pw2g,
1438 struct txpower_info_5g *pw5g,
1439 bool autoload_fail, u8 *hwinfo)
1440{
1441 struct rtl_priv *rtlpriv = rtl_priv(hw);
1442 u32 path, addr = EEPROM_TX_PWR_INX, group, cnt = 0;
1443
1444 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1445 "hal_ReadPowerValueFromPROM8723BE(): "
1446 "PROMContent[0x%x]= 0x%x\n",
1447 (addr + 1), hwinfo[addr + 1]);
1448 if (0xFF == hwinfo[addr + 1]) /*YJ, add, 120316*/
1449 autoload_fail = true;
1450
1451 if (autoload_fail) {
1452 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1453 "auto load fail : Use Default value!\n");
1454 for (path = 0; path < MAX_RF_PATH; path++) {
1455 /* 2.4G default value */
1456 for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
1457 pw2g->index_cck_base[path][group] = 0x2D;
1458 pw2g->index_bw40_base[path][group] = 0x2D;
1459 }
1460 for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1461 if (cnt == 0) {
1462 pw2g->bw20_diff[path][0] = 0x02;
1463 pw2g->ofdm_diff[path][0] = 0x04;
1464 } else {
1465 pw2g->bw20_diff[path][cnt] = 0xFE;
1466 pw2g->bw40_diff[path][cnt] = 0xFE;
1467 pw2g->cck_diff[path][cnt] = 0xFE;
1468 pw2g->ofdm_diff[path][cnt] = 0xFE;
1469 }
1470 }
1471 }
1472 return;
1473 }
1474 for (path = 0; path < MAX_RF_PATH; path++) {
1475 /*2.4G default value*/
1476 for (group = 0; group < MAX_CHNL_GROUP_24G; group++) {
1477 pw2g->index_cck_base[path][group] = hwinfo[addr++];
1478 if (pw2g->index_cck_base[path][group] == 0xFF)
1479 pw2g->index_cck_base[path][group] = 0x2D;
1480 }
1481 for (group = 0; group < MAX_CHNL_GROUP_24G - 1; group++) {
1482 pw2g->index_bw40_base[path][group] = hwinfo[addr++];
1483 if (pw2g->index_bw40_base[path][group] == 0xFF)
1484 pw2g->index_bw40_base[path][group] = 0x2D;
1485 }
1486 for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1487 if (cnt == 0) {
1488 pw2g->bw40_diff[path][cnt] = 0;
1489 if (hwinfo[addr] == 0xFF) {
1490 pw2g->bw20_diff[path][cnt] = 0x02;
1491 } else {
1492 pw2g->bw20_diff[path][cnt] =
1493 (hwinfo[addr] & 0xf0) >> 4;
1494 /*bit sign number to 8 bit sign number*/
1495 if (pw2g->bw20_diff[path][cnt] & BIT(3))
1496 pw2g->bw20_diff[path][cnt] |= 0xF0;
1497 }
1498 if (hwinfo[addr] == 0xFF) {
1499 pw2g->ofdm_diff[path][cnt] = 0x04;
1500 } else {
1501 pw2g->ofdm_diff[path][cnt] =
1502 (hwinfo[addr] & 0x0f);
1503 /*bit sign number to 8 bit sign number*/
1504 if (pw2g->ofdm_diff[path][cnt] & BIT(3))
1505 pw2g->ofdm_diff[path][cnt] |=
1506 0xF0;
1507 }
1508 pw2g->cck_diff[path][cnt] = 0;
1509 addr++;
1510 } else {
1511 if (hwinfo[addr] == 0xFF) {
1512 pw2g->bw40_diff[path][cnt] = 0xFE;
1513 } else {
1514 pw2g->bw40_diff[path][cnt] =
1515 (hwinfo[addr] & 0xf0) >> 4;
1516 if (pw2g->bw40_diff[path][cnt] & BIT(3))
1517 pw2g->bw40_diff[path][cnt] |=
1518 0xF0;
1519 }
1520 if (hwinfo[addr] == 0xFF) {
1521 pw2g->bw20_diff[path][cnt] = 0xFE;
1522 } else {
1523 pw2g->bw20_diff[path][cnt] =
1524 (hwinfo[addr] & 0x0f);
1525 if (pw2g->bw20_diff[path][cnt] & BIT(3))
1526 pw2g->bw20_diff[path][cnt] |=
1527 0xF0;
1528 }
1529 addr++;
1530
1531 if (hwinfo[addr] == 0xFF) {
1532 pw2g->ofdm_diff[path][cnt] = 0xFE;
1533 } else {
1534 pw2g->ofdm_diff[path][cnt] =
1535 (hwinfo[addr] & 0xf0) >> 4;
1536 if (pw2g->ofdm_diff[path][cnt] & BIT(3))
1537 pw2g->ofdm_diff[path][cnt] |=
1538 0xF0;
1539 }
1540 if (hwinfo[addr] == 0xFF) {
1541 pw2g->cck_diff[path][cnt] = 0xFE;
1542 } else {
1543 pw2g->cck_diff[path][cnt] =
1544 (hwinfo[addr] & 0x0f);
1545 if (pw2g->cck_diff[path][cnt] & BIT(3))
1546 pw2g->cck_diff[path][cnt] |=
1547 0xF0;
1548 }
1549 addr++;
1550 }
1551 }
1552 /*5G default value*/
1553 for (group = 0; group < MAX_CHNL_GROUP_5G; group++) {
1554 pw5g->index_bw40_base[path][group] = hwinfo[addr++];
1555 if (pw5g->index_bw40_base[path][group] == 0xFF)
1556 pw5g->index_bw40_base[path][group] = 0xFE;
1557 }
1558 for (cnt = 0; cnt < MAX_TX_COUNT; cnt++) {
1559 if (cnt == 0) {
1560 pw5g->bw40_diff[path][cnt] = 0;
1561
1562 if (hwinfo[addr] == 0xFF) {
1563 pw5g->bw20_diff[path][cnt] = 0;
1564 } else {
1565 pw5g->bw20_diff[path][0] =
1566 (hwinfo[addr] & 0xf0) >> 4;
1567 if (pw5g->bw20_diff[path][cnt] & BIT(3))
1568 pw5g->bw20_diff[path][cnt] |=
1569 0xF0;
1570 }
1571 if (hwinfo[addr] == 0xFF) {
1572 pw5g->ofdm_diff[path][cnt] = 0x04;
1573 } else {
1574 pw5g->ofdm_diff[path][0] =
1575 (hwinfo[addr] & 0x0f);
1576 if (pw5g->ofdm_diff[path][cnt] & BIT(3))
1577 pw5g->ofdm_diff[path][cnt] |=
1578 0xF0;
1579 }
1580 addr++;
1581 } else {
1582 if (hwinfo[addr] == 0xFF) {
1583 pw5g->bw40_diff[path][cnt] = 0xFE;
1584 } else {
1585 pw5g->bw40_diff[path][cnt] =
1586 (hwinfo[addr] & 0xf0) >> 4;
1587 if (pw5g->bw40_diff[path][cnt] & BIT(3))
1588 pw5g->bw40_diff[path][cnt] |= 0xF0;
1589 }
1590 if (hwinfo[addr] == 0xFF) {
1591 pw5g->bw20_diff[path][cnt] = 0xFE;
1592 } else {
1593 pw5g->bw20_diff[path][cnt] =
1594 (hwinfo[addr] & 0x0f);
1595 if (pw5g->bw20_diff[path][cnt] & BIT(3))
1596 pw5g->bw20_diff[path][cnt] |= 0xF0;
1597 }
1598 addr++;
1599 }
1600 }
1601 if (hwinfo[addr] == 0xFF) {
1602 pw5g->ofdm_diff[path][1] = 0xFE;
1603 pw5g->ofdm_diff[path][2] = 0xFE;
1604 } else {
1605 pw5g->ofdm_diff[path][1] = (hwinfo[addr] & 0xf0) >> 4;
1606 pw5g->ofdm_diff[path][2] = (hwinfo[addr] & 0x0f);
1607 }
1608 addr++;
1609
1610 if (hwinfo[addr] == 0xFF)
1611 pw5g->ofdm_diff[path][3] = 0xFE;
1612 else
1613 pw5g->ofdm_diff[path][3] = (hwinfo[addr] & 0x0f);
1614 addr++;
1615
1616 for (cnt = 1; cnt < MAX_TX_COUNT; cnt++) {
1617 if (pw5g->ofdm_diff[path][cnt] == 0xFF)
1618 pw5g->ofdm_diff[path][cnt] = 0xFE;
1619 else if (pw5g->ofdm_diff[path][cnt] & BIT(3))
1620 pw5g->ofdm_diff[path][cnt] |= 0xF0;
1621 }
1622 }
1623}
1624
1625static void _rtl8723be_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
1626 bool autoload_fail,
1627 u8 *hwinfo)
1628{
1629 struct rtl_priv *rtlpriv = rtl_priv(hw);
1630 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1631 struct txpower_info_2g pw2g;
1632 struct txpower_info_5g pw5g;
1633 u8 rf_path, index;
1634 u8 i;
1635
1636 _rtl8723be_read_power_value_fromprom(hw, &pw2g, &pw5g, autoload_fail,
1637 hwinfo);
1638
1639 for (rf_path = 0; rf_path < 2; rf_path++) {
1640 for (i = 0; i < 14; i++) {
1641 index = _rtl8723be_get_chnl_group(i+1);
1642
1643 rtlefuse->txpwrlevel_cck[rf_path][i] =
1644 pw2g.index_cck_base[rf_path][index];
1645 rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
1646 pw2g.index_bw40_base[rf_path][index];
1647 }
1648 for (i = 0; i < MAX_TX_COUNT; i++) {
1649 rtlefuse->txpwr_ht20diff[rf_path][i] =
1650 pw2g.bw20_diff[rf_path][i];
1651 rtlefuse->txpwr_ht40diff[rf_path][i] =
1652 pw2g.bw40_diff[rf_path][i];
1653 rtlefuse->txpwr_legacyhtdiff[rf_path][i] =
1654 pw2g.ofdm_diff[rf_path][i];
1655 }
1656 for (i = 0; i < 14; i++) {
1657 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1658 "RF(%d)-Ch(%d) [CCK / HT40_1S ] = "
1659 "[0x%x / 0x%x ]\n", rf_path, i,
1660 rtlefuse->txpwrlevel_cck[rf_path][i],
1661 rtlefuse->txpwrlevel_ht40_1s[rf_path][i]);
1662 }
1663 }
1664 if (!autoload_fail)
1665 rtlefuse->eeprom_thermalmeter =
1666 hwinfo[EEPROM_THERMAL_METER_88E];
1667 else
1668 rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
1669
1670 if (rtlefuse->eeprom_thermalmeter == 0xff || autoload_fail) {
1671 rtlefuse->apk_thermalmeterignore = true;
1672 rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER;
1673 }
1674 rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
1675 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1676 "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
1677
1678 if (!autoload_fail) {
1679 rtlefuse->eeprom_regulatory =
1680 hwinfo[EEPROM_RF_BOARD_OPTION_88E] & 0x07;/*bit0~2*/
1681 if (hwinfo[EEPROM_RF_BOARD_OPTION_88E] == 0xFF)
1682 rtlefuse->eeprom_regulatory = 0;
1683 } else {
1684 rtlefuse->eeprom_regulatory = 0;
1685 }
1686 RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1687 "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
1688}
1689
1690static void _rtl8723be_read_adapter_info(struct ieee80211_hw *hw,
1691 bool pseudo_test)
1692{
1693 struct rtl_priv *rtlpriv = rtl_priv(hw);
1694 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1695 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1696 u16 i, usvalue;
1697 u8 hwinfo[HWSET_MAX_SIZE];
1698 u16 eeprom_id;
1699 bool is_toshiba_smid1 = false;
1700 bool is_toshiba_smid2 = false;
1701 bool is_samsung_smid = false;
1702 bool is_lenovo_smid = false;
1703 u16 toshiba_smid1[] = {
1704 0x6151, 0x6152, 0x6154, 0x6155, 0x6177, 0x6178, 0x6179, 0x6180,
1705 0x7151, 0x7152, 0x7154, 0x7155, 0x7177, 0x7178, 0x7179, 0x7180,
1706 0x8151, 0x8152, 0x8154, 0x8155, 0x8181, 0x8182, 0x8184, 0x8185,
1707 0x9151, 0x9152, 0x9154, 0x9155, 0x9181, 0x9182, 0x9184, 0x9185
1708 };
1709 u16 toshiba_smid2[] = {
1710 0x6181, 0x6184, 0x6185, 0x7181, 0x7182, 0x7184, 0x7185, 0x8181,
1711 0x8182, 0x8184, 0x8185, 0x9181, 0x9182, 0x9184, 0x9185
1712 };
1713 u16 samsung_smid[] = {
1714 0x6191, 0x6192, 0x6193, 0x7191, 0x7192, 0x7193, 0x8191, 0x8192,
1715 0x8193, 0x9191, 0x9192, 0x9193
1716 };
1717 u16 lenovo_smid[] = {
1718 0x8195, 0x9195, 0x7194, 0x8200, 0x8201, 0x8202, 0x9199, 0x9200
1719 };
1720
1721 if (pseudo_test) {
1722 /* needs to be added */
1723 return;
1724 }
1725 if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
1726 rtl_efuse_shadow_map_update(hw);
1727
1728 memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
1729 HWSET_MAX_SIZE);
1730 } else if (rtlefuse->epromtype == EEPROM_93C46) {
1731 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1732 "RTL819X Not boot from eeprom, check it !!");
1733 }
1734 RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"),
1735 hwinfo, HWSET_MAX_SIZE);
1736
1737 eeprom_id = *((u16 *)&hwinfo[0]);
1738 if (eeprom_id != RTL8723BE_EEPROM_ID) {
1739 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1740 "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
1741 rtlefuse->autoload_failflag = true;
1742 } else {
1743 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
1744 rtlefuse->autoload_failflag = false;
1745 }
1746 if (rtlefuse->autoload_failflag)
1747 return;
1748
1749 rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID];
1750 rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID];
1751 rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID];
1752 rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID];
1753 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1754 "EEPROMId = 0x%4x\n", eeprom_id);
1755 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1756 "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid);
1757 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1758 "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did);
1759 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1760 "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid);
1761 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1762 "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid);
1763
1764 for (i = 0; i < 6; i += 2) {
1765 usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i];
1766 *((u16 *)(&rtlefuse->dev_addr[i])) = usvalue;
1767 }
1768 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "dev_addr: %pM\n",
1769 rtlefuse->dev_addr);
1770
1771 /*parse xtal*/
1772 rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_8723BE];
1773 if (rtlefuse->crystalcap == 0xFF)
1774 rtlefuse->crystalcap = 0x20;
1775
1776 _rtl8723be_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag,
1777 hwinfo);
1778
1779 rtl8723be_read_bt_coexist_info_from_hwpg(hw,
1780 rtlefuse->autoload_failflag,
1781 hwinfo);
1782
Joe Perches9cb76aa2014-03-24 10:46:20 -07001783 rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN];
Larry Fingera619d1a2014-02-28 15:16:50 -06001784 rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
1785 rtlefuse->txpwr_fromeprom = true;
Joe Perches9cb76aa2014-03-24 10:46:20 -07001786 rtlefuse->eeprom_oemid = hwinfo[EEPROM_CUSTOMER_ID];
Larry Fingera619d1a2014-02-28 15:16:50 -06001787
1788 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1789 "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid);
1790
1791 /* set channel plan to world wide 13 */
1792 rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13;
1793
1794 if (rtlhal->oem_id == RT_CID_DEFAULT) {
1795 /* Does this one have a Toshiba SMID from group 1? */
1796 for (i = 0; i < sizeof(toshiba_smid1) / sizeof(u16); i++) {
1797 if (rtlefuse->eeprom_smid == toshiba_smid1[i]) {
1798 is_toshiba_smid1 = true;
1799 break;
1800 }
1801 }
1802 /* Does this one have a Toshiba SMID from group 2? */
1803 for (i = 0; i < sizeof(toshiba_smid2) / sizeof(u16); i++) {
1804 if (rtlefuse->eeprom_smid == toshiba_smid2[i]) {
1805 is_toshiba_smid2 = true;
1806 break;
1807 }
1808 }
1809 /* Does this one have a Samsung SMID? */
1810 for (i = 0; i < sizeof(samsung_smid) / sizeof(u16); i++) {
1811 if (rtlefuse->eeprom_smid == samsung_smid[i]) {
1812 is_samsung_smid = true;
1813 break;
1814 }
1815 }
1816 /* Does this one have a Lenovo SMID? */
1817 for (i = 0; i < sizeof(lenovo_smid) / sizeof(u16); i++) {
1818 if (rtlefuse->eeprom_smid == lenovo_smid[i]) {
1819 is_lenovo_smid = true;
1820 break;
1821 }
1822 }
1823 switch (rtlefuse->eeprom_oemid) {
1824 case EEPROM_CID_DEFAULT:
1825 if (rtlefuse->eeprom_did == 0x8176) {
1826 if (rtlefuse->eeprom_svid == 0x10EC &&
1827 is_toshiba_smid1) {
1828 rtlhal->oem_id = RT_CID_TOSHIBA;
1829 } else if (rtlefuse->eeprom_svid == 0x1025) {
1830 rtlhal->oem_id = RT_CID_819X_ACER;
1831 } else if (rtlefuse->eeprom_svid == 0x10EC &&
1832 is_samsung_smid) {
1833 rtlhal->oem_id = RT_CID_819X_SAMSUNG;
1834 } else if (rtlefuse->eeprom_svid == 0x10EC &&
1835 is_lenovo_smid) {
1836 rtlhal->oem_id = RT_CID_819X_LENOVO;
1837 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
1838 rtlefuse->eeprom_smid == 0x8197) ||
1839 (rtlefuse->eeprom_svid == 0x10EC &&
1840 rtlefuse->eeprom_smid == 0x9196)) {
1841 rtlhal->oem_id = RT_CID_819X_CLEVO;
1842 } else if ((rtlefuse->eeprom_svid == 0x1028 &&
1843 rtlefuse->eeprom_smid == 0x8194) ||
1844 (rtlefuse->eeprom_svid == 0x1028 &&
1845 rtlefuse->eeprom_smid == 0x8198) ||
1846 (rtlefuse->eeprom_svid == 0x1028 &&
1847 rtlefuse->eeprom_smid == 0x9197) ||
1848 (rtlefuse->eeprom_svid == 0x1028 &&
1849 rtlefuse->eeprom_smid == 0x9198)) {
1850 rtlhal->oem_id = RT_CID_819X_DELL;
1851 } else if ((rtlefuse->eeprom_svid == 0x103C &&
1852 rtlefuse->eeprom_smid == 0x1629)) {
1853 rtlhal->oem_id = RT_CID_819X_HP;
1854 } else if ((rtlefuse->eeprom_svid == 0x1A32 &&
1855 rtlefuse->eeprom_smid == 0x2315)) {
1856 rtlhal->oem_id = RT_CID_819X_QMI;
1857 } else if ((rtlefuse->eeprom_svid == 0x10EC &&
1858 rtlefuse->eeprom_smid == 0x8203)) {
1859 rtlhal->oem_id = RT_CID_819X_PRONETS;
1860 } else if ((rtlefuse->eeprom_svid == 0x1043 &&
1861 rtlefuse->eeprom_smid == 0x84B5)) {
1862 rtlhal->oem_id = RT_CID_819X_EDIMAX_ASUS;
1863 } else {
1864 rtlhal->oem_id = RT_CID_DEFAULT;
1865 }
1866 } else if (rtlefuse->eeprom_did == 0x8178) {
1867 if (rtlefuse->eeprom_svid == 0x10EC &&
1868 is_toshiba_smid2)
1869 rtlhal->oem_id = RT_CID_TOSHIBA;
1870 else if (rtlefuse->eeprom_svid == 0x1025)
1871 rtlhal->oem_id = RT_CID_819X_ACER;
1872 else if ((rtlefuse->eeprom_svid == 0x10EC &&
1873 rtlefuse->eeprom_smid == 0x8186))
1874 rtlhal->oem_id = RT_CID_819X_PRONETS;
1875 else if ((rtlefuse->eeprom_svid == 0x1043 &&
1876 rtlefuse->eeprom_smid == 0x84B6))
1877 rtlhal->oem_id =
1878 RT_CID_819X_EDIMAX_ASUS;
1879 else
1880 rtlhal->oem_id = RT_CID_DEFAULT;
1881 } else {
1882 rtlhal->oem_id = RT_CID_DEFAULT;
1883 }
1884 break;
1885 case EEPROM_CID_TOSHIBA:
1886 rtlhal->oem_id = RT_CID_TOSHIBA;
1887 break;
1888 case EEPROM_CID_CCX:
1889 rtlhal->oem_id = RT_CID_CCX;
1890 break;
1891 case EEPROM_CID_QMI:
1892 rtlhal->oem_id = RT_CID_819X_QMI;
1893 break;
1894 case EEPROM_CID_WHQL:
1895 break;
1896 default:
1897 rtlhal->oem_id = RT_CID_DEFAULT;
1898 break;
1899 }
1900 }
1901}
1902
1903static void _rtl8723be_hal_customized_behavior(struct ieee80211_hw *hw)
1904{
1905 struct rtl_priv *rtlpriv = rtl_priv(hw);
1906 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
1907 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1908
1909 pcipriv->ledctl.led_opendrain = true;
1910 switch (rtlhal->oem_id) {
1911 case RT_CID_819X_HP:
1912 pcipriv->ledctl.led_opendrain = true;
1913 break;
1914 case RT_CID_819X_LENOVO:
1915 case RT_CID_DEFAULT:
1916 case RT_CID_TOSHIBA:
1917 case RT_CID_CCX:
1918 case RT_CID_819X_ACER:
1919 case RT_CID_WHQL:
1920 default:
1921 break;
1922 }
1923 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1924 "RT Customized ID: 0x%02X\n", rtlhal->oem_id);
1925}
1926
1927void rtl8723be_read_eeprom_info(struct ieee80211_hw *hw)
1928{
1929 struct rtl_priv *rtlpriv = rtl_priv(hw);
1930 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1931 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1932 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1933 u8 tmp_u1b;
1934
1935 rtlhal->version = _rtl8723be_read_chip_version(hw);
1936 if (get_rf_type(rtlphy) == RF_1T1R)
1937 rtlpriv->dm.rfpath_rxenable[0] = true;
1938 else
1939 rtlpriv->dm.rfpath_rxenable[0] =
1940 rtlpriv->dm.rfpath_rxenable[1] = true;
1941 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n",
1942 rtlhal->version);
1943 tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
1944 if (tmp_u1b & BIT(4)) {
1945 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
1946 rtlefuse->epromtype = EEPROM_93C46;
1947 } else {
1948 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
1949 rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
1950 }
1951 if (tmp_u1b & BIT(5)) {
1952 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
1953 rtlefuse->autoload_failflag = false;
1954 _rtl8723be_read_adapter_info(hw, false);
1955 } else {
1956 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n");
1957 }
1958 _rtl8723be_hal_customized_behavior(hw);
1959}
1960
1961static void rtl8723be_update_hal_rate_table(struct ieee80211_hw *hw,
1962 struct ieee80211_sta *sta)
1963{
1964 struct rtl_priv *rtlpriv = rtl_priv(hw);
1965 struct rtl_phy *rtlphy = &(rtlpriv->phy);
1966 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1967 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1968 u32 ratr_value;
1969 u8 ratr_index = 0;
1970 u8 nmode = mac->ht_enable;
1971 u8 mimo_ps = IEEE80211_SMPS_OFF;
1972 u16 shortgi_rate;
1973 u32 tmp_ratr_value;
1974 u8 curtxbw_40mhz = mac->bw_40;
1975 u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
1976 1 : 0;
1977 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
1978 1 : 0;
1979 enum wireless_mode wirelessmode = mac->mode;
1980
1981 if (rtlhal->current_bandtype == BAND_ON_5G)
1982 ratr_value = sta->supp_rates[1] << 4;
1983 else
1984 ratr_value = sta->supp_rates[0];
1985 if (mac->opmode == NL80211_IFTYPE_ADHOC)
1986 ratr_value = 0xfff;
1987 ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
1988 sta->ht_cap.mcs.rx_mask[0] << 12);
1989 switch (wirelessmode) {
1990 case WIRELESS_MODE_B:
1991 if (ratr_value & 0x0000000c)
1992 ratr_value &= 0x0000000d;
1993 else
1994 ratr_value &= 0x0000000f;
1995 break;
1996 case WIRELESS_MODE_G:
1997 ratr_value &= 0x00000FF5;
1998 break;
1999 case WIRELESS_MODE_N_24G:
2000 case WIRELESS_MODE_N_5G:
2001 nmode = 1;
2002 if (mimo_ps == IEEE80211_SMPS_STATIC) {
2003 ratr_value &= 0x0007F005;
2004 } else {
2005 u32 ratr_mask;
2006
2007 if (get_rf_type(rtlphy) == RF_1T2R ||
2008 get_rf_type(rtlphy) == RF_1T1R)
2009 ratr_mask = 0x000ff005;
2010 else
2011 ratr_mask = 0x0f0ff005;
2012 ratr_value &= ratr_mask;
2013 }
2014 break;
2015 default:
2016 if (rtlphy->rf_type == RF_1T2R)
2017 ratr_value &= 0x000ff0ff;
2018 else
2019 ratr_value &= 0x0f0ff0ff;
2020 break;
2021 }
2022 if ((rtlpriv->btcoexist.bt_coexistence) &&
2023 (rtlpriv->btcoexist.bt_coexist_type == BT_CSR_BC4) &&
2024 (rtlpriv->btcoexist.bt_cur_state) &&
2025 (rtlpriv->btcoexist.bt_ant_isolation) &&
2026 ((rtlpriv->btcoexist.bt_service == BT_SCO) ||
2027 (rtlpriv->btcoexist.bt_service == BT_BUSY)))
2028 ratr_value &= 0x0fffcfc0;
2029 else
2030 ratr_value &= 0x0FFFFFFF;
2031
2032 if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) ||
2033 (!curtxbw_40mhz && curshortgi_20mhz))) {
2034 ratr_value |= 0x10000000;
2035 tmp_ratr_value = (ratr_value >> 12);
2036
2037 for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
2038 if ((1 << shortgi_rate) & tmp_ratr_value)
2039 break;
2040 }
2041 shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
2042 (shortgi_rate << 4) | (shortgi_rate);
2043 }
2044 rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
2045
2046 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2047 "%x\n", rtl_read_dword(rtlpriv, REG_ARFR0));
2048}
2049
2050static u8 _rtl8723be_mrate_idx_to_arfr_id(struct ieee80211_hw *hw,
2051 u8 rate_index)
2052{
2053 u8 ret = 0;
2054
2055 switch (rate_index) {
2056 case RATR_INX_WIRELESS_NGB:
2057 ret = 1;
2058 break;
2059 case RATR_INX_WIRELESS_N:
2060 case RATR_INX_WIRELESS_NG:
2061 ret = 5;
2062 break;
2063 case RATR_INX_WIRELESS_NB:
2064 ret = 3;
2065 break;
2066 case RATR_INX_WIRELESS_GB:
2067 ret = 6;
2068 break;
2069 case RATR_INX_WIRELESS_G:
2070 ret = 7;
2071 break;
2072 case RATR_INX_WIRELESS_B:
2073 ret = 8;
2074 break;
2075 default:
2076 ret = 0;
2077 break;
2078 }
2079 return ret;
2080}
2081
2082static void rtl8723be_update_hal_rate_mask(struct ieee80211_hw *hw,
2083 struct ieee80211_sta *sta,
2084 u8 rssi_level)
2085{
2086 struct rtl_priv *rtlpriv = rtl_priv(hw);
2087 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2088 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2089 struct rtl_sta_info *sta_entry = NULL;
2090 u32 ratr_bitmap;
2091 u8 ratr_index;
2092 u8 curtxbw_40mhz = (sta->ht_cap.cap &
2093 IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0;
2094 u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
2095 1 : 0;
2096 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
2097 1 : 0;
2098 enum wireless_mode wirelessmode = 0;
2099 bool shortgi = false;
2100 u8 rate_mask[7];
2101 u8 macid = 0;
2102 u8 mimo_ps = IEEE80211_SMPS_OFF;
2103
2104 sta_entry = (struct rtl_sta_info *)sta->drv_priv;
2105 wirelessmode = sta_entry->wireless_mode;
2106 if (mac->opmode == NL80211_IFTYPE_STATION ||
2107 mac->opmode == NL80211_IFTYPE_MESH_POINT)
2108 curtxbw_40mhz = mac->bw_40;
2109 else if (mac->opmode == NL80211_IFTYPE_AP ||
2110 mac->opmode == NL80211_IFTYPE_ADHOC)
2111 macid = sta->aid + 1;
2112
2113 ratr_bitmap = sta->supp_rates[0];
2114
2115 if (mac->opmode == NL80211_IFTYPE_ADHOC)
2116 ratr_bitmap = 0xfff;
2117
2118 ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
2119 sta->ht_cap.mcs.rx_mask[0] << 12);
2120 switch (wirelessmode) {
2121 case WIRELESS_MODE_B:
2122 ratr_index = RATR_INX_WIRELESS_B;
2123 if (ratr_bitmap & 0x0000000c)
2124 ratr_bitmap &= 0x0000000d;
2125 else
2126 ratr_bitmap &= 0x0000000f;
2127 break;
2128 case WIRELESS_MODE_G:
2129 ratr_index = RATR_INX_WIRELESS_GB;
2130
2131 if (rssi_level == 1)
2132 ratr_bitmap &= 0x00000f00;
2133 else if (rssi_level == 2)
2134 ratr_bitmap &= 0x00000ff0;
2135 else
2136 ratr_bitmap &= 0x00000ff5;
2137 break;
2138 case WIRELESS_MODE_A:
2139 ratr_index = RATR_INX_WIRELESS_A;
2140 ratr_bitmap &= 0x00000ff0;
2141 break;
2142 case WIRELESS_MODE_N_24G:
2143 case WIRELESS_MODE_N_5G:
2144 ratr_index = RATR_INX_WIRELESS_NGB;
2145
2146 if (mimo_ps == IEEE80211_SMPS_STATIC ||
2147 mimo_ps == IEEE80211_SMPS_DYNAMIC) {
2148 if (rssi_level == 1)
2149 ratr_bitmap &= 0x00070000;
2150 else if (rssi_level == 2)
2151 ratr_bitmap &= 0x0007f000;
2152 else
2153 ratr_bitmap &= 0x0007f005;
2154 } else {
2155 if (rtlphy->rf_type == RF_1T1R) {
2156 if (curtxbw_40mhz) {
2157 if (rssi_level == 1)
2158 ratr_bitmap &= 0x000f0000;
2159 else if (rssi_level == 2)
2160 ratr_bitmap &= 0x000ff000;
2161 else
2162 ratr_bitmap &= 0x000ff015;
2163 } else {
2164 if (rssi_level == 1)
2165 ratr_bitmap &= 0x000f0000;
2166 else if (rssi_level == 2)
2167 ratr_bitmap &= 0x000ff000;
2168 else
2169 ratr_bitmap &= 0x000ff005;
2170 }
2171 } else {
2172 if (curtxbw_40mhz) {
2173 if (rssi_level == 1)
2174 ratr_bitmap &= 0x0f8f0000;
2175 else if (rssi_level == 2)
2176 ratr_bitmap &= 0x0f8ff000;
2177 else
2178 ratr_bitmap &= 0x0f8ff015;
2179 } else {
2180 if (rssi_level == 1)
2181 ratr_bitmap &= 0x0f8f0000;
2182 else if (rssi_level == 2)
2183 ratr_bitmap &= 0x0f8ff000;
2184 else
2185 ratr_bitmap &= 0x0f8ff005;
2186 }
2187 }
2188 }
2189 if ((curtxbw_40mhz && curshortgi_40mhz) ||
2190 (!curtxbw_40mhz && curshortgi_20mhz)) {
2191 if (macid == 0)
2192 shortgi = true;
2193 else if (macid == 1)
2194 shortgi = false;
2195 }
2196 break;
2197 default:
2198 ratr_index = RATR_INX_WIRELESS_NGB;
2199
2200 if (rtlphy->rf_type == RF_1T2R)
2201 ratr_bitmap &= 0x000ff0ff;
2202 else
2203 ratr_bitmap &= 0x0f0ff0ff;
2204 break;
2205 }
2206 sta_entry->ratr_index = ratr_index;
2207
2208 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2209 "ratr_bitmap :%x\n", ratr_bitmap);
Larry Finger2903d042014-03-05 17:26:00 -06002210 *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | (ratr_index << 28);
Larry Fingera619d1a2014-02-28 15:16:50 -06002211 rate_mask[0] = macid;
2212 rate_mask[1] = _rtl8723be_mrate_idx_to_arfr_id(hw, ratr_index) |
2213 (shortgi ? 0x80 : 0x00);
2214 rate_mask[2] = curtxbw_40mhz;
2215 /* if (prox_priv->proxim_modeinfo->power_output > 0)
2216 * rate_mask[2] |= BIT(6);
2217 */
2218
2219 rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff);
2220 rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >> 8);
2221 rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16);
2222 rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24);
2223
2224 RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2225 "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x:%x:%x\n",
2226 ratr_index, ratr_bitmap,
2227 rate_mask[0], rate_mask[1],
2228 rate_mask[2], rate_mask[3],
2229 rate_mask[4], rate_mask[5],
2230 rate_mask[6]);
2231 rtl8723be_fill_h2c_cmd(hw, H2C_8723BE_RA_MASK, 7, rate_mask);
2232 _rtl8723be_set_bcn_ctrl_reg(hw, BIT(3), 0);
2233}
2234
2235void rtl8723be_update_hal_rate_tbl(struct ieee80211_hw *hw,
2236 struct ieee80211_sta *sta,
2237 u8 rssi_level)
2238{
2239 struct rtl_priv *rtlpriv = rtl_priv(hw);
2240 if (rtlpriv->dm.useramask)
2241 rtl8723be_update_hal_rate_mask(hw, sta, rssi_level);
2242 else
2243 rtl8723be_update_hal_rate_table(hw, sta);
2244}
2245
2246void rtl8723be_update_channel_access_setting(struct ieee80211_hw *hw)
2247{
2248 struct rtl_priv *rtlpriv = rtl_priv(hw);
2249 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2250 u16 sifs_timer;
2251
Joe Perches9cb76aa2014-03-24 10:46:20 -07002252 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, &mac->slot_time);
Larry Fingera619d1a2014-02-28 15:16:50 -06002253 if (!mac->ht_enable)
2254 sifs_timer = 0x0a0a;
2255 else
2256 sifs_timer = 0x0e0e;
2257 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
2258}
2259
2260bool rtl8723be_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
2261{
2262 struct rtl_priv *rtlpriv = rtl_priv(hw);
2263 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2264 struct rtl_phy *rtlphy = &(rtlpriv->phy);
2265 enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate;
2266 u8 u1tmp;
2267 bool actuallyset = false;
2268
2269 if (rtlpriv->rtlhal.being_init_adapter)
2270 return false;
2271
2272 if (ppsc->swrf_processing)
2273 return false;
2274
2275 spin_lock(&rtlpriv->locks.rf_ps_lock);
2276 if (ppsc->rfchange_inprogress) {
2277 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2278 return false;
2279 } else {
2280 ppsc->rfchange_inprogress = true;
2281 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2282 }
2283 cur_rfstate = ppsc->rfpwr_state;
2284
2285 rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2,
2286 rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2) & ~(BIT(1)));
2287
2288 u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2);
2289
2290 if (rtlphy->polarity_ctl)
2291 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON;
2292 else
2293 e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF;
2294
2295 if (ppsc->hwradiooff &&
2296 (e_rfpowerstate_toset == ERFON)) {
2297 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2298 "GPIOChangeRF - HW Radio ON, RF ON\n");
2299
2300 e_rfpowerstate_toset = ERFON;
2301 ppsc->hwradiooff = false;
2302 actuallyset = true;
2303 } else if (!ppsc->hwradiooff &&
2304 (e_rfpowerstate_toset == ERFOFF)) {
2305 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2306 "GPIOChangeRF - HW Radio OFF, RF OFF\n");
2307
2308 e_rfpowerstate_toset = ERFOFF;
2309 ppsc->hwradiooff = true;
2310 actuallyset = true;
2311 }
2312 if (actuallyset) {
2313 spin_lock(&rtlpriv->locks.rf_ps_lock);
2314 ppsc->rfchange_inprogress = false;
2315 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2316 } else {
2317 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
2318 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2319
2320 spin_lock(&rtlpriv->locks.rf_ps_lock);
2321 ppsc->rfchange_inprogress = false;
2322 spin_unlock(&rtlpriv->locks.rf_ps_lock);
2323 }
2324 *valid = 1;
2325 return !ppsc->hwradiooff;
2326}
2327
2328void rtl8723be_set_key(struct ieee80211_hw *hw, u32 key_index,
2329 u8 *p_macaddr, bool is_group, u8 enc_algo,
2330 bool is_wepkey, bool clear_all)
2331{
2332 struct rtl_priv *rtlpriv = rtl_priv(hw);
2333 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2334 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2335 u8 *macaddr = p_macaddr;
2336 u32 entry_id = 0;
2337 bool is_pairwise = false;
2338
2339 static u8 cam_const_addr[4][6] = {
2340 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
2341 {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
2342 {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
2343 {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
2344 };
2345 static u8 cam_const_broad[] = {
2346 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2347 };
2348
2349 if (clear_all) {
2350 u8 idx = 0;
2351 u8 cam_offset = 0;
2352 u8 clear_number = 5;
2353
2354 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
2355
2356 for (idx = 0; idx < clear_number; idx++) {
2357 rtl_cam_mark_invalid(hw, cam_offset + idx);
2358 rtl_cam_empty_entry(hw, cam_offset + idx);
2359
2360 if (idx < 5) {
2361 memset(rtlpriv->sec.key_buf[idx], 0,
2362 MAX_KEY_LEN);
2363 rtlpriv->sec.key_len[idx] = 0;
2364 }
2365 }
2366 } else {
2367 switch (enc_algo) {
2368 case WEP40_ENCRYPTION:
2369 enc_algo = CAM_WEP40;
2370 break;
2371 case WEP104_ENCRYPTION:
2372 enc_algo = CAM_WEP104;
2373 break;
2374 case TKIP_ENCRYPTION:
2375 enc_algo = CAM_TKIP;
2376 break;
2377 case AESCCMP_ENCRYPTION:
2378 enc_algo = CAM_AES;
2379 break;
2380 default:
2381 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2382 "switch case not process\n");
2383 enc_algo = CAM_TKIP;
2384 break;
2385 }
2386
2387 if (is_wepkey || rtlpriv->sec.use_defaultkey) {
2388 macaddr = cam_const_addr[key_index];
2389 entry_id = key_index;
2390 } else {
2391 if (is_group) {
2392 macaddr = cam_const_broad;
2393 entry_id = key_index;
2394 } else {
2395 if (mac->opmode == NL80211_IFTYPE_AP) {
2396 entry_id = rtl_cam_get_free_entry(hw,
2397 p_macaddr);
2398 if (entry_id >= TOTAL_CAM_ENTRY) {
2399 RT_TRACE(rtlpriv, COMP_SEC,
2400 DBG_EMERG,
2401 "Can not find free"
2402 " hw security cam "
2403 "entry\n");
2404 return;
2405 }
2406 } else {
2407 entry_id = CAM_PAIRWISE_KEY_POSITION;
2408 }
2409 key_index = PAIRWISE_KEYIDX;
2410 is_pairwise = true;
2411 }
2412 }
2413 if (rtlpriv->sec.key_len[key_index] == 0) {
2414 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2415 "delete one entry, entry_id is %d\n",
2416 entry_id);
2417 if (mac->opmode == NL80211_IFTYPE_AP)
2418 rtl_cam_del_entry(hw, p_macaddr);
2419 rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
2420 } else {
2421 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2422 "add one entry\n");
2423 if (is_pairwise) {
2424 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2425 "set Pairwise key\n");
2426
2427 rtl_cam_add_one_entry(hw, macaddr, key_index,
2428 entry_id, enc_algo,
2429 CAM_CONFIG_NO_USEDK,
2430 rtlpriv->sec.key_buf[key_index]);
2431 } else {
2432 RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
2433 "set group key\n");
2434
2435 if (mac->opmode == NL80211_IFTYPE_ADHOC) {
2436 rtl_cam_add_one_entry(hw,
2437 rtlefuse->dev_addr,
2438 PAIRWISE_KEYIDX,
2439 CAM_PAIRWISE_KEY_POSITION,
2440 enc_algo,
2441 CAM_CONFIG_NO_USEDK,
2442 rtlpriv->sec.key_buf
2443 [entry_id]);
2444 }
2445 rtl_cam_add_one_entry(hw, macaddr, key_index,
2446 entry_id, enc_algo,
2447 CAM_CONFIG_NO_USEDK,
2448 rtlpriv->sec.key_buf[entry_id]);
2449 }
2450 }
2451 }
2452}
2453
2454void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
2455 bool auto_load_fail, u8 *hwinfo)
2456{
2457 struct rtl_priv *rtlpriv = rtl_priv(hw);
2458 u8 value;
2459 u32 tmpu_32;
2460
2461 if (!auto_load_fail) {
2462 tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL);
2463 if (tmpu_32 & BIT(18))
2464 rtlpriv->btcoexist.btc_info.btcoexist = 1;
2465 else
2466 rtlpriv->btcoexist.btc_info.btcoexist = 0;
2467 value = hwinfo[RF_OPTION4];
2468 rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2469 rtlpriv->btcoexist.btc_info.ant_num = (value & 0x1);
2470 } else {
2471 rtlpriv->btcoexist.btc_info.btcoexist = 0;
2472 rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8723B;
2473 rtlpriv->btcoexist.btc_info.ant_num = ANT_X2;
2474 }
2475}
2476
2477void rtl8723be_bt_reg_init(struct ieee80211_hw *hw)
2478{
2479 struct rtl_priv *rtlpriv = rtl_priv(hw);
2480
2481 /* 0:Low, 1:High, 2:From Efuse. */
2482 rtlpriv->btcoexist.reg_bt_iso = 2;
2483 /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */
2484 rtlpriv->btcoexist.reg_bt_sco = 3;
2485 /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
2486 rtlpriv->btcoexist.reg_bt_sco = 0;
2487}
2488
2489void rtl8723be_bt_hw_init(struct ieee80211_hw *hw)
2490{
2491 struct rtl_priv *rtlpriv = rtl_priv(hw);
2492
2493 if (rtlpriv->cfg->ops->get_btc_status())
2494 rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv);
2495}
2496
2497void rtl8723be_suspend(struct ieee80211_hw *hw)
2498{
2499}
2500
2501void rtl8723be_resume(struct ieee80211_hw *hw)
2502{
2503}
2504
2505/* Turn on AAP (RCR:bit 0) for promicuous mode. */
2506void rtl8723be_allow_all_destaddr(struct ieee80211_hw *hw, bool allow_all_da,
2507 bool write_into_reg)
2508{
2509 struct rtl_priv *rtlpriv = rtl_priv(hw);
2510 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
2511
2512 if (allow_all_da) /* Set BIT0 */
2513 rtlpci->receive_config |= RCR_AAP;
2514 else /* Clear BIT0 */
2515 rtlpci->receive_config &= ~RCR_AAP;
2516
2517 if (write_into_reg)
2518 rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config);
2519
2520 RT_TRACE(rtlpriv, COMP_TURBO | COMP_INIT, DBG_LOUD,
2521 "receive_config = 0x%08X, write_into_reg =%d\n",
2522 rtlpci->receive_config, write_into_reg);
2523}