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