diff options
author | Larry Finger <Larry.Finger@lwfinger.net> | 2012-10-25 14:46:32 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-11-14 14:54:53 -0500 |
commit | c592e631bcec4d858695eee8bf321d60390d38e9 (patch) | |
tree | 721760de02b9b0df3bc0294b77b7ba15b45d6e6b /drivers/net/wireless/rtlwifi/rtl8723ae/dm.c | |
parent | b7fd76d114568d0b1e0d443049ed597b3a55f9c6 (diff) |
rtlwifi: rtl8723ae: Add new driver
This patch is the addition of files for a new driver to handle
the Realtek RTL8723AE wireless device.
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: <chaoming_li@realsil.com.cn>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rtlwifi/rtl8723ae/dm.c')
-rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8723ae/dm.c | 920 |
1 files changed, 920 insertions, 0 deletions
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c new file mode 100644 index 000000000000..12e2a3cb0701 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c | |||
@@ -0,0 +1,920 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | **************************************************************************** | ||
29 | */ | ||
30 | |||
31 | #include "../wifi.h" | ||
32 | #include "../base.h" | ||
33 | #include "../pci.h" | ||
34 | #include "reg.h" | ||
35 | #include "def.h" | ||
36 | #include "phy.h" | ||
37 | #include "dm.h" | ||
38 | #include "fw.h" | ||
39 | #include "hal_btc.h" | ||
40 | |||
41 | static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { | ||
42 | 0x7f8001fe, | ||
43 | 0x788001e2, | ||
44 | 0x71c001c7, | ||
45 | 0x6b8001ae, | ||
46 | 0x65400195, | ||
47 | 0x5fc0017f, | ||
48 | 0x5a400169, | ||
49 | 0x55400155, | ||
50 | 0x50800142, | ||
51 | 0x4c000130, | ||
52 | 0x47c0011f, | ||
53 | 0x43c0010f, | ||
54 | 0x40000100, | ||
55 | 0x3c8000f2, | ||
56 | 0x390000e4, | ||
57 | 0x35c000d7, | ||
58 | 0x32c000cb, | ||
59 | 0x300000c0, | ||
60 | 0x2d4000b5, | ||
61 | 0x2ac000ab, | ||
62 | 0x288000a2, | ||
63 | 0x26000098, | ||
64 | 0x24000090, | ||
65 | 0x22000088, | ||
66 | 0x20000080, | ||
67 | 0x1e400079, | ||
68 | 0x1c800072, | ||
69 | 0x1b00006c, | ||
70 | 0x19800066, | ||
71 | 0x18000060, | ||
72 | 0x16c0005b, | ||
73 | 0x15800056, | ||
74 | 0x14400051, | ||
75 | 0x1300004c, | ||
76 | 0x12000048, | ||
77 | 0x11000044, | ||
78 | 0x10000040, | ||
79 | }; | ||
80 | |||
81 | static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = { | ||
82 | {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, | ||
83 | {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, | ||
84 | {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, | ||
85 | {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, | ||
86 | {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, | ||
87 | {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, | ||
88 | {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, | ||
89 | {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, | ||
90 | {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, | ||
91 | {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, | ||
92 | {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, | ||
93 | {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, | ||
94 | {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, | ||
95 | {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, | ||
96 | {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, | ||
97 | {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, | ||
98 | {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, | ||
99 | {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, | ||
100 | {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, | ||
101 | {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, | ||
102 | {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, | ||
103 | {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, | ||
104 | {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, | ||
105 | {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, | ||
106 | {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, | ||
107 | {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, | ||
108 | {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, | ||
109 | {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, | ||
110 | {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, | ||
111 | {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, | ||
112 | {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, | ||
113 | {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, | ||
114 | {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} | ||
115 | }; | ||
116 | |||
117 | static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = { | ||
118 | {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, | ||
119 | {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, | ||
120 | {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, | ||
121 | {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, | ||
122 | {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, | ||
123 | {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, | ||
124 | {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, | ||
125 | {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, | ||
126 | {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, | ||
127 | {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, | ||
128 | {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, | ||
129 | {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, | ||
130 | {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, | ||
131 | {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, | ||
132 | {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, | ||
133 | {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, | ||
134 | {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, | ||
135 | {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, | ||
136 | {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, | ||
137 | {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, | ||
138 | {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, | ||
139 | {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, | ||
140 | {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, | ||
141 | {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, | ||
142 | {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, | ||
143 | {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, | ||
144 | {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, | ||
145 | {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, | ||
146 | {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, | ||
147 | {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, | ||
148 | {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, | ||
149 | {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, | ||
150 | {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} | ||
151 | }; | ||
152 | |||
153 | static void rtl8723ae_dm_diginit(struct ieee80211_hw *hw) | ||
154 | { | ||
155 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
156 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | ||
157 | |||
158 | dm_digtable->dig_enable_flag = true; | ||
159 | dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; | ||
160 | dm_digtable->cur_igvalue = 0x20; | ||
161 | dm_digtable->pre_igvalue = 0x0; | ||
162 | dm_digtable->cursta_cstate = DIG_STA_DISCONNECT; | ||
163 | dm_digtable->presta_cstate = DIG_STA_DISCONNECT; | ||
164 | dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT; | ||
165 | dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW; | ||
166 | dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; | ||
167 | dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW; | ||
168 | dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH; | ||
169 | dm_digtable->rx_gain_range_max = DM_DIG_MAX; | ||
170 | dm_digtable->rx_gain_range_min = DM_DIG_MIN; | ||
171 | dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; | ||
172 | dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX; | ||
173 | dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN; | ||
174 | dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX; | ||
175 | dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; | ||
176 | } | ||
177 | |||
178 | static u8 rtl_init_gain_min_pwdb(struct ieee80211_hw *hw) | ||
179 | { | ||
180 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
181 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | ||
182 | long rssi_val_min = 0; | ||
183 | |||
184 | if ((dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) && | ||
185 | (dm_digtable->cursta_cstate == DIG_STA_CONNECT)) { | ||
186 | if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0) | ||
187 | rssi_val_min = | ||
188 | (rtlpriv->dm.entry_min_undec_sm_pwdb > | ||
189 | rtlpriv->dm.undec_sm_pwdb) ? | ||
190 | rtlpriv->dm.undec_sm_pwdb : | ||
191 | rtlpriv->dm.entry_min_undec_sm_pwdb; | ||
192 | else | ||
193 | rssi_val_min = rtlpriv->dm.undec_sm_pwdb; | ||
194 | } else if (dm_digtable->cursta_cstate == DIG_STA_CONNECT || | ||
195 | dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT) { | ||
196 | rssi_val_min = rtlpriv->dm.undec_sm_pwdb; | ||
197 | } else if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) { | ||
198 | rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb; | ||
199 | } | ||
200 | |||
201 | return (u8) rssi_val_min; | ||
202 | } | ||
203 | |||
204 | static void rtl8723ae_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) | ||
205 | { | ||
206 | u32 ret_value; | ||
207 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
208 | struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); | ||
209 | |||
210 | ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD); | ||
211 | falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); | ||
212 | |||
213 | ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD); | ||
214 | falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); | ||
215 | falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); | ||
216 | |||
217 | ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); | ||
218 | falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); | ||
219 | falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + | ||
220 | falsealm_cnt->cnt_rate_illegal + | ||
221 | falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail; | ||
222 | |||
223 | rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1); | ||
224 | ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); | ||
225 | falsealm_cnt->cnt_cck_fail = ret_value; | ||
226 | |||
227 | ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3); | ||
228 | falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; | ||
229 | falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail + | ||
230 | falsealm_cnt->cnt_rate_illegal + | ||
231 | falsealm_cnt->cnt_crc8_fail + | ||
232 | falsealm_cnt->cnt_mcs_fail + | ||
233 | falsealm_cnt->cnt_cck_fail); | ||
234 | |||
235 | rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1); | ||
236 | rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0); | ||
237 | rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0); | ||
238 | rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); | ||
239 | |||
240 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
241 | "cnt_parity_fail = %d, cnt_rate_illegal = %d, " | ||
242 | "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", | ||
243 | falsealm_cnt->cnt_parity_fail, | ||
244 | falsealm_cnt->cnt_rate_illegal, | ||
245 | falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail); | ||
246 | |||
247 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
248 | "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", | ||
249 | falsealm_cnt->cnt_ofdm_fail, | ||
250 | falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all); | ||
251 | } | ||
252 | |||
253 | static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) | ||
254 | { | ||
255 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
256 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | ||
257 | u8 value_igi = dm_digtable->cur_igvalue; | ||
258 | |||
259 | if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) | ||
260 | value_igi--; | ||
261 | else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1) | ||
262 | value_igi += 0; | ||
263 | else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2) | ||
264 | value_igi++; | ||
265 | else | ||
266 | value_igi += 2; | ||
267 | |||
268 | value_igi = clamp(value_igi, (u8)DM_DIG_FA_LOWER, (u8)DM_DIG_FA_UPPER); | ||
269 | if (rtlpriv->falsealm_cnt.cnt_all > 10000) | ||
270 | value_igi = 0x32; | ||
271 | |||
272 | dm_digtable->cur_igvalue = value_igi; | ||
273 | rtl8723ae_dm_write_dig(hw); | ||
274 | } | ||
275 | |||
276 | static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) | ||
277 | { | ||
278 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
279 | struct dig_t *dgtbl = &rtlpriv->dm_digtable; | ||
280 | |||
281 | if (rtlpriv->falsealm_cnt.cnt_all > dgtbl->fa_highthresh) { | ||
282 | if ((dgtbl->back_val - 2) < dgtbl->back_range_min) | ||
283 | dgtbl->back_val = dgtbl->back_range_min; | ||
284 | else | ||
285 | dgtbl->back_val -= 2; | ||
286 | } else if (rtlpriv->falsealm_cnt.cnt_all < dgtbl->fa_lowthresh) { | ||
287 | if ((dgtbl->back_val + 2) > dgtbl->back_range_max) | ||
288 | dgtbl->back_val = dgtbl->back_range_max; | ||
289 | else | ||
290 | dgtbl->back_val += 2; | ||
291 | } | ||
292 | |||
293 | if ((dgtbl->rssi_val_min + 10 - dgtbl->back_val) > | ||
294 | dgtbl->rx_gain_range_max) | ||
295 | dgtbl->cur_igvalue = dgtbl->rx_gain_range_max; | ||
296 | else if ((dgtbl->rssi_val_min + 10 - | ||
297 | dgtbl->back_val) < dgtbl->rx_gain_range_min) | ||
298 | dgtbl->cur_igvalue = dgtbl->rx_gain_range_min; | ||
299 | else | ||
300 | dgtbl->cur_igvalue = dgtbl->rssi_val_min + 10 - dgtbl->back_val; | ||
301 | |||
302 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
303 | "rssi_val_min = %x back_val %x\n", | ||
304 | dgtbl->rssi_val_min, dgtbl->back_val); | ||
305 | |||
306 | rtl8723ae_dm_write_dig(hw); | ||
307 | } | ||
308 | |||
309 | static void rtl8723ae_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) | ||
310 | { | ||
311 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
312 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
313 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | ||
314 | long rssi_strength = rtlpriv->dm.entry_min_undec_sm_pwdb; | ||
315 | bool multi_sta = false; | ||
316 | |||
317 | if (mac->opmode == NL80211_IFTYPE_ADHOC) | ||
318 | multi_sta = true; | ||
319 | |||
320 | if ((!multi_sta) || | ||
321 | (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT)) { | ||
322 | rtlpriv->initialized = false; | ||
323 | dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; | ||
324 | return; | ||
325 | } else if (!rtlpriv->initialized) { | ||
326 | rtlpriv->initialized = true; | ||
327 | dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; | ||
328 | dm_digtable->cur_igvalue = 0x20; | ||
329 | rtl8723ae_dm_write_dig(hw); | ||
330 | } | ||
331 | |||
332 | if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) { | ||
333 | if ((rssi_strength < dm_digtable->rssi_lowthresh) && | ||
334 | (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) { | ||
335 | |||
336 | if (dm_digtable->dig_ext_port_stage == | ||
337 | DIG_EXT_PORT_STAGE_2) { | ||
338 | dm_digtable->cur_igvalue = 0x20; | ||
339 | rtl8723ae_dm_write_dig(hw); | ||
340 | } | ||
341 | |||
342 | dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_1; | ||
343 | } else if (rssi_strength > dm_digtable->rssi_highthresh) { | ||
344 | dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_2; | ||
345 | rtl92c_dm_ctrl_initgain_by_fa(hw); | ||
346 | } | ||
347 | } else if (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) { | ||
348 | dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; | ||
349 | dm_digtable->cur_igvalue = 0x20; | ||
350 | rtl8723ae_dm_write_dig(hw); | ||
351 | } | ||
352 | |||
353 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
354 | "curmultista_cstate = %x dig_ext_port_stage %x\n", | ||
355 | dm_digtable->curmultista_cstate, | ||
356 | dm_digtable->dig_ext_port_stage); | ||
357 | } | ||
358 | |||
359 | static void rtl8723ae_dm_initial_gain_sta(struct ieee80211_hw *hw) | ||
360 | { | ||
361 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
362 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | ||
363 | |||
364 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
365 | "presta_cstate = %x, cursta_cstate = %x\n", | ||
366 | dm_digtable->presta_cstate, | ||
367 | dm_digtable->cursta_cstate); | ||
368 | |||
369 | if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate || | ||
370 | dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT || | ||
371 | dm_digtable->cursta_cstate == DIG_STA_CONNECT) { | ||
372 | |||
373 | if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) { | ||
374 | dm_digtable->rssi_val_min = rtl_init_gain_min_pwdb(hw); | ||
375 | rtl92c_dm_ctrl_initgain_by_rssi(hw); | ||
376 | } | ||
377 | } else { | ||
378 | dm_digtable->rssi_val_min = 0; | ||
379 | dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; | ||
380 | dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; | ||
381 | dm_digtable->cur_igvalue = 0x20; | ||
382 | dm_digtable->pre_igvalue = 0; | ||
383 | rtl8723ae_dm_write_dig(hw); | ||
384 | } | ||
385 | } | ||
386 | static void rtl8723ae_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) | ||
387 | { | ||
388 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
389 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | ||
390 | |||
391 | if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) { | ||
392 | dm_digtable->rssi_val_min = rtl_init_gain_min_pwdb(hw); | ||
393 | |||
394 | if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { | ||
395 | if (dm_digtable->rssi_val_min <= 25) | ||
396 | dm_digtable->cur_cck_pd_state = | ||
397 | CCK_PD_STAGE_LowRssi; | ||
398 | else | ||
399 | dm_digtable->cur_cck_pd_state = | ||
400 | CCK_PD_STAGE_HighRssi; | ||
401 | } else { | ||
402 | if (dm_digtable->rssi_val_min <= 20) | ||
403 | dm_digtable->cur_cck_pd_state = | ||
404 | CCK_PD_STAGE_LowRssi; | ||
405 | else | ||
406 | dm_digtable->cur_cck_pd_state = | ||
407 | CCK_PD_STAGE_HighRssi; | ||
408 | } | ||
409 | } else { | ||
410 | dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; | ||
411 | } | ||
412 | |||
413 | if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) { | ||
414 | if (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LowRssi) { | ||
415 | if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800) | ||
416 | dm_digtable->cur_cck_fa_state = | ||
417 | CCK_FA_STAGE_High; | ||
418 | else | ||
419 | dm_digtable->cur_cck_fa_state = | ||
420 | CCK_FA_STAGE_Low; | ||
421 | |||
422 | if (dm_digtable->pre_cck_fa_state != | ||
423 | dm_digtable->cur_cck_fa_state) { | ||
424 | if (dm_digtable->cur_cck_fa_state == | ||
425 | CCK_FA_STAGE_Low) | ||
426 | rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, | ||
427 | 0x83); | ||
428 | else | ||
429 | rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, | ||
430 | 0xcd); | ||
431 | |||
432 | dm_digtable->pre_cck_fa_state = | ||
433 | dm_digtable->cur_cck_fa_state; | ||
434 | } | ||
435 | |||
436 | rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40); | ||
437 | |||
438 | } else { | ||
439 | rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); | ||
440 | rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47); | ||
441 | |||
442 | } | ||
443 | dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state; | ||
444 | } | ||
445 | |||
446 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
447 | "CCKPDStage=%x\n", dm_digtable->cur_cck_pd_state); | ||
448 | |||
449 | } | ||
450 | |||
451 | static void rtl8723ae_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) | ||
452 | { | ||
453 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
454 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
455 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | ||
456 | |||
457 | if (mac->act_scanning == true) | ||
458 | return; | ||
459 | |||
460 | if (mac->link_state >= MAC80211_LINKED) | ||
461 | dm_digtable->cursta_cstate = DIG_STA_CONNECT; | ||
462 | else | ||
463 | dm_digtable->cursta_cstate = DIG_STA_DISCONNECT; | ||
464 | |||
465 | rtl8723ae_dm_initial_gain_sta(hw); | ||
466 | rtl8723ae_dm_initial_gain_multi_sta(hw); | ||
467 | rtl8723ae_dm_cck_packet_detection_thresh(hw); | ||
468 | |||
469 | dm_digtable->presta_cstate = dm_digtable->cursta_cstate; | ||
470 | |||
471 | } | ||
472 | |||
473 | static void rtl8723ae_dm_dig(struct ieee80211_hw *hw) | ||
474 | { | ||
475 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
476 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | ||
477 | |||
478 | if (rtlpriv->dm.dm_initialgain_enable == false) | ||
479 | return; | ||
480 | if (dm_digtable->dig_enable_flag == false) | ||
481 | return; | ||
482 | |||
483 | rtl8723ae_dm_ctrl_initgain_by_twoport(hw); | ||
484 | } | ||
485 | |||
486 | static void rtl8723ae_dm_init_dynamic_txpower(struct ieee80211_hw *hw) | ||
487 | { | ||
488 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
489 | |||
490 | rtlpriv->dm.dynamic_txpower_enable = false; | ||
491 | |||
492 | rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
493 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
494 | } | ||
495 | |||
496 | static void rtl8723ae_dm_dynamic_txpower(struct ieee80211_hw *hw) | ||
497 | { | ||
498 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
499 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
500 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
501 | long undec_sm_pwdb; | ||
502 | |||
503 | if (!rtlpriv->dm.dynamic_txpower_enable) | ||
504 | return; | ||
505 | |||
506 | if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { | ||
507 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
508 | return; | ||
509 | } | ||
510 | |||
511 | if ((mac->link_state < MAC80211_LINKED) && | ||
512 | (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { | ||
513 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, | ||
514 | "Not connected\n"); | ||
515 | |||
516 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
517 | |||
518 | rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
519 | return; | ||
520 | } | ||
521 | |||
522 | if (mac->link_state >= MAC80211_LINKED) { | ||
523 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
524 | undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; | ||
525 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
526 | "AP Client PWDB = 0x%lx\n", | ||
527 | undec_sm_pwdb); | ||
528 | } else { | ||
529 | undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; | ||
530 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
531 | "STA Default Port PWDB = 0x%lx\n", | ||
532 | undec_sm_pwdb); | ||
533 | } | ||
534 | } else { | ||
535 | undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; | ||
536 | |||
537 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
538 | "AP Ext Port PWDB = 0x%lx\n", | ||
539 | undec_sm_pwdb); | ||
540 | } | ||
541 | |||
542 | if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { | ||
543 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; | ||
544 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
545 | "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); | ||
546 | } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && | ||
547 | (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) { | ||
548 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; | ||
549 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
550 | "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); | ||
551 | } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { | ||
552 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
553 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
554 | "TXHIGHPWRLEVEL_NORMAL\n"); | ||
555 | } | ||
556 | |||
557 | if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { | ||
558 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
559 | "PHY_SetTxPowerLevel8192S() Channel = %d\n", | ||
560 | rtlphy->current_channel); | ||
561 | rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel); | ||
562 | } | ||
563 | |||
564 | rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; | ||
565 | } | ||
566 | |||
567 | void rtl8723ae_dm_write_dig(struct ieee80211_hw *hw) | ||
568 | { | ||
569 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
570 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | ||
571 | |||
572 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, | ||
573 | "cur_igvalue = 0x%x, " | ||
574 | "pre_igvalue = 0x%x, back_val = %d\n", | ||
575 | dm_digtable->cur_igvalue, dm_digtable->pre_igvalue, | ||
576 | dm_digtable->back_val); | ||
577 | |||
578 | if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) { | ||
579 | rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, | ||
580 | dm_digtable->cur_igvalue); | ||
581 | rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, | ||
582 | dm_digtable->cur_igvalue); | ||
583 | |||
584 | dm_digtable->pre_igvalue = dm_digtable->cur_igvalue; | ||
585 | } | ||
586 | } | ||
587 | |||
588 | static void rtl8723ae_dm_pwdmonitor(struct ieee80211_hw *hw) | ||
589 | { | ||
590 | } | ||
591 | |||
592 | void rtl8723ae_dm_init_edca_turbo(struct ieee80211_hw *hw) | ||
593 | { | ||
594 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
595 | |||
596 | rtlpriv->dm.current_turbo_edca = false; | ||
597 | rtlpriv->dm.is_any_nonbepkts = false; | ||
598 | rtlpriv->dm.is_cur_rdlstate = false; | ||
599 | } | ||
600 | |||
601 | static void rtl8723ae_dm_check_edca_turbo(struct ieee80211_hw *hw) | ||
602 | { | ||
603 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
604 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
605 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
606 | |||
607 | u64 cur_txok_cnt = 0; | ||
608 | u64 cur_rxok_cnt = 0; | ||
609 | u32 edca_be_ul = 0x5ea42b; | ||
610 | u32 edca_be_dl = 0x5ea42b; | ||
611 | bool bt_change_edca = false; | ||
612 | |||
613 | if ((mac->last_bt_edca_ul != rtlpcipriv->bt_coexist.bt_edca_ul) || | ||
614 | (mac->last_bt_edca_dl != rtlpcipriv->bt_coexist.bt_edca_dl)) { | ||
615 | rtlpriv->dm.current_turbo_edca = false; | ||
616 | mac->last_bt_edca_ul = rtlpcipriv->bt_coexist.bt_edca_ul; | ||
617 | mac->last_bt_edca_dl = rtlpcipriv->bt_coexist.bt_edca_dl; | ||
618 | } | ||
619 | |||
620 | if (rtlpcipriv->bt_coexist.bt_edca_ul != 0) { | ||
621 | edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_ul; | ||
622 | bt_change_edca = true; | ||
623 | } | ||
624 | |||
625 | if (rtlpcipriv->bt_coexist.bt_edca_dl != 0) { | ||
626 | edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_dl; | ||
627 | bt_change_edca = true; | ||
628 | } | ||
629 | |||
630 | if (mac->link_state != MAC80211_LINKED) { | ||
631 | rtlpriv->dm.current_turbo_edca = false; | ||
632 | return; | ||
633 | } | ||
634 | |||
635 | if ((!mac->ht_enable) && (!rtlpcipriv->bt_coexist.bt_coexistence)) { | ||
636 | if (!(edca_be_ul & 0xffff0000)) | ||
637 | edca_be_ul |= 0x005e0000; | ||
638 | |||
639 | if (!(edca_be_dl & 0xffff0000)) | ||
640 | edca_be_dl |= 0x005e0000; | ||
641 | } | ||
642 | |||
643 | if ((bt_change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) && | ||
644 | (!rtlpriv->dm.disable_framebursting))) { | ||
645 | |||
646 | cur_txok_cnt = rtlpriv->stats.txbytesunicast - | ||
647 | mac->last_txok_cnt; | ||
648 | cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - | ||
649 | mac->last_rxok_cnt; | ||
650 | |||
651 | if (cur_rxok_cnt > 4 * cur_txok_cnt) { | ||
652 | if (!rtlpriv->dm.is_cur_rdlstate || | ||
653 | !rtlpriv->dm.current_turbo_edca) { | ||
654 | rtl_write_dword(rtlpriv, | ||
655 | REG_EDCA_BE_PARAM, | ||
656 | edca_be_dl); | ||
657 | rtlpriv->dm.is_cur_rdlstate = true; | ||
658 | } | ||
659 | } else { | ||
660 | if (rtlpriv->dm.is_cur_rdlstate || | ||
661 | !rtlpriv->dm.current_turbo_edca) { | ||
662 | rtl_write_dword(rtlpriv, | ||
663 | REG_EDCA_BE_PARAM, | ||
664 | edca_be_ul); | ||
665 | rtlpriv->dm.is_cur_rdlstate = false; | ||
666 | } | ||
667 | } | ||
668 | rtlpriv->dm.current_turbo_edca = true; | ||
669 | } else { | ||
670 | if (rtlpriv->dm.current_turbo_edca) { | ||
671 | u8 tmp = AC0_BE; | ||
672 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
673 | HW_VAR_AC_PARAM, | ||
674 | (u8 *) (&tmp)); | ||
675 | rtlpriv->dm.current_turbo_edca = false; | ||
676 | } | ||
677 | } | ||
678 | |||
679 | rtlpriv->dm.is_any_nonbepkts = false; | ||
680 | mac->last_txok_cnt = rtlpriv->stats.txbytesunicast; | ||
681 | mac->last_rxok_cnt = rtlpriv->stats.rxbytesunicast; | ||
682 | } | ||
683 | |||
684 | static void rtl8723ae_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) | ||
685 | { | ||
686 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
687 | |||
688 | rtlpriv->dm.txpower_tracking = true; | ||
689 | rtlpriv->dm.txpower_trackinginit = false; | ||
690 | |||
691 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
692 | "pMgntInfo->txpower_tracking = %d\n", | ||
693 | rtlpriv->dm.txpower_tracking); | ||
694 | } | ||
695 | |||
696 | void rtl8723ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) | ||
697 | { | ||
698 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
699 | struct rate_adaptive *p_ra = &(rtlpriv->ra); | ||
700 | |||
701 | p_ra->ratr_state = DM_RATR_STA_INIT; | ||
702 | p_ra->pre_ratr_state = DM_RATR_STA_INIT; | ||
703 | |||
704 | if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) | ||
705 | rtlpriv->dm.useramask = true; | ||
706 | else | ||
707 | rtlpriv->dm.useramask = false; | ||
708 | } | ||
709 | |||
710 | static void rtl8723ae_dm_init_dynamic_bpowersaving(struct ieee80211_hw *hw) | ||
711 | { | ||
712 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
713 | |||
714 | rtlpriv->dm_pstable.pre_ccastate = CCA_MAX; | ||
715 | rtlpriv->dm_pstable.cur_ccasate = CCA_MAX; | ||
716 | rtlpriv->dm_pstable.pre_rfstate = RF_MAX; | ||
717 | rtlpriv->dm_pstable.cur_rfstate = RF_MAX; | ||
718 | rtlpriv->dm_pstable.rssi_val_min = 0; | ||
719 | } | ||
720 | |||
721 | void rtl8723ae_dm_rf_saving(struct ieee80211_hw *hw, u8 force_in_normal) | ||
722 | { | ||
723 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
724 | struct ps_t *dm_pstable = &rtlpriv->dm_pstable; | ||
725 | |||
726 | if (!rtlpriv->reg_init) { | ||
727 | rtlpriv->reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | ||
728 | MASKDWORD) & 0x1CC000) >> 14; | ||
729 | |||
730 | rtlpriv->reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, | ||
731 | MASKDWORD) & BIT(3)) >> 3; | ||
732 | |||
733 | rtlpriv->reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, | ||
734 | MASKDWORD) & 0xFF000000) >> 24; | ||
735 | |||
736 | rtlpriv->reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & | ||
737 | 0xF000) >> 12; | ||
738 | |||
739 | rtlpriv->reg_init = true; | ||
740 | } | ||
741 | |||
742 | if (!force_in_normal) { | ||
743 | if (dm_pstable->rssi_val_min != 0) { | ||
744 | if (dm_pstable->pre_rfstate == RF_NORMAL) { | ||
745 | if (dm_pstable->rssi_val_min >= 30) | ||
746 | dm_pstable->cur_rfstate = RF_SAVE; | ||
747 | else | ||
748 | dm_pstable->cur_rfstate = RF_NORMAL; | ||
749 | } else { | ||
750 | if (dm_pstable->rssi_val_min <= 25) | ||
751 | dm_pstable->cur_rfstate = RF_NORMAL; | ||
752 | else | ||
753 | dm_pstable->cur_rfstate = RF_SAVE; | ||
754 | } | ||
755 | } else { | ||
756 | dm_pstable->cur_rfstate = RF_MAX; | ||
757 | } | ||
758 | } else { | ||
759 | dm_pstable->cur_rfstate = RF_NORMAL; | ||
760 | } | ||
761 | |||
762 | if (dm_pstable->pre_rfstate != dm_pstable->cur_rfstate) { | ||
763 | if (dm_pstable->cur_rfstate == RF_SAVE) { | ||
764 | |||
765 | rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | ||
766 | BIT(5), 0x1); | ||
767 | rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | ||
768 | 0x1C0000, 0x2); | ||
769 | rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0); | ||
770 | rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, | ||
771 | 0xFF000000, 0x63); | ||
772 | rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | ||
773 | 0xC000, 0x2); | ||
774 | rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3); | ||
775 | rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); | ||
776 | rtl_set_bbreg(hw, 0x818, BIT(28), 0x1); | ||
777 | } else { | ||
778 | rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | ||
779 | 0x1CC000, rtlpriv->reg_874); | ||
780 | rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), | ||
781 | rtlpriv->reg_c70); | ||
782 | rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000, | ||
783 | rtlpriv->reg_85c); | ||
784 | rtl_set_bbreg(hw, 0xa74, 0xF000, rtlpriv->reg_a74); | ||
785 | rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); | ||
786 | rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | ||
787 | BIT(5), 0x0); | ||
788 | } | ||
789 | |||
790 | dm_pstable->pre_rfstate = dm_pstable->cur_rfstate; | ||
791 | } | ||
792 | } | ||
793 | |||
794 | static void rtl8723ae_dm_dynamic_bpowersaving(struct ieee80211_hw *hw) | ||
795 | { | ||
796 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
797 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
798 | struct ps_t *dm_pstable = &rtlpriv->dm_pstable; | ||
799 | |||
800 | if (((mac->link_state == MAC80211_NOLINK)) && | ||
801 | (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { | ||
802 | dm_pstable->rssi_val_min = 0; | ||
803 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | ||
804 | "Not connected to any\n"); | ||
805 | } | ||
806 | |||
807 | if (mac->link_state == MAC80211_LINKED) { | ||
808 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
809 | dm_pstable->rssi_val_min = | ||
810 | rtlpriv->dm.entry_min_undec_sm_pwdb; | ||
811 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | ||
812 | "AP Client PWDB = 0x%lx\n", | ||
813 | dm_pstable->rssi_val_min); | ||
814 | } else { | ||
815 | dm_pstable->rssi_val_min = rtlpriv->dm.undec_sm_pwdb; | ||
816 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | ||
817 | "STA Default Port PWDB = 0x%lx\n", | ||
818 | dm_pstable->rssi_val_min); | ||
819 | } | ||
820 | } else { | ||
821 | dm_pstable->rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb; | ||
822 | |||
823 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | ||
824 | "AP Ext Port PWDB = 0x%lx\n", | ||
825 | dm_pstable->rssi_val_min); | ||
826 | } | ||
827 | |||
828 | rtl8723ae_dm_rf_saving(hw, false); | ||
829 | } | ||
830 | |||
831 | void rtl8723ae_dm_init(struct ieee80211_hw *hw) | ||
832 | { | ||
833 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
834 | |||
835 | rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; | ||
836 | rtl8723ae_dm_diginit(hw); | ||
837 | rtl8723ae_dm_init_dynamic_txpower(hw); | ||
838 | rtl8723ae_dm_init_edca_turbo(hw); | ||
839 | rtl8723ae_dm_init_rate_adaptive_mask(hw); | ||
840 | rtl8723ae_dm_initialize_txpower_tracking(hw); | ||
841 | rtl8723ae_dm_init_dynamic_bpowersaving(hw); | ||
842 | } | ||
843 | |||
844 | void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw) | ||
845 | { | ||
846 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
847 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
848 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
849 | bool fw_current_inpsmode = false; | ||
850 | bool fw_ps_awake = true; | ||
851 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, | ||
852 | (u8 *) (&fw_current_inpsmode)); | ||
853 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, | ||
854 | (u8 *) (&fw_ps_awake)); | ||
855 | |||
856 | if ((ppsc->rfpwr_state == ERFON) && | ||
857 | ((!fw_current_inpsmode) && fw_ps_awake) && | ||
858 | (!ppsc->rfchange_inprogress)) { | ||
859 | rtl8723ae_dm_pwdmonitor(hw); | ||
860 | rtl8723ae_dm_dig(hw); | ||
861 | rtl8723ae_dm_false_alarm_counter_statistics(hw); | ||
862 | rtl8723ae_dm_dynamic_bpowersaving(hw); | ||
863 | rtl8723ae_dm_dynamic_txpower(hw); | ||
864 | /* rtl92c_dm_refresh_rate_adaptive_mask(hw); */ | ||
865 | rtl8723ae_dm_bt_coexist(hw); | ||
866 | rtl8723ae_dm_check_edca_turbo(hw); | ||
867 | } | ||
868 | if (rtlpcipriv->bt_coexist.init_set) | ||
869 | rtl_write_byte(rtlpriv, 0x76e, 0xc); | ||
870 | } | ||
871 | |||
872 | static void rtl8723ae_dm_init_bt_coexist(struct ieee80211_hw *hw) | ||
873 | { | ||
874 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
875 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
876 | |||
877 | rtlpcipriv->bt_coexist.bt_rfreg_origin_1e | ||
878 | = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK1, 0xfffff); | ||
879 | rtlpcipriv->bt_coexist.bt_rfreg_origin_1f | ||
880 | = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK2, 0xf0); | ||
881 | |||
882 | rtlpcipriv->bt_coexist.cstate = 0; | ||
883 | rtlpcipriv->bt_coexist.previous_state = 0; | ||
884 | rtlpcipriv->bt_coexist.cstate_h = 0; | ||
885 | rtlpcipriv->bt_coexist.previous_state_h = 0; | ||
886 | rtlpcipriv->bt_coexist.lps_counter = 0; | ||
887 | |||
888 | /* Enable counter statistics */ | ||
889 | rtl_write_byte(rtlpriv, 0x76e, 0x4); | ||
890 | rtl_write_byte(rtlpriv, 0x778, 0x3); | ||
891 | rtl_write_byte(rtlpriv, 0x40, 0x20); | ||
892 | |||
893 | rtlpcipriv->bt_coexist.init_set = true; | ||
894 | } | ||
895 | |||
896 | void rtl8723ae_dm_bt_coexist(struct ieee80211_hw *hw) | ||
897 | { | ||
898 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
899 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
900 | u8 tmp_byte = 0; | ||
901 | if (!rtlpcipriv->bt_coexist.bt_coexistence) { | ||
902 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, | ||
903 | "[DM]{BT], BT not exist!!\n"); | ||
904 | return; | ||
905 | } | ||
906 | |||
907 | if (!rtlpcipriv->bt_coexist.init_set) { | ||
908 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, | ||
909 | "[DM][BT], rtl8723ae_dm_bt_coexist()\n"); | ||
910 | |||
911 | rtl8723ae_dm_init_bt_coexist(hw); | ||
912 | } | ||
913 | |||
914 | tmp_byte = rtl_read_byte(rtlpriv, 0x40); | ||
915 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, | ||
916 | "[DM][BT], 0x40 is 0x%x", tmp_byte); | ||
917 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
918 | "[DM][BT], bt_dm_coexist start"); | ||
919 | rtl8723ae_dm_bt_coexist_8723(hw); | ||
920 | } | ||