16f3fcdc8SLarry Finger // SPDX-License-Identifier: GPL-2.0
26f3fcdc8SLarry Finger /* Copyright(c) 2009-2012 Realtek Corporation.*/
3f1d2b4d3SLarry Finger
4f1d2b4d3SLarry Finger #include "../wifi.h"
5f1d2b4d3SLarry Finger #include "../efuse.h"
6f1d2b4d3SLarry Finger #include "../base.h"
7f1d2b4d3SLarry Finger #include "../regd.h"
8f1d2b4d3SLarry Finger #include "../cam.h"
9f1d2b4d3SLarry Finger #include "../ps.h"
10f1d2b4d3SLarry Finger #include "../pci.h"
11f1d2b4d3SLarry Finger #include "reg.h"
12f1d2b4d3SLarry Finger #include "def.h"
13f1d2b4d3SLarry Finger #include "phy.h"
14f1d2b4d3SLarry Finger #include "dm.h"
15f1d2b4d3SLarry Finger #include "fw.h"
16f1d2b4d3SLarry Finger #include "led.h"
17f1d2b4d3SLarry Finger #include "hw.h"
18f1d2b4d3SLarry Finger
rtl92se_get_hw_reg(struct ieee80211_hw * hw,u8 variable,u8 * val)19f1d2b4d3SLarry Finger void rtl92se_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
20f1d2b4d3SLarry Finger {
21f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
22f1d2b4d3SLarry Finger struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
23f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
24f1d2b4d3SLarry Finger
25f1d2b4d3SLarry Finger switch (variable) {
26f1d2b4d3SLarry Finger case HW_VAR_RCR: {
27f1d2b4d3SLarry Finger *((u32 *) (val)) = rtlpci->receive_config;
28f1d2b4d3SLarry Finger break;
29f1d2b4d3SLarry Finger }
30f1d2b4d3SLarry Finger case HW_VAR_RF_STATE: {
31f1d2b4d3SLarry Finger *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
32f1d2b4d3SLarry Finger break;
33f1d2b4d3SLarry Finger }
34f1d2b4d3SLarry Finger case HW_VAR_FW_PSMODE_STATUS: {
35f1d2b4d3SLarry Finger *((bool *) (val)) = ppsc->fw_current_inpsmode;
36f1d2b4d3SLarry Finger break;
37f1d2b4d3SLarry Finger }
38f1d2b4d3SLarry Finger case HW_VAR_CORRECT_TSF: {
39f1d2b4d3SLarry Finger u64 tsf;
40f1d2b4d3SLarry Finger u32 *ptsf_low = (u32 *)&tsf;
41f1d2b4d3SLarry Finger u32 *ptsf_high = ((u32 *)&tsf) + 1;
42f1d2b4d3SLarry Finger
43f1d2b4d3SLarry Finger *ptsf_high = rtl_read_dword(rtlpriv, (TSFR + 4));
44f1d2b4d3SLarry Finger *ptsf_low = rtl_read_dword(rtlpriv, TSFR);
45f1d2b4d3SLarry Finger
46f1d2b4d3SLarry Finger *((u64 *) (val)) = tsf;
47f1d2b4d3SLarry Finger
48f1d2b4d3SLarry Finger break;
49f1d2b4d3SLarry Finger }
50f1d2b4d3SLarry Finger case HW_VAR_MRC: {
51f1d2b4d3SLarry Finger *((bool *)(val)) = rtlpriv->dm.current_mrc_switch;
52f1d2b4d3SLarry Finger break;
53f1d2b4d3SLarry Finger }
541cc49a5bSLarry Finger case HAL_DEF_WOWLAN:
551cc49a5bSLarry Finger break;
562d15acacSLarry Finger default:
572d15acacSLarry Finger pr_err("switch case %#x not processed\n", variable);
58f1d2b4d3SLarry Finger break;
59f1d2b4d3SLarry Finger }
60f1d2b4d3SLarry Finger }
61f1d2b4d3SLarry Finger
rtl92se_set_hw_reg(struct ieee80211_hw * hw,u8 variable,u8 * val)62f1d2b4d3SLarry Finger void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
63f1d2b4d3SLarry Finger {
64f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
65f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
66f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
67f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
68f1d2b4d3SLarry Finger struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
69f1d2b4d3SLarry Finger struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
70f1d2b4d3SLarry Finger
71f1d2b4d3SLarry Finger switch (variable) {
72f1d2b4d3SLarry Finger case HW_VAR_ETHER_ADDR:{
73f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, IDR0, ((u32 *)(val))[0]);
74f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, IDR4, ((u16 *)(val + 4))[0]);
75f1d2b4d3SLarry Finger break;
76f1d2b4d3SLarry Finger }
77f1d2b4d3SLarry Finger case HW_VAR_BASIC_RATE:{
78f1d2b4d3SLarry Finger u16 rate_cfg = ((u16 *) val)[0];
79f1d2b4d3SLarry Finger u8 rate_index = 0;
80f1d2b4d3SLarry Finger
81f1d2b4d3SLarry Finger if (rtlhal->version == VERSION_8192S_ACUT)
82f1d2b4d3SLarry Finger rate_cfg = rate_cfg & 0x150;
83f1d2b4d3SLarry Finger else
84f1d2b4d3SLarry Finger rate_cfg = rate_cfg & 0x15f;
85f1d2b4d3SLarry Finger
86f1d2b4d3SLarry Finger rate_cfg |= 0x01;
87f1d2b4d3SLarry Finger
88f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, RRSR, rate_cfg & 0xff);
89f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, RRSR + 1,
90f1d2b4d3SLarry Finger (rate_cfg >> 8) & 0xff);
91f1d2b4d3SLarry Finger
92f1d2b4d3SLarry Finger while (rate_cfg > 0x1) {
93f1d2b4d3SLarry Finger rate_cfg = (rate_cfg >> 1);
94f1d2b4d3SLarry Finger rate_index++;
95f1d2b4d3SLarry Finger }
96f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, INIRTSMCS_SEL, rate_index);
97f1d2b4d3SLarry Finger
98f1d2b4d3SLarry Finger break;
99f1d2b4d3SLarry Finger }
100f1d2b4d3SLarry Finger case HW_VAR_BSSID:{
101f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, BSSIDR, ((u32 *)(val))[0]);
102f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, BSSIDR + 4,
103f1d2b4d3SLarry Finger ((u16 *)(val + 4))[0]);
104f1d2b4d3SLarry Finger break;
105f1d2b4d3SLarry Finger }
106f1d2b4d3SLarry Finger case HW_VAR_SIFS:{
107f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, SIFS_OFDM, val[0]);
108f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, SIFS_OFDM + 1, val[1]);
109f1d2b4d3SLarry Finger break;
110f1d2b4d3SLarry Finger }
111f1d2b4d3SLarry Finger case HW_VAR_SLOT_TIME:{
112f1d2b4d3SLarry Finger u8 e_aci;
113f1d2b4d3SLarry Finger
114fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD,
115f1d2b4d3SLarry Finger "HW_VAR_SLOT_TIME %x\n", val[0]);
116f1d2b4d3SLarry Finger
117f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, SLOT_TIME, val[0]);
118f1d2b4d3SLarry Finger
119f1d2b4d3SLarry Finger for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
120f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw,
121f1d2b4d3SLarry Finger HW_VAR_AC_PARAM,
122f1d2b4d3SLarry Finger (&e_aci));
123f1d2b4d3SLarry Finger }
124f1d2b4d3SLarry Finger break;
125f1d2b4d3SLarry Finger }
126f1d2b4d3SLarry Finger case HW_VAR_ACK_PREAMBLE:{
127f1d2b4d3SLarry Finger u8 reg_tmp;
128f1d2b4d3SLarry Finger u8 short_preamble = (bool) (*val);
129f1d2b4d3SLarry Finger reg_tmp = (mac->cur_40_prime_sc) << 5;
130f1d2b4d3SLarry Finger if (short_preamble)
131f1d2b4d3SLarry Finger reg_tmp |= 0x80;
132f1d2b4d3SLarry Finger
133f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, RRSR + 2, reg_tmp);
134f1d2b4d3SLarry Finger break;
135f1d2b4d3SLarry Finger }
136f1d2b4d3SLarry Finger case HW_VAR_AMPDU_MIN_SPACE:{
137f1d2b4d3SLarry Finger u8 min_spacing_to_set;
138f1d2b4d3SLarry Finger u8 sec_min_space;
139f1d2b4d3SLarry Finger
140f1d2b4d3SLarry Finger min_spacing_to_set = *val;
141f1d2b4d3SLarry Finger if (min_spacing_to_set <= 7) {
142f1d2b4d3SLarry Finger if (rtlpriv->sec.pairwise_enc_algorithm ==
143f1d2b4d3SLarry Finger NO_ENCRYPTION)
144f1d2b4d3SLarry Finger sec_min_space = 0;
145f1d2b4d3SLarry Finger else
146f1d2b4d3SLarry Finger sec_min_space = 1;
147f1d2b4d3SLarry Finger
148f1d2b4d3SLarry Finger if (min_spacing_to_set < sec_min_space)
149f1d2b4d3SLarry Finger min_spacing_to_set = sec_min_space;
150f1d2b4d3SLarry Finger if (min_spacing_to_set > 5)
151f1d2b4d3SLarry Finger min_spacing_to_set = 5;
152f1d2b4d3SLarry Finger
153f1d2b4d3SLarry Finger mac->min_space_cfg =
154f1d2b4d3SLarry Finger ((mac->min_space_cfg & 0xf8) |
155f1d2b4d3SLarry Finger min_spacing_to_set);
156f1d2b4d3SLarry Finger
157f1d2b4d3SLarry Finger *val = min_spacing_to_set;
158f1d2b4d3SLarry Finger
159fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD,
160f1d2b4d3SLarry Finger "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
161f1d2b4d3SLarry Finger mac->min_space_cfg);
162f1d2b4d3SLarry Finger
163f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE,
164f1d2b4d3SLarry Finger mac->min_space_cfg);
165f1d2b4d3SLarry Finger }
166f1d2b4d3SLarry Finger break;
167f1d2b4d3SLarry Finger }
168f1d2b4d3SLarry Finger case HW_VAR_SHORTGI_DENSITY:{
169f1d2b4d3SLarry Finger u8 density_to_set;
170f1d2b4d3SLarry Finger
171f1d2b4d3SLarry Finger density_to_set = *val;
172f1d2b4d3SLarry Finger mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg;
173f1d2b4d3SLarry Finger mac->min_space_cfg |= (density_to_set << 3);
174f1d2b4d3SLarry Finger
175fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD,
176f1d2b4d3SLarry Finger "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
177f1d2b4d3SLarry Finger mac->min_space_cfg);
178f1d2b4d3SLarry Finger
179f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE,
180f1d2b4d3SLarry Finger mac->min_space_cfg);
181f1d2b4d3SLarry Finger
182f1d2b4d3SLarry Finger break;
183f1d2b4d3SLarry Finger }
184f1d2b4d3SLarry Finger case HW_VAR_AMPDU_FACTOR:{
185f1d2b4d3SLarry Finger u8 factor_toset;
186f1d2b4d3SLarry Finger u8 regtoset;
187f1d2b4d3SLarry Finger u8 factorlevel[18] = {
188f1d2b4d3SLarry Finger 2, 4, 4, 7, 7, 13, 13,
189f1d2b4d3SLarry Finger 13, 2, 7, 7, 13, 13,
190f1d2b4d3SLarry Finger 15, 15, 15, 15, 0};
191f1d2b4d3SLarry Finger u8 index = 0;
192f1d2b4d3SLarry Finger
193f1d2b4d3SLarry Finger factor_toset = *val;
194f1d2b4d3SLarry Finger if (factor_toset <= 3) {
195f1d2b4d3SLarry Finger factor_toset = (1 << (factor_toset + 2));
196f1d2b4d3SLarry Finger if (factor_toset > 0xf)
197f1d2b4d3SLarry Finger factor_toset = 0xf;
198f1d2b4d3SLarry Finger
199f1d2b4d3SLarry Finger for (index = 0; index < 17; index++) {
200f1d2b4d3SLarry Finger if (factorlevel[index] > factor_toset)
201f1d2b4d3SLarry Finger factorlevel[index] =
202f1d2b4d3SLarry Finger factor_toset;
203f1d2b4d3SLarry Finger }
204f1d2b4d3SLarry Finger
205f1d2b4d3SLarry Finger for (index = 0; index < 8; index++) {
206f1d2b4d3SLarry Finger regtoset = ((factorlevel[index * 2]) |
207f1d2b4d3SLarry Finger (factorlevel[index *
208f1d2b4d3SLarry Finger 2 + 1] << 4));
209f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv,
210f1d2b4d3SLarry Finger AGGLEN_LMT_L + index,
211f1d2b4d3SLarry Finger regtoset);
212f1d2b4d3SLarry Finger }
213f1d2b4d3SLarry Finger
214f1d2b4d3SLarry Finger regtoset = ((factorlevel[16]) |
215f1d2b4d3SLarry Finger (factorlevel[17] << 4));
216f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AGGLEN_LMT_H, regtoset);
217f1d2b4d3SLarry Finger
218fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD,
219f1d2b4d3SLarry Finger "Set HW_VAR_AMPDU_FACTOR: %#x\n",
220f1d2b4d3SLarry Finger factor_toset);
221f1d2b4d3SLarry Finger }
222f1d2b4d3SLarry Finger break;
223f1d2b4d3SLarry Finger }
224f1d2b4d3SLarry Finger case HW_VAR_AC_PARAM:{
225f1d2b4d3SLarry Finger u8 e_aci = *val;
226f1d2b4d3SLarry Finger rtl92s_dm_init_edca_turbo(hw);
227f1d2b4d3SLarry Finger
228f1d2b4d3SLarry Finger if (rtlpci->acm_method != EACMWAY2_SW)
229f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw,
230f1d2b4d3SLarry Finger HW_VAR_ACM_CTRL,
231f1d2b4d3SLarry Finger &e_aci);
232f1d2b4d3SLarry Finger break;
233f1d2b4d3SLarry Finger }
234f1d2b4d3SLarry Finger case HW_VAR_ACM_CTRL:{
235f1d2b4d3SLarry Finger u8 e_aci = *val;
236f1d2b4d3SLarry Finger union aci_aifsn *p_aci_aifsn = (union aci_aifsn *)(&(
237f1d2b4d3SLarry Finger mac->ac[0].aifs));
238f1d2b4d3SLarry Finger u8 acm = p_aci_aifsn->f.acm;
2392a83ad1fSLarry Finger u8 acm_ctrl = rtl_read_byte(rtlpriv, ACMHWCTRL);
240f1d2b4d3SLarry Finger
241f1d2b4d3SLarry Finger acm_ctrl = acm_ctrl | ((rtlpci->acm_method == 2) ?
242f1d2b4d3SLarry Finger 0x0 : 0x1);
243f1d2b4d3SLarry Finger
244f1d2b4d3SLarry Finger if (acm) {
245f1d2b4d3SLarry Finger switch (e_aci) {
246f1d2b4d3SLarry Finger case AC0_BE:
2472a83ad1fSLarry Finger acm_ctrl |= ACMHW_BEQEN;
248f1d2b4d3SLarry Finger break;
249f1d2b4d3SLarry Finger case AC2_VI:
2502a83ad1fSLarry Finger acm_ctrl |= ACMHW_VIQEN;
251f1d2b4d3SLarry Finger break;
252f1d2b4d3SLarry Finger case AC3_VO:
2532a83ad1fSLarry Finger acm_ctrl |= ACMHW_VOQEN;
254f1d2b4d3SLarry Finger break;
255f1d2b4d3SLarry Finger default:
256fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
257f1d2b4d3SLarry Finger "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
258f1d2b4d3SLarry Finger acm);
259f1d2b4d3SLarry Finger break;
260f1d2b4d3SLarry Finger }
261f1d2b4d3SLarry Finger } else {
262f1d2b4d3SLarry Finger switch (e_aci) {
263f1d2b4d3SLarry Finger case AC0_BE:
2642a83ad1fSLarry Finger acm_ctrl &= (~ACMHW_BEQEN);
265f1d2b4d3SLarry Finger break;
266f1d2b4d3SLarry Finger case AC2_VI:
2672a83ad1fSLarry Finger acm_ctrl &= (~ACMHW_VIQEN);
268f1d2b4d3SLarry Finger break;
269f1d2b4d3SLarry Finger case AC3_VO:
2702a83ad1fSLarry Finger acm_ctrl &= (~ACMHW_VOQEN);
271f1d2b4d3SLarry Finger break;
272f1d2b4d3SLarry Finger default:
2732d15acacSLarry Finger pr_err("switch case %#x not processed\n",
274ad574889SJoe Perches e_aci);
275f1d2b4d3SLarry Finger break;
276f1d2b4d3SLarry Finger }
277f1d2b4d3SLarry Finger }
278f1d2b4d3SLarry Finger
279fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_QOS, DBG_TRACE,
280f1d2b4d3SLarry Finger "HW_VAR_ACM_CTRL Write 0x%X\n", acm_ctrl);
2812a83ad1fSLarry Finger rtl_write_byte(rtlpriv, ACMHWCTRL, acm_ctrl);
282f1d2b4d3SLarry Finger break;
283f1d2b4d3SLarry Finger }
284f1d2b4d3SLarry Finger case HW_VAR_RCR:{
285f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, RCR, ((u32 *) (val))[0]);
286f1d2b4d3SLarry Finger rtlpci->receive_config = ((u32 *) (val))[0];
287f1d2b4d3SLarry Finger break;
288f1d2b4d3SLarry Finger }
289f1d2b4d3SLarry Finger case HW_VAR_RETRY_LIMIT:{
290f1d2b4d3SLarry Finger u8 retry_limit = val[0];
291f1d2b4d3SLarry Finger
292f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, RETRY_LIMIT,
293f1d2b4d3SLarry Finger retry_limit << RETRY_LIMIT_SHORT_SHIFT |
294f1d2b4d3SLarry Finger retry_limit << RETRY_LIMIT_LONG_SHIFT);
295f1d2b4d3SLarry Finger break;
296f1d2b4d3SLarry Finger }
297f1d2b4d3SLarry Finger case HW_VAR_DUAL_TSF_RST: {
298f1d2b4d3SLarry Finger break;
299f1d2b4d3SLarry Finger }
300f1d2b4d3SLarry Finger case HW_VAR_EFUSE_BYTES: {
301f1d2b4d3SLarry Finger rtlefuse->efuse_usedbytes = *((u16 *) val);
302f1d2b4d3SLarry Finger break;
303f1d2b4d3SLarry Finger }
304f1d2b4d3SLarry Finger case HW_VAR_EFUSE_USAGE: {
305f1d2b4d3SLarry Finger rtlefuse->efuse_usedpercentage = *val;
306f1d2b4d3SLarry Finger break;
307f1d2b4d3SLarry Finger }
308f1d2b4d3SLarry Finger case HW_VAR_IO_CMD: {
309f1d2b4d3SLarry Finger break;
310f1d2b4d3SLarry Finger }
311f1d2b4d3SLarry Finger case HW_VAR_WPA_CONFIG: {
312f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SECR, *val);
313f1d2b4d3SLarry Finger break;
314f1d2b4d3SLarry Finger }
315f1d2b4d3SLarry Finger case HW_VAR_SET_RPWM:{
316f1d2b4d3SLarry Finger break;
317f1d2b4d3SLarry Finger }
318f1d2b4d3SLarry Finger case HW_VAR_H2C_FW_PWRMODE:{
319f1d2b4d3SLarry Finger break;
320f1d2b4d3SLarry Finger }
321f1d2b4d3SLarry Finger case HW_VAR_FW_PSMODE_STATUS: {
322f1d2b4d3SLarry Finger ppsc->fw_current_inpsmode = *((bool *) val);
323f1d2b4d3SLarry Finger break;
324f1d2b4d3SLarry Finger }
325f1d2b4d3SLarry Finger case HW_VAR_H2C_FW_JOINBSSRPT:{
326f1d2b4d3SLarry Finger break;
327f1d2b4d3SLarry Finger }
328f1d2b4d3SLarry Finger case HW_VAR_AID:{
329f1d2b4d3SLarry Finger break;
330f1d2b4d3SLarry Finger }
331f1d2b4d3SLarry Finger case HW_VAR_CORRECT_TSF:{
332f1d2b4d3SLarry Finger break;
333f1d2b4d3SLarry Finger }
334f1d2b4d3SLarry Finger case HW_VAR_MRC: {
335f1d2b4d3SLarry Finger bool bmrc_toset = *((bool *)val);
336f1d2b4d3SLarry Finger u8 u1bdata = 0;
337f1d2b4d3SLarry Finger
338f1d2b4d3SLarry Finger if (bmrc_toset) {
339f1d2b4d3SLarry Finger rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
340f1d2b4d3SLarry Finger MASKBYTE0, 0x33);
341f1d2b4d3SLarry Finger u1bdata = (u8)rtl_get_bbreg(hw,
342f1d2b4d3SLarry Finger ROFDM1_TRXPATHENABLE,
343f1d2b4d3SLarry Finger MASKBYTE0);
344f1d2b4d3SLarry Finger rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE,
345f1d2b4d3SLarry Finger MASKBYTE0,
346f1d2b4d3SLarry Finger ((u1bdata & 0xf0) | 0x03));
347f1d2b4d3SLarry Finger u1bdata = (u8)rtl_get_bbreg(hw,
348f1d2b4d3SLarry Finger ROFDM0_TRXPATHENABLE,
349f1d2b4d3SLarry Finger MASKBYTE1);
350f1d2b4d3SLarry Finger rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
351f1d2b4d3SLarry Finger MASKBYTE1,
352f1d2b4d3SLarry Finger (u1bdata | 0x04));
353f1d2b4d3SLarry Finger
354f1d2b4d3SLarry Finger /* Update current settings. */
355f1d2b4d3SLarry Finger rtlpriv->dm.current_mrc_switch = bmrc_toset;
356f1d2b4d3SLarry Finger } else {
357f1d2b4d3SLarry Finger rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
358f1d2b4d3SLarry Finger MASKBYTE0, 0x13);
359f1d2b4d3SLarry Finger u1bdata = (u8)rtl_get_bbreg(hw,
360f1d2b4d3SLarry Finger ROFDM1_TRXPATHENABLE,
361f1d2b4d3SLarry Finger MASKBYTE0);
362f1d2b4d3SLarry Finger rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE,
363f1d2b4d3SLarry Finger MASKBYTE0,
364f1d2b4d3SLarry Finger ((u1bdata & 0xf0) | 0x01));
365f1d2b4d3SLarry Finger u1bdata = (u8)rtl_get_bbreg(hw,
366f1d2b4d3SLarry Finger ROFDM0_TRXPATHENABLE,
367f1d2b4d3SLarry Finger MASKBYTE1);
368f1d2b4d3SLarry Finger rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
369f1d2b4d3SLarry Finger MASKBYTE1, (u1bdata & 0xfb));
370f1d2b4d3SLarry Finger
371f1d2b4d3SLarry Finger /* Update current settings. */
372f1d2b4d3SLarry Finger rtlpriv->dm.current_mrc_switch = bmrc_toset;
373f1d2b4d3SLarry Finger }
374f1d2b4d3SLarry Finger
375f1d2b4d3SLarry Finger break;
376f1d2b4d3SLarry Finger }
377f1d2b4d3SLarry Finger case HW_VAR_FW_LPS_ACTION: {
378f1d2b4d3SLarry Finger bool enter_fwlps = *((bool *)val);
379f1d2b4d3SLarry Finger u8 rpwm_val, fw_pwrmode;
380f1d2b4d3SLarry Finger bool fw_current_inps;
381f1d2b4d3SLarry Finger
382f1d2b4d3SLarry Finger if (enter_fwlps) {
383f1d2b4d3SLarry Finger rpwm_val = 0x02; /* RF off */
384f1d2b4d3SLarry Finger fw_current_inps = true;
385f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw,
386f1d2b4d3SLarry Finger HW_VAR_FW_PSMODE_STATUS,
387f1d2b4d3SLarry Finger (u8 *)(&fw_current_inps));
388f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw,
389f1d2b4d3SLarry Finger HW_VAR_H2C_FW_PWRMODE,
390f1d2b4d3SLarry Finger &ppsc->fwctrl_psmode);
391f1d2b4d3SLarry Finger
392f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
393f1d2b4d3SLarry Finger &rpwm_val);
394f1d2b4d3SLarry Finger } else {
395f1d2b4d3SLarry Finger rpwm_val = 0x0C; /* RF on */
396f1d2b4d3SLarry Finger fw_pwrmode = FW_PS_ACTIVE_MODE;
397f1d2b4d3SLarry Finger fw_current_inps = false;
398f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM,
399f1d2b4d3SLarry Finger &rpwm_val);
400f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE,
401f1d2b4d3SLarry Finger &fw_pwrmode);
402f1d2b4d3SLarry Finger
403f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw,
404f1d2b4d3SLarry Finger HW_VAR_FW_PSMODE_STATUS,
405f1d2b4d3SLarry Finger (u8 *)(&fw_current_inps));
406f1d2b4d3SLarry Finger }
407f1d2b4d3SLarry Finger break; }
408f1d2b4d3SLarry Finger default:
4092d15acacSLarry Finger pr_err("switch case %#x not processed\n", variable);
410f1d2b4d3SLarry Finger break;
411f1d2b4d3SLarry Finger }
412f1d2b4d3SLarry Finger
413f1d2b4d3SLarry Finger }
414f1d2b4d3SLarry Finger
rtl92se_enable_hw_security_config(struct ieee80211_hw * hw)415f1d2b4d3SLarry Finger void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw)
416f1d2b4d3SLarry Finger {
417f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
418f1d2b4d3SLarry Finger u8 sec_reg_value = 0x0;
419f1d2b4d3SLarry Finger
420fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
421f1d2b4d3SLarry Finger "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
422f1d2b4d3SLarry Finger rtlpriv->sec.pairwise_enc_algorithm,
423f1d2b4d3SLarry Finger rtlpriv->sec.group_enc_algorithm);
424f1d2b4d3SLarry Finger
425f1d2b4d3SLarry Finger if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
426fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
427f1d2b4d3SLarry Finger "not open hw encryption\n");
428f1d2b4d3SLarry Finger return;
429f1d2b4d3SLarry Finger }
430f1d2b4d3SLarry Finger
431f1d2b4d3SLarry Finger sec_reg_value = SCR_TXENCENABLE | SCR_RXENCENABLE;
432f1d2b4d3SLarry Finger
433f1d2b4d3SLarry Finger if (rtlpriv->sec.use_defaultkey) {
434f1d2b4d3SLarry Finger sec_reg_value |= SCR_TXUSEDK;
435f1d2b4d3SLarry Finger sec_reg_value |= SCR_RXUSEDK;
436f1d2b4d3SLarry Finger }
437f1d2b4d3SLarry Finger
438fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, "The SECR-value %x\n",
439f1d2b4d3SLarry Finger sec_reg_value);
440f1d2b4d3SLarry Finger
441f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
442f1d2b4d3SLarry Finger
443f1d2b4d3SLarry Finger }
444f1d2b4d3SLarry Finger
_rtl92se_halset_sysclk(struct ieee80211_hw * hw,u8 data)445f1d2b4d3SLarry Finger static u8 _rtl92se_halset_sysclk(struct ieee80211_hw *hw, u8 data)
446f1d2b4d3SLarry Finger {
447f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
448f1d2b4d3SLarry Finger u8 waitcount = 100;
449f1d2b4d3SLarry Finger bool bresult = false;
450f1d2b4d3SLarry Finger u8 tmpvalue;
451f1d2b4d3SLarry Finger
452f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, SYS_CLKR + 1, data);
453f1d2b4d3SLarry Finger
454f1d2b4d3SLarry Finger /* Wait the MAC synchronized. */
455f1d2b4d3SLarry Finger udelay(400);
456f1d2b4d3SLarry Finger
457f1d2b4d3SLarry Finger /* Check if it is set ready. */
458f1d2b4d3SLarry Finger tmpvalue = rtl_read_byte(rtlpriv, SYS_CLKR + 1);
459f1d2b4d3SLarry Finger bresult = ((tmpvalue & BIT(7)) == (data & BIT(7)));
460f1d2b4d3SLarry Finger
46133ae4623SAditya Srivastava if (!(data & (BIT(6) | BIT(7)))) {
462f1d2b4d3SLarry Finger waitcount = 100;
463f1d2b4d3SLarry Finger tmpvalue = 0;
464f1d2b4d3SLarry Finger
465f1d2b4d3SLarry Finger while (1) {
466f1d2b4d3SLarry Finger waitcount--;
467f1d2b4d3SLarry Finger
468f1d2b4d3SLarry Finger tmpvalue = rtl_read_byte(rtlpriv, SYS_CLKR + 1);
469f1d2b4d3SLarry Finger if ((tmpvalue & BIT(6)))
470f1d2b4d3SLarry Finger break;
471f1d2b4d3SLarry Finger
472f1d2b4d3SLarry Finger pr_err("wait for BIT(6) return value %x\n", tmpvalue);
473f1d2b4d3SLarry Finger if (waitcount == 0)
474f1d2b4d3SLarry Finger break;
475f1d2b4d3SLarry Finger
476f1d2b4d3SLarry Finger udelay(10);
477f1d2b4d3SLarry Finger }
478f1d2b4d3SLarry Finger
479f1d2b4d3SLarry Finger if (waitcount == 0)
480f1d2b4d3SLarry Finger bresult = false;
481f1d2b4d3SLarry Finger else
482f1d2b4d3SLarry Finger bresult = true;
483f1d2b4d3SLarry Finger }
484f1d2b4d3SLarry Finger
485f1d2b4d3SLarry Finger return bresult;
486f1d2b4d3SLarry Finger }
487f1d2b4d3SLarry Finger
rtl8192se_gpiobit3_cfg_inputmode(struct ieee80211_hw * hw)488f1d2b4d3SLarry Finger void rtl8192se_gpiobit3_cfg_inputmode(struct ieee80211_hw *hw)
489f1d2b4d3SLarry Finger {
490f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
491f1d2b4d3SLarry Finger u8 u1tmp;
492f1d2b4d3SLarry Finger
493f1d2b4d3SLarry Finger /* The following config GPIO function */
494f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, MAC_PINMUX_CFG, (GPIOMUX_EN | GPIOSEL_GPIO));
495f1d2b4d3SLarry Finger u1tmp = rtl_read_byte(rtlpriv, GPIO_IO_SEL);
496f1d2b4d3SLarry Finger
497f1d2b4d3SLarry Finger /* config GPIO3 to input */
498f1d2b4d3SLarry Finger u1tmp &= HAL_8192S_HW_GPIO_OFF_MASK;
499f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, GPIO_IO_SEL, u1tmp);
500f1d2b4d3SLarry Finger
501f1d2b4d3SLarry Finger }
502f1d2b4d3SLarry Finger
_rtl92se_rf_onoff_detect(struct ieee80211_hw * hw)503f1d2b4d3SLarry Finger static u8 _rtl92se_rf_onoff_detect(struct ieee80211_hw *hw)
504f1d2b4d3SLarry Finger {
505f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
506f1d2b4d3SLarry Finger u8 u1tmp;
507f1d2b4d3SLarry Finger u8 retval = ERFON;
508f1d2b4d3SLarry Finger
509f1d2b4d3SLarry Finger /* The following config GPIO function */
510f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, MAC_PINMUX_CFG, (GPIOMUX_EN | GPIOSEL_GPIO));
511f1d2b4d3SLarry Finger u1tmp = rtl_read_byte(rtlpriv, GPIO_IO_SEL);
512f1d2b4d3SLarry Finger
513f1d2b4d3SLarry Finger /* config GPIO3 to input */
514f1d2b4d3SLarry Finger u1tmp &= HAL_8192S_HW_GPIO_OFF_MASK;
515f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, GPIO_IO_SEL, u1tmp);
516f1d2b4d3SLarry Finger
517f1d2b4d3SLarry Finger /* On some of the platform, driver cannot read correct
518f1d2b4d3SLarry Finger * value without delay between Write_GPIO_SEL and Read_GPIO_IN */
519f1d2b4d3SLarry Finger mdelay(10);
520f1d2b4d3SLarry Finger
521f1d2b4d3SLarry Finger /* check GPIO3 */
522f1d2b4d3SLarry Finger u1tmp = rtl_read_byte(rtlpriv, GPIO_IN_SE);
523f1d2b4d3SLarry Finger retval = (u1tmp & HAL_8192S_HW_GPIO_OFF_BIT) ? ERFON : ERFOFF;
524f1d2b4d3SLarry Finger
525f1d2b4d3SLarry Finger return retval;
526f1d2b4d3SLarry Finger }
527f1d2b4d3SLarry Finger
_rtl92se_macconfig_before_fwdownload(struct ieee80211_hw * hw)528f1d2b4d3SLarry Finger static void _rtl92se_macconfig_before_fwdownload(struct ieee80211_hw *hw)
529f1d2b4d3SLarry Finger {
530f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
531f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
532f1d2b4d3SLarry Finger struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
533f1d2b4d3SLarry Finger
534f1d2b4d3SLarry Finger u8 i;
535f1d2b4d3SLarry Finger u8 tmpu1b;
536f1d2b4d3SLarry Finger u16 tmpu2b;
537f1d2b4d3SLarry Finger u8 pollingcnt = 20;
538f1d2b4d3SLarry Finger
539f1d2b4d3SLarry Finger if (rtlpci->first_init) {
540f1d2b4d3SLarry Finger /* Reset PCIE Digital */
541f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
542f1d2b4d3SLarry Finger tmpu1b &= 0xFE;
543f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b);
544f1d2b4d3SLarry Finger udelay(1);
545f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b | BIT(0));
546f1d2b4d3SLarry Finger }
547f1d2b4d3SLarry Finger
548f1d2b4d3SLarry Finger /* Switch to SW IO control */
549f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
550f1d2b4d3SLarry Finger if (tmpu1b & BIT(7)) {
551f1d2b4d3SLarry Finger tmpu1b &= ~(BIT(6) | BIT(7));
552f1d2b4d3SLarry Finger
553f1d2b4d3SLarry Finger /* Set failed, return to prevent hang. */
554f1d2b4d3SLarry Finger if (!_rtl92se_halset_sysclk(hw, tmpu1b))
555f1d2b4d3SLarry Finger return;
556f1d2b4d3SLarry Finger }
557f1d2b4d3SLarry Finger
558f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AFE_PLL_CTRL, 0x0);
559f1d2b4d3SLarry Finger udelay(50);
560f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34);
561f1d2b4d3SLarry Finger udelay(50);
562f1d2b4d3SLarry Finger
563f1d2b4d3SLarry Finger /* Clear FW RPWM for FW control LPS.*/
564f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, RPWM, 0x0);
565f1d2b4d3SLarry Finger
566f1d2b4d3SLarry Finger /* Reset MAC-IO and CPU and Core Digital BIT(10)/11/15 */
567f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
568f1d2b4d3SLarry Finger tmpu1b &= 0x73;
569f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b);
570f1d2b4d3SLarry Finger /* wait for BIT 10/11/15 to pull high automatically!! */
571f1d2b4d3SLarry Finger mdelay(1);
572f1d2b4d3SLarry Finger
573f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, CMDR, 0);
574f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, TCR, 0);
575f1d2b4d3SLarry Finger
576f1d2b4d3SLarry Finger /* Data sheet not define 0x562!!! Copy from WMAC!!!!! */
577f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, 0x562);
578f1d2b4d3SLarry Finger tmpu1b |= 0x08;
579f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x562, tmpu1b);
580f1d2b4d3SLarry Finger tmpu1b &= ~(BIT(3));
581f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x562, tmpu1b);
582f1d2b4d3SLarry Finger
583f1d2b4d3SLarry Finger /* Enable AFE clock source */
584f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL);
585f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AFE_XTAL_CTRL, (tmpu1b | 0x01));
586f1d2b4d3SLarry Finger /* Delay 1.5ms */
587f1d2b4d3SLarry Finger mdelay(2);
588f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL + 1);
589f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, (tmpu1b & 0xfb));
590f1d2b4d3SLarry Finger
591f1d2b4d3SLarry Finger /* Enable AFE Macro Block's Bandgap */
592f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC);
593f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | BIT(0)));
594f1d2b4d3SLarry Finger mdelay(1);
595f1d2b4d3SLarry Finger
596f1d2b4d3SLarry Finger /* Enable AFE Mbias */
597f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC);
598f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | 0x02));
599f1d2b4d3SLarry Finger mdelay(1);
600f1d2b4d3SLarry Finger
601f1d2b4d3SLarry Finger /* Enable LDOA15 block */
602f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, LDOA15_CTRL);
603f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, LDOA15_CTRL, (tmpu1b | BIT(0)));
604f1d2b4d3SLarry Finger
605f1d2b4d3SLarry Finger /* Set Digital Vdd to Retention isolation Path. */
606f1d2b4d3SLarry Finger tmpu2b = rtl_read_word(rtlpriv, REG_SYS_ISO_CTRL);
607f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_SYS_ISO_CTRL, (tmpu2b | BIT(11)));
608f1d2b4d3SLarry Finger
609f1d2b4d3SLarry Finger /* For warm reboot NIC disappera bug. */
610f1d2b4d3SLarry Finger tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
611f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(13)));
612f1d2b4d3SLarry Finger
613f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x68);
614f1d2b4d3SLarry Finger
615f1d2b4d3SLarry Finger /* Enable AFE PLL Macro Block */
616f1d2b4d3SLarry Finger /* We need to delay 100u before enabling PLL. */
617f1d2b4d3SLarry Finger udelay(200);
618f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL);
619f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4)));
620f1d2b4d3SLarry Finger
621f1d2b4d3SLarry Finger /* for divider reset */
622f1d2b4d3SLarry Finger udelay(100);
623f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) |
624f1d2b4d3SLarry Finger BIT(4) | BIT(6)));
625f1d2b4d3SLarry Finger udelay(10);
626f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4)));
627f1d2b4d3SLarry Finger udelay(10);
628f1d2b4d3SLarry Finger
629f1d2b4d3SLarry Finger /* Enable MAC 80MHZ clock */
630f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL + 1);
631f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AFE_PLL_CTRL + 1, (tmpu1b | BIT(0)));
632f1d2b4d3SLarry Finger mdelay(1);
633f1d2b4d3SLarry Finger
634f1d2b4d3SLarry Finger /* Release isolation AFE PLL & MD */
635f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, 0xA6);
636f1d2b4d3SLarry Finger
637f1d2b4d3SLarry Finger /* Enable MAC clock */
638f1d2b4d3SLarry Finger tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR);
639f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b | BIT(12) | BIT(11)));
640f1d2b4d3SLarry Finger
641f1d2b4d3SLarry Finger /* Enable Core digital and enable IOREG R/W */
642f1d2b4d3SLarry Finger tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
643f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11)));
644f1d2b4d3SLarry Finger
645f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
646f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b & ~(BIT(7)));
647f1d2b4d3SLarry Finger
648f1d2b4d3SLarry Finger /* enable REG_EN */
649f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11) | BIT(15)));
650f1d2b4d3SLarry Finger
651f1d2b4d3SLarry Finger /* Switch the control path. */
652f1d2b4d3SLarry Finger tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR);
653f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b & (~BIT(2))));
654f1d2b4d3SLarry Finger
655f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
656f1d2b4d3SLarry Finger tmpu1b = ((tmpu1b | BIT(7)) & (~BIT(6)));
657f1d2b4d3SLarry Finger if (!_rtl92se_halset_sysclk(hw, tmpu1b))
658f1d2b4d3SLarry Finger return; /* Set failed, return to prevent hang. */
659f1d2b4d3SLarry Finger
660f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, CMDR, 0x07FC);
661f1d2b4d3SLarry Finger
662f1d2b4d3SLarry Finger /* MH We must enable the section of code to prevent load IMEM fail. */
663f1d2b4d3SLarry Finger /* Load MAC register from WMAc temporarily We simulate macreg. */
664f1d2b4d3SLarry Finger /* txt HW will provide MAC txt later */
665f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x6, 0x30);
666f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x49, 0xf0);
667f1d2b4d3SLarry Finger
668f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x4b, 0x81);
669f1d2b4d3SLarry Finger
670f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0xb5, 0x21);
671f1d2b4d3SLarry Finger
672f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0xdc, 0xff);
673f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0xdd, 0xff);
674f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0xde, 0xff);
675f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0xdf, 0xff);
676f1d2b4d3SLarry Finger
677f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x11a, 0x00);
678f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x11b, 0x00);
679f1d2b4d3SLarry Finger
680f1d2b4d3SLarry Finger for (i = 0; i < 32; i++)
681f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, INIMCS_SEL + i, 0x1b);
682f1d2b4d3SLarry Finger
683f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x236, 0xff);
684f1d2b4d3SLarry Finger
685f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x503, 0x22);
686f1d2b4d3SLarry Finger
687f1d2b4d3SLarry Finger if (ppsc->support_aspm && !ppsc->support_backdoor)
688f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x560, 0x40);
689f1d2b4d3SLarry Finger else
690f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x560, 0x00);
691f1d2b4d3SLarry Finger
692f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, DBG_PORT, 0x91);
693f1d2b4d3SLarry Finger
694f1d2b4d3SLarry Finger /* Set RX Desc Address */
695f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, RDQDA, rtlpci->rx_ring[RX_MPDU_QUEUE].dma);
696f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, RCDA, rtlpci->rx_ring[RX_CMD_QUEUE].dma);
697f1d2b4d3SLarry Finger
698f1d2b4d3SLarry Finger /* Set TX Desc Address */
699f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, TBKDA, rtlpci->tx_ring[BK_QUEUE].dma);
700f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, TBEDA, rtlpci->tx_ring[BE_QUEUE].dma);
701f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, TVIDA, rtlpci->tx_ring[VI_QUEUE].dma);
702f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, TVODA, rtlpci->tx_ring[VO_QUEUE].dma);
703f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, TBDA, rtlpci->tx_ring[BEACON_QUEUE].dma);
704f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, TCDA, rtlpci->tx_ring[TXCMD_QUEUE].dma);
705f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, TMDA, rtlpci->tx_ring[MGNT_QUEUE].dma);
706f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, THPDA, rtlpci->tx_ring[HIGH_QUEUE].dma);
707f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, HDA, rtlpci->tx_ring[HCCA_QUEUE].dma);
708f1d2b4d3SLarry Finger
709f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, CMDR, 0x37FC);
710f1d2b4d3SLarry Finger
711f1d2b4d3SLarry Finger /* To make sure that TxDMA can ready to download FW. */
712f1d2b4d3SLarry Finger /* We should reset TxDMA if IMEM RPT was not ready. */
713f1d2b4d3SLarry Finger do {
714f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, TCR);
715f1d2b4d3SLarry Finger if ((tmpu1b & TXDMA_INIT_VALUE) == TXDMA_INIT_VALUE)
716f1d2b4d3SLarry Finger break;
717f1d2b4d3SLarry Finger
718f1d2b4d3SLarry Finger udelay(5);
719f1d2b4d3SLarry Finger } while (pollingcnt--);
720f1d2b4d3SLarry Finger
721f1d2b4d3SLarry Finger if (pollingcnt <= 0) {
7222d15acacSLarry Finger pr_err("Polling TXDMA_INIT_VALUE timeout!! Current TCR(%#x)\n",
723f1d2b4d3SLarry Finger tmpu1b);
724f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, CMDR);
725f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, CMDR, tmpu1b & (~TXDMA_EN));
726f1d2b4d3SLarry Finger udelay(2);
727f1d2b4d3SLarry Finger /* Reset TxDMA */
728f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, CMDR, tmpu1b | TXDMA_EN);
729f1d2b4d3SLarry Finger }
730f1d2b4d3SLarry Finger
731f1d2b4d3SLarry Finger /* After MACIO reset,we must refresh LED state. */
732f1d2b4d3SLarry Finger if ((ppsc->rfoff_reason == RF_CHANGE_BY_IPS) ||
733f1d2b4d3SLarry Finger (ppsc->rfoff_reason == 0)) {
734d5efe153SLarry Finger enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0;
735f1d2b4d3SLarry Finger enum rf_pwrstate rfpwr_state_toset;
736f1d2b4d3SLarry Finger rfpwr_state_toset = _rtl92se_rf_onoff_detect(hw);
737f1d2b4d3SLarry Finger
738f1d2b4d3SLarry Finger if (rfpwr_state_toset == ERFON)
739d5efe153SLarry Finger rtl92se_sw_led_on(hw, pin0);
740f1d2b4d3SLarry Finger }
741f1d2b4d3SLarry Finger }
742f1d2b4d3SLarry Finger
_rtl92se_macconfig_after_fwdownload(struct ieee80211_hw * hw)743f1d2b4d3SLarry Finger static void _rtl92se_macconfig_after_fwdownload(struct ieee80211_hw *hw)
744f1d2b4d3SLarry Finger {
745f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
746f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
747f1d2b4d3SLarry Finger struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
748f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
749f1d2b4d3SLarry Finger u8 i;
750f1d2b4d3SLarry Finger u16 tmpu2b;
751f1d2b4d3SLarry Finger
752f1d2b4d3SLarry Finger /* 1. System Configure Register (Offset: 0x0000 - 0x003F) */
753f1d2b4d3SLarry Finger
754f1d2b4d3SLarry Finger /* 2. Command Control Register (Offset: 0x0040 - 0x004F) */
755f1d2b4d3SLarry Finger /* Turn on 0x40 Command register */
756f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, CMDR, (BBRSTN | BB_GLB_RSTN |
757f1d2b4d3SLarry Finger SCHEDULE_EN | MACRXEN | MACTXEN | DDMA_EN | FW2HW_EN |
758f1d2b4d3SLarry Finger RXDMA_EN | TXDMA_EN | HCI_RXDMA_EN | HCI_TXDMA_EN));
759f1d2b4d3SLarry Finger
760f1d2b4d3SLarry Finger /* Set TCR TX DMA pre 2 FULL enable bit */
761f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, TCR, rtl_read_dword(rtlpriv, TCR) |
762f1d2b4d3SLarry Finger TXDMAPRE2FULL);
763f1d2b4d3SLarry Finger
764f1d2b4d3SLarry Finger /* Set RCR */
765f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, RCR, rtlpci->receive_config);
766f1d2b4d3SLarry Finger
767f1d2b4d3SLarry Finger /* 3. MACID Setting Register (Offset: 0x0050 - 0x007F) */
768f1d2b4d3SLarry Finger
769f1d2b4d3SLarry Finger /* 4. Timing Control Register (Offset: 0x0080 - 0x009F) */
770f1d2b4d3SLarry Finger /* Set CCK/OFDM SIFS */
771f1d2b4d3SLarry Finger /* CCK SIFS shall always be 10us. */
772f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, SIFS_CCK, 0x0a0a);
773f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, SIFS_OFDM, 0x1010);
774f1d2b4d3SLarry Finger
775f1d2b4d3SLarry Finger /* Set AckTimeout */
776f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, ACK_TIMEOUT, 0x40);
777f1d2b4d3SLarry Finger
778f1d2b4d3SLarry Finger /* Beacon related */
779f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, BCN_INTERVAL, 100);
780f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, ATIMWND, 2);
781f1d2b4d3SLarry Finger
782f1d2b4d3SLarry Finger /* 5. FIFO Control Register (Offset: 0x00A0 - 0x015F) */
783f1d2b4d3SLarry Finger /* 5.1 Initialize Number of Reserved Pages in Firmware Queue */
784f1d2b4d3SLarry Finger /* Firmware allocate now, associate with FW internal setting.!!! */
785f1d2b4d3SLarry Finger
786f1d2b4d3SLarry Finger /* 5.2 Setting TX/RX page size 0/1/2/3/4=64/128/256/512/1024 */
787f1d2b4d3SLarry Finger /* 5.3 Set driver info, we only accept PHY status now. */
788f1d2b4d3SLarry Finger /* 5.4 Set RXDMA arbitration to control RXDMA/MAC/FW R/W for RXFIFO */
789f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, RXDMA, rtl_read_byte(rtlpriv, RXDMA) | BIT(6));
790f1d2b4d3SLarry Finger
791f1d2b4d3SLarry Finger /* 6. Adaptive Control Register (Offset: 0x0160 - 0x01CF) */
792f1d2b4d3SLarry Finger /* Set RRSR to all legacy rate and HT rate
793f1d2b4d3SLarry Finger * CCK rate is supported by default.
794f1d2b4d3SLarry Finger * CCK rate will be filtered out only when associated
795f1d2b4d3SLarry Finger * AP does not support it.
796f1d2b4d3SLarry Finger * Only enable ACK rate to OFDM 24M
797f1d2b4d3SLarry Finger * Disable RRSR for CCK rate in A-Cut */
798f1d2b4d3SLarry Finger
799f1d2b4d3SLarry Finger if (rtlhal->version == VERSION_8192S_ACUT)
800f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, RRSR, 0xf0);
801f1d2b4d3SLarry Finger else if (rtlhal->version == VERSION_8192S_BCUT)
802f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, RRSR, 0xff);
803f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, RRSR + 1, 0x01);
804f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, RRSR + 2, 0x00);
805f1d2b4d3SLarry Finger
806f1d2b4d3SLarry Finger /* A-Cut IC do not support CCK rate. We forbid ARFR to */
807f1d2b4d3SLarry Finger /* fallback to CCK rate */
808f1d2b4d3SLarry Finger for (i = 0; i < 8; i++) {
809f1d2b4d3SLarry Finger /*Disable RRSR for CCK rate in A-Cut */
810f1d2b4d3SLarry Finger if (rtlhal->version == VERSION_8192S_ACUT)
811f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, ARFR0 + i * 4, 0x1f0ff0f0);
812f1d2b4d3SLarry Finger }
813f1d2b4d3SLarry Finger
814f1d2b4d3SLarry Finger /* Different rate use different AMPDU size */
815f1d2b4d3SLarry Finger /* MCS32/ MCS15_SG use max AMPDU size 15*2=30K */
816f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AGGLEN_LMT_H, 0x0f);
817f1d2b4d3SLarry Finger /* MCS0/1/2/3 use max AMPDU size 4*2=8K */
818f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, AGGLEN_LMT_L, 0x7442);
819f1d2b4d3SLarry Finger /* MCS4/5 use max AMPDU size 8*2=16K 6/7 use 10*2=20K */
820f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, AGGLEN_LMT_L + 2, 0xddd7);
821f1d2b4d3SLarry Finger /* MCS8/9 use max AMPDU size 8*2=16K 10/11 use 10*2=20K */
822f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, AGGLEN_LMT_L + 4, 0xd772);
823f1d2b4d3SLarry Finger /* MCS12/13/14/15 use max AMPDU size 15*2=30K */
824f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, AGGLEN_LMT_L + 6, 0xfffd);
825f1d2b4d3SLarry Finger
826f1d2b4d3SLarry Finger /* Set Data / Response auto rate fallack retry count */
827f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, DARFRC, 0x04010000);
828f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, DARFRC + 4, 0x09070605);
829f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, RARFRC, 0x04010000);
830f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, RARFRC + 4, 0x09070605);
831f1d2b4d3SLarry Finger
832f1d2b4d3SLarry Finger /* 7. EDCA Setting Register (Offset: 0x01D0 - 0x01FF) */
833f1d2b4d3SLarry Finger /* Set all rate to support SG */
834f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, SG_RATE, 0xFFFF);
835f1d2b4d3SLarry Finger
836f1d2b4d3SLarry Finger /* 8. WMAC, BA, and CCX related Register (Offset: 0x0200 - 0x023F) */
837f1d2b4d3SLarry Finger /* Set NAV protection length */
838f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, NAV_PROT_LEN, 0x0080);
839f1d2b4d3SLarry Finger /* CF-END Threshold */
840f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, CFEND_TH, 0xFF);
841f1d2b4d3SLarry Finger /* Set AMPDU minimum space */
842f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, 0x07);
843f1d2b4d3SLarry Finger /* Set TXOP stall control for several queue/HI/BCN/MGT/ */
844f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, TXOP_STALL_CTRL, 0x00);
845f1d2b4d3SLarry Finger
846f1d2b4d3SLarry Finger /* 9. Security Control Register (Offset: 0x0240 - 0x025F) */
847f1d2b4d3SLarry Finger /* 10. Power Save Control Register (Offset: 0x0260 - 0x02DF) */
848f1d2b4d3SLarry Finger /* 11. General Purpose Register (Offset: 0x02E0 - 0x02FF) */
849f1d2b4d3SLarry Finger /* 12. Host Interrupt Status Register (Offset: 0x0300 - 0x030F) */
8502a83ad1fSLarry Finger /* 13. Test mode and Debug Control Register (Offset: 0x0310 - 0x034F) */
851f1d2b4d3SLarry Finger
852f1d2b4d3SLarry Finger /* 14. Set driver info, we only accept PHY status now. */
853f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, RXDRVINFO_SZ, 4);
854f1d2b4d3SLarry Finger
855f1d2b4d3SLarry Finger /* 15. For EEPROM R/W Workaround */
856f1d2b4d3SLarry Finger /* 16. For EFUSE to share REG_SYS_FUNC_EN with EEPROM!!! */
857f1d2b4d3SLarry Finger tmpu2b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN);
858f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, tmpu2b | BIT(13));
859f1d2b4d3SLarry Finger tmpu2b = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL);
860f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, tmpu2b & (~BIT(8)));
861f1d2b4d3SLarry Finger
862f1d2b4d3SLarry Finger /* 17. For EFUSE */
863f1d2b4d3SLarry Finger /* We may R/W EFUSE in EEPROM mode */
864f1d2b4d3SLarry Finger if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
865f1d2b4d3SLarry Finger u8 tempval;
866f1d2b4d3SLarry Finger
867f1d2b4d3SLarry Finger tempval = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL + 1);
868f1d2b4d3SLarry Finger tempval &= 0xFE;
869f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, tempval);
870f1d2b4d3SLarry Finger
871f1d2b4d3SLarry Finger /* Change Program timing */
872f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_EFUSE_CTRL + 3, 0x72);
873fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "EFUSE CONFIG OK\n");
874f1d2b4d3SLarry Finger }
875f1d2b4d3SLarry Finger
876fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "OK\n");
877f1d2b4d3SLarry Finger
878f1d2b4d3SLarry Finger }
879f1d2b4d3SLarry Finger
_rtl92se_hw_configure(struct ieee80211_hw * hw)880f1d2b4d3SLarry Finger static void _rtl92se_hw_configure(struct ieee80211_hw *hw)
881f1d2b4d3SLarry Finger {
882f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
883f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
884f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
885f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
886f1d2b4d3SLarry Finger
887f1d2b4d3SLarry Finger u8 reg_bw_opmode = 0;
888f1d2b4d3SLarry Finger u32 reg_rrsr = 0;
889f1d2b4d3SLarry Finger u8 regtmp = 0;
890f1d2b4d3SLarry Finger
891f1d2b4d3SLarry Finger reg_bw_opmode = BW_OPMODE_20MHZ;
892f1d2b4d3SLarry Finger reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
893f1d2b4d3SLarry Finger
894f1d2b4d3SLarry Finger regtmp = rtl_read_byte(rtlpriv, INIRTSMCS_SEL);
895f1d2b4d3SLarry Finger reg_rrsr = ((reg_rrsr & 0x000fffff) << 8) | regtmp;
896f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, INIRTSMCS_SEL, reg_rrsr);
897f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode);
898f1d2b4d3SLarry Finger
899f1d2b4d3SLarry Finger /* Set Retry Limit here */
900f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
901f1d2b4d3SLarry Finger (u8 *)(&rtlpci->shortretry_limit));
902f1d2b4d3SLarry Finger
903f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, MLT, 0x8f);
904f1d2b4d3SLarry Finger
905f1d2b4d3SLarry Finger /* For Min Spacing configuration. */
906f1d2b4d3SLarry Finger switch (rtlphy->rf_type) {
907f1d2b4d3SLarry Finger case RF_1T2R:
908f1d2b4d3SLarry Finger case RF_1T1R:
909f1d2b4d3SLarry Finger rtlhal->minspace_cfg = (MAX_MSS_DENSITY_1T << 3);
910f1d2b4d3SLarry Finger break;
911f1d2b4d3SLarry Finger case RF_2T2R:
912f1d2b4d3SLarry Finger case RF_2T2R_GREEN:
913f1d2b4d3SLarry Finger rtlhal->minspace_cfg = (MAX_MSS_DENSITY_2T << 3);
914f1d2b4d3SLarry Finger break;
915f1d2b4d3SLarry Finger }
916f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, rtlhal->minspace_cfg);
917f1d2b4d3SLarry Finger }
918f1d2b4d3SLarry Finger
rtl92se_hw_init(struct ieee80211_hw * hw)919f1d2b4d3SLarry Finger int rtl92se_hw_init(struct ieee80211_hw *hw)
920f1d2b4d3SLarry Finger {
921f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
922f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
923f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
924f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
925f1d2b4d3SLarry Finger struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
926f1d2b4d3SLarry Finger u8 tmp_byte = 0;
927f1d2b4d3SLarry Finger unsigned long flags;
928f1d2b4d3SLarry Finger bool rtstatus = true;
929f1d2b4d3SLarry Finger u8 tmp_u1b;
930f1d2b4d3SLarry Finger int err = false;
931f1d2b4d3SLarry Finger u8 i;
932f1d2b4d3SLarry Finger int wdcapra_add[] = {
933f1d2b4d3SLarry Finger EDCAPARA_BE, EDCAPARA_BK,
934f1d2b4d3SLarry Finger EDCAPARA_VI, EDCAPARA_VO};
935f1d2b4d3SLarry Finger u8 secr_value = 0x0;
936f1d2b4d3SLarry Finger
937f1d2b4d3SLarry Finger rtlpci->being_init_adapter = true;
938f1d2b4d3SLarry Finger
939f1d2b4d3SLarry Finger /* As this function can take a very long time (up to 350 ms)
940f1d2b4d3SLarry Finger * and can be called with irqs disabled, reenable the irqs
941f1d2b4d3SLarry Finger * to let the other devices continue being serviced.
942f1d2b4d3SLarry Finger *
943f1d2b4d3SLarry Finger * It is safe doing so since our own interrupts will only be enabled
944f1d2b4d3SLarry Finger * in a subsequent step.
945f1d2b4d3SLarry Finger */
946f1d2b4d3SLarry Finger local_save_flags(flags);
947f1d2b4d3SLarry Finger local_irq_enable();
948f1d2b4d3SLarry Finger
949f1d2b4d3SLarry Finger rtlpriv->intf_ops->disable_aspm(hw);
950f1d2b4d3SLarry Finger
951f1d2b4d3SLarry Finger /* 1. MAC Initialize */
952f1d2b4d3SLarry Finger /* Before FW download, we have to set some MAC register */
953f1d2b4d3SLarry Finger _rtl92se_macconfig_before_fwdownload(hw);
954f1d2b4d3SLarry Finger
955f1d2b4d3SLarry Finger rtlhal->version = (enum version_8192s)((rtl_read_dword(rtlpriv,
956f1d2b4d3SLarry Finger PMC_FSM) >> 16) & 0xF);
957f1d2b4d3SLarry Finger
958f1d2b4d3SLarry Finger rtl8192se_gpiobit3_cfg_inputmode(hw);
959f1d2b4d3SLarry Finger
960f1d2b4d3SLarry Finger /* 2. download firmware */
961f1d2b4d3SLarry Finger rtstatus = rtl92s_download_fw(hw);
962f1d2b4d3SLarry Finger if (!rtstatus) {
963fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
964fca8218dSLarry Finger "Failed to download FW. Init HW without FW now... Please copy FW into /lib/firmware/rtlwifi\n");
965f1d2b4d3SLarry Finger err = 1;
966f1d2b4d3SLarry Finger goto exit;
967f1d2b4d3SLarry Finger }
968f1d2b4d3SLarry Finger
969f1d2b4d3SLarry Finger /* After FW download, we have to reset MAC register */
970f1d2b4d3SLarry Finger _rtl92se_macconfig_after_fwdownload(hw);
971f1d2b4d3SLarry Finger
972f1d2b4d3SLarry Finger /*Retrieve default FW Cmd IO map. */
973f1d2b4d3SLarry Finger rtlhal->fwcmd_iomap = rtl_read_word(rtlpriv, LBUS_MON_ADDR);
974f1d2b4d3SLarry Finger rtlhal->fwcmd_ioparam = rtl_read_dword(rtlpriv, LBUS_ADDR_MASK);
975f1d2b4d3SLarry Finger
976f1d2b4d3SLarry Finger /* 3. Initialize MAC/PHY Config by MACPHY_reg.txt */
977f1d2b4d3SLarry Finger if (!rtl92s_phy_mac_config(hw)) {
9782d15acacSLarry Finger pr_err("MAC Config failed\n");
979f1d2b4d3SLarry Finger err = rtstatus;
980f1d2b4d3SLarry Finger goto exit;
981f1d2b4d3SLarry Finger }
982f1d2b4d3SLarry Finger
983f1d2b4d3SLarry Finger /* because last function modify RCR, so we update
984f1d2b4d3SLarry Finger * rcr var here, or TP will unstable for receive_config
985f1d2b4d3SLarry Finger * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx
986f1d2b4d3SLarry Finger * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252
987f1d2b4d3SLarry Finger */
988f1d2b4d3SLarry Finger rtlpci->receive_config = rtl_read_dword(rtlpriv, RCR);
989f1d2b4d3SLarry Finger rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV);
990f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, RCR, rtlpci->receive_config);
991f1d2b4d3SLarry Finger
992f1d2b4d3SLarry Finger /* Make sure BB/RF write OK. We should prevent enter IPS. radio off. */
993f1d2b4d3SLarry Finger /* We must set flag avoid BB/RF config period later!! */
994f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, CMDR, 0x37FC);
995f1d2b4d3SLarry Finger
996f1d2b4d3SLarry Finger /* 4. Initialize BB After MAC Config PHY_reg.txt, AGC_Tab.txt */
997f1d2b4d3SLarry Finger if (!rtl92s_phy_bb_config(hw)) {
9982d15acacSLarry Finger pr_err("BB Config failed\n");
999f1d2b4d3SLarry Finger err = rtstatus;
1000f1d2b4d3SLarry Finger goto exit;
1001f1d2b4d3SLarry Finger }
1002f1d2b4d3SLarry Finger
1003f1d2b4d3SLarry Finger /* 5. Initiailze RF RAIO_A.txt RF RAIO_B.txt */
1004f1d2b4d3SLarry Finger /* Before initalizing RF. We can not use FW to do RF-R/W. */
1005f1d2b4d3SLarry Finger
1006f1d2b4d3SLarry Finger rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
1007f1d2b4d3SLarry Finger
1008f1d2b4d3SLarry Finger /* Before RF-R/W we must execute the IO from Scott's suggestion. */
1009f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, 0xDB);
1010f1d2b4d3SLarry Finger if (rtlhal->version == VERSION_8192S_ACUT)
1011f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, SPS1_CTRL + 3, 0x07);
1012f1d2b4d3SLarry Finger else
1013f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, RF_CTRL, 0x07);
1014f1d2b4d3SLarry Finger
1015f1d2b4d3SLarry Finger if (!rtl92s_phy_rf_config(hw)) {
1016fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "RF Config failed\n");
1017f1d2b4d3SLarry Finger err = rtstatus;
1018f1d2b4d3SLarry Finger goto exit;
1019f1d2b4d3SLarry Finger }
1020f1d2b4d3SLarry Finger
1021f1d2b4d3SLarry Finger /* After read predefined TXT, we must set BB/MAC/RF
1022f1d2b4d3SLarry Finger * register as our requirement */
1023f1d2b4d3SLarry Finger
1024f1d2b4d3SLarry Finger rtlphy->rfreg_chnlval[0] = rtl92s_phy_query_rf_reg(hw,
1025f1d2b4d3SLarry Finger (enum radio_path)0,
1026f1d2b4d3SLarry Finger RF_CHNLBW,
1027f1d2b4d3SLarry Finger RFREG_OFFSET_MASK);
1028f1d2b4d3SLarry Finger rtlphy->rfreg_chnlval[1] = rtl92s_phy_query_rf_reg(hw,
1029f1d2b4d3SLarry Finger (enum radio_path)1,
1030f1d2b4d3SLarry Finger RF_CHNLBW,
1031f1d2b4d3SLarry Finger RFREG_OFFSET_MASK);
1032f1d2b4d3SLarry Finger
1033f1d2b4d3SLarry Finger /*---- Set CCK and OFDM Block "ON"----*/
1034f1d2b4d3SLarry Finger rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
1035f1d2b4d3SLarry Finger rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
1036f1d2b4d3SLarry Finger
1037f1d2b4d3SLarry Finger /*3 Set Hardware(Do nothing now) */
1038f1d2b4d3SLarry Finger _rtl92se_hw_configure(hw);
1039f1d2b4d3SLarry Finger
1040f1d2b4d3SLarry Finger /* Read EEPROM TX power index and PHY_REG_PG.txt to capture correct */
1041f1d2b4d3SLarry Finger /* TX power index for different rate set. */
1042f1d2b4d3SLarry Finger /* Get original hw reg values */
1043f1d2b4d3SLarry Finger rtl92s_phy_get_hw_reg_originalvalue(hw);
1044f1d2b4d3SLarry Finger /* Write correct tx power index */
1045f1d2b4d3SLarry Finger rtl92s_phy_set_txpower(hw, rtlphy->current_channel);
1046f1d2b4d3SLarry Finger
1047f1d2b4d3SLarry Finger /* We must set MAC address after firmware download. */
1048f1d2b4d3SLarry Finger for (i = 0; i < 6; i++)
1049f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]);
1050f1d2b4d3SLarry Finger
1051f1d2b4d3SLarry Finger /* EEPROM R/W workaround */
1052f1d2b4d3SLarry Finger tmp_u1b = rtl_read_byte(rtlpriv, MAC_PINMUX_CFG);
1053f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, MAC_PINMUX_CFG, tmp_u1b & (~BIT(3)));
1054f1d2b4d3SLarry Finger
1055f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x4d, 0x0);
1056f1d2b4d3SLarry Finger
1057f1d2b4d3SLarry Finger if (hal_get_firmwareversion(rtlpriv) >= 0x49) {
1058f1d2b4d3SLarry Finger tmp_byte = rtl_read_byte(rtlpriv, FW_RSVD_PG_CRTL) & (~BIT(4));
1059f1d2b4d3SLarry Finger tmp_byte = tmp_byte | BIT(5);
1060f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, FW_RSVD_PG_CRTL, tmp_byte);
1061f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, TXDESC_MSK, 0xFFFFCFFF);
1062f1d2b4d3SLarry Finger }
1063f1d2b4d3SLarry Finger
1064f1d2b4d3SLarry Finger /* We enable high power and RA related mechanism after NIC
1065f1d2b4d3SLarry Finger * initialized. */
1066f1d2b4d3SLarry Finger if (hal_get_firmwareversion(rtlpriv) >= 0x35) {
1067f1d2b4d3SLarry Finger /* Fw v.53 and later. */
1068f1d2b4d3SLarry Finger rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_INIT);
1069f1d2b4d3SLarry Finger } else if (hal_get_firmwareversion(rtlpriv) == 0x34) {
1070f1d2b4d3SLarry Finger /* Fw v.52. */
1071f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM5, FW_RA_INIT);
1072f1d2b4d3SLarry Finger rtl92s_phy_chk_fwcmd_iodone(hw);
1073f1d2b4d3SLarry Finger } else {
1074f1d2b4d3SLarry Finger /* Compatible earlier FW version. */
1075f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET);
1076f1d2b4d3SLarry Finger rtl92s_phy_chk_fwcmd_iodone(hw);
1077f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE);
1078f1d2b4d3SLarry Finger rtl92s_phy_chk_fwcmd_iodone(hw);
1079f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH);
1080f1d2b4d3SLarry Finger rtl92s_phy_chk_fwcmd_iodone(hw);
1081f1d2b4d3SLarry Finger }
1082f1d2b4d3SLarry Finger
1083f1d2b4d3SLarry Finger /* Add to prevent ASPM bug. */
1084f1d2b4d3SLarry Finger /* Always enable hst and NIC clock request. */
1085f1d2b4d3SLarry Finger rtl92s_phy_switch_ephy_parameter(hw);
1086f1d2b4d3SLarry Finger
1087f1d2b4d3SLarry Finger /* Security related
1088f1d2b4d3SLarry Finger * 1. Clear all H/W keys.
1089f1d2b4d3SLarry Finger * 2. Enable H/W encryption/decryption. */
1090f1d2b4d3SLarry Finger rtl_cam_reset_all_entry(hw);
1091f1d2b4d3SLarry Finger secr_value |= SCR_TXENCENABLE;
1092f1d2b4d3SLarry Finger secr_value |= SCR_RXENCENABLE;
1093f1d2b4d3SLarry Finger secr_value |= SCR_NOSKMC;
1094f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SECR, secr_value);
1095f1d2b4d3SLarry Finger
1096f1d2b4d3SLarry Finger for (i = 0; i < 4; i++)
1097f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, wdcapra_add[i], 0x5e4322);
1098f1d2b4d3SLarry Finger
1099f1d2b4d3SLarry Finger if (rtlphy->rf_type == RF_1T2R) {
1100f1d2b4d3SLarry Finger bool mrc2set = true;
1101f1d2b4d3SLarry Finger /* Turn on B-Path */
1102f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MRC, (u8 *)&mrc2set);
1103f1d2b4d3SLarry Finger }
1104f1d2b4d3SLarry Finger
1105f1d2b4d3SLarry Finger rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_ON);
1106f1d2b4d3SLarry Finger rtl92s_dm_init(hw);
1107f1d2b4d3SLarry Finger exit:
1108f1d2b4d3SLarry Finger local_irq_restore(flags);
1109f1d2b4d3SLarry Finger rtlpci->being_init_adapter = false;
1110f1d2b4d3SLarry Finger return err;
1111f1d2b4d3SLarry Finger }
1112f1d2b4d3SLarry Finger
rtl92se_set_mac_addr(struct rtl_io * io,const u8 * addr)1113f1d2b4d3SLarry Finger void rtl92se_set_mac_addr(struct rtl_io *io, const u8 *addr)
1114f1d2b4d3SLarry Finger {
1115f1d2b4d3SLarry Finger /* This is a stub. */
1116f1d2b4d3SLarry Finger }
1117f1d2b4d3SLarry Finger
rtl92se_set_check_bssid(struct ieee80211_hw * hw,bool check_bssid)1118f1d2b4d3SLarry Finger void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1119f1d2b4d3SLarry Finger {
1120f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1121f1d2b4d3SLarry Finger u32 reg_rcr;
1122f1d2b4d3SLarry Finger
1123f1d2b4d3SLarry Finger if (rtlpriv->psc.rfpwr_state != ERFON)
1124f1d2b4d3SLarry Finger return;
1125f1d2b4d3SLarry Finger
1126f1d2b4d3SLarry Finger rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr));
1127f1d2b4d3SLarry Finger
1128f1d2b4d3SLarry Finger if (check_bssid) {
1129f1d2b4d3SLarry Finger reg_rcr |= (RCR_CBSSID);
1130f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr));
1131f1d2b4d3SLarry Finger } else if (!check_bssid) {
1132f1d2b4d3SLarry Finger reg_rcr &= (~RCR_CBSSID);
1133f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr));
1134f1d2b4d3SLarry Finger }
1135f1d2b4d3SLarry Finger
1136f1d2b4d3SLarry Finger }
1137f1d2b4d3SLarry Finger
_rtl92se_set_media_status(struct ieee80211_hw * hw,enum nl80211_iftype type)1138f1d2b4d3SLarry Finger static int _rtl92se_set_media_status(struct ieee80211_hw *hw,
1139f1d2b4d3SLarry Finger enum nl80211_iftype type)
1140f1d2b4d3SLarry Finger {
1141f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1142f1d2b4d3SLarry Finger u8 bt_msr = rtl_read_byte(rtlpriv, MSR);
1143f1d2b4d3SLarry Finger u32 temp;
1144f1d2b4d3SLarry Finger bt_msr &= ~MSR_LINK_MASK;
1145f1d2b4d3SLarry Finger
1146f1d2b4d3SLarry Finger switch (type) {
1147f1d2b4d3SLarry Finger case NL80211_IFTYPE_UNSPECIFIED:
1148f1d2b4d3SLarry Finger bt_msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT);
1149fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
1150f1d2b4d3SLarry Finger "Set Network type to NO LINK!\n");
1151f1d2b4d3SLarry Finger break;
1152f1d2b4d3SLarry Finger case NL80211_IFTYPE_ADHOC:
1153f1d2b4d3SLarry Finger bt_msr |= (MSR_LINK_ADHOC << MSR_LINK_SHIFT);
1154fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
1155f1d2b4d3SLarry Finger "Set Network type to Ad Hoc!\n");
1156f1d2b4d3SLarry Finger break;
1157f1d2b4d3SLarry Finger case NL80211_IFTYPE_STATION:
1158f1d2b4d3SLarry Finger bt_msr |= (MSR_LINK_MANAGED << MSR_LINK_SHIFT);
1159fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
1160f1d2b4d3SLarry Finger "Set Network type to STA!\n");
1161f1d2b4d3SLarry Finger break;
1162f1d2b4d3SLarry Finger case NL80211_IFTYPE_AP:
1163f1d2b4d3SLarry Finger bt_msr |= (MSR_LINK_MASTER << MSR_LINK_SHIFT);
1164fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
1165f1d2b4d3SLarry Finger "Set Network type to AP!\n");
1166f1d2b4d3SLarry Finger break;
1167f1d2b4d3SLarry Finger default:
11682d15acacSLarry Finger pr_err("Network type %d not supported!\n", type);
1169f1d2b4d3SLarry Finger return 1;
1170f1d2b4d3SLarry Finger
1171f1d2b4d3SLarry Finger }
1172f1d2b4d3SLarry Finger
1173f1d2b4d3SLarry Finger if (type != NL80211_IFTYPE_AP &&
1174f1d2b4d3SLarry Finger rtlpriv->mac80211.link_state < MAC80211_LINKED)
1175f1d2b4d3SLarry Finger bt_msr = rtl_read_byte(rtlpriv, MSR) & ~MSR_LINK_MASK;
1176f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, MSR, bt_msr);
1177f1d2b4d3SLarry Finger
1178f1d2b4d3SLarry Finger temp = rtl_read_dword(rtlpriv, TCR);
1179f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, TCR, temp & (~BIT(8)));
1180f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, TCR, temp | BIT(8));
1181f1d2b4d3SLarry Finger
1182f1d2b4d3SLarry Finger
1183f1d2b4d3SLarry Finger return 0;
1184f1d2b4d3SLarry Finger }
1185f1d2b4d3SLarry Finger
1186f1d2b4d3SLarry Finger /* HW_VAR_MEDIA_STATUS & HW_VAR_CECHK_BSSID */
rtl92se_set_network_type(struct ieee80211_hw * hw,enum nl80211_iftype type)1187f1d2b4d3SLarry Finger int rtl92se_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
1188f1d2b4d3SLarry Finger {
1189f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1190f1d2b4d3SLarry Finger
1191f1d2b4d3SLarry Finger if (_rtl92se_set_media_status(hw, type))
1192f1d2b4d3SLarry Finger return -EOPNOTSUPP;
1193f1d2b4d3SLarry Finger
1194f1d2b4d3SLarry Finger if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
1195f1d2b4d3SLarry Finger if (type != NL80211_IFTYPE_AP)
1196f1d2b4d3SLarry Finger rtl92se_set_check_bssid(hw, true);
1197f1d2b4d3SLarry Finger } else {
1198f1d2b4d3SLarry Finger rtl92se_set_check_bssid(hw, false);
1199f1d2b4d3SLarry Finger }
1200f1d2b4d3SLarry Finger
1201f1d2b4d3SLarry Finger return 0;
1202f1d2b4d3SLarry Finger }
1203f1d2b4d3SLarry Finger
1204f1d2b4d3SLarry Finger /* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */
rtl92se_set_qos(struct ieee80211_hw * hw,int aci)1205f1d2b4d3SLarry Finger void rtl92se_set_qos(struct ieee80211_hw *hw, int aci)
1206f1d2b4d3SLarry Finger {
1207f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1208f1d2b4d3SLarry Finger rtl92s_dm_init_edca_turbo(hw);
1209f1d2b4d3SLarry Finger
1210f1d2b4d3SLarry Finger switch (aci) {
1211f1d2b4d3SLarry Finger case AC1_BK:
1212f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, EDCAPARA_BK, 0xa44f);
1213f1d2b4d3SLarry Finger break;
1214f1d2b4d3SLarry Finger case AC0_BE:
1215f1d2b4d3SLarry Finger /* rtl_write_dword(rtlpriv, EDCAPARA_BE, u4b_ac_param); */
1216f1d2b4d3SLarry Finger break;
1217f1d2b4d3SLarry Finger case AC2_VI:
1218f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, EDCAPARA_VI, 0x5e4322);
1219f1d2b4d3SLarry Finger break;
1220f1d2b4d3SLarry Finger case AC3_VO:
1221f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, EDCAPARA_VO, 0x2f3222);
1222f1d2b4d3SLarry Finger break;
1223f1d2b4d3SLarry Finger default:
1224531940f9SLarry Finger WARN_ONCE(true, "rtl8192se: invalid aci: %d !\n", aci);
1225f1d2b4d3SLarry Finger break;
1226f1d2b4d3SLarry Finger }
1227f1d2b4d3SLarry Finger }
1228f1d2b4d3SLarry Finger
rtl92se_enable_interrupt(struct ieee80211_hw * hw)1229f1d2b4d3SLarry Finger void rtl92se_enable_interrupt(struct ieee80211_hw *hw)
1230f1d2b4d3SLarry Finger {
1231f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1232f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1233f1d2b4d3SLarry Finger
1234f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, INTA_MASK, rtlpci->irq_mask[0]);
1235f1d2b4d3SLarry Finger /* Support Bit 32-37(Assign as Bit 0-5) interrupt setting now */
1236f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, INTA_MASK + 4, rtlpci->irq_mask[1] & 0x3F);
1237f1d2b4d3SLarry Finger rtlpci->irq_enabled = true;
1238f1d2b4d3SLarry Finger }
1239f1d2b4d3SLarry Finger
rtl92se_disable_interrupt(struct ieee80211_hw * hw)1240f1d2b4d3SLarry Finger void rtl92se_disable_interrupt(struct ieee80211_hw *hw)
1241f1d2b4d3SLarry Finger {
1242f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv;
1243f1d2b4d3SLarry Finger struct rtl_pci *rtlpci;
1244f1d2b4d3SLarry Finger
1245f1d2b4d3SLarry Finger rtlpriv = rtl_priv(hw);
1246f1d2b4d3SLarry Finger /* if firmware not available, no interrupts */
1247f1d2b4d3SLarry Finger if (!rtlpriv || !rtlpriv->max_fw_size)
1248f1d2b4d3SLarry Finger return;
1249f1d2b4d3SLarry Finger rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1250f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, INTA_MASK, 0);
1251f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, INTA_MASK + 4, 0);
1252f1d2b4d3SLarry Finger rtlpci->irq_enabled = false;
1253f1d2b4d3SLarry Finger }
1254f1d2b4d3SLarry Finger
_rtl92s_set_sysclk(struct ieee80211_hw * hw,u8 data)1255f1d2b4d3SLarry Finger static u8 _rtl92s_set_sysclk(struct ieee80211_hw *hw, u8 data)
1256f1d2b4d3SLarry Finger {
1257f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1258f1d2b4d3SLarry Finger u8 waitcnt = 100;
1259f1d2b4d3SLarry Finger bool result = false;
1260f1d2b4d3SLarry Finger u8 tmp;
1261f1d2b4d3SLarry Finger
1262f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, SYS_CLKR + 1, data);
1263f1d2b4d3SLarry Finger
1264f1d2b4d3SLarry Finger /* Wait the MAC synchronized. */
1265f1d2b4d3SLarry Finger udelay(400);
1266f1d2b4d3SLarry Finger
1267f1d2b4d3SLarry Finger /* Check if it is set ready. */
1268f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, SYS_CLKR + 1);
1269f1d2b4d3SLarry Finger result = ((tmp & BIT(7)) == (data & BIT(7)));
1270f1d2b4d3SLarry Finger
127133ae4623SAditya Srivastava if (!(data & (BIT(6) | BIT(7)))) {
1272f1d2b4d3SLarry Finger waitcnt = 100;
1273f1d2b4d3SLarry Finger tmp = 0;
1274f1d2b4d3SLarry Finger
1275f1d2b4d3SLarry Finger while (1) {
1276f1d2b4d3SLarry Finger waitcnt--;
1277f1d2b4d3SLarry Finger tmp = rtl_read_byte(rtlpriv, SYS_CLKR + 1);
1278f1d2b4d3SLarry Finger
1279f1d2b4d3SLarry Finger if ((tmp & BIT(6)))
1280f1d2b4d3SLarry Finger break;
1281f1d2b4d3SLarry Finger
1282f1d2b4d3SLarry Finger pr_err("wait for BIT(6) return value %x\n", tmp);
1283f1d2b4d3SLarry Finger
1284f1d2b4d3SLarry Finger if (waitcnt == 0)
1285f1d2b4d3SLarry Finger break;
1286f1d2b4d3SLarry Finger udelay(10);
1287f1d2b4d3SLarry Finger }
1288f1d2b4d3SLarry Finger
1289f1d2b4d3SLarry Finger if (waitcnt == 0)
1290f1d2b4d3SLarry Finger result = false;
1291f1d2b4d3SLarry Finger else
1292f1d2b4d3SLarry Finger result = true;
1293f1d2b4d3SLarry Finger }
1294f1d2b4d3SLarry Finger
1295f1d2b4d3SLarry Finger return result;
1296f1d2b4d3SLarry Finger }
1297f1d2b4d3SLarry Finger
_rtl92s_phy_set_rfhalt(struct ieee80211_hw * hw)1298f1d2b4d3SLarry Finger static void _rtl92s_phy_set_rfhalt(struct ieee80211_hw *hw)
1299f1d2b4d3SLarry Finger {
1300f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1301f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1302f1d2b4d3SLarry Finger struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1303f1d2b4d3SLarry Finger u8 u1btmp;
1304f1d2b4d3SLarry Finger
1305f1d2b4d3SLarry Finger if (rtlhal->driver_is_goingto_unload)
1306f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x560, 0x0);
1307f1d2b4d3SLarry Finger
1308f1d2b4d3SLarry Finger /* Power save for BB/RF */
1309f1d2b4d3SLarry Finger u1btmp = rtl_read_byte(rtlpriv, LDOV12D_CTRL);
1310f1d2b4d3SLarry Finger u1btmp |= BIT(0);
1311f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, LDOV12D_CTRL, u1btmp);
1312f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, SPS1_CTRL, 0x0);
1313f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, TXPAUSE, 0xFF);
1314f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, CMDR, 0x57FC);
1315f1d2b4d3SLarry Finger udelay(100);
1316f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, CMDR, 0x77FC);
1317f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, PHY_CCA, 0x0);
1318f1d2b4d3SLarry Finger udelay(10);
1319f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, CMDR, 0x37FC);
1320f1d2b4d3SLarry Finger udelay(10);
1321f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, CMDR, 0x77FC);
1322f1d2b4d3SLarry Finger udelay(10);
1323f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, CMDR, 0x57FC);
1324f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, CMDR, 0x0000);
1325f1d2b4d3SLarry Finger
1326f1d2b4d3SLarry Finger if (rtlhal->driver_is_goingto_unload) {
1327f1d2b4d3SLarry Finger u1btmp = rtl_read_byte(rtlpriv, (REG_SYS_FUNC_EN + 1));
1328f1d2b4d3SLarry Finger u1btmp &= ~(BIT(0));
1329f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, u1btmp);
1330f1d2b4d3SLarry Finger }
1331f1d2b4d3SLarry Finger
1332f1d2b4d3SLarry Finger u1btmp = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
1333f1d2b4d3SLarry Finger
1334f1d2b4d3SLarry Finger /* Add description. After switch control path. register
1335f1d2b4d3SLarry Finger * after page1 will be invisible. We can not do any IO
1336f1d2b4d3SLarry Finger * for register>0x40. After resume&MACIO reset, we need
1337f1d2b4d3SLarry Finger * to remember previous reg content. */
1338f1d2b4d3SLarry Finger if (u1btmp & BIT(7)) {
1339f1d2b4d3SLarry Finger u1btmp &= ~(BIT(6) | BIT(7));
1340f1d2b4d3SLarry Finger if (!_rtl92s_set_sysclk(hw, u1btmp)) {
1341f1d2b4d3SLarry Finger pr_err("Switch ctrl path fail\n");
1342f1d2b4d3SLarry Finger return;
1343f1d2b4d3SLarry Finger }
1344f1d2b4d3SLarry Finger }
1345f1d2b4d3SLarry Finger
1346f1d2b4d3SLarry Finger /* Power save for MAC */
1347f1d2b4d3SLarry Finger if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS &&
1348f1d2b4d3SLarry Finger !rtlhal->driver_is_goingto_unload) {
1349f1d2b4d3SLarry Finger /* enable LED function */
1350f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x03, 0xF9);
1351f1d2b4d3SLarry Finger /* SW/HW radio off or halt adapter!! For example S3/S4 */
1352f1d2b4d3SLarry Finger } else {
1353f1d2b4d3SLarry Finger /* LED function disable. Power range is about 8mA now. */
1354e1b18549SGeert Uytterhoeven /* if write 0xF1 disconnect_pci power
1355f1d2b4d3SLarry Finger * ifconfig wlan0 down power are both high 35:70 */
1356e1b18549SGeert Uytterhoeven /* if write oxF9 disconnect_pci power
1357f1d2b4d3SLarry Finger * ifconfig wlan0 down power are both low 12:45*/
1358f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x03, 0xF9);
1359f1d2b4d3SLarry Finger }
1360f1d2b4d3SLarry Finger
1361f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, SYS_CLKR + 1, 0x70);
1362f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AFE_PLL_CTRL + 1, 0x68);
1363f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AFE_PLL_CTRL, 0x00);
1364f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34);
1365f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AFE_XTAL_CTRL, 0x0E);
1366f1d2b4d3SLarry Finger RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1367f1d2b4d3SLarry Finger
1368f1d2b4d3SLarry Finger }
1369f1d2b4d3SLarry Finger
_rtl92se_gen_refreshledstate(struct ieee80211_hw * hw)1370f1d2b4d3SLarry Finger static void _rtl92se_gen_refreshledstate(struct ieee80211_hw *hw)
1371f1d2b4d3SLarry Finger {
1372f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1373f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1374d5efe153SLarry Finger enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0;
1375f1d2b4d3SLarry Finger
137615085446SJiapeng Chong if (rtlpci->up_first_time)
1377f1d2b4d3SLarry Finger return;
1378f1d2b4d3SLarry Finger
1379f1d2b4d3SLarry Finger if (rtlpriv->psc.rfoff_reason == RF_CHANGE_BY_IPS)
1380d5efe153SLarry Finger rtl92se_sw_led_on(hw, pin0);
1381f1d2b4d3SLarry Finger else
1382d5efe153SLarry Finger rtl92se_sw_led_off(hw, pin0);
1383f1d2b4d3SLarry Finger }
1384f1d2b4d3SLarry Finger
1385f1d2b4d3SLarry Finger
_rtl92se_power_domain_init(struct ieee80211_hw * hw)1386f1d2b4d3SLarry Finger static void _rtl92se_power_domain_init(struct ieee80211_hw *hw)
1387f1d2b4d3SLarry Finger {
1388f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1389f1d2b4d3SLarry Finger u16 tmpu2b;
1390f1d2b4d3SLarry Finger u8 tmpu1b;
1391f1d2b4d3SLarry Finger
1392f1d2b4d3SLarry Finger rtlpriv->psc.pwrdomain_protect = true;
1393f1d2b4d3SLarry Finger
1394f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
1395f1d2b4d3SLarry Finger if (tmpu1b & BIT(7)) {
1396f1d2b4d3SLarry Finger tmpu1b &= ~(BIT(6) | BIT(7));
1397f1d2b4d3SLarry Finger if (!_rtl92s_set_sysclk(hw, tmpu1b)) {
1398f1d2b4d3SLarry Finger rtlpriv->psc.pwrdomain_protect = false;
1399f1d2b4d3SLarry Finger return;
1400f1d2b4d3SLarry Finger }
1401f1d2b4d3SLarry Finger }
1402f1d2b4d3SLarry Finger
1403f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AFE_PLL_CTRL, 0x0);
1404f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34);
1405f1d2b4d3SLarry Finger
1406f1d2b4d3SLarry Finger /* Reset MAC-IO and CPU and Core Digital BIT10/11/15 */
1407f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1408f1d2b4d3SLarry Finger
1409f1d2b4d3SLarry Finger /* If IPS we need to turn LED on. So we not
1410*9c817cb7SJilin Yuan * disable BIT 3/7 of reg3. */
1411f1d2b4d3SLarry Finger if (rtlpriv->psc.rfoff_reason & (RF_CHANGE_BY_IPS | RF_CHANGE_BY_HW))
1412f1d2b4d3SLarry Finger tmpu1b &= 0xFB;
1413f1d2b4d3SLarry Finger else
1414f1d2b4d3SLarry Finger tmpu1b &= 0x73;
1415f1d2b4d3SLarry Finger
1416f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b);
1417f1d2b4d3SLarry Finger /* wait for BIT 10/11/15 to pull high automatically!! */
1418f1d2b4d3SLarry Finger mdelay(1);
1419f1d2b4d3SLarry Finger
1420f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, CMDR, 0);
1421f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, TCR, 0);
1422f1d2b4d3SLarry Finger
1423f1d2b4d3SLarry Finger /* Data sheet not define 0x562!!! Copy from WMAC!!!!! */
1424f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, 0x562);
1425f1d2b4d3SLarry Finger tmpu1b |= 0x08;
1426f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x562, tmpu1b);
1427f1d2b4d3SLarry Finger tmpu1b &= ~(BIT(3));
1428f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, 0x562, tmpu1b);
1429f1d2b4d3SLarry Finger
1430f1d2b4d3SLarry Finger /* Enable AFE clock source */
1431f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL);
1432f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AFE_XTAL_CTRL, (tmpu1b | 0x01));
1433f1d2b4d3SLarry Finger /* Delay 1.5ms */
1434f1d2b4d3SLarry Finger udelay(1500);
1435f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL + 1);
1436f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, (tmpu1b & 0xfb));
1437f1d2b4d3SLarry Finger
1438f1d2b4d3SLarry Finger /* Enable AFE Macro Block's Bandgap */
1439f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC);
1440f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | BIT(0)));
1441f1d2b4d3SLarry Finger mdelay(1);
1442f1d2b4d3SLarry Finger
1443f1d2b4d3SLarry Finger /* Enable AFE Mbias */
1444f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC);
1445f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | 0x02));
1446f1d2b4d3SLarry Finger mdelay(1);
1447f1d2b4d3SLarry Finger
1448f1d2b4d3SLarry Finger /* Enable LDOA15 block */
1449f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, LDOA15_CTRL);
1450f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, LDOA15_CTRL, (tmpu1b | BIT(0)));
1451f1d2b4d3SLarry Finger
1452f1d2b4d3SLarry Finger /* Set Digital Vdd to Retention isolation Path. */
1453f1d2b4d3SLarry Finger tmpu2b = rtl_read_word(rtlpriv, REG_SYS_ISO_CTRL);
1454f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_SYS_ISO_CTRL, (tmpu2b | BIT(11)));
1455f1d2b4d3SLarry Finger
1456f1d2b4d3SLarry Finger
1457f1d2b4d3SLarry Finger /* For warm reboot NIC disappera bug. */
1458f1d2b4d3SLarry Finger tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
1459f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(13)));
1460f1d2b4d3SLarry Finger
1461f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x68);
1462f1d2b4d3SLarry Finger
1463f1d2b4d3SLarry Finger /* Enable AFE PLL Macro Block */
1464f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL);
1465f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4)));
1466f1d2b4d3SLarry Finger /* Enable MAC 80MHZ clock */
1467f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL + 1);
1468f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, AFE_PLL_CTRL + 1, (tmpu1b | BIT(0)));
1469f1d2b4d3SLarry Finger mdelay(1);
1470f1d2b4d3SLarry Finger
1471f1d2b4d3SLarry Finger /* Release isolation AFE PLL & MD */
1472f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, 0xA6);
1473f1d2b4d3SLarry Finger
1474f1d2b4d3SLarry Finger /* Enable MAC clock */
1475f1d2b4d3SLarry Finger tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR);
1476f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b | BIT(12) | BIT(11)));
1477f1d2b4d3SLarry Finger
1478f1d2b4d3SLarry Finger /* Enable Core digital and enable IOREG R/W */
1479f1d2b4d3SLarry Finger tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
1480f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11)));
1481f1d2b4d3SLarry Finger /* enable REG_EN */
1482f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11) | BIT(15)));
1483f1d2b4d3SLarry Finger
1484f1d2b4d3SLarry Finger /* Switch the control path. */
1485f1d2b4d3SLarry Finger tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR);
1486f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b & (~BIT(2))));
1487f1d2b4d3SLarry Finger
1488f1d2b4d3SLarry Finger tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
1489f1d2b4d3SLarry Finger tmpu1b = ((tmpu1b | BIT(7)) & (~BIT(6)));
1490f1d2b4d3SLarry Finger if (!_rtl92s_set_sysclk(hw, tmpu1b)) {
1491f1d2b4d3SLarry Finger rtlpriv->psc.pwrdomain_protect = false;
1492f1d2b4d3SLarry Finger return;
1493f1d2b4d3SLarry Finger }
1494f1d2b4d3SLarry Finger
1495f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, CMDR, 0x37FC);
1496f1d2b4d3SLarry Finger
1497f1d2b4d3SLarry Finger /* After MACIO reset,we must refresh LED state. */
1498f1d2b4d3SLarry Finger _rtl92se_gen_refreshledstate(hw);
1499f1d2b4d3SLarry Finger
1500f1d2b4d3SLarry Finger rtlpriv->psc.pwrdomain_protect = false;
1501f1d2b4d3SLarry Finger }
1502f1d2b4d3SLarry Finger
rtl92se_card_disable(struct ieee80211_hw * hw)1503f1d2b4d3SLarry Finger void rtl92se_card_disable(struct ieee80211_hw *hw)
1504f1d2b4d3SLarry Finger {
1505f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1506f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1507f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1508f1d2b4d3SLarry Finger struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1509f1d2b4d3SLarry Finger enum nl80211_iftype opmode;
1510f1d2b4d3SLarry Finger u8 wait = 30;
1511f1d2b4d3SLarry Finger
1512f1d2b4d3SLarry Finger rtlpriv->intf_ops->enable_aspm(hw);
1513f1d2b4d3SLarry Finger
1514f1d2b4d3SLarry Finger if (rtlpci->driver_is_goingto_unload ||
1515f1d2b4d3SLarry Finger ppsc->rfoff_reason > RF_CHANGE_BY_PS)
1516f1d2b4d3SLarry Finger rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
1517f1d2b4d3SLarry Finger
1518f1d2b4d3SLarry Finger /* we should chnge GPIO to input mode
1519f1d2b4d3SLarry Finger * this will drop away current about 25mA*/
1520f1d2b4d3SLarry Finger rtl8192se_gpiobit3_cfg_inputmode(hw);
1521f1d2b4d3SLarry Finger
1522f1d2b4d3SLarry Finger /* this is very important for ips power save */
1523f1d2b4d3SLarry Finger while (wait-- >= 10 && rtlpriv->psc.pwrdomain_protect) {
1524f1d2b4d3SLarry Finger if (rtlpriv->psc.pwrdomain_protect)
1525f1d2b4d3SLarry Finger mdelay(20);
1526f1d2b4d3SLarry Finger else
1527f1d2b4d3SLarry Finger break;
1528f1d2b4d3SLarry Finger }
1529f1d2b4d3SLarry Finger
1530f1d2b4d3SLarry Finger mac->link_state = MAC80211_NOLINK;
1531f1d2b4d3SLarry Finger opmode = NL80211_IFTYPE_UNSPECIFIED;
1532f1d2b4d3SLarry Finger _rtl92se_set_media_status(hw, opmode);
1533f1d2b4d3SLarry Finger
1534f1d2b4d3SLarry Finger _rtl92s_phy_set_rfhalt(hw);
1535f1d2b4d3SLarry Finger udelay(100);
1536f1d2b4d3SLarry Finger }
1537f1d2b4d3SLarry Finger
rtl92se_interrupt_recognized(struct ieee80211_hw * hw,struct rtl_int * intvec)153878aa6012SLarry Finger void rtl92se_interrupt_recognized(struct ieee80211_hw *hw,
153978aa6012SLarry Finger struct rtl_int *intvec)
1540f1d2b4d3SLarry Finger {
1541f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1542f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1543f1d2b4d3SLarry Finger
154478aa6012SLarry Finger intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0];
154578aa6012SLarry Finger rtl_write_dword(rtlpriv, ISR, intvec->inta);
1546f1d2b4d3SLarry Finger
154778aa6012SLarry Finger intvec->intb = rtl_read_dword(rtlpriv, ISR + 4) & rtlpci->irq_mask[1];
154878aa6012SLarry Finger rtl_write_dword(rtlpriv, ISR + 4, intvec->intb);
1549f1d2b4d3SLarry Finger }
1550f1d2b4d3SLarry Finger
rtl92se_set_beacon_related_registers(struct ieee80211_hw * hw)1551f1d2b4d3SLarry Finger void rtl92se_set_beacon_related_registers(struct ieee80211_hw *hw)
1552f1d2b4d3SLarry Finger {
1553f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1554f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1555f1d2b4d3SLarry Finger u16 atim_window = 2;
1556f1d2b4d3SLarry Finger
1557f1d2b4d3SLarry Finger /* ATIM Window (in unit of TU). */
1558f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, ATIMWND, atim_window);
1559f1d2b4d3SLarry Finger
1560f1d2b4d3SLarry Finger /* Beacon interval (in unit of TU). */
1561f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, BCN_INTERVAL, mac->beacon_interval);
1562f1d2b4d3SLarry Finger
1563f1d2b4d3SLarry Finger /* DrvErlyInt (in unit of TU). (Time to send
1564f1d2b4d3SLarry Finger * interrupt to notify driver to change
1565f1d2b4d3SLarry Finger * beacon content) */
1566f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, BCN_DRV_EARLY_INT, 10 << 4);
1567f1d2b4d3SLarry Finger
1568f1d2b4d3SLarry Finger /* BcnDMATIM(in unit of us). Indicates the
1569f1d2b4d3SLarry Finger * time before TBTT to perform beacon queue DMA */
1570f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, BCN_DMATIME, 256);
1571f1d2b4d3SLarry Finger
1572f1d2b4d3SLarry Finger /* Force beacon frame transmission even
1573f1d2b4d3SLarry Finger * after receiving beacon frame from
1574f1d2b4d3SLarry Finger * other ad hoc STA */
1575f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, BCN_ERR_THRESH, 100);
1576f1d2b4d3SLarry Finger
1577f1d2b4d3SLarry Finger /*for beacon changed */
1578f1d2b4d3SLarry Finger rtl92s_phy_set_beacon_hwreg(hw, mac->beacon_interval);
1579f1d2b4d3SLarry Finger }
1580f1d2b4d3SLarry Finger
rtl92se_set_beacon_interval(struct ieee80211_hw * hw)1581f1d2b4d3SLarry Finger void rtl92se_set_beacon_interval(struct ieee80211_hw *hw)
1582f1d2b4d3SLarry Finger {
1583f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1584f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1585f1d2b4d3SLarry Finger u16 bcn_interval = mac->beacon_interval;
1586f1d2b4d3SLarry Finger
1587f1d2b4d3SLarry Finger /* Beacon interval (in unit of TU). */
1588f1d2b4d3SLarry Finger rtl_write_word(rtlpriv, BCN_INTERVAL, bcn_interval);
1589f1d2b4d3SLarry Finger /* 2008.10.24 added by tynli for beacon changed. */
1590f1d2b4d3SLarry Finger rtl92s_phy_set_beacon_hwreg(hw, bcn_interval);
1591f1d2b4d3SLarry Finger }
1592f1d2b4d3SLarry Finger
rtl92se_update_interrupt_mask(struct ieee80211_hw * hw,u32 add_msr,u32 rm_msr)1593f1d2b4d3SLarry Finger void rtl92se_update_interrupt_mask(struct ieee80211_hw *hw,
1594f1d2b4d3SLarry Finger u32 add_msr, u32 rm_msr)
1595f1d2b4d3SLarry Finger {
1596f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1597f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
1598f1d2b4d3SLarry Finger
1599fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n",
1600f1d2b4d3SLarry Finger add_msr, rm_msr);
1601f1d2b4d3SLarry Finger
1602f1d2b4d3SLarry Finger if (add_msr)
1603f1d2b4d3SLarry Finger rtlpci->irq_mask[0] |= add_msr;
1604f1d2b4d3SLarry Finger
1605f1d2b4d3SLarry Finger if (rm_msr)
1606f1d2b4d3SLarry Finger rtlpci->irq_mask[0] &= (~rm_msr);
1607f1d2b4d3SLarry Finger
1608f1d2b4d3SLarry Finger rtl92se_disable_interrupt(hw);
1609f1d2b4d3SLarry Finger rtl92se_enable_interrupt(hw);
1610f1d2b4d3SLarry Finger }
1611f1d2b4d3SLarry Finger
_rtl8192se_get_ic_inferiority(struct ieee80211_hw * hw)16122a83ad1fSLarry Finger static void _rtl8192se_get_ic_inferiority(struct ieee80211_hw *hw)
1613f1d2b4d3SLarry Finger {
1614f1d2b4d3SLarry Finger struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1615f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1616f1d2b4d3SLarry Finger u8 efuse_id;
1617f1d2b4d3SLarry Finger
1618f1d2b4d3SLarry Finger rtlhal->ic_class = IC_INFERIORITY_A;
1619f1d2b4d3SLarry Finger
1620f1d2b4d3SLarry Finger /* Only retrieving while using EFUSE. */
1621f1d2b4d3SLarry Finger if ((rtlefuse->epromtype == EEPROM_BOOT_EFUSE) &&
1622f1d2b4d3SLarry Finger !rtlefuse->autoload_failflag) {
1623f1d2b4d3SLarry Finger efuse_id = efuse_read_1byte(hw, EFUSE_IC_ID_OFFSET);
1624f1d2b4d3SLarry Finger
1625f1d2b4d3SLarry Finger if (efuse_id == 0xfe)
1626f1d2b4d3SLarry Finger rtlhal->ic_class = IC_INFERIORITY_B;
1627f1d2b4d3SLarry Finger }
1628f1d2b4d3SLarry Finger }
1629f1d2b4d3SLarry Finger
_rtl92se_read_adapter_info(struct ieee80211_hw * hw)1630f1d2b4d3SLarry Finger static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
1631f1d2b4d3SLarry Finger {
1632f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1633f1d2b4d3SLarry Finger struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1634f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
16355345ea6aSArnd Bergmann struct device *dev = &rtl_pcipriv(hw)->dev.pdev->dev;
1636f1d2b4d3SLarry Finger u16 i, usvalue;
1637f1d2b4d3SLarry Finger u16 eeprom_id;
1638f1d2b4d3SLarry Finger u8 tempval;
1639f1d2b4d3SLarry Finger u8 hwinfo[HWSET_MAX_SIZE_92S];
1640f1d2b4d3SLarry Finger u8 rf_path, index;
1641f1d2b4d3SLarry Finger
16425345ea6aSArnd Bergmann switch (rtlefuse->epromtype) {
16435345ea6aSArnd Bergmann case EEPROM_BOOT_EFUSE:
16445345ea6aSArnd Bergmann rtl_efuse_shadow_map_update(hw);
16455345ea6aSArnd Bergmann break;
16465345ea6aSArnd Bergmann
16475345ea6aSArnd Bergmann case EEPROM_93C46:
16482d15acacSLarry Finger pr_err("RTL819X Not boot from eeprom, check it !!\n");
16495345ea6aSArnd Bergmann return;
1650f1d2b4d3SLarry Finger
16515345ea6aSArnd Bergmann default:
16525345ea6aSArnd Bergmann dev_warn(dev, "no efuse data\n");
16535345ea6aSArnd Bergmann return;
1654f1d2b4d3SLarry Finger }
1655f1d2b4d3SLarry Finger
16565345ea6aSArnd Bergmann memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
16575345ea6aSArnd Bergmann HWSET_MAX_SIZE_92S);
16585345ea6aSArnd Bergmann
1659f1d2b4d3SLarry Finger RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP",
1660f1d2b4d3SLarry Finger hwinfo, HWSET_MAX_SIZE_92S);
1661f1d2b4d3SLarry Finger
1662f1d2b4d3SLarry Finger eeprom_id = *((u16 *)&hwinfo[0]);
1663f1d2b4d3SLarry Finger if (eeprom_id != RTL8190_EEPROM_ID) {
1664fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
1665f1d2b4d3SLarry Finger "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
1666f1d2b4d3SLarry Finger rtlefuse->autoload_failflag = true;
1667f1d2b4d3SLarry Finger } else {
1668fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
1669f1d2b4d3SLarry Finger rtlefuse->autoload_failflag = false;
1670f1d2b4d3SLarry Finger }
1671f1d2b4d3SLarry Finger
1672f1d2b4d3SLarry Finger if (rtlefuse->autoload_failflag)
1673f1d2b4d3SLarry Finger return;
1674f1d2b4d3SLarry Finger
16752a83ad1fSLarry Finger _rtl8192se_get_ic_inferiority(hw);
1676f1d2b4d3SLarry Finger
1677f1d2b4d3SLarry Finger /* Read IC Version && Channel Plan */
1678f1d2b4d3SLarry Finger /* VID, DID SE 0xA-D */
1679f1d2b4d3SLarry Finger rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID];
1680f1d2b4d3SLarry Finger rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID];
1681f1d2b4d3SLarry Finger rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID];
1682f1d2b4d3SLarry Finger rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID];
1683f1d2b4d3SLarry Finger rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
1684f1d2b4d3SLarry Finger
1685fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1686f1d2b4d3SLarry Finger "EEPROMId = 0x%4x\n", eeprom_id);
1687fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1688f1d2b4d3SLarry Finger "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid);
1689fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1690f1d2b4d3SLarry Finger "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did);
1691fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1692f1d2b4d3SLarry Finger "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid);
1693fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1694f1d2b4d3SLarry Finger "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid);
1695f1d2b4d3SLarry Finger
1696f1d2b4d3SLarry Finger for (i = 0; i < 6; i += 2) {
1697f1d2b4d3SLarry Finger usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i];
1698f1d2b4d3SLarry Finger *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue;
1699f1d2b4d3SLarry Finger }
1700f1d2b4d3SLarry Finger
1701f1d2b4d3SLarry Finger for (i = 0; i < 6; i++)
1702f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]);
1703f1d2b4d3SLarry Finger
1704fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr);
1705f1d2b4d3SLarry Finger
1706f1d2b4d3SLarry Finger /* Get Tx Power Level by Channel */
1707f1d2b4d3SLarry Finger /* Read Tx power of Channel 1 ~ 14 from EEPROM. */
1708f1d2b4d3SLarry Finger /* 92S suupport RF A & B */
1709f1d2b4d3SLarry Finger for (rf_path = 0; rf_path < 2; rf_path++) {
1710f1d2b4d3SLarry Finger for (i = 0; i < 3; i++) {
1711f1d2b4d3SLarry Finger /* Read CCK RF A & B Tx power */
1712f1d2b4d3SLarry Finger rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][i] =
1713f1d2b4d3SLarry Finger hwinfo[EEPROM_TXPOWERBASE + rf_path * 3 + i];
1714f1d2b4d3SLarry Finger
1715f1d2b4d3SLarry Finger /* Read OFDM RF A & B Tx power for 1T */
1716f1d2b4d3SLarry Finger rtlefuse->eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] =
1717f1d2b4d3SLarry Finger hwinfo[EEPROM_TXPOWERBASE + 6 + rf_path * 3 + i];
1718f1d2b4d3SLarry Finger
1719f1d2b4d3SLarry Finger /* Read OFDM RF A & B Tx power for 2T */
1720f1d2b4d3SLarry Finger rtlefuse->eprom_chnl_txpwr_ht40_2sdf[rf_path][i]
1721f1d2b4d3SLarry Finger = hwinfo[EEPROM_TXPOWERBASE + 12 +
1722f1d2b4d3SLarry Finger rf_path * 3 + i];
1723f1d2b4d3SLarry Finger }
1724f1d2b4d3SLarry Finger }
1725f1d2b4d3SLarry Finger
1726f1d2b4d3SLarry Finger for (rf_path = 0; rf_path < 2; rf_path++)
1727f1d2b4d3SLarry Finger for (i = 0; i < 3; i++)
1728f1d2b4d3SLarry Finger RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1729f1d2b4d3SLarry Finger "RF(%d) EEPROM CCK Area(%d) = 0x%x\n",
1730f1d2b4d3SLarry Finger rf_path, i,
1731f1d2b4d3SLarry Finger rtlefuse->eeprom_chnlarea_txpwr_cck
1732f1d2b4d3SLarry Finger [rf_path][i]);
1733f1d2b4d3SLarry Finger for (rf_path = 0; rf_path < 2; rf_path++)
1734f1d2b4d3SLarry Finger for (i = 0; i < 3; i++)
1735f1d2b4d3SLarry Finger RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1736f1d2b4d3SLarry Finger "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
1737f1d2b4d3SLarry Finger rf_path, i,
1738f1d2b4d3SLarry Finger rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
1739f1d2b4d3SLarry Finger [rf_path][i]);
1740f1d2b4d3SLarry Finger for (rf_path = 0; rf_path < 2; rf_path++)
1741f1d2b4d3SLarry Finger for (i = 0; i < 3; i++)
1742f1d2b4d3SLarry Finger RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1743f1d2b4d3SLarry Finger "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
1744f1d2b4d3SLarry Finger rf_path, i,
1745f1d2b4d3SLarry Finger rtlefuse->eprom_chnl_txpwr_ht40_2sdf
1746f1d2b4d3SLarry Finger [rf_path][i]);
1747f1d2b4d3SLarry Finger
1748f1d2b4d3SLarry Finger for (rf_path = 0; rf_path < 2; rf_path++) {
1749f1d2b4d3SLarry Finger
1750f1d2b4d3SLarry Finger /* Assign dedicated channel tx power */
1751f1d2b4d3SLarry Finger for (i = 0; i < 14; i++) {
1752f1d2b4d3SLarry Finger /* channel 1~3 use the same Tx Power Level. */
1753f1d2b4d3SLarry Finger if (i < 3)
1754f1d2b4d3SLarry Finger index = 0;
1755f1d2b4d3SLarry Finger /* Channel 4-8 */
1756f1d2b4d3SLarry Finger else if (i < 8)
1757f1d2b4d3SLarry Finger index = 1;
1758f1d2b4d3SLarry Finger /* Channel 9-14 */
1759f1d2b4d3SLarry Finger else
1760f1d2b4d3SLarry Finger index = 2;
1761f1d2b4d3SLarry Finger
1762f1d2b4d3SLarry Finger /* Record A & B CCK /OFDM - 1T/2T Channel area
1763f1d2b4d3SLarry Finger * tx power */
1764f1d2b4d3SLarry Finger rtlefuse->txpwrlevel_cck[rf_path][i] =
1765f1d2b4d3SLarry Finger rtlefuse->eeprom_chnlarea_txpwr_cck
1766f1d2b4d3SLarry Finger [rf_path][index];
1767f1d2b4d3SLarry Finger rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
1768f1d2b4d3SLarry Finger rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
1769f1d2b4d3SLarry Finger [rf_path][index];
1770f1d2b4d3SLarry Finger rtlefuse->txpwrlevel_ht40_2s[rf_path][i] =
1771f1d2b4d3SLarry Finger rtlefuse->eprom_chnl_txpwr_ht40_2sdf
1772f1d2b4d3SLarry Finger [rf_path][index];
1773f1d2b4d3SLarry Finger }
1774f1d2b4d3SLarry Finger
1775f1d2b4d3SLarry Finger for (i = 0; i < 14; i++) {
1776f1d2b4d3SLarry Finger RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1777f1d2b4d3SLarry Finger "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n",
1778f1d2b4d3SLarry Finger rf_path, i,
1779f1d2b4d3SLarry Finger rtlefuse->txpwrlevel_cck[rf_path][i],
1780f1d2b4d3SLarry Finger rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
1781f1d2b4d3SLarry Finger rtlefuse->txpwrlevel_ht40_2s[rf_path][i]);
1782f1d2b4d3SLarry Finger }
1783f1d2b4d3SLarry Finger }
1784f1d2b4d3SLarry Finger
1785f1d2b4d3SLarry Finger for (rf_path = 0; rf_path < 2; rf_path++) {
1786f1d2b4d3SLarry Finger for (i = 0; i < 3; i++) {
1787f1d2b4d3SLarry Finger /* Read Power diff limit. */
1788f1d2b4d3SLarry Finger rtlefuse->eeprom_pwrgroup[rf_path][i] =
1789f1d2b4d3SLarry Finger hwinfo[EEPROM_TXPWRGROUP + rf_path * 3 + i];
1790f1d2b4d3SLarry Finger }
1791f1d2b4d3SLarry Finger }
1792f1d2b4d3SLarry Finger
1793f1d2b4d3SLarry Finger for (rf_path = 0; rf_path < 2; rf_path++) {
1794f1d2b4d3SLarry Finger /* Fill Pwr group */
1795f1d2b4d3SLarry Finger for (i = 0; i < 14; i++) {
1796f1d2b4d3SLarry Finger /* Chanel 1-3 */
1797f1d2b4d3SLarry Finger if (i < 3)
1798f1d2b4d3SLarry Finger index = 0;
1799f1d2b4d3SLarry Finger /* Channel 4-8 */
1800f1d2b4d3SLarry Finger else if (i < 8)
1801f1d2b4d3SLarry Finger index = 1;
1802f1d2b4d3SLarry Finger /* Channel 9-13 */
1803f1d2b4d3SLarry Finger else
1804f1d2b4d3SLarry Finger index = 2;
1805f1d2b4d3SLarry Finger
1806f1d2b4d3SLarry Finger rtlefuse->pwrgroup_ht20[rf_path][i] =
1807f1d2b4d3SLarry Finger (rtlefuse->eeprom_pwrgroup[rf_path][index] &
1808f1d2b4d3SLarry Finger 0xf);
1809f1d2b4d3SLarry Finger rtlefuse->pwrgroup_ht40[rf_path][i] =
1810f1d2b4d3SLarry Finger ((rtlefuse->eeprom_pwrgroup[rf_path][index] &
1811f1d2b4d3SLarry Finger 0xf0) >> 4);
1812f1d2b4d3SLarry Finger
1813f1d2b4d3SLarry Finger RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1814f1d2b4d3SLarry Finger "RF-%d pwrgroup_ht20[%d] = 0x%x\n",
1815f1d2b4d3SLarry Finger rf_path, i,
1816f1d2b4d3SLarry Finger rtlefuse->pwrgroup_ht20[rf_path][i]);
1817f1d2b4d3SLarry Finger RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1818f1d2b4d3SLarry Finger "RF-%d pwrgroup_ht40[%d] = 0x%x\n",
1819f1d2b4d3SLarry Finger rf_path, i,
1820f1d2b4d3SLarry Finger rtlefuse->pwrgroup_ht40[rf_path][i]);
1821f1d2b4d3SLarry Finger }
1822f1d2b4d3SLarry Finger }
1823f1d2b4d3SLarry Finger
1824f1d2b4d3SLarry Finger for (i = 0; i < 14; i++) {
1825f1d2b4d3SLarry Finger /* Read tx power difference between HT OFDM 20/40 MHZ */
1826f1d2b4d3SLarry Finger /* channel 1-3 */
1827f1d2b4d3SLarry Finger if (i < 3)
1828f1d2b4d3SLarry Finger index = 0;
1829f1d2b4d3SLarry Finger /* Channel 4-8 */
1830f1d2b4d3SLarry Finger else if (i < 8)
1831f1d2b4d3SLarry Finger index = 1;
1832f1d2b4d3SLarry Finger /* Channel 9-14 */
1833f1d2b4d3SLarry Finger else
1834f1d2b4d3SLarry Finger index = 2;
1835f1d2b4d3SLarry Finger
1836f1d2b4d3SLarry Finger tempval = hwinfo[EEPROM_TX_PWR_HT20_DIFF + index] & 0xff;
1837f1d2b4d3SLarry Finger rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF);
1838f1d2b4d3SLarry Finger rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] =
1839f1d2b4d3SLarry Finger ((tempval >> 4) & 0xF);
1840f1d2b4d3SLarry Finger
1841f1d2b4d3SLarry Finger /* Read OFDM<->HT tx power diff */
1842f1d2b4d3SLarry Finger /* Channel 1-3 */
1843f1d2b4d3SLarry Finger if (i < 3)
1844f1d2b4d3SLarry Finger index = 0;
1845f1d2b4d3SLarry Finger /* Channel 4-8 */
1846f1d2b4d3SLarry Finger else if (i < 8)
1847f1d2b4d3SLarry Finger index = 0x11;
1848f1d2b4d3SLarry Finger /* Channel 9-14 */
1849f1d2b4d3SLarry Finger else
1850f1d2b4d3SLarry Finger index = 1;
1851f1d2b4d3SLarry Finger
1852f1d2b4d3SLarry Finger tempval = hwinfo[EEPROM_TX_PWR_OFDM_DIFF + index] & 0xff;
1853f1d2b4d3SLarry Finger rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] =
1854f1d2b4d3SLarry Finger (tempval & 0xF);
1855f1d2b4d3SLarry Finger rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] =
1856f1d2b4d3SLarry Finger ((tempval >> 4) & 0xF);
1857f1d2b4d3SLarry Finger
1858f1d2b4d3SLarry Finger tempval = hwinfo[TX_PWR_SAFETY_CHK];
1859f1d2b4d3SLarry Finger rtlefuse->txpwr_safetyflag = (tempval & 0x01);
1860f1d2b4d3SLarry Finger }
1861f1d2b4d3SLarry Finger
1862f1d2b4d3SLarry Finger rtlefuse->eeprom_regulatory = 0;
1863f1d2b4d3SLarry Finger if (rtlefuse->eeprom_version >= 2) {
1864f1d2b4d3SLarry Finger /* BIT(0)~2 */
1865f1d2b4d3SLarry Finger if (rtlefuse->eeprom_version >= 4)
1866f1d2b4d3SLarry Finger rtlefuse->eeprom_regulatory =
1867f1d2b4d3SLarry Finger (hwinfo[EEPROM_REGULATORY] & 0x7);
1868f1d2b4d3SLarry Finger else /* BIT(0) */
1869f1d2b4d3SLarry Finger rtlefuse->eeprom_regulatory =
1870f1d2b4d3SLarry Finger (hwinfo[EEPROM_REGULATORY] & 0x1);
1871f1d2b4d3SLarry Finger }
1872f1d2b4d3SLarry Finger RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1873f1d2b4d3SLarry Finger "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
1874f1d2b4d3SLarry Finger
1875f1d2b4d3SLarry Finger for (i = 0; i < 14; i++)
1876f1d2b4d3SLarry Finger RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1877f1d2b4d3SLarry Finger "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n",
1878f1d2b4d3SLarry Finger i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]);
1879f1d2b4d3SLarry Finger for (i = 0; i < 14; i++)
1880f1d2b4d3SLarry Finger RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1881f1d2b4d3SLarry Finger "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n",
1882f1d2b4d3SLarry Finger i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]);
1883f1d2b4d3SLarry Finger for (i = 0; i < 14; i++)
1884f1d2b4d3SLarry Finger RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1885f1d2b4d3SLarry Finger "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n",
1886f1d2b4d3SLarry Finger i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]);
1887f1d2b4d3SLarry Finger for (i = 0; i < 14; i++)
1888f1d2b4d3SLarry Finger RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1889f1d2b4d3SLarry Finger "RF-B Legacy to HT40 Diff[%d] = 0x%x\n",
1890f1d2b4d3SLarry Finger i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]);
1891f1d2b4d3SLarry Finger
1892f1d2b4d3SLarry Finger RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1893f1d2b4d3SLarry Finger "TxPwrSafetyFlag = %d\n", rtlefuse->txpwr_safetyflag);
1894f1d2b4d3SLarry Finger
1895f1d2b4d3SLarry Finger /* Read RF-indication and Tx Power gain
1896f1d2b4d3SLarry Finger * index diff of legacy to HT OFDM rate. */
1897f1d2b4d3SLarry Finger tempval = hwinfo[EEPROM_RFIND_POWERDIFF] & 0xff;
1898f1d2b4d3SLarry Finger rtlefuse->eeprom_txpowerdiff = tempval;
18998b2426c5SChris Chiu rtlefuse->legacy_ht_txpowerdiff =
1900f1d2b4d3SLarry Finger rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][0];
1901f1d2b4d3SLarry Finger
1902f1d2b4d3SLarry Finger RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1903f1d2b4d3SLarry Finger "TxPowerDiff = %#x\n", rtlefuse->eeprom_txpowerdiff);
1904f1d2b4d3SLarry Finger
1905f1d2b4d3SLarry Finger /* Get TSSI value for each path. */
1906f1d2b4d3SLarry Finger usvalue = *(u16 *)&hwinfo[EEPROM_TSSI_A];
1907f1d2b4d3SLarry Finger rtlefuse->eeprom_tssi[RF90_PATH_A] = (u8)((usvalue & 0xff00) >> 8);
1908f1d2b4d3SLarry Finger usvalue = hwinfo[EEPROM_TSSI_B];
1909f1d2b4d3SLarry Finger rtlefuse->eeprom_tssi[RF90_PATH_B] = (u8)(usvalue & 0xff);
1910f1d2b4d3SLarry Finger
1911f1d2b4d3SLarry Finger RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "TSSI_A = 0x%x, TSSI_B = 0x%x\n",
1912f1d2b4d3SLarry Finger rtlefuse->eeprom_tssi[RF90_PATH_A],
1913f1d2b4d3SLarry Finger rtlefuse->eeprom_tssi[RF90_PATH_B]);
1914f1d2b4d3SLarry Finger
1915f1d2b4d3SLarry Finger /* Read antenna tx power offset of B/C/D to A from EEPROM */
1916f1d2b4d3SLarry Finger /* and read ThermalMeter from EEPROM */
1917f1d2b4d3SLarry Finger tempval = hwinfo[EEPROM_THERMALMETER];
1918f1d2b4d3SLarry Finger rtlefuse->eeprom_thermalmeter = tempval;
1919f1d2b4d3SLarry Finger RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1920f1d2b4d3SLarry Finger "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
1921f1d2b4d3SLarry Finger
1922f1d2b4d3SLarry Finger /* ThermalMeter, BIT(0)~3 for RFIC1, BIT(4)~7 for RFIC2 */
1923f1d2b4d3SLarry Finger rtlefuse->thermalmeter[0] = (rtlefuse->eeprom_thermalmeter & 0x1f);
1924f1d2b4d3SLarry Finger rtlefuse->tssi_13dbm = rtlefuse->eeprom_thermalmeter * 100;
1925f1d2b4d3SLarry Finger
1926f1d2b4d3SLarry Finger /* Read CrystalCap from EEPROM */
1927f1d2b4d3SLarry Finger tempval = hwinfo[EEPROM_CRYSTALCAP] >> 4;
1928f1d2b4d3SLarry Finger rtlefuse->eeprom_crystalcap = tempval;
1929f1d2b4d3SLarry Finger /* CrystalCap, BIT(12)~15 */
1930f1d2b4d3SLarry Finger rtlefuse->crystalcap = rtlefuse->eeprom_crystalcap;
1931f1d2b4d3SLarry Finger
1932f1d2b4d3SLarry Finger /* Read IC Version && Channel Plan */
1933f1d2b4d3SLarry Finger /* Version ID, Channel plan */
1934f1d2b4d3SLarry Finger rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN];
1935f1d2b4d3SLarry Finger rtlefuse->txpwr_fromeprom = true;
1936f1d2b4d3SLarry Finger RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
1937f1d2b4d3SLarry Finger "EEPROM ChannelPlan = 0x%4x\n", rtlefuse->eeprom_channelplan);
1938f1d2b4d3SLarry Finger
1939f1d2b4d3SLarry Finger /* Read Customer ID or Board Type!!! */
1940f1d2b4d3SLarry Finger tempval = hwinfo[EEPROM_BOARDTYPE];
1941f1d2b4d3SLarry Finger /* Change RF type definition */
1942f1d2b4d3SLarry Finger if (tempval == 0)
1943f1d2b4d3SLarry Finger rtlphy->rf_type = RF_2T2R;
1944f1d2b4d3SLarry Finger else if (tempval == 1)
1945f1d2b4d3SLarry Finger rtlphy->rf_type = RF_1T2R;
1946f1d2b4d3SLarry Finger else if (tempval == 2)
1947f1d2b4d3SLarry Finger rtlphy->rf_type = RF_1T2R;
1948f1d2b4d3SLarry Finger else if (tempval == 3)
1949f1d2b4d3SLarry Finger rtlphy->rf_type = RF_1T1R;
1950f1d2b4d3SLarry Finger
1951f1d2b4d3SLarry Finger /* 1T2R but 1SS (1x1 receive combining) */
1952f1d2b4d3SLarry Finger rtlefuse->b1x1_recvcombine = false;
1953f1d2b4d3SLarry Finger if (rtlphy->rf_type == RF_1T2R) {
1954f1d2b4d3SLarry Finger tempval = rtl_read_byte(rtlpriv, 0x07);
1955f1d2b4d3SLarry Finger if (!(tempval & BIT(0))) {
1956f1d2b4d3SLarry Finger rtlefuse->b1x1_recvcombine = true;
1957fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
1958f1d2b4d3SLarry Finger "RF_TYPE=1T2R but only 1SS\n");
1959f1d2b4d3SLarry Finger }
1960f1d2b4d3SLarry Finger }
1961f1d2b4d3SLarry Finger rtlefuse->b1ss_support = rtlefuse->b1x1_recvcombine;
1962f1d2b4d3SLarry Finger rtlefuse->eeprom_oemid = *&hwinfo[EEPROM_CUSTOMID];
1963f1d2b4d3SLarry Finger
1964fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x\n",
1965f1d2b4d3SLarry Finger rtlefuse->eeprom_oemid);
1966f1d2b4d3SLarry Finger
1967f1d2b4d3SLarry Finger /* set channel paln to world wide 13 */
1968f1d2b4d3SLarry Finger rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13;
1969f1d2b4d3SLarry Finger }
1970f1d2b4d3SLarry Finger
rtl92se_read_eeprom_info(struct ieee80211_hw * hw)1971f1d2b4d3SLarry Finger void rtl92se_read_eeprom_info(struct ieee80211_hw *hw)
1972f1d2b4d3SLarry Finger {
1973f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
1974f1d2b4d3SLarry Finger struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1975f1d2b4d3SLarry Finger u8 tmp_u1b = 0;
1976f1d2b4d3SLarry Finger
1977f1d2b4d3SLarry Finger tmp_u1b = rtl_read_byte(rtlpriv, EPROM_CMD);
1978f1d2b4d3SLarry Finger
1979f1d2b4d3SLarry Finger if (tmp_u1b & BIT(4)) {
1980fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n");
1981f1d2b4d3SLarry Finger rtlefuse->epromtype = EEPROM_93C46;
1982f1d2b4d3SLarry Finger } else {
1983fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n");
1984f1d2b4d3SLarry Finger rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
1985f1d2b4d3SLarry Finger }
1986f1d2b4d3SLarry Finger
1987f1d2b4d3SLarry Finger if (tmp_u1b & BIT(5)) {
1988fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
1989f1d2b4d3SLarry Finger rtlefuse->autoload_failflag = false;
1990f1d2b4d3SLarry Finger _rtl92se_read_adapter_info(hw);
1991f1d2b4d3SLarry Finger } else {
19922d15acacSLarry Finger pr_err("Autoload ERR!!\n");
1993f1d2b4d3SLarry Finger rtlefuse->autoload_failflag = true;
1994f1d2b4d3SLarry Finger }
1995f1d2b4d3SLarry Finger }
1996f1d2b4d3SLarry Finger
rtl92se_update_hal_rate_table(struct ieee80211_hw * hw,struct ieee80211_sta * sta)1997f1d2b4d3SLarry Finger static void rtl92se_update_hal_rate_table(struct ieee80211_hw *hw,
1998f1d2b4d3SLarry Finger struct ieee80211_sta *sta)
1999f1d2b4d3SLarry Finger {
2000f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
2001f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
2002f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2003f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2004f1d2b4d3SLarry Finger u32 ratr_value;
2005f1d2b4d3SLarry Finger u8 ratr_index = 0;
2006f1d2b4d3SLarry Finger u8 nmode = mac->ht_enable;
2007f1d2b4d3SLarry Finger u8 mimo_ps = IEEE80211_SMPS_OFF;
2008f1d2b4d3SLarry Finger u16 shortgi_rate = 0;
2009f1d2b4d3SLarry Finger u32 tmp_ratr_value = 0;
2010f1d2b4d3SLarry Finger u8 curtxbw_40mhz = mac->bw_40;
2011046d2e7cSSriram R u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
2012f1d2b4d3SLarry Finger 1 : 0;
2013046d2e7cSSriram R u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
2014f1d2b4d3SLarry Finger 1 : 0;
2015f1d2b4d3SLarry Finger enum wireless_mode wirelessmode = mac->mode;
2016f1d2b4d3SLarry Finger
2017f1d2b4d3SLarry Finger if (rtlhal->current_bandtype == BAND_ON_5G)
2018046d2e7cSSriram R ratr_value = sta->deflink.supp_rates[1] << 4;
2019f1d2b4d3SLarry Finger else
2020046d2e7cSSriram R ratr_value = sta->deflink.supp_rates[0];
2021f1d2b4d3SLarry Finger if (mac->opmode == NL80211_IFTYPE_ADHOC)
2022f1d2b4d3SLarry Finger ratr_value = 0xfff;
2023046d2e7cSSriram R ratr_value |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 |
2024046d2e7cSSriram R sta->deflink.ht_cap.mcs.rx_mask[0] << 12);
2025f1d2b4d3SLarry Finger switch (wirelessmode) {
2026f1d2b4d3SLarry Finger case WIRELESS_MODE_B:
2027f1d2b4d3SLarry Finger ratr_value &= 0x0000000D;
2028f1d2b4d3SLarry Finger break;
2029f1d2b4d3SLarry Finger case WIRELESS_MODE_G:
2030f1d2b4d3SLarry Finger ratr_value &= 0x00000FF5;
2031f1d2b4d3SLarry Finger break;
2032f1d2b4d3SLarry Finger case WIRELESS_MODE_N_24G:
2033f1d2b4d3SLarry Finger case WIRELESS_MODE_N_5G:
2034f1d2b4d3SLarry Finger nmode = 1;
2035f1d2b4d3SLarry Finger if (mimo_ps == IEEE80211_SMPS_STATIC) {
2036f1d2b4d3SLarry Finger ratr_value &= 0x0007F005;
2037f1d2b4d3SLarry Finger } else {
2038f1d2b4d3SLarry Finger u32 ratr_mask;
2039f1d2b4d3SLarry Finger
2040f1d2b4d3SLarry Finger if (get_rf_type(rtlphy) == RF_1T2R ||
2041f1d2b4d3SLarry Finger get_rf_type(rtlphy) == RF_1T1R) {
2042f1d2b4d3SLarry Finger if (curtxbw_40mhz)
2043f1d2b4d3SLarry Finger ratr_mask = 0x000ff015;
2044f1d2b4d3SLarry Finger else
2045f1d2b4d3SLarry Finger ratr_mask = 0x000ff005;
2046f1d2b4d3SLarry Finger } else {
2047f1d2b4d3SLarry Finger if (curtxbw_40mhz)
2048f1d2b4d3SLarry Finger ratr_mask = 0x0f0ff015;
2049f1d2b4d3SLarry Finger else
2050f1d2b4d3SLarry Finger ratr_mask = 0x0f0ff005;
2051f1d2b4d3SLarry Finger }
2052f1d2b4d3SLarry Finger
2053f1d2b4d3SLarry Finger ratr_value &= ratr_mask;
2054f1d2b4d3SLarry Finger }
2055f1d2b4d3SLarry Finger break;
2056f1d2b4d3SLarry Finger default:
2057f1d2b4d3SLarry Finger if (rtlphy->rf_type == RF_1T2R)
2058f1d2b4d3SLarry Finger ratr_value &= 0x000ff0ff;
2059f1d2b4d3SLarry Finger else
2060f1d2b4d3SLarry Finger ratr_value &= 0x0f0ff0ff;
2061f1d2b4d3SLarry Finger
2062f1d2b4d3SLarry Finger break;
2063f1d2b4d3SLarry Finger }
2064f1d2b4d3SLarry Finger
2065f1d2b4d3SLarry Finger if (rtlpriv->rtlhal.version >= VERSION_8192S_BCUT)
2066f1d2b4d3SLarry Finger ratr_value &= 0x0FFFFFFF;
2067f1d2b4d3SLarry Finger else if (rtlpriv->rtlhal.version == VERSION_8192S_ACUT)
2068f1d2b4d3SLarry Finger ratr_value &= 0x0FFFFFF0;
2069f1d2b4d3SLarry Finger
2070f1d2b4d3SLarry Finger if (nmode && ((curtxbw_40mhz &&
2071f1d2b4d3SLarry Finger curshortgi_40mhz) || (!curtxbw_40mhz &&
2072f1d2b4d3SLarry Finger curshortgi_20mhz))) {
2073f1d2b4d3SLarry Finger
2074f1d2b4d3SLarry Finger ratr_value |= 0x10000000;
2075f1d2b4d3SLarry Finger tmp_ratr_value = (ratr_value >> 12);
2076f1d2b4d3SLarry Finger
2077f1d2b4d3SLarry Finger for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
2078f1d2b4d3SLarry Finger if ((1 << shortgi_rate) & tmp_ratr_value)
2079f1d2b4d3SLarry Finger break;
2080f1d2b4d3SLarry Finger }
2081f1d2b4d3SLarry Finger
2082f1d2b4d3SLarry Finger shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
2083f1d2b4d3SLarry Finger (shortgi_rate << 4) | (shortgi_rate);
2084f1d2b4d3SLarry Finger
2085f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, SG_RATE, shortgi_rate);
2086f1d2b4d3SLarry Finger }
2087f1d2b4d3SLarry Finger
2088f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, ARFR0 + ratr_index * 4, ratr_value);
2089f1d2b4d3SLarry Finger if (ratr_value & 0xfffff000)
2090f1d2b4d3SLarry Finger rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_REFRESH_N);
2091f1d2b4d3SLarry Finger else
2092f1d2b4d3SLarry Finger rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_REFRESH_BG);
2093f1d2b4d3SLarry Finger
2094fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n",
2095f1d2b4d3SLarry Finger rtl_read_dword(rtlpriv, ARFR0));
2096f1d2b4d3SLarry Finger }
2097f1d2b4d3SLarry Finger
rtl92se_update_hal_rate_mask(struct ieee80211_hw * hw,struct ieee80211_sta * sta,u8 rssi_level,bool update_bw)2098f1d2b4d3SLarry Finger static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw,
2099f1d2b4d3SLarry Finger struct ieee80211_sta *sta,
21001d22b177SPing-Ke Shih u8 rssi_level, bool update_bw)
2101f1d2b4d3SLarry Finger {
2102f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
2103f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
2104f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2105f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2106f1d2b4d3SLarry Finger struct rtl_sta_info *sta_entry = NULL;
2107f1d2b4d3SLarry Finger u32 ratr_bitmap;
2108f1d2b4d3SLarry Finger u8 ratr_index = 0;
2109046d2e7cSSriram R u8 curtxbw_40mhz = (sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0;
2110046d2e7cSSriram R u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
2111f1d2b4d3SLarry Finger 1 : 0;
2112046d2e7cSSriram R u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
2113f1d2b4d3SLarry Finger 1 : 0;
2114f1d2b4d3SLarry Finger enum wireless_mode wirelessmode = 0;
2115f1d2b4d3SLarry Finger bool shortgi = false;
2116f1d2b4d3SLarry Finger u32 ratr_value = 0;
2117f1d2b4d3SLarry Finger u8 shortgi_rate = 0;
2118f1d2b4d3SLarry Finger u32 mask = 0;
2119f1d2b4d3SLarry Finger u32 band = 0;
2120f1d2b4d3SLarry Finger bool bmulticast = false;
2121f1d2b4d3SLarry Finger u8 macid = 0;
2122f1d2b4d3SLarry Finger u8 mimo_ps = IEEE80211_SMPS_OFF;
2123f1d2b4d3SLarry Finger
2124f1d2b4d3SLarry Finger sta_entry = (struct rtl_sta_info *) sta->drv_priv;
2125f1d2b4d3SLarry Finger wirelessmode = sta_entry->wireless_mode;
2126f1d2b4d3SLarry Finger if (mac->opmode == NL80211_IFTYPE_STATION)
2127f1d2b4d3SLarry Finger curtxbw_40mhz = mac->bw_40;
2128f1d2b4d3SLarry Finger else if (mac->opmode == NL80211_IFTYPE_AP ||
2129f1d2b4d3SLarry Finger mac->opmode == NL80211_IFTYPE_ADHOC)
2130f1d2b4d3SLarry Finger macid = sta->aid + 1;
2131f1d2b4d3SLarry Finger
2132f1d2b4d3SLarry Finger if (rtlhal->current_bandtype == BAND_ON_5G)
2133046d2e7cSSriram R ratr_bitmap = sta->deflink.supp_rates[1] << 4;
2134f1d2b4d3SLarry Finger else
2135046d2e7cSSriram R ratr_bitmap = sta->deflink.supp_rates[0];
2136f1d2b4d3SLarry Finger if (mac->opmode == NL80211_IFTYPE_ADHOC)
2137f1d2b4d3SLarry Finger ratr_bitmap = 0xfff;
2138046d2e7cSSriram R ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 |
2139046d2e7cSSriram R sta->deflink.ht_cap.mcs.rx_mask[0] << 12);
2140f1d2b4d3SLarry Finger switch (wirelessmode) {
2141f1d2b4d3SLarry Finger case WIRELESS_MODE_B:
2142f1d2b4d3SLarry Finger band |= WIRELESS_11B;
2143f1d2b4d3SLarry Finger ratr_index = RATR_INX_WIRELESS_B;
2144f1d2b4d3SLarry Finger if (ratr_bitmap & 0x0000000c)
2145f1d2b4d3SLarry Finger ratr_bitmap &= 0x0000000d;
2146f1d2b4d3SLarry Finger else
2147f1d2b4d3SLarry Finger ratr_bitmap &= 0x0000000f;
2148f1d2b4d3SLarry Finger break;
2149f1d2b4d3SLarry Finger case WIRELESS_MODE_G:
2150f1d2b4d3SLarry Finger band |= (WIRELESS_11G | WIRELESS_11B);
2151f1d2b4d3SLarry Finger ratr_index = RATR_INX_WIRELESS_GB;
2152f1d2b4d3SLarry Finger
2153f1d2b4d3SLarry Finger if (rssi_level == 1)
2154f1d2b4d3SLarry Finger ratr_bitmap &= 0x00000f00;
2155f1d2b4d3SLarry Finger else if (rssi_level == 2)
2156f1d2b4d3SLarry Finger ratr_bitmap &= 0x00000ff0;
2157f1d2b4d3SLarry Finger else
2158f1d2b4d3SLarry Finger ratr_bitmap &= 0x00000ff5;
2159f1d2b4d3SLarry Finger break;
2160f1d2b4d3SLarry Finger case WIRELESS_MODE_A:
2161f1d2b4d3SLarry Finger band |= WIRELESS_11A;
2162f1d2b4d3SLarry Finger ratr_index = RATR_INX_WIRELESS_A;
2163f1d2b4d3SLarry Finger ratr_bitmap &= 0x00000ff0;
2164f1d2b4d3SLarry Finger break;
2165f1d2b4d3SLarry Finger case WIRELESS_MODE_N_24G:
2166f1d2b4d3SLarry Finger case WIRELESS_MODE_N_5G:
2167f1d2b4d3SLarry Finger band |= (WIRELESS_11N | WIRELESS_11G | WIRELESS_11B);
2168f1d2b4d3SLarry Finger ratr_index = RATR_INX_WIRELESS_NGB;
2169f1d2b4d3SLarry Finger
2170f1d2b4d3SLarry Finger if (mimo_ps == IEEE80211_SMPS_STATIC) {
2171f1d2b4d3SLarry Finger if (rssi_level == 1)
2172f1d2b4d3SLarry Finger ratr_bitmap &= 0x00070000;
2173f1d2b4d3SLarry Finger else if (rssi_level == 2)
2174f1d2b4d3SLarry Finger ratr_bitmap &= 0x0007f000;
2175f1d2b4d3SLarry Finger else
2176f1d2b4d3SLarry Finger ratr_bitmap &= 0x0007f005;
2177f1d2b4d3SLarry Finger } else {
2178f1d2b4d3SLarry Finger if (rtlphy->rf_type == RF_1T2R ||
2179f1d2b4d3SLarry Finger rtlphy->rf_type == RF_1T1R) {
2180f1d2b4d3SLarry Finger if (rssi_level == 1) {
2181f1d2b4d3SLarry Finger ratr_bitmap &= 0x000f0000;
2182f1d2b4d3SLarry Finger } else if (rssi_level == 3) {
2183f1d2b4d3SLarry Finger ratr_bitmap &= 0x000fc000;
2184f1d2b4d3SLarry Finger } else if (rssi_level == 5) {
2185f1d2b4d3SLarry Finger ratr_bitmap &= 0x000ff000;
2186f1d2b4d3SLarry Finger } else {
2187f1d2b4d3SLarry Finger if (curtxbw_40mhz)
2188f1d2b4d3SLarry Finger ratr_bitmap &= 0x000ff015;
2189f1d2b4d3SLarry Finger else
2190f1d2b4d3SLarry Finger ratr_bitmap &= 0x000ff005;
2191f1d2b4d3SLarry Finger }
2192f1d2b4d3SLarry Finger } else {
2193f1d2b4d3SLarry Finger if (rssi_level == 1) {
2194f1d2b4d3SLarry Finger ratr_bitmap &= 0x0f8f0000;
2195f1d2b4d3SLarry Finger } else if (rssi_level == 3) {
2196f1d2b4d3SLarry Finger ratr_bitmap &= 0x0f8fc000;
2197f1d2b4d3SLarry Finger } else if (rssi_level == 5) {
2198f1d2b4d3SLarry Finger ratr_bitmap &= 0x0f8ff000;
2199f1d2b4d3SLarry Finger } else {
2200f1d2b4d3SLarry Finger if (curtxbw_40mhz)
2201f1d2b4d3SLarry Finger ratr_bitmap &= 0x0f8ff015;
2202f1d2b4d3SLarry Finger else
2203f1d2b4d3SLarry Finger ratr_bitmap &= 0x0f8ff005;
2204f1d2b4d3SLarry Finger }
2205f1d2b4d3SLarry Finger }
2206f1d2b4d3SLarry Finger }
2207f1d2b4d3SLarry Finger
2208f1d2b4d3SLarry Finger if ((curtxbw_40mhz && curshortgi_40mhz) ||
2209f1d2b4d3SLarry Finger (!curtxbw_40mhz && curshortgi_20mhz)) {
2210f1d2b4d3SLarry Finger if (macid == 0)
2211f1d2b4d3SLarry Finger shortgi = true;
2212f1d2b4d3SLarry Finger else if (macid == 1)
2213f1d2b4d3SLarry Finger shortgi = false;
2214f1d2b4d3SLarry Finger }
2215f1d2b4d3SLarry Finger break;
2216f1d2b4d3SLarry Finger default:
2217f1d2b4d3SLarry Finger band |= (WIRELESS_11N | WIRELESS_11G | WIRELESS_11B);
2218f1d2b4d3SLarry Finger ratr_index = RATR_INX_WIRELESS_NGB;
2219f1d2b4d3SLarry Finger
2220f1d2b4d3SLarry Finger if (rtlphy->rf_type == RF_1T2R)
2221f1d2b4d3SLarry Finger ratr_bitmap &= 0x000ff0ff;
2222f1d2b4d3SLarry Finger else
2223f1d2b4d3SLarry Finger ratr_bitmap &= 0x0f8ff0ff;
2224f1d2b4d3SLarry Finger break;
2225f1d2b4d3SLarry Finger }
2226f1d2b4d3SLarry Finger sta_entry->ratr_index = ratr_index;
2227f1d2b4d3SLarry Finger
2228f1d2b4d3SLarry Finger if (rtlpriv->rtlhal.version >= VERSION_8192S_BCUT)
2229f1d2b4d3SLarry Finger ratr_bitmap &= 0x0FFFFFFF;
2230f1d2b4d3SLarry Finger else if (rtlpriv->rtlhal.version == VERSION_8192S_ACUT)
2231f1d2b4d3SLarry Finger ratr_bitmap &= 0x0FFFFFF0;
2232f1d2b4d3SLarry Finger
2233f1d2b4d3SLarry Finger if (shortgi) {
2234f1d2b4d3SLarry Finger ratr_bitmap |= 0x10000000;
2235f1d2b4d3SLarry Finger /* Get MAX MCS available. */
2236f1d2b4d3SLarry Finger ratr_value = (ratr_bitmap >> 12);
2237f1d2b4d3SLarry Finger for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
2238f1d2b4d3SLarry Finger if ((1 << shortgi_rate) & ratr_value)
2239f1d2b4d3SLarry Finger break;
2240f1d2b4d3SLarry Finger }
2241f1d2b4d3SLarry Finger
2242f1d2b4d3SLarry Finger shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
2243f1d2b4d3SLarry Finger (shortgi_rate << 4) | (shortgi_rate);
2244f1d2b4d3SLarry Finger rtl_write_byte(rtlpriv, SG_RATE, shortgi_rate);
2245f1d2b4d3SLarry Finger }
2246f1d2b4d3SLarry Finger
2247f1d2b4d3SLarry Finger mask |= (bmulticast ? 1 : 0) << 9 | (macid & 0x1f) << 4 | (band & 0xf);
2248f1d2b4d3SLarry Finger
2249fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_RATR, DBG_TRACE, "mask = %x, bitmap = %x\n",
2250f1d2b4d3SLarry Finger mask, ratr_bitmap);
2251f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, 0x2c4, ratr_bitmap);
2252f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM5, (FW_RA_UPDATE_MASK | (mask << 8)));
2253f1d2b4d3SLarry Finger
2254f1d2b4d3SLarry Finger if (macid != 0)
2255f1d2b4d3SLarry Finger sta_entry->ratr_index = ratr_index;
2256f1d2b4d3SLarry Finger }
2257f1d2b4d3SLarry Finger
rtl92se_update_hal_rate_tbl(struct ieee80211_hw * hw,struct ieee80211_sta * sta,u8 rssi_level,bool update_bw)2258f1d2b4d3SLarry Finger void rtl92se_update_hal_rate_tbl(struct ieee80211_hw *hw,
22591d22b177SPing-Ke Shih struct ieee80211_sta *sta, u8 rssi_level, bool update_bw)
2260f1d2b4d3SLarry Finger {
2261f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
2262f1d2b4d3SLarry Finger
2263f1d2b4d3SLarry Finger if (rtlpriv->dm.useramask)
22641d22b177SPing-Ke Shih rtl92se_update_hal_rate_mask(hw, sta, rssi_level, update_bw);
2265f1d2b4d3SLarry Finger else
2266f1d2b4d3SLarry Finger rtl92se_update_hal_rate_table(hw, sta);
2267f1d2b4d3SLarry Finger }
2268f1d2b4d3SLarry Finger
rtl92se_update_channel_access_setting(struct ieee80211_hw * hw)2269f1d2b4d3SLarry Finger void rtl92se_update_channel_access_setting(struct ieee80211_hw *hw)
2270f1d2b4d3SLarry Finger {
2271f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
2272f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2273f1d2b4d3SLarry Finger u16 sifs_timer;
2274f1d2b4d3SLarry Finger
2275f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
2276f1d2b4d3SLarry Finger &mac->slot_time);
2277f1d2b4d3SLarry Finger sifs_timer = 0x0e0e;
2278f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
2279f1d2b4d3SLarry Finger
2280f1d2b4d3SLarry Finger }
2281f1d2b4d3SLarry Finger
2282f1d2b4d3SLarry Finger /* this ifunction is for RFKILL, it's different with windows,
2283f1d2b4d3SLarry Finger * because UI will disable wireless when GPIO Radio Off.
2284f1d2b4d3SLarry Finger * And here we not check or Disable/Enable ASPM like windows*/
rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw * hw,u8 * valid)2285f1d2b4d3SLarry Finger bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
2286f1d2b4d3SLarry Finger {
2287f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
2288f1d2b4d3SLarry Finger struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2289f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
2290f1d2b4d3SLarry Finger enum rf_pwrstate rfpwr_toset /*, cur_rfstate */;
2291f1d2b4d3SLarry Finger unsigned long flag = 0;
2292f1d2b4d3SLarry Finger bool actuallyset = false;
2293f1d2b4d3SLarry Finger bool turnonbypowerdomain = false;
2294f1d2b4d3SLarry Finger
2295f1d2b4d3SLarry Finger /* just 8191se can check gpio before firstup, 92c/92d have fixed it */
229615085446SJiapeng Chong if (rtlpci->up_first_time || rtlpci->being_init_adapter)
2297f1d2b4d3SLarry Finger return false;
2298f1d2b4d3SLarry Finger
2299f1d2b4d3SLarry Finger if (ppsc->swrf_processing)
2300f1d2b4d3SLarry Finger return false;
2301f1d2b4d3SLarry Finger
2302f1d2b4d3SLarry Finger spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
2303f1d2b4d3SLarry Finger if (ppsc->rfchange_inprogress) {
2304f1d2b4d3SLarry Finger spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
2305f1d2b4d3SLarry Finger return false;
2306f1d2b4d3SLarry Finger } else {
2307f1d2b4d3SLarry Finger ppsc->rfchange_inprogress = true;
2308f1d2b4d3SLarry Finger spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
2309f1d2b4d3SLarry Finger }
2310f1d2b4d3SLarry Finger
2311f1d2b4d3SLarry Finger /* cur_rfstate = ppsc->rfpwr_state;*/
2312f1d2b4d3SLarry Finger
2313f1d2b4d3SLarry Finger /* because after _rtl92s_phy_set_rfhalt, all power
2314f1d2b4d3SLarry Finger * closed, so we must open some power for GPIO check,
2315f1d2b4d3SLarry Finger * or we will always check GPIO RFOFF here,
2316f1d2b4d3SLarry Finger * And we should close power after GPIO check */
2317f1d2b4d3SLarry Finger if (RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2318f1d2b4d3SLarry Finger _rtl92se_power_domain_init(hw);
2319f1d2b4d3SLarry Finger turnonbypowerdomain = true;
2320f1d2b4d3SLarry Finger }
2321f1d2b4d3SLarry Finger
2322f1d2b4d3SLarry Finger rfpwr_toset = _rtl92se_rf_onoff_detect(hw);
2323f1d2b4d3SLarry Finger
2324f1d2b4d3SLarry Finger if ((ppsc->hwradiooff) && (rfpwr_toset == ERFON)) {
2325fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
2326f1d2b4d3SLarry Finger "RFKILL-HW Radio ON, RF ON\n");
2327f1d2b4d3SLarry Finger
2328f1d2b4d3SLarry Finger rfpwr_toset = ERFON;
2329f1d2b4d3SLarry Finger ppsc->hwradiooff = false;
2330f1d2b4d3SLarry Finger actuallyset = true;
2331f1d2b4d3SLarry Finger } else if ((!ppsc->hwradiooff) && (rfpwr_toset == ERFOFF)) {
2332fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_RF,
2333f1d2b4d3SLarry Finger DBG_DMESG, "RFKILL-HW Radio OFF, RF OFF\n");
2334f1d2b4d3SLarry Finger
2335f1d2b4d3SLarry Finger rfpwr_toset = ERFOFF;
2336f1d2b4d3SLarry Finger ppsc->hwradiooff = true;
2337f1d2b4d3SLarry Finger actuallyset = true;
2338f1d2b4d3SLarry Finger }
2339f1d2b4d3SLarry Finger
2340f1d2b4d3SLarry Finger if (actuallyset) {
2341f1d2b4d3SLarry Finger spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
2342f1d2b4d3SLarry Finger ppsc->rfchange_inprogress = false;
2343f1d2b4d3SLarry Finger spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
2344f1d2b4d3SLarry Finger
2345f1d2b4d3SLarry Finger /* this not include ifconfig wlan0 down case */
2346f1d2b4d3SLarry Finger /* } else if (rfpwr_toset == ERFOFF || cur_rfstate == ERFOFF) { */
2347f1d2b4d3SLarry Finger } else {
2348f1d2b4d3SLarry Finger /* because power_domain_init may be happen when
2349f1d2b4d3SLarry Finger * _rtl92s_phy_set_rfhalt, this will open some powers
2350f1d2b4d3SLarry Finger * and cause current increasing about 40 mA for ips,
2351f1d2b4d3SLarry Finger * rfoff and ifconfig down, so we set
2352f1d2b4d3SLarry Finger * _rtl92s_phy_set_rfhalt again here */
2353f1d2b4d3SLarry Finger if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC &&
2354f1d2b4d3SLarry Finger turnonbypowerdomain) {
2355f1d2b4d3SLarry Finger _rtl92s_phy_set_rfhalt(hw);
2356f1d2b4d3SLarry Finger RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2357f1d2b4d3SLarry Finger }
2358f1d2b4d3SLarry Finger
2359f1d2b4d3SLarry Finger spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
2360f1d2b4d3SLarry Finger ppsc->rfchange_inprogress = false;
2361f1d2b4d3SLarry Finger spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
2362f1d2b4d3SLarry Finger }
2363f1d2b4d3SLarry Finger
2364f1d2b4d3SLarry Finger *valid = 1;
2365f1d2b4d3SLarry Finger return !ppsc->hwradiooff;
2366f1d2b4d3SLarry Finger
2367f1d2b4d3SLarry Finger }
2368f1d2b4d3SLarry Finger
2369f1d2b4d3SLarry Finger /* Is_wepkey just used for WEP used as group & pairwise key
2370f1d2b4d3SLarry Finger * if pairwise is AES ang group is WEP Is_wepkey == false.*/
rtl92se_set_key(struct ieee80211_hw * hw,u32 key_index,u8 * p_macaddr,bool is_group,u8 enc_algo,bool is_wepkey,bool clear_all)2371f1d2b4d3SLarry Finger void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr,
2372f1d2b4d3SLarry Finger bool is_group, u8 enc_algo, bool is_wepkey, bool clear_all)
2373f1d2b4d3SLarry Finger {
2374f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
2375f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2376f1d2b4d3SLarry Finger struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2377f1d2b4d3SLarry Finger u8 *macaddr = p_macaddr;
2378f1d2b4d3SLarry Finger
2379f1d2b4d3SLarry Finger u32 entry_id = 0;
2380f1d2b4d3SLarry Finger bool is_pairwise = false;
2381f1d2b4d3SLarry Finger
2382f1d2b4d3SLarry Finger static u8 cam_const_addr[4][6] = {
2383f1d2b4d3SLarry Finger {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
2384f1d2b4d3SLarry Finger {0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
2385f1d2b4d3SLarry Finger {0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
2386f1d2b4d3SLarry Finger {0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
2387f1d2b4d3SLarry Finger };
2388f1d2b4d3SLarry Finger static u8 cam_const_broad[] = {
2389f1d2b4d3SLarry Finger 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2390f1d2b4d3SLarry Finger };
2391f1d2b4d3SLarry Finger
2392f1d2b4d3SLarry Finger if (clear_all) {
2393f1d2b4d3SLarry Finger u8 idx = 0;
2394f1d2b4d3SLarry Finger u8 cam_offset = 0;
2395f1d2b4d3SLarry Finger u8 clear_number = 5;
2396f1d2b4d3SLarry Finger
2397fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n");
2398f1d2b4d3SLarry Finger
2399f1d2b4d3SLarry Finger for (idx = 0; idx < clear_number; idx++) {
2400f1d2b4d3SLarry Finger rtl_cam_mark_invalid(hw, cam_offset + idx);
2401f1d2b4d3SLarry Finger rtl_cam_empty_entry(hw, cam_offset + idx);
2402f1d2b4d3SLarry Finger
2403f1d2b4d3SLarry Finger if (idx < 5) {
2404f1d2b4d3SLarry Finger memset(rtlpriv->sec.key_buf[idx], 0,
2405f1d2b4d3SLarry Finger MAX_KEY_LEN);
2406f1d2b4d3SLarry Finger rtlpriv->sec.key_len[idx] = 0;
2407f1d2b4d3SLarry Finger }
2408f1d2b4d3SLarry Finger }
2409f1d2b4d3SLarry Finger
2410f1d2b4d3SLarry Finger } else {
2411f1d2b4d3SLarry Finger switch (enc_algo) {
2412f1d2b4d3SLarry Finger case WEP40_ENCRYPTION:
2413f1d2b4d3SLarry Finger enc_algo = CAM_WEP40;
2414f1d2b4d3SLarry Finger break;
2415f1d2b4d3SLarry Finger case WEP104_ENCRYPTION:
2416f1d2b4d3SLarry Finger enc_algo = CAM_WEP104;
2417f1d2b4d3SLarry Finger break;
2418f1d2b4d3SLarry Finger case TKIP_ENCRYPTION:
2419f1d2b4d3SLarry Finger enc_algo = CAM_TKIP;
2420f1d2b4d3SLarry Finger break;
2421f1d2b4d3SLarry Finger case AESCCMP_ENCRYPTION:
2422f1d2b4d3SLarry Finger enc_algo = CAM_AES;
2423f1d2b4d3SLarry Finger break;
2424f1d2b4d3SLarry Finger default:
24252d15acacSLarry Finger pr_err("switch case %#x not processed\n",
24262d15acacSLarry Finger enc_algo);
2427f1d2b4d3SLarry Finger enc_algo = CAM_TKIP;
2428f1d2b4d3SLarry Finger break;
2429f1d2b4d3SLarry Finger }
2430f1d2b4d3SLarry Finger
2431f1d2b4d3SLarry Finger if (is_wepkey || rtlpriv->sec.use_defaultkey) {
2432f1d2b4d3SLarry Finger macaddr = cam_const_addr[key_index];
2433f1d2b4d3SLarry Finger entry_id = key_index;
2434f1d2b4d3SLarry Finger } else {
2435f1d2b4d3SLarry Finger if (is_group) {
2436f1d2b4d3SLarry Finger macaddr = cam_const_broad;
2437f1d2b4d3SLarry Finger entry_id = key_index;
2438f1d2b4d3SLarry Finger } else {
2439f1d2b4d3SLarry Finger if (mac->opmode == NL80211_IFTYPE_AP) {
2440f1d2b4d3SLarry Finger entry_id = rtl_cam_get_free_entry(hw,
2441f1d2b4d3SLarry Finger p_macaddr);
2442f1d2b4d3SLarry Finger if (entry_id >= TOTAL_CAM_ENTRY) {
24432d15acacSLarry Finger pr_err("Can not find free hw security cam entry\n");
2444f1d2b4d3SLarry Finger return;
2445f1d2b4d3SLarry Finger }
2446f1d2b4d3SLarry Finger } else {
2447f1d2b4d3SLarry Finger entry_id = CAM_PAIRWISE_KEY_POSITION;
2448f1d2b4d3SLarry Finger }
2449f1d2b4d3SLarry Finger
2450f1d2b4d3SLarry Finger key_index = PAIRWISE_KEYIDX;
2451f1d2b4d3SLarry Finger is_pairwise = true;
2452f1d2b4d3SLarry Finger }
2453f1d2b4d3SLarry Finger }
2454f1d2b4d3SLarry Finger
2455f1d2b4d3SLarry Finger if (rtlpriv->sec.key_len[key_index] == 0) {
2456fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
2457f1d2b4d3SLarry Finger "delete one entry, entry_id is %d\n",
2458f1d2b4d3SLarry Finger entry_id);
2459f1d2b4d3SLarry Finger if (mac->opmode == NL80211_IFTYPE_AP)
2460f1d2b4d3SLarry Finger rtl_cam_del_entry(hw, p_macaddr);
2461f1d2b4d3SLarry Finger rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
2462f1d2b4d3SLarry Finger } else {
2463fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
2464f1d2b4d3SLarry Finger "add one entry\n");
2465f1d2b4d3SLarry Finger if (is_pairwise) {
2466fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
2467f1d2b4d3SLarry Finger "set Pairwise key\n");
2468f1d2b4d3SLarry Finger
2469f1d2b4d3SLarry Finger rtl_cam_add_one_entry(hw, macaddr, key_index,
2470f1d2b4d3SLarry Finger entry_id, enc_algo,
2471f1d2b4d3SLarry Finger CAM_CONFIG_NO_USEDK,
2472f1d2b4d3SLarry Finger rtlpriv->sec.key_buf[key_index]);
2473f1d2b4d3SLarry Finger } else {
2474fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
2475f1d2b4d3SLarry Finger "set group key\n");
2476f1d2b4d3SLarry Finger
2477f1d2b4d3SLarry Finger if (mac->opmode == NL80211_IFTYPE_ADHOC) {
2478f1d2b4d3SLarry Finger rtl_cam_add_one_entry(hw,
2479f1d2b4d3SLarry Finger rtlefuse->dev_addr,
2480f1d2b4d3SLarry Finger PAIRWISE_KEYIDX,
2481f1d2b4d3SLarry Finger CAM_PAIRWISE_KEY_POSITION,
2482f1d2b4d3SLarry Finger enc_algo, CAM_CONFIG_NO_USEDK,
2483f1d2b4d3SLarry Finger rtlpriv->sec.key_buf[entry_id]);
2484f1d2b4d3SLarry Finger }
2485f1d2b4d3SLarry Finger
2486f1d2b4d3SLarry Finger rtl_cam_add_one_entry(hw, macaddr, key_index,
2487f1d2b4d3SLarry Finger entry_id, enc_algo,
2488f1d2b4d3SLarry Finger CAM_CONFIG_NO_USEDK,
2489f1d2b4d3SLarry Finger rtlpriv->sec.key_buf[entry_id]);
2490f1d2b4d3SLarry Finger }
2491f1d2b4d3SLarry Finger
2492f1d2b4d3SLarry Finger }
2493f1d2b4d3SLarry Finger }
2494f1d2b4d3SLarry Finger }
2495f1d2b4d3SLarry Finger
rtl92se_suspend(struct ieee80211_hw * hw)2496f1d2b4d3SLarry Finger void rtl92se_suspend(struct ieee80211_hw *hw)
2497f1d2b4d3SLarry Finger {
2498f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
2499f1d2b4d3SLarry Finger
2500f1d2b4d3SLarry Finger rtlpci->up_first_time = true;
2501f1d2b4d3SLarry Finger }
2502f1d2b4d3SLarry Finger
rtl92se_resume(struct ieee80211_hw * hw)2503f1d2b4d3SLarry Finger void rtl92se_resume(struct ieee80211_hw *hw)
2504f1d2b4d3SLarry Finger {
2505f1d2b4d3SLarry Finger struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
2506f1d2b4d3SLarry Finger u32 val;
2507f1d2b4d3SLarry Finger
2508f1d2b4d3SLarry Finger pci_read_config_dword(rtlpci->pdev, 0x40, &val);
2509f1d2b4d3SLarry Finger if ((val & 0x0000ff00) != 0)
2510f1d2b4d3SLarry Finger pci_write_config_dword(rtlpci->pdev, 0x40,
2511f1d2b4d3SLarry Finger val & 0xffff00ff);
2512f1d2b4d3SLarry Finger }
2513