Commit | Line | Data |
---|---|---|
c592e631 LF |
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; | |
e6deaf81 LF |
169 | dm_digtable->rx_gain_max = DM_DIG_MAX; |
170 | dm_digtable->rx_gain_min = DM_DIG_MIN; | |
c592e631 LF |
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) > | |
e6deaf81 LF |
294 | dgtbl->rx_gain_max) |
295 | dgtbl->cur_igvalue = dgtbl->rx_gain_max; | |
c592e631 | 296 | else if ((dgtbl->rssi_val_min + 10 - |
e6deaf81 LF |
297 | dgtbl->back_val) < dgtbl->rx_gain_min) |
298 | dgtbl->cur_igvalue = dgtbl->rx_gain_min; | |
c592e631 LF |
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 | ||
4b04edc1 LF |
710 | static void rtl8723ae_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) |
711 | { | |
712 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
713 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | |
714 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | |
715 | struct rate_adaptive *p_ra = &(rtlpriv->ra); | |
716 | u32 low_rssithresh_for_ra, high_rssithresh_for_ra; | |
717 | struct ieee80211_sta *sta = NULL; | |
718 | ||
719 | if (is_hal_stop(rtlhal)) { | |
720 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, | |
721 | " driver is going to unload\n"); | |
722 | return; | |
723 | } | |
724 | ||
725 | if (!rtlpriv->dm.useramask) { | |
726 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, | |
727 | " driver does not control rate adaptive mask\n"); | |
728 | return; | |
729 | } | |
730 | ||
731 | if (mac->link_state == MAC80211_LINKED && | |
732 | mac->opmode == NL80211_IFTYPE_STATION) { | |
733 | switch (p_ra->pre_ratr_state) { | |
734 | case DM_RATR_STA_HIGH: | |
735 | high_rssithresh_for_ra = 50; | |
736 | low_rssithresh_for_ra = 20; | |
737 | break; | |
738 | case DM_RATR_STA_MIDDLE: | |
739 | high_rssithresh_for_ra = 55; | |
740 | low_rssithresh_for_ra = 20; | |
741 | break; | |
742 | case DM_RATR_STA_LOW: | |
743 | high_rssithresh_for_ra = 50; | |
744 | low_rssithresh_for_ra = 25; | |
745 | break; | |
746 | default: | |
747 | high_rssithresh_for_ra = 50; | |
748 | low_rssithresh_for_ra = 20; | |
749 | break; | |
750 | } | |
751 | ||
752 | if (rtlpriv->dm.undec_sm_pwdb > high_rssithresh_for_ra) | |
753 | p_ra->ratr_state = DM_RATR_STA_HIGH; | |
754 | else if (rtlpriv->dm.undec_sm_pwdb > low_rssithresh_for_ra) | |
755 | p_ra->ratr_state = DM_RATR_STA_MIDDLE; | |
756 | else | |
757 | p_ra->ratr_state = DM_RATR_STA_LOW; | |
758 | ||
759 | if (p_ra->pre_ratr_state != p_ra->ratr_state) { | |
760 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, | |
761 | "RSSI = %ld\n", | |
762 | rtlpriv->dm.undec_sm_pwdb); | |
763 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, | |
764 | "RSSI_LEVEL = %d\n", p_ra->ratr_state); | |
765 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, | |
766 | "PreState = %d, CurState = %d\n", | |
767 | p_ra->pre_ratr_state, p_ra->ratr_state); | |
768 | ||
769 | rcu_read_lock(); | |
770 | sta = rtl_find_sta(hw, mac->bssid); | |
771 | if (sta) | |
772 | rtlpriv->cfg->ops->update_rate_tbl(hw, sta, | |
773 | p_ra->ratr_state); | |
774 | rcu_read_unlock(); | |
775 | ||
776 | p_ra->pre_ratr_state = p_ra->ratr_state; | |
777 | } | |
778 | } | |
779 | } | |
780 | ||
c592e631 LF |
781 | static void rtl8723ae_dm_init_dynamic_bpowersaving(struct ieee80211_hw *hw) |
782 | { | |
783 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
784 | ||
785 | rtlpriv->dm_pstable.pre_ccastate = CCA_MAX; | |
786 | rtlpriv->dm_pstable.cur_ccasate = CCA_MAX; | |
787 | rtlpriv->dm_pstable.pre_rfstate = RF_MAX; | |
788 | rtlpriv->dm_pstable.cur_rfstate = RF_MAX; | |
789 | rtlpriv->dm_pstable.rssi_val_min = 0; | |
790 | } | |
791 | ||
792 | void rtl8723ae_dm_rf_saving(struct ieee80211_hw *hw, u8 force_in_normal) | |
793 | { | |
794 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
795 | struct ps_t *dm_pstable = &rtlpriv->dm_pstable; | |
796 | ||
797 | if (!rtlpriv->reg_init) { | |
798 | rtlpriv->reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | |
799 | MASKDWORD) & 0x1CC000) >> 14; | |
800 | ||
801 | rtlpriv->reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, | |
802 | MASKDWORD) & BIT(3)) >> 3; | |
803 | ||
804 | rtlpriv->reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, | |
805 | MASKDWORD) & 0xFF000000) >> 24; | |
806 | ||
807 | rtlpriv->reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & | |
808 | 0xF000) >> 12; | |
809 | ||
810 | rtlpriv->reg_init = true; | |
811 | } | |
812 | ||
813 | if (!force_in_normal) { | |
814 | if (dm_pstable->rssi_val_min != 0) { | |
815 | if (dm_pstable->pre_rfstate == RF_NORMAL) { | |
816 | if (dm_pstable->rssi_val_min >= 30) | |
817 | dm_pstable->cur_rfstate = RF_SAVE; | |
818 | else | |
819 | dm_pstable->cur_rfstate = RF_NORMAL; | |
820 | } else { | |
821 | if (dm_pstable->rssi_val_min <= 25) | |
822 | dm_pstable->cur_rfstate = RF_NORMAL; | |
823 | else | |
824 | dm_pstable->cur_rfstate = RF_SAVE; | |
825 | } | |
826 | } else { | |
827 | dm_pstable->cur_rfstate = RF_MAX; | |
828 | } | |
829 | } else { | |
830 | dm_pstable->cur_rfstate = RF_NORMAL; | |
831 | } | |
832 | ||
833 | if (dm_pstable->pre_rfstate != dm_pstable->cur_rfstate) { | |
834 | if (dm_pstable->cur_rfstate == RF_SAVE) { | |
835 | ||
836 | rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | |
837 | BIT(5), 0x1); | |
838 | rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | |
839 | 0x1C0000, 0x2); | |
840 | rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0); | |
841 | rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, | |
842 | 0xFF000000, 0x63); | |
843 | rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | |
844 | 0xC000, 0x2); | |
845 | rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3); | |
846 | rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); | |
847 | rtl_set_bbreg(hw, 0x818, BIT(28), 0x1); | |
848 | } else { | |
849 | rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | |
850 | 0x1CC000, rtlpriv->reg_874); | |
851 | rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), | |
852 | rtlpriv->reg_c70); | |
853 | rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000, | |
854 | rtlpriv->reg_85c); | |
855 | rtl_set_bbreg(hw, 0xa74, 0xF000, rtlpriv->reg_a74); | |
856 | rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); | |
857 | rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | |
858 | BIT(5), 0x0); | |
859 | } | |
860 | ||
861 | dm_pstable->pre_rfstate = dm_pstable->cur_rfstate; | |
862 | } | |
863 | } | |
864 | ||
865 | static void rtl8723ae_dm_dynamic_bpowersaving(struct ieee80211_hw *hw) | |
866 | { | |
867 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
868 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | |
869 | struct ps_t *dm_pstable = &rtlpriv->dm_pstable; | |
870 | ||
871 | if (((mac->link_state == MAC80211_NOLINK)) && | |
872 | (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { | |
873 | dm_pstable->rssi_val_min = 0; | |
874 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | |
875 | "Not connected to any\n"); | |
876 | } | |
877 | ||
878 | if (mac->link_state == MAC80211_LINKED) { | |
879 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | |
880 | dm_pstable->rssi_val_min = | |
881 | rtlpriv->dm.entry_min_undec_sm_pwdb; | |
882 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | |
883 | "AP Client PWDB = 0x%lx\n", | |
884 | dm_pstable->rssi_val_min); | |
885 | } else { | |
886 | dm_pstable->rssi_val_min = rtlpriv->dm.undec_sm_pwdb; | |
887 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | |
888 | "STA Default Port PWDB = 0x%lx\n", | |
889 | dm_pstable->rssi_val_min); | |
890 | } | |
891 | } else { | |
892 | dm_pstable->rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb; | |
893 | ||
894 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | |
895 | "AP Ext Port PWDB = 0x%lx\n", | |
896 | dm_pstable->rssi_val_min); | |
897 | } | |
898 | ||
899 | rtl8723ae_dm_rf_saving(hw, false); | |
900 | } | |
901 | ||
902 | void rtl8723ae_dm_init(struct ieee80211_hw *hw) | |
903 | { | |
904 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
905 | ||
906 | rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; | |
907 | rtl8723ae_dm_diginit(hw); | |
908 | rtl8723ae_dm_init_dynamic_txpower(hw); | |
909 | rtl8723ae_dm_init_edca_turbo(hw); | |
910 | rtl8723ae_dm_init_rate_adaptive_mask(hw); | |
911 | rtl8723ae_dm_initialize_txpower_tracking(hw); | |
912 | rtl8723ae_dm_init_dynamic_bpowersaving(hw); | |
913 | } | |
914 | ||
915 | void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw) | |
916 | { | |
917 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
918 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | |
919 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | |
920 | bool fw_current_inpsmode = false; | |
921 | bool fw_ps_awake = true; | |
922 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, | |
923 | (u8 *) (&fw_current_inpsmode)); | |
924 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, | |
925 | (u8 *) (&fw_ps_awake)); | |
926 | ||
4b04edc1 LF |
927 | if (ppsc->p2p_ps_info.p2p_ps_mode) |
928 | fw_ps_awake = false; | |
929 | ||
c592e631 LF |
930 | if ((ppsc->rfpwr_state == ERFON) && |
931 | ((!fw_current_inpsmode) && fw_ps_awake) && | |
932 | (!ppsc->rfchange_inprogress)) { | |
933 | rtl8723ae_dm_pwdmonitor(hw); | |
934 | rtl8723ae_dm_dig(hw); | |
935 | rtl8723ae_dm_false_alarm_counter_statistics(hw); | |
936 | rtl8723ae_dm_dynamic_bpowersaving(hw); | |
937 | rtl8723ae_dm_dynamic_txpower(hw); | |
4b04edc1 | 938 | rtl8723ae_dm_refresh_rate_adaptive_mask(hw); |
c592e631 LF |
939 | rtl8723ae_dm_bt_coexist(hw); |
940 | rtl8723ae_dm_check_edca_turbo(hw); | |
941 | } | |
942 | if (rtlpcipriv->bt_coexist.init_set) | |
943 | rtl_write_byte(rtlpriv, 0x76e, 0xc); | |
944 | } | |
945 | ||
946 | static void rtl8723ae_dm_init_bt_coexist(struct ieee80211_hw *hw) | |
947 | { | |
948 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
949 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | |
950 | ||
951 | rtlpcipriv->bt_coexist.bt_rfreg_origin_1e | |
952 | = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK1, 0xfffff); | |
953 | rtlpcipriv->bt_coexist.bt_rfreg_origin_1f | |
954 | = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK2, 0xf0); | |
955 | ||
956 | rtlpcipriv->bt_coexist.cstate = 0; | |
957 | rtlpcipriv->bt_coexist.previous_state = 0; | |
958 | rtlpcipriv->bt_coexist.cstate_h = 0; | |
959 | rtlpcipriv->bt_coexist.previous_state_h = 0; | |
960 | rtlpcipriv->bt_coexist.lps_counter = 0; | |
961 | ||
962 | /* Enable counter statistics */ | |
963 | rtl_write_byte(rtlpriv, 0x76e, 0x4); | |
964 | rtl_write_byte(rtlpriv, 0x778, 0x3); | |
965 | rtl_write_byte(rtlpriv, 0x40, 0x20); | |
966 | ||
967 | rtlpcipriv->bt_coexist.init_set = true; | |
968 | } | |
969 | ||
970 | void rtl8723ae_dm_bt_coexist(struct ieee80211_hw *hw) | |
971 | { | |
972 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
973 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | |
974 | u8 tmp_byte = 0; | |
975 | if (!rtlpcipriv->bt_coexist.bt_coexistence) { | |
976 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, | |
977 | "[DM]{BT], BT not exist!!\n"); | |
978 | return; | |
979 | } | |
980 | ||
981 | if (!rtlpcipriv->bt_coexist.init_set) { | |
982 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, | |
983 | "[DM][BT], rtl8723ae_dm_bt_coexist()\n"); | |
984 | ||
985 | rtl8723ae_dm_init_bt_coexist(hw); | |
986 | } | |
987 | ||
988 | tmp_byte = rtl_read_byte(rtlpriv, 0x40); | |
989 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, | |
990 | "[DM][BT], 0x40 is 0x%x", tmp_byte); | |
991 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | |
992 | "[DM][BT], bt_dm_coexist start"); | |
993 | rtl8723ae_dm_bt_coexist_8723(hw); | |
994 | } |