]>
Commit | Line | Data |
---|---|---|
94a79942 LF |
1 | /****************************************************************************** |
2 | * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. | |
3 | * | |
4 | * This program is distributed in the hope that it will be useful, but WITHOUT | |
5 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
6 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
7 | * more details. | |
8 | * | |
9 | * You should have received a copy of the GNU General Public License along with | |
10 | * this program; if not, write to the Free Software Foundation, Inc., | |
11 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | |
12 | * | |
13 | * The full GNU General Public License is included in this distribution in the | |
14 | * file called LICENSE. | |
15 | * | |
16 | * Contact Information: | |
17 | * wlanfae <wlanfae@realtek.com> | |
18 | ******************************************************************************/ | |
19 | #include "rtl_core.h" | |
20 | #include "rtl_dm.h" | |
21 | #include "r8192E_hw.h" | |
22 | #include "r8192E_phy.h" | |
23 | #include "r8192E_phyreg.h" | |
24 | #include "r8190P_rtl8256.h" | |
25 | #include "r8192E_cmdpkt.h" | |
26 | ||
27 | /*---------------------------Define Local Constant---------------------------*/ | |
b448b0cc LF |
28 | static u32 edca_setting_DL[HT_IOT_PEER_MAX] = { |
29 | 0x5e4322, | |
30 | 0x5e4322, | |
31 | 0x5ea44f, | |
32 | 0x5e4322, | |
33 | 0x604322, | |
34 | 0xa44f, | |
35 | 0x5e4322, | |
36 | 0x5e4332 | |
94a79942 LF |
37 | }; |
38 | ||
b448b0cc LF |
39 | static u32 edca_setting_DL_GMode[HT_IOT_PEER_MAX] = { |
40 | 0x5e4322, | |
41 | 0x5e4322, | |
42 | 0x5e4322, | |
43 | 0x5e4322, | |
44 | 0x604322, | |
45 | 0xa44f, | |
46 | 0x5e4322, | |
47 | 0x5e4322 | |
48 | }; | |
49 | ||
50 | static u32 edca_setting_UL[HT_IOT_PEER_MAX] = { | |
51 | 0x5e4322, | |
52 | 0xa44f, | |
53 | 0x5ea44f, | |
54 | 0x5e4322, | |
55 | 0x604322, | |
56 | 0x5e4322, | |
57 | 0x5e4322, | |
58 | 0x5e4332 | |
94a79942 LF |
59 | }; |
60 | ||
20b7ec09 MK |
61 | const u32 dm_tx_bb_gain[TxBBGainTableLength] = { |
62 | 0x7f8001fe, /* 12 dB */ | |
63 | 0x788001e2, /* 11 dB */ | |
64 | 0x71c001c7, | |
65 | 0x6b8001ae, | |
66 | 0x65400195, | |
67 | 0x5fc0017f, | |
68 | 0x5a400169, | |
69 | 0x55400155, | |
70 | 0x50800142, | |
71 | 0x4c000130, | |
72 | 0x47c0011f, | |
73 | 0x43c0010f, | |
74 | 0x40000100, | |
75 | 0x3c8000f2, | |
76 | 0x390000e4, | |
77 | 0x35c000d7, | |
78 | 0x32c000cb, | |
79 | 0x300000c0, | |
80 | 0x2d4000b5, | |
81 | 0x2ac000ab, | |
82 | 0x288000a2, | |
83 | 0x26000098, | |
84 | 0x24000090, | |
85 | 0x22000088, | |
86 | 0x20000080, | |
87 | 0x1a00006c, | |
88 | 0x1c800072, | |
89 | 0x18000060, | |
90 | 0x19800066, | |
91 | 0x15800056, | |
92 | 0x26c0005b, | |
93 | 0x14400051, | |
94 | 0x24400051, | |
95 | 0x1300004c, | |
96 | 0x12000048, | |
97 | 0x11000044, | |
98 | 0x10000040, /* -24 dB */ | |
99 | }; | |
100 | ||
101 | const u8 dm_cck_tx_bb_gain[CCKTxBBGainTableLength][8] = { | |
102 | {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, | |
103 | {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, | |
104 | {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, | |
105 | {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, | |
106 | {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, | |
107 | {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, | |
108 | {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, | |
109 | {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, | |
110 | {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, | |
111 | {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, | |
112 | {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, | |
113 | {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, | |
114 | {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, | |
115 | {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, | |
116 | {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, | |
117 | {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, | |
118 | {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, | |
119 | {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, | |
120 | {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, | |
121 | {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, | |
122 | {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, | |
123 | {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, | |
124 | {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01} | |
125 | }; | |
126 | ||
127 | const u8 dm_cck_tx_bb_gain_ch14[CCKTxBBGainTableLength][8] = { | |
128 | {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, | |
129 | {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, | |
130 | {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, | |
131 | {0x2d, 0x2d, 0x27, 0x17, 0x00, 0x00, 0x00, 0x00}, | |
132 | {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, | |
133 | {0x28, 0x28, 0x22, 0x14, 0x00, 0x00, 0x00, 0x00}, | |
134 | {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, | |
135 | {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, | |
136 | {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, | |
137 | {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, | |
138 | {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, | |
139 | {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, | |
140 | {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, | |
141 | {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, | |
142 | {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, | |
143 | {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, | |
144 | {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, | |
145 | {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, | |
146 | {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, | |
147 | {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, | |
148 | {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, | |
149 | {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, | |
150 | {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00} | |
151 | }; | |
152 | ||
94a79942 LF |
153 | /*---------------------------Define Local Constant---------------------------*/ |
154 | ||
155 | ||
156 | /*------------------------Define global variable-----------------------------*/ | |
7204b51e | 157 | struct dig_t dm_digtable; |
b448b0cc | 158 | |
8e8b90c6 | 159 | struct drx_path_sel DM_RxPathSelTable; |
94a79942 LF |
160 | /*------------------------Define global variable-----------------------------*/ |
161 | ||
162 | ||
163 | /*------------------------Define local variable------------------------------*/ | |
164 | /*------------------------Define local variable------------------------------*/ | |
165 | ||
166 | ||
94a79942 LF |
167 | |
168 | /*---------------------Define local function prototype-----------------------*/ | |
169 | static void dm_check_rate_adaptive(struct net_device *dev); | |
170 | ||
b448b0cc LF |
171 | static void dm_init_bandwidth_autoswitch(struct net_device *dev); |
172 | static void dm_bandwidth_autoswitch(struct net_device *dev); | |
94a79942 LF |
173 | |
174 | ||
175 | static void dm_check_txpower_tracking(struct net_device *dev); | |
176 | ||
177 | ||
178 | ||
179 | ||
180 | ||
94a79942 LF |
181 | static void dm_bb_initialgain_restore(struct net_device *dev); |
182 | ||
183 | ||
184 | static void dm_bb_initialgain_backup(struct net_device *dev); | |
94a79942 LF |
185 | |
186 | static void dm_dig_init(struct net_device *dev); | |
187 | static void dm_ctrl_initgain_byrssi(struct net_device *dev); | |
188 | static void dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev); | |
b448b0cc | 189 | static void dm_ctrl_initgain_byrssi_by_driverrssi(struct net_device *dev); |
94a79942 LF |
190 | static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct net_device *dev); |
191 | static void dm_initial_gain(struct net_device *dev); | |
192 | static void dm_pd_th(struct net_device *dev); | |
193 | static void dm_cs_ratio(struct net_device *dev); | |
194 | ||
195 | static void dm_init_ctstoself(struct net_device *dev); | |
196 | static void dm_Init_WA_Broadcom_IOT(struct net_device *dev); | |
94a79942 LF |
197 | |
198 | static void dm_check_edca_turbo(struct net_device *dev); | |
199 | ||
94a79942 LF |
200 | static void dm_check_pbc_gpio(struct net_device *dev); |
201 | ||
202 | ||
203 | static void dm_check_rx_path_selection(struct net_device *dev); | |
204 | static void dm_init_rxpath_selection(struct net_device *dev); | |
205 | static void dm_rxpath_sel_byrssi(struct net_device *dev); | |
206 | ||
207 | ||
208 | static void dm_init_fsync(struct net_device *dev); | |
209 | static void dm_deInit_fsync(struct net_device *dev); | |
210 | ||
211 | static void dm_check_txrateandretrycount(struct net_device *dev); | |
212 | static void dm_check_ac_dc_power(struct net_device *dev); | |
735b7861 MK |
213 | static void dm_check_fsync(struct net_device *dev); |
214 | static void dm_CheckRfCtrlGPIO(void *data); | |
215 | static void dm_fsync_timer_callback(unsigned long data); | |
94a79942 LF |
216 | |
217 | /*---------------------Define local function prototype-----------------------*/ | |
218 | ||
219 | static void dm_init_dynamic_txpower(struct net_device *dev); | |
220 | static void dm_dynamic_txpower(struct net_device *dev); | |
221 | ||
222 | ||
223 | static void dm_send_rssi_tofw(struct net_device *dev); | |
224 | static void dm_ctstoself(struct net_device *dev); | |
94a79942 LF |
225 | /*---------------------------Define function prototype------------------------*/ |
226 | ||
ab743598 | 227 | void rtl92e_dm_init(struct net_device *dev) |
94a79942 LF |
228 | { |
229 | struct r8192_priv *priv = rtllib_priv(dev); | |
3a6b70c3 | 230 | |
94a79942 LF |
231 | priv->DM_Type = DM_Type_ByDriver; |
232 | ||
233 | priv->undecorated_smoothed_pwdb = -1; | |
234 | ||
235 | dm_init_dynamic_txpower(dev); | |
236 | ||
2e3ba83a | 237 | rtl92e_init_adaptive_rate(dev); |
94a79942 LF |
238 | |
239 | dm_dig_init(dev); | |
7842c2d5 | 240 | rtl92e_dm_init_edca_turbo(dev); |
b448b0cc | 241 | dm_init_bandwidth_autoswitch(dev); |
94a79942 LF |
242 | dm_init_fsync(dev); |
243 | dm_init_rxpath_selection(dev); | |
244 | dm_init_ctstoself(dev); | |
b448b0cc LF |
245 | if (IS_HARDWARE_TYPE_8192SE(dev)) |
246 | dm_Init_WA_Broadcom_IOT(dev); | |
94a79942 | 247 | |
35e33b04 MK |
248 | INIT_DELAYED_WORK_RSL(&priv->gpio_change_rf_wq, |
249 | (void *)dm_CheckRfCtrlGPIO, dev); | |
94a79942 LF |
250 | } |
251 | ||
fd9e3171 | 252 | void rtl92e_dm_deinit(struct net_device *dev) |
94a79942 LF |
253 | { |
254 | ||
255 | dm_deInit_fsync(dev); | |
256 | ||
257 | } | |
258 | ||
8e1e64bb | 259 | void rtl92e_dm_watchdog(struct net_device *dev) |
94a79942 LF |
260 | { |
261 | struct r8192_priv *priv = rtllib_priv(dev); | |
3a6b70c3 | 262 | |
94a79942 LF |
263 | if (priv->being_init_adapter) |
264 | return; | |
265 | ||
266 | dm_check_ac_dc_power(dev); | |
267 | ||
268 | dm_check_pbc_gpio(dev); | |
269 | dm_check_txrateandretrycount(dev); | |
270 | dm_check_edca_turbo(dev); | |
271 | ||
94a79942 LF |
272 | dm_check_rate_adaptive(dev); |
273 | dm_dynamic_txpower(dev); | |
274 | dm_check_txpower_tracking(dev); | |
275 | ||
276 | dm_ctrl_initgain_byrssi(dev); | |
b448b0cc | 277 | dm_bandwidth_autoswitch(dev); |
94a79942 LF |
278 | |
279 | dm_check_rx_path_selection(dev); | |
280 | dm_check_fsync(dev); | |
281 | ||
282 | dm_send_rssi_tofw(dev); | |
283 | dm_ctstoself(dev); | |
94a79942 LF |
284 | } |
285 | ||
49aab5fd | 286 | static void dm_check_ac_dc_power(struct net_device *dev) |
94a79942 LF |
287 | { |
288 | struct r8192_priv *priv = rtllib_priv(dev); | |
35e33b04 MK |
289 | static char *ac_dc_script = "/etc/acpi/wireless-rtl-ac-dc-power.sh"; |
290 | char *argv[] = {ac_dc_script, DRV_NAME, NULL}; | |
94a79942 LF |
291 | static char *envp[] = {"HOME=/", |
292 | "TERM=linux", | |
293 | "PATH=/usr/bin:/bin", | |
294 | NULL}; | |
295 | ||
b448b0cc LF |
296 | if (priv->ResetProgress == RESET_TYPE_SILENT) { |
297 | RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF), | |
db2c8da0 | 298 | "GPIOChangeRFWorkItemCallBack(): Silent Reset!!!!!!!\n"); |
94a79942 LF |
299 | return; |
300 | } | |
301 | ||
b448b0cc | 302 | if (priv->rtllib->state != RTLLIB_LINKED) |
94a79942 | 303 | return; |
35e33b04 | 304 | call_usermodehelper(ac_dc_script, argv, envp, UMH_WAIT_PROC); |
94a79942 LF |
305 | |
306 | return; | |
307 | }; | |
308 | ||
309 | ||
2e3ba83a | 310 | void rtl92e_init_adaptive_rate(struct net_device *dev) |
94a79942 LF |
311 | { |
312 | ||
313 | struct r8192_priv *priv = rtllib_priv(dev); | |
35e33b04 | 314 | struct rate_adaptive *pra = &priv->rate_adaptive; |
94a79942 LF |
315 | |
316 | pra->ratr_state = DM_RATR_STA_MAX; | |
317 | pra->high2low_rssi_thresh_for_ra = RateAdaptiveTH_High; | |
318 | pra->low2high_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M+5; | |
319 | pra->low2high_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M+5; | |
320 | ||
321 | pra->high_rssi_thresh_for_ra = RateAdaptiveTH_High+5; | |
322 | pra->low_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M; | |
323 | pra->low_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M; | |
324 | ||
325 | if (priv->CustomerID == RT_CID_819x_Netcore) | |
326 | pra->ping_rssi_enable = 1; | |
327 | else | |
328 | pra->ping_rssi_enable = 0; | |
329 | pra->ping_rssi_thresh_for_ra = 15; | |
330 | ||
331 | ||
b448b0cc | 332 | if (priv->rf_type == RF_2T4R) { |
94a79942 LF |
333 | pra->upper_rssi_threshold_ratr = 0x8f0f0000; |
334 | pra->middle_rssi_threshold_ratr = 0x8f0ff000; | |
335 | pra->low_rssi_threshold_ratr = 0x8f0ff001; | |
336 | pra->low_rssi_threshold_ratr_40M = 0x8f0ff005; | |
337 | pra->low_rssi_threshold_ratr_20M = 0x8f0ff001; | |
338 | pra->ping_rssi_ratr = 0x0000000d; | |
b448b0cc | 339 | } else if (priv->rf_type == RF_1T2R) { |
94a79942 LF |
340 | pra->upper_rssi_threshold_ratr = 0x000fc000; |
341 | pra->middle_rssi_threshold_ratr = 0x000ff000; | |
342 | pra->low_rssi_threshold_ratr = 0x000ff001; | |
343 | pra->low_rssi_threshold_ratr_40M = 0x000ff005; | |
344 | pra->low_rssi_threshold_ratr_20M = 0x000ff001; | |
345 | pra->ping_rssi_ratr = 0x0000000d; | |
346 | } | |
347 | ||
348 | } | |
349 | ||
350 | ||
b448b0cc | 351 | static void dm_check_rate_adaptive(struct net_device *dev) |
94a79942 LF |
352 | { |
353 | struct r8192_priv *priv = rtllib_priv(dev); | |
7796d93e | 354 | struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo; |
35e33b04 | 355 | struct rate_adaptive *pra = &priv->rate_adaptive; |
b448b0cc LF |
356 | u32 currentRATR, targetRATR = 0; |
357 | u32 LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0; | |
358 | bool bshort_gi_enabled = false; | |
359 | static u8 ping_rssi_state; | |
94a79942 | 360 | |
5dc42962 | 361 | if (!priv->up) { |
35e33b04 MK |
362 | RT_TRACE(COMP_RATE, |
363 | "<---- dm_check_rate_adaptive(): driver is going to unload\n"); | |
94a79942 LF |
364 | return; |
365 | } | |
366 | ||
367 | if (pra->rate_adaptive_disabled) | |
368 | return; | |
369 | ||
b448b0cc LF |
370 | if (!(priv->rtllib->mode == WIRELESS_MODE_N_24G || |
371 | priv->rtllib->mode == WIRELESS_MODE_N_5G)) | |
372 | return; | |
94a79942 | 373 | |
b448b0cc | 374 | if (priv->rtllib->state == RTLLIB_LINKED) { |
94a79942 | 375 | |
35e33b04 MK |
376 | bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && |
377 | pHTInfo->bCurShortGI40MHz) || | |
378 | (!pHTInfo->bCurTxBW40MHz && | |
379 | pHTInfo->bCurShortGI20MHz); | |
94a79942 LF |
380 | |
381 | pra->upper_rssi_threshold_ratr = | |
35e33b04 MK |
382 | (pra->upper_rssi_threshold_ratr & (~BIT31)) | |
383 | ((bshort_gi_enabled) ? BIT31 : 0); | |
94a79942 LF |
384 | |
385 | pra->middle_rssi_threshold_ratr = | |
35e33b04 MK |
386 | (pra->middle_rssi_threshold_ratr & (~BIT31)) | |
387 | ((bshort_gi_enabled) ? BIT31 : 0); | |
94a79942 | 388 | |
b448b0cc | 389 | if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) { |
94a79942 | 390 | pra->low_rssi_threshold_ratr = |
35e33b04 MK |
391 | (pra->low_rssi_threshold_ratr_40M & (~BIT31)) | |
392 | ((bshort_gi_enabled) ? BIT31 : 0); | |
b448b0cc | 393 | } else { |
94a79942 | 394 | pra->low_rssi_threshold_ratr = |
35e33b04 MK |
395 | (pra->low_rssi_threshold_ratr_20M & (~BIT31)) | |
396 | ((bshort_gi_enabled) ? BIT31 : 0); | |
94a79942 LF |
397 | } |
398 | pra->ping_rssi_ratr = | |
35e33b04 MK |
399 | (pra->ping_rssi_ratr & (~BIT31)) | |
400 | ((bshort_gi_enabled) ? BIT31 : 0); | |
94a79942 | 401 | |
b448b0cc | 402 | if (pra->ratr_state == DM_RATR_STA_HIGH) { |
d9c1fff5 MK |
403 | HighRSSIThreshForRA = pra->high2low_rssi_thresh_for_ra; |
404 | LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ? | |
b448b0cc LF |
405 | (pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M); |
406 | } else if (pra->ratr_state == DM_RATR_STA_LOW) { | |
d9c1fff5 MK |
407 | HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra; |
408 | LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ? | |
b448b0cc LF |
409 | (pra->low2high_rssi_thresh_for_ra40M) : (pra->low2high_rssi_thresh_for_ra20M); |
410 | } else { | |
d9c1fff5 MK |
411 | HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra; |
412 | LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ? | |
b448b0cc | 413 | (pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M); |
94a79942 LF |
414 | } |
415 | ||
35e33b04 MK |
416 | if (priv->undecorated_smoothed_pwdb >= |
417 | (long)HighRSSIThreshForRA) { | |
94a79942 LF |
418 | pra->ratr_state = DM_RATR_STA_HIGH; |
419 | targetRATR = pra->upper_rssi_threshold_ratr; | |
35e33b04 MK |
420 | } else if (priv->undecorated_smoothed_pwdb >= |
421 | (long)LowRSSIThreshForRA) { | |
94a79942 LF |
422 | pra->ratr_state = DM_RATR_STA_MIDDLE; |
423 | targetRATR = pra->middle_rssi_threshold_ratr; | |
b448b0cc | 424 | } else { |
94a79942 LF |
425 | pra->ratr_state = DM_RATR_STA_LOW; |
426 | targetRATR = pra->low_rssi_threshold_ratr; | |
427 | } | |
428 | ||
b448b0cc | 429 | if (pra->ping_rssi_enable) { |
35e33b04 MK |
430 | if (priv->undecorated_smoothed_pwdb < |
431 | (long)(pra->ping_rssi_thresh_for_ra+5)) { | |
432 | if ((priv->undecorated_smoothed_pwdb < | |
433 | (long)pra->ping_rssi_thresh_for_ra) || | |
b448b0cc | 434 | ping_rssi_state) { |
94a79942 LF |
435 | pra->ratr_state = DM_RATR_STA_LOW; |
436 | targetRATR = pra->ping_rssi_ratr; | |
437 | ping_rssi_state = 1; | |
438 | } | |
b448b0cc | 439 | } else { |
94a79942 LF |
440 | ping_rssi_state = 0; |
441 | } | |
442 | } | |
443 | ||
94a79942 LF |
444 | if (priv->rtllib->GetHalfNmodeSupportByAPsHandler(dev)) |
445 | targetRATR &= 0xf00fffff; | |
94a79942 | 446 | |
99aa47e0 | 447 | currentRATR = rtl92e_readl(dev, RATR0); |
b448b0cc | 448 | if (targetRATR != currentRATR) { |
94a79942 | 449 | u32 ratr_value; |
3a6b70c3 | 450 | |
94a79942 | 451 | ratr_value = targetRATR; |
b448b0cc LF |
452 | RT_TRACE(COMP_RATE, |
453 | "currentRATR = %x, targetRATR = %x\n", | |
454 | currentRATR, targetRATR); | |
94a79942 | 455 | if (priv->rf_type == RF_1T2R) |
94a79942 | 456 | ratr_value &= ~(RATE_ALL_OFDM_2SS); |
8ea54100 | 457 | rtl92e_writel(dev, RATR0, ratr_value); |
d8ae1967 | 458 | rtl92e_writeb(dev, UFWP, 1); |
94a79942 LF |
459 | |
460 | pra->last_ratr = targetRATR; | |
461 | } | |
462 | ||
b448b0cc | 463 | } else { |
94a79942 LF |
464 | pra->ratr_state = DM_RATR_STA_MAX; |
465 | } | |
94a79942 LF |
466 | } |
467 | ||
b448b0cc | 468 | static void dm_init_bandwidth_autoswitch(struct net_device *dev) |
94a79942 LF |
469 | { |
470 | struct r8192_priv *priv = rtllib_priv(dev); | |
471 | ||
472 | priv->rtllib->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH; | |
473 | priv->rtllib->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW; | |
474 | priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = false; | |
475 | priv->rtllib->bandwidth_auto_switch.bautoswitch_enable = false; | |
94a79942 LF |
476 | } |
477 | ||
b448b0cc | 478 | static void dm_bandwidth_autoswitch(struct net_device *dev) |
94a79942 LF |
479 | { |
480 | struct r8192_priv *priv = rtllib_priv(dev); | |
481 | ||
b448b0cc | 482 | if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 || |
285b7c00 | 483 | !priv->rtllib->bandwidth_auto_switch.bautoswitch_enable) |
94a79942 | 484 | return; |
285b7c00 MK |
485 | if (priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz == false) { |
486 | if (priv->undecorated_smoothed_pwdb <= | |
487 | priv->rtllib->bandwidth_auto_switch.threshold_40Mhzto20Mhz) | |
488 | priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = true; | |
b448b0cc | 489 | } else { |
285b7c00 MK |
490 | if (priv->undecorated_smoothed_pwdb >= |
491 | priv->rtllib->bandwidth_auto_switch.threshold_20Mhzto40Mhz) | |
492 | priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = false; | |
94a79942 LF |
493 | } |
494 | } | |
495 | ||
94a79942 LF |
496 | static u32 OFDMSwingTable[OFDM_Table_Length] = { |
497 | 0x7f8001fe, | |
498 | 0x71c001c7, | |
499 | 0x65400195, | |
500 | 0x5a400169, | |
501 | 0x50800142, | |
502 | 0x47c0011f, | |
503 | 0x40000100, | |
504 | 0x390000e4, | |
505 | 0x32c000cb, | |
506 | 0x2d4000b5, | |
507 | 0x288000a2, | |
508 | 0x24000090, | |
509 | 0x20000080, | |
510 | 0x1c800072, | |
511 | 0x19800066, | |
512 | 0x26c0005b, | |
513 | 0x24400051, | |
514 | 0x12000048, | |
515 | 0x10000040 | |
516 | }; | |
b448b0cc | 517 | |
94a79942 LF |
518 | static u8 CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = { |
519 | {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, | |
520 | {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, | |
521 | {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, | |
522 | {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, | |
523 | {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, | |
524 | {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, | |
525 | {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, | |
526 | {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, | |
527 | {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, | |
528 | {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, | |
529 | {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, | |
530 | {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01} | |
531 | }; | |
532 | ||
533 | static u8 CCKSwingTable_Ch14[CCK_Table_length][8] = { | |
534 | {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, | |
535 | {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, | |
536 | {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, | |
537 | {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, | |
538 | {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, | |
539 | {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, | |
540 | {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, | |
541 | {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, | |
542 | {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, | |
543 | {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, | |
544 | {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, | |
545 | {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00} | |
546 | }; | |
b448b0cc | 547 | |
94a79942 LF |
548 | #define Pw_Track_Flag 0x11d |
549 | #define Tssi_Mea_Value 0x13c | |
550 | #define Tssi_Report_Value1 0x134 | |
551 | #define Tssi_Report_Value2 0x13e | |
552 | #define FW_Busy_Flag 0x13f | |
553 | ||
eae10b8e MK |
554 | static void dm_tx_update_tssi_weak_signal(struct net_device *dev, u8 RF_Type) |
555 | { | |
556 | struct r8192_priv *p = rtllib_priv(dev); | |
557 | ||
558 | if (RF_Type == RF_2T4R) { | |
559 | if ((p->rfa_txpowertrackingindex > 0) && | |
560 | (p->rfc_txpowertrackingindex > 0)) { | |
561 | p->rfa_txpowertrackingindex--; | |
562 | if (p->rfa_txpowertrackingindex_real > 4) { | |
563 | p->rfa_txpowertrackingindex_real--; | |
153f9ddb MK |
564 | rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, |
565 | bMaskDWord, | |
566 | dm_tx_bb_gain[p->rfa_txpowertrackingindex_real]); | |
eae10b8e MK |
567 | } |
568 | ||
569 | p->rfc_txpowertrackingindex--; | |
570 | if (p->rfc_txpowertrackingindex_real > 4) { | |
571 | p->rfc_txpowertrackingindex_real--; | |
153f9ddb MK |
572 | rtl92e_set_bb_reg(dev, |
573 | rOFDM0_XCTxIQImbalance, | |
574 | bMaskDWord, | |
575 | dm_tx_bb_gain[p->rfc_txpowertrackingindex_real]); | |
eae10b8e MK |
576 | } |
577 | } else { | |
153f9ddb MK |
578 | rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, |
579 | bMaskDWord, | |
580 | dm_tx_bb_gain[4]); | |
581 | rtl92e_set_bb_reg(dev, | |
582 | rOFDM0_XCTxIQImbalance, | |
583 | bMaskDWord, dm_tx_bb_gain[4]); | |
eae10b8e MK |
584 | } |
585 | } else { | |
586 | if (p->rfa_txpowertrackingindex > 0) { | |
587 | p->rfa_txpowertrackingindex--; | |
588 | if (p->rfa_txpowertrackingindex_real > 4) { | |
589 | p->rfa_txpowertrackingindex_real--; | |
153f9ddb MK |
590 | rtl92e_set_bb_reg(dev, |
591 | rOFDM0_XATxIQImbalance, | |
592 | bMaskDWord, | |
593 | dm_tx_bb_gain[p->rfa_txpowertrackingindex_real]); | |
eae10b8e MK |
594 | } |
595 | } else { | |
153f9ddb MK |
596 | rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, |
597 | bMaskDWord, dm_tx_bb_gain[4]); | |
eae10b8e MK |
598 | } |
599 | } | |
600 | } | |
601 | ||
602 | static void dm_tx_update_tssi_strong_signal(struct net_device *dev, u8 RF_Type) | |
603 | { | |
604 | struct r8192_priv *p = rtllib_priv(dev); | |
605 | ||
606 | if (RF_Type == RF_2T4R) { | |
607 | if ((p->rfa_txpowertrackingindex < TxBBGainTableLength - 1) && | |
608 | (p->rfc_txpowertrackingindex < TxBBGainTableLength - 1)) { | |
609 | p->rfa_txpowertrackingindex++; | |
610 | p->rfa_txpowertrackingindex_real++; | |
153f9ddb MK |
611 | rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, |
612 | bMaskDWord, | |
613 | dm_tx_bb_gain[p->rfa_txpowertrackingindex_real]); | |
eae10b8e MK |
614 | p->rfc_txpowertrackingindex++; |
615 | p->rfc_txpowertrackingindex_real++; | |
153f9ddb MK |
616 | rtl92e_set_bb_reg(dev, rOFDM0_XCTxIQImbalance, |
617 | bMaskDWord, | |
618 | dm_tx_bb_gain[p->rfc_txpowertrackingindex_real]); | |
eae10b8e | 619 | } else { |
153f9ddb MK |
620 | rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, |
621 | bMaskDWord, | |
622 | dm_tx_bb_gain[TxBBGainTableLength - 1]); | |
623 | rtl92e_set_bb_reg(dev, rOFDM0_XCTxIQImbalance, | |
624 | bMaskDWord, | |
625 | dm_tx_bb_gain[TxBBGainTableLength - 1]); | |
eae10b8e MK |
626 | } |
627 | } else { | |
628 | if (p->rfa_txpowertrackingindex < (TxBBGainTableLength - 1)) { | |
629 | p->rfa_txpowertrackingindex++; | |
630 | p->rfa_txpowertrackingindex_real++; | |
153f9ddb MK |
631 | rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, |
632 | bMaskDWord, | |
633 | dm_tx_bb_gain[p->rfa_txpowertrackingindex_real]); | |
eae10b8e | 634 | } else { |
153f9ddb MK |
635 | rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, |
636 | bMaskDWord, | |
637 | dm_tx_bb_gain[TxBBGainTableLength - 1]); | |
eae10b8e MK |
638 | } |
639 | } | |
640 | } | |
641 | ||
b448b0cc LF |
642 | static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev) |
643 | { | |
94a79942 | 644 | struct r8192_priv *priv = rtllib_priv(dev); |
b448b0cc | 645 | bool bHighpowerstate, viviflag = false; |
bdc632bc | 646 | struct dcmd_txcmd tx_cmd; |
b448b0cc LF |
647 | u8 powerlevelOFDM24G; |
648 | int i = 0, j = 0, k = 0; | |
649 | u8 RF_Type, tmp_report[5] = {0, 0, 0, 0, 0}; | |
650 | u32 Value; | |
651 | u8 Pwr_Flag; | |
652 | u16 Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver = 0; | |
653 | u32 delta = 0; | |
654 | ||
655 | RT_TRACE(COMP_POWER_TRACKING, "%s()\n", __func__); | |
d8ae1967 MK |
656 | rtl92e_writeb(dev, Pw_Track_Flag, 0); |
657 | rtl92e_writeb(dev, FW_Busy_Flag, 0); | |
94a79942 LF |
658 | priv->rtllib->bdynamic_txpower_enable = false; |
659 | bHighpowerstate = priv->bDynamicTxHighPower; | |
660 | ||
661 | powerlevelOFDM24G = (u8)(priv->Pwr_Track>>24); | |
662 | RF_Type = priv->rf_type; | |
663 | Value = (RF_Type<<8) | powerlevelOFDM24G; | |
664 | ||
b448b0cc LF |
665 | RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n", |
666 | powerlevelOFDM24G); | |
94a79942 LF |
667 | |
668 | ||
b448b0cc | 669 | for (j = 0; j <= 30; j++) { |
94a79942 | 670 | |
b448b0cc LF |
671 | tx_cmd.Op = TXCMD_SET_TX_PWR_TRACKING; |
672 | tx_cmd.Length = 4; | |
673 | tx_cmd.Value = Value; | |
12656e2b MK |
674 | rtl92e_send_cmd_pkt(dev, (u8 *)&tx_cmd, DESC_PACKET_TYPE_INIT, |
675 | sizeof(struct dcmd_txcmd)); | |
b448b0cc LF |
676 | mdelay(1); |
677 | for (i = 0; i <= 30; i++) { | |
b59a4ca3 | 678 | Pwr_Flag = rtl92e_readb(dev, Pw_Track_Flag); |
94a79942 | 679 | |
b448b0cc LF |
680 | if (Pwr_Flag == 0) { |
681 | mdelay(1); | |
94a79942 | 682 | |
b448b0cc LF |
683 | if (priv->bResetInProgress) { |
684 | RT_TRACE(COMP_POWER_TRACKING, | |
cd017123 | 685 | "we are in silent reset progress, so return\n"); |
d8ae1967 MK |
686 | rtl92e_writeb(dev, Pw_Track_Flag, 0); |
687 | rtl92e_writeb(dev, FW_Busy_Flag, 0); | |
b448b0cc LF |
688 | return; |
689 | } | |
025b8bbe | 690 | if (priv->rtllib->eRFPowerState != eRfOn) { |
b448b0cc LF |
691 | RT_TRACE(COMP_POWER_TRACKING, |
692 | "we are in power save, so return\n"); | |
d8ae1967 MK |
693 | rtl92e_writeb(dev, Pw_Track_Flag, 0); |
694 | rtl92e_writeb(dev, FW_Busy_Flag, 0); | |
b448b0cc LF |
695 | return; |
696 | } | |
697 | ||
698 | continue; | |
94a79942 | 699 | } |
b448b0cc | 700 | |
1c0a7c0e | 701 | Avg_TSSI_Meas = rtl92e_readw(dev, Tssi_Mea_Value); |
b448b0cc LF |
702 | |
703 | if (Avg_TSSI_Meas == 0) { | |
d8ae1967 MK |
704 | rtl92e_writeb(dev, Pw_Track_Flag, 0); |
705 | rtl92e_writeb(dev, FW_Busy_Flag, 0); | |
94a79942 LF |
706 | return; |
707 | } | |
708 | ||
b448b0cc LF |
709 | for (k = 0; k < 5; k++) { |
710 | if (k != 4) | |
b59a4ca3 | 711 | tmp_report[k] = rtl92e_readb(dev, |
b448b0cc LF |
712 | Tssi_Report_Value1+k); |
713 | else | |
b59a4ca3 | 714 | tmp_report[k] = rtl92e_readb(dev, |
b448b0cc | 715 | Tssi_Report_Value2); |
94a79942 | 716 | |
b448b0cc LF |
717 | RT_TRACE(COMP_POWER_TRACKING, |
718 | "TSSI_report_value = %d\n", | |
719 | tmp_report[k]); | |
94a79942 | 720 | |
b448b0cc LF |
721 | if (tmp_report[k] <= 20) { |
722 | viviflag = true; | |
723 | break; | |
724 | } | |
725 | } | |
94a79942 | 726 | |
4bb01423 | 727 | if (viviflag) { |
d8ae1967 | 728 | rtl92e_writeb(dev, Pw_Track_Flag, 0); |
b448b0cc | 729 | viviflag = false; |
35e33b04 MK |
730 | RT_TRACE(COMP_POWER_TRACKING, |
731 | "we filted this data\n"); | |
b448b0cc LF |
732 | for (k = 0; k < 5; k++) |
733 | tmp_report[k] = 0; | |
734 | break; | |
735 | } | |
94a79942 | 736 | |
b448b0cc LF |
737 | for (k = 0; k < 5; k++) |
738 | Avg_TSSI_Meas_from_driver += tmp_report[k]; | |
94a79942 | 739 | |
35e33b04 | 740 | Avg_TSSI_Meas_from_driver *= 100 / 5; |
b448b0cc LF |
741 | RT_TRACE(COMP_POWER_TRACKING, |
742 | "Avg_TSSI_Meas_from_driver = %d\n", | |
743 | Avg_TSSI_Meas_from_driver); | |
744 | TSSI_13dBm = priv->TSSI_13dBm; | |
d9c1fff5 MK |
745 | RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", |
746 | TSSI_13dBm); | |
94a79942 | 747 | |
b448b0cc LF |
748 | if (Avg_TSSI_Meas_from_driver > TSSI_13dBm) |
749 | delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm; | |
750 | else | |
751 | delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver; | |
94a79942 | 752 | |
b448b0cc LF |
753 | if (delta <= E_FOR_TX_POWER_TRACK) { |
754 | priv->rtllib->bdynamic_txpower_enable = true; | |
d8ae1967 MK |
755 | rtl92e_writeb(dev, Pw_Track_Flag, 0); |
756 | rtl92e_writeb(dev, FW_Busy_Flag, 0); | |
b448b0cc LF |
757 | RT_TRACE(COMP_POWER_TRACKING, |
758 | "tx power track is done\n"); | |
759 | RT_TRACE(COMP_POWER_TRACKING, | |
760 | "priv->rfa_txpowertrackingindex = %d\n", | |
761 | priv->rfa_txpowertrackingindex); | |
762 | RT_TRACE(COMP_POWER_TRACKING, | |
763 | "priv->rfa_txpowertrackingindex_real = %d\n", | |
764 | priv->rfa_txpowertrackingindex_real); | |
765 | RT_TRACE(COMP_POWER_TRACKING, | |
766 | "priv->CCKPresentAttentuation_difference = %d\n", | |
767 | priv->CCKPresentAttentuation_difference); | |
768 | RT_TRACE(COMP_POWER_TRACKING, | |
769 | "priv->CCKPresentAttentuation = %d\n", | |
770 | priv->CCKPresentAttentuation); | |
771 | return; | |
285b7c00 | 772 | } |
eae10b8e MK |
773 | if (Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK) |
774 | dm_tx_update_tssi_weak_signal(dev, RF_Type); | |
775 | else | |
776 | dm_tx_update_tssi_strong_signal(dev, RF_Type); | |
285b7c00 | 777 | |
285b7c00 MK |
778 | if (RF_Type == RF_2T4R) { |
779 | priv->CCKPresentAttentuation_difference | |
780 | = priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default; | |
781 | } else { | |
782 | priv->CCKPresentAttentuation_difference | |
783 | = priv->rfa_txpowertrackingindex_real - priv->rfa_txpowertracking_default; | |
784 | } | |
b448b0cc | 785 | |
285b7c00 MK |
786 | if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20) |
787 | priv->CCKPresentAttentuation = | |
788 | priv->CCKPresentAttentuation_20Mdefault + | |
789 | priv->CCKPresentAttentuation_difference; | |
790 | else | |
791 | priv->CCKPresentAttentuation = | |
792 | priv->CCKPresentAttentuation_40Mdefault + | |
793 | priv->CCKPresentAttentuation_difference; | |
794 | ||
795 | if (priv->CCKPresentAttentuation > (CCKTxBBGainTableLength-1)) | |
796 | priv->CCKPresentAttentuation = CCKTxBBGainTableLength-1; | |
797 | if (priv->CCKPresentAttentuation < 0) | |
798 | priv->CCKPresentAttentuation = 0; | |
799 | ||
800 | if (priv->CCKPresentAttentuation > -1 && | |
801 | priv->CCKPresentAttentuation < CCKTxBBGainTableLength) { | |
802 | if (priv->rtllib->current_network.channel == 14 && | |
803 | !priv->bcck_in_ch14) { | |
804 | priv->bcck_in_ch14 = true; | |
59e84dc3 | 805 | rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); |
285b7c00 MK |
806 | } else if (priv->rtllib->current_network.channel != 14 && priv->bcck_in_ch14) { |
807 | priv->bcck_in_ch14 = false; | |
59e84dc3 | 808 | rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); |
285b7c00 | 809 | } else |
59e84dc3 | 810 | rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); |
94a79942 | 811 | } |
285b7c00 MK |
812 | RT_TRACE(COMP_POWER_TRACKING, |
813 | "priv->rfa_txpowertrackingindex = %d\n", | |
814 | priv->rfa_txpowertrackingindex); | |
815 | RT_TRACE(COMP_POWER_TRACKING, | |
816 | "priv->rfa_txpowertrackingindex_real = %d\n", | |
817 | priv->rfa_txpowertrackingindex_real); | |
818 | RT_TRACE(COMP_POWER_TRACKING, | |
819 | "priv->CCKPresentAttentuation_difference = %d\n", | |
820 | priv->CCKPresentAttentuation_difference); | |
821 | RT_TRACE(COMP_POWER_TRACKING, | |
822 | "priv->CCKPresentAttentuation = %d\n", | |
823 | priv->CCKPresentAttentuation); | |
824 | ||
d9c1fff5 MK |
825 | if (priv->CCKPresentAttentuation_difference <= -12 || |
826 | priv->CCKPresentAttentuation_difference >= 24) { | |
285b7c00 | 827 | priv->rtllib->bdynamic_txpower_enable = true; |
d8ae1967 MK |
828 | rtl92e_writeb(dev, Pw_Track_Flag, 0); |
829 | rtl92e_writeb(dev, FW_Busy_Flag, 0); | |
d9c1fff5 MK |
830 | RT_TRACE(COMP_POWER_TRACKING, |
831 | "tx power track--->limited\n"); | |
285b7c00 MK |
832 | return; |
833 | } | |
834 | ||
d8ae1967 | 835 | rtl92e_writeb(dev, Pw_Track_Flag, 0); |
b448b0cc LF |
836 | Avg_TSSI_Meas_from_driver = 0; |
837 | for (k = 0; k < 5; k++) | |
838 | tmp_report[k] = 0; | |
839 | break; | |
94a79942 | 840 | } |
d8ae1967 | 841 | rtl92e_writeb(dev, FW_Busy_Flag, 0); |
94a79942 | 842 | } |
b448b0cc | 843 | priv->rtllib->bdynamic_txpower_enable = true; |
d8ae1967 | 844 | rtl92e_writeb(dev, Pw_Track_Flag, 0); |
94a79942 | 845 | } |
94a79942 | 846 | |
b448b0cc | 847 | static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device *dev) |
94a79942 LF |
848 | { |
849 | #define ThermalMeterVal 9 | |
850 | struct r8192_priv *priv = rtllib_priv(dev); | |
851 | u32 tmpRegA, TempCCk; | |
852 | u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval; | |
b448b0cc LF |
853 | int i = 0, CCKSwingNeedUpdate = 0; |
854 | ||
855 | if (!priv->btxpower_trackingInit) { | |
3c351fec MK |
856 | tmpRegA = rtl92e_get_bb_reg(dev, rOFDM0_XATxIQImbalance, |
857 | bMaskDWord); | |
b448b0cc LF |
858 | for (i = 0; i < OFDM_Table_Length; i++) { |
859 | if (tmpRegA == OFDMSwingTable[i]) { | |
860 | priv->OFDM_index[0] = (u8)i; | |
35e33b04 MK |
861 | RT_TRACE(COMP_POWER_TRACKING, |
862 | "Initial reg0x%x = 0x%x, OFDM_index = 0x%x\n", | |
863 | rOFDM0_XATxIQImbalance, tmpRegA, | |
864 | priv->OFDM_index[0]); | |
94a79942 LF |
865 | } |
866 | } | |
867 | ||
3c351fec | 868 | TempCCk = rtl92e_get_bb_reg(dev, rCCK0_TxFilter1, bMaskByte2); |
b448b0cc LF |
869 | for (i = 0; i < CCK_Table_length; i++) { |
870 | if (TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0]) { | |
871 | priv->CCK_index = (u8) i; | |
0822339b MK |
872 | RT_TRACE(COMP_POWER_TRACKING, |
873 | "Initial reg0x%x = 0x%x, CCK_index = 0x%x\n", | |
b448b0cc LF |
874 | rCCK0_TxFilter1, TempCCk, |
875 | priv->CCK_index); | |
876 | break; | |
877 | } | |
878 | } | |
94a79942 LF |
879 | priv->btxpower_trackingInit = true; |
880 | return; | |
881 | } | |
882 | ||
4d415dec | 883 | tmpRegA = rtl92e_get_rf_reg(dev, RF90_PATH_A, 0x12, 0x078); |
b448b0cc | 884 | RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d\n", tmpRegA); |
94a79942 LF |
885 | if (tmpRegA < 3 || tmpRegA > 13) |
886 | return; | |
887 | if (tmpRegA >= 12) | |
888 | tmpRegA = 12; | |
b448b0cc | 889 | RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d\n", tmpRegA); |
94a79942 LF |
890 | priv->ThermalMeter[0] = ThermalMeterVal; |
891 | priv->ThermalMeter[1] = ThermalMeterVal; | |
892 | ||
b448b0cc LF |
893 | if (priv->ThermalMeter[0] >= (u8)tmpRegA) { |
894 | tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0] - | |
895 | (u8)tmpRegA); | |
94a79942 LF |
896 | tmpCCK40Mindex = tmpCCK20Mindex - 6; |
897 | if (tmpOFDMindex >= OFDM_Table_Length) | |
898 | tmpOFDMindex = OFDM_Table_Length-1; | |
899 | if (tmpCCK20Mindex >= CCK_Table_length) | |
900 | tmpCCK20Mindex = CCK_Table_length-1; | |
901 | if (tmpCCK40Mindex >= CCK_Table_length) | |
902 | tmpCCK40Mindex = CCK_Table_length-1; | |
b448b0cc | 903 | } else { |
94a79942 LF |
904 | tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]); |
905 | if (tmpval >= 6) | |
906 | tmpOFDMindex = tmpCCK20Mindex = 0; | |
907 | else | |
908 | tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval; | |
909 | tmpCCK40Mindex = 0; | |
910 | } | |
911 | if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) | |
912 | tmpCCKindex = tmpCCK40Mindex; | |
913 | else | |
914 | tmpCCKindex = tmpCCK20Mindex; | |
915 | ||
916 | priv->Record_CCK_20Mindex = tmpCCK20Mindex; | |
917 | priv->Record_CCK_40Mindex = tmpCCK40Mindex; | |
0822339b MK |
918 | RT_TRACE(COMP_POWER_TRACKING, |
919 | "Record_CCK_20Mindex / Record_CCK_40Mindex = %d / %d.\n", | |
b448b0cc | 920 | priv->Record_CCK_20Mindex, priv->Record_CCK_40Mindex); |
94a79942 | 921 | |
b448b0cc LF |
922 | if (priv->rtllib->current_network.channel == 14 && |
923 | !priv->bcck_in_ch14) { | |
94a79942 LF |
924 | priv->bcck_in_ch14 = true; |
925 | CCKSwingNeedUpdate = 1; | |
b448b0cc LF |
926 | } else if (priv->rtllib->current_network.channel != 14 && |
927 | priv->bcck_in_ch14) { | |
94a79942 LF |
928 | priv->bcck_in_ch14 = false; |
929 | CCKSwingNeedUpdate = 1; | |
930 | } | |
931 | ||
b448b0cc | 932 | if (priv->CCK_index != tmpCCKindex) { |
94a79942 LF |
933 | priv->CCK_index = tmpCCKindex; |
934 | CCKSwingNeedUpdate = 1; | |
935 | } | |
936 | ||
937 | if (CCKSwingNeedUpdate) | |
59e84dc3 | 938 | rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); |
b448b0cc | 939 | if (priv->OFDM_index[0] != tmpOFDMindex) { |
94a79942 | 940 | priv->OFDM_index[0] = tmpOFDMindex; |
153f9ddb MK |
941 | rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, |
942 | OFDMSwingTable[priv->OFDM_index[0]]); | |
94a79942 | 943 | RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n", |
b448b0cc LF |
944 | priv->OFDM_index[0], |
945 | OFDMSwingTable[priv->OFDM_index[0]]); | |
94a79942 LF |
946 | } |
947 | priv->txpower_count = 0; | |
948 | } | |
94a79942 | 949 | |
33059f54 | 950 | void rtl92e_dm_txpower_tracking_wq(void *data) |
94a79942 | 951 | { |
b448b0cc LF |
952 | struct r8192_priv *priv = container_of_dwork_rsl(data, |
953 | struct r8192_priv, txpower_tracking_wq); | |
94a79942 | 954 | struct net_device *dev = priv->rtllib->dev; |
94a79942 | 955 | |
94a79942 LF |
956 | if (priv->IC_Cut >= IC_VersionCut_D) |
957 | dm_TXPowerTrackingCallback_TSSI(dev); | |
958 | else | |
959 | dm_TXPowerTrackingCallback_ThermalMeter(dev); | |
94a79942 LF |
960 | } |
961 | ||
94a79942 LF |
962 | static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev) |
963 | { | |
964 | ||
965 | struct r8192_priv *priv = rtllib_priv(dev); | |
867ebbae | 966 | |
94a79942 LF |
967 | priv->btxpower_tracking = true; |
968 | priv->txpower_count = 0; | |
969 | priv->btxpower_trackingInit = false; | |
970 | ||
971 | } | |
1e71e6d0 | 972 | |
94a79942 LF |
973 | static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev) |
974 | { | |
975 | struct r8192_priv *priv = rtllib_priv(dev); | |
976 | ||
94a79942 LF |
977 | |
978 | if (priv->rtllib->FwRWRF) | |
979 | priv->btxpower_tracking = true; | |
980 | else | |
981 | priv->btxpower_tracking = false; | |
982 | priv->txpower_count = 0; | |
983 | priv->btxpower_trackingInit = false; | |
b448b0cc LF |
984 | RT_TRACE(COMP_POWER_TRACKING, "pMgntInfo->bTXPowerTracking = %d\n", |
985 | priv->btxpower_tracking); | |
94a79942 | 986 | } |
94a79942 | 987 | |
5a9f18cf | 988 | void rtl92e_dm_init_txpower_tracking(struct net_device *dev) |
94a79942 | 989 | { |
94a79942 | 990 | struct r8192_priv *priv = rtllib_priv(dev); |
3a6b70c3 | 991 | |
94a79942 LF |
992 | if (priv->IC_Cut >= IC_VersionCut_D) |
993 | dm_InitializeTXPowerTracking_TSSI(dev); | |
994 | else | |
995 | dm_InitializeTXPowerTracking_ThermalMeter(dev); | |
94a79942 LF |
996 | } |
997 | ||
94a79942 LF |
998 | static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev) |
999 | { | |
1000 | struct r8192_priv *priv = rtllib_priv(dev); | |
b448b0cc | 1001 | static u32 tx_power_track_counter; |
3a6b70c3 | 1002 | |
b448b0cc | 1003 | RT_TRACE(COMP_POWER_TRACKING, "%s()\n", __func__); |
b59a4ca3 | 1004 | if (rtl92e_readb(dev, 0x11e) == 1) |
94a79942 LF |
1005 | return; |
1006 | if (!priv->btxpower_tracking) | |
1007 | return; | |
1008 | tx_power_track_counter++; | |
1009 | ||
1010 | ||
b448b0cc | 1011 | if (tx_power_track_counter >= 180) { |
35e33b04 MK |
1012 | queue_delayed_work_rsl(priv->priv_wq, |
1013 | &priv->txpower_tracking_wq, 0); | |
b448b0cc LF |
1014 | tx_power_track_counter = 0; |
1015 | } | |
94a79942 LF |
1016 | |
1017 | } | |
94a79942 LF |
1018 | static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev) |
1019 | { | |
1020 | struct r8192_priv *priv = rtllib_priv(dev); | |
b448b0cc | 1021 | static u8 TM_Trigger; |
94a79942 LF |
1022 | u8 TxPowerCheckCnt = 0; |
1023 | ||
1024 | if (IS_HARDWARE_TYPE_8192SE(dev)) | |
1025 | TxPowerCheckCnt = 5; | |
1026 | else | |
1027 | TxPowerCheckCnt = 2; | |
285b7c00 MK |
1028 | if (!priv->btxpower_tracking) |
1029 | return; | |
1030 | ||
1031 | if (priv->txpower_count <= TxPowerCheckCnt) { | |
1032 | priv->txpower_count++; | |
b448b0cc | 1033 | return; |
94a79942 LF |
1034 | } |
1035 | ||
b448b0cc LF |
1036 | if (!TM_Trigger) { |
1037 | { | |
b0e044fe MK |
1038 | rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); |
1039 | rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f); | |
1040 | rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); | |
1041 | rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f); | |
b448b0cc | 1042 | } |
94a79942 LF |
1043 | TM_Trigger = 1; |
1044 | return; | |
94a79942 | 1045 | } |
285b7c00 MK |
1046 | netdev_info(dev, "===============>Schedule TxPowerTrackingWorkItem\n"); |
1047 | queue_delayed_work_rsl(priv->priv_wq, &priv->txpower_tracking_wq, 0); | |
1048 | TM_Trigger = 0; | |
1049 | ||
1050 | } | |
94a79942 | 1051 | |
94a79942 LF |
1052 | static void dm_check_txpower_tracking(struct net_device *dev) |
1053 | { | |
94a79942 | 1054 | struct r8192_priv *priv = rtllib_priv(dev); |
1e71e6d0 | 1055 | |
94a79942 LF |
1056 | if (priv->IC_Cut >= IC_VersionCut_D) |
1057 | dm_CheckTXPowerTracking_TSSI(dev); | |
1058 | else | |
1059 | dm_CheckTXPowerTracking_ThermalMeter(dev); | |
94a79942 LF |
1060 | } |
1061 | ||
94a79942 LF |
1062 | static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14) |
1063 | { | |
1064 | u32 TempVal; | |
1065 | struct r8192_priv *priv = rtllib_priv(dev); | |
20b7ec09 | 1066 | u8 attenuation = (u8)priv->CCKPresentAttentuation; |
3a6b70c3 | 1067 | |
94a79942 | 1068 | TempVal = 0; |
b448b0cc | 1069 | if (!bInCH14) { |
20b7ec09 MK |
1070 | TempVal = (u32)(dm_cck_tx_bb_gain[attenuation][0] + |
1071 | (dm_cck_tx_bb_gain[attenuation][1] << 8)); | |
94a79942 | 1072 | |
153f9ddb | 1073 | rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); |
20b7ec09 MK |
1074 | TempVal = (u32)((dm_cck_tx_bb_gain[attenuation][2]) + |
1075 | (dm_cck_tx_bb_gain[attenuation][3] << 8) + | |
1076 | (dm_cck_tx_bb_gain[attenuation][4] << 16)+ | |
1077 | (dm_cck_tx_bb_gain[attenuation][5] << 24)); | |
153f9ddb | 1078 | rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); |
20b7ec09 MK |
1079 | TempVal = (u32)(dm_cck_tx_bb_gain[attenuation][6] + |
1080 | (dm_cck_tx_bb_gain[attenuation][7] << 8)); | |
94a79942 | 1081 | |
153f9ddb | 1082 | rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); |
b448b0cc | 1083 | } else { |
20b7ec09 MK |
1084 | TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][0]) + |
1085 | (dm_cck_tx_bb_gain_ch14[attenuation][1] << 8)); | |
94a79942 | 1086 | |
153f9ddb | 1087 | rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); |
20b7ec09 MK |
1088 | TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][2]) + |
1089 | (dm_cck_tx_bb_gain_ch14[attenuation][3] << 8) + | |
1090 | (dm_cck_tx_bb_gain_ch14[attenuation][4] << 16)+ | |
1091 | (dm_cck_tx_bb_gain_ch14[attenuation][5] << 24)); | |
153f9ddb | 1092 | rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); |
20b7ec09 MK |
1093 | TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][6]) + |
1094 | (dm_cck_tx_bb_gain_ch14[attenuation][7] << 8)); | |
94a79942 | 1095 | |
153f9ddb | 1096 | rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); |
94a79942 | 1097 | } |
94a79942 | 1098 | } |
f8f3b8a5 | 1099 | |
35e33b04 MK |
1100 | static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, |
1101 | bool bInCH14) | |
94a79942 LF |
1102 | { |
1103 | u32 TempVal; | |
1104 | struct r8192_priv *priv = rtllib_priv(dev); | |
1105 | ||
1106 | TempVal = 0; | |
b448b0cc | 1107 | if (!bInCH14) { |
35e33b04 MK |
1108 | TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] + |
1109 | (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1] << 8); | |
153f9ddb | 1110 | rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); |
35e33b04 MK |
1111 | RT_TRACE(COMP_POWER_TRACKING, |
1112 | "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter1, | |
1113 | TempVal); | |
1114 | TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] + | |
1115 | (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3] << 8) + | |
1116 | (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4] << 16)+ | |
1117 | (CCKSwingTable_Ch1_Ch13[priv->CCK_index][5] << 24); | |
153f9ddb | 1118 | rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); |
35e33b04 MK |
1119 | RT_TRACE(COMP_POWER_TRACKING, |
1120 | "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter2, | |
1121 | TempVal); | |
1122 | TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] + | |
1123 | (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7] << 8); | |
94a79942 | 1124 | |
153f9ddb | 1125 | rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); |
35e33b04 MK |
1126 | RT_TRACE(COMP_POWER_TRACKING, |
1127 | "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_DebugPort, | |
1128 | TempVal); | |
b448b0cc | 1129 | } else { |
35e33b04 MK |
1130 | TempVal = CCKSwingTable_Ch14[priv->CCK_index][0] + |
1131 | (CCKSwingTable_Ch14[priv->CCK_index][1] << 8); | |
94a79942 | 1132 | |
153f9ddb | 1133 | rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); |
94a79942 LF |
1134 | RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", |
1135 | rCCK0_TxFilter1, TempVal); | |
35e33b04 MK |
1136 | TempVal = CCKSwingTable_Ch14[priv->CCK_index][2] + |
1137 | (CCKSwingTable_Ch14[priv->CCK_index][3] << 8) + | |
1138 | (CCKSwingTable_Ch14[priv->CCK_index][4] << 16)+ | |
1139 | (CCKSwingTable_Ch14[priv->CCK_index][5] << 24); | |
153f9ddb | 1140 | rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); |
94a79942 LF |
1141 | RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", |
1142 | rCCK0_TxFilter2, TempVal); | |
35e33b04 MK |
1143 | TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] + |
1144 | (CCKSwingTable_Ch14[priv->CCK_index][7]<<8); | |
94a79942 | 1145 | |
153f9ddb | 1146 | rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); |
b448b0cc | 1147 | RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", |
94a79942 LF |
1148 | rCCK0_DebugPort, TempVal); |
1149 | } | |
35e33b04 | 1150 | } |
94a79942 | 1151 | |
59e84dc3 | 1152 | void rtl92e_dm_cck_txpower_adjust(struct net_device *dev, bool binch14) |
94a79942 | 1153 | { |
94a79942 | 1154 | struct r8192_priv *priv = rtllib_priv(dev); |
3a6b70c3 | 1155 | |
94a79942 LF |
1156 | if (priv->IC_Cut >= IC_VersionCut_D) |
1157 | dm_CCKTxPowerAdjust_TSSI(dev, binch14); | |
1158 | else | |
1159 | dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14); | |
94a79942 | 1160 | } |
94a79942 | 1161 | |
49aab5fd | 1162 | static void dm_txpower_reset_recovery(struct net_device *dev) |
94a79942 LF |
1163 | { |
1164 | struct r8192_priv *priv = rtllib_priv(dev); | |
1165 | ||
1166 | RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n"); | |
153f9ddb MK |
1167 | rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, |
1168 | dm_tx_bb_gain[priv->rfa_txpowertrackingindex]); | |
b448b0cc | 1169 | RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n", |
20b7ec09 MK |
1170 | dm_tx_bb_gain[priv->rfa_txpowertrackingindex]); |
1171 | RT_TRACE(COMP_POWER_TRACKING, | |
1172 | "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n", | |
b448b0cc | 1173 | priv->rfa_txpowertrackingindex); |
20b7ec09 MK |
1174 | RT_TRACE(COMP_POWER_TRACKING, |
1175 | "Reset Recovery : RF A I/Q Amplify Gain is %d\n", | |
1176 | dm_tx_bb_gain_idx_to_amplify(priv->rfa_txpowertrackingindex)); | |
1177 | RT_TRACE(COMP_POWER_TRACKING, | |
1178 | "Reset Recovery: CCK Attenuation is %d dB\n", | |
b448b0cc | 1179 | priv->CCKPresentAttentuation); |
59e84dc3 | 1180 | rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); |
b448b0cc | 1181 | |
153f9ddb MK |
1182 | rtl92e_set_bb_reg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, |
1183 | dm_tx_bb_gain[priv->rfc_txpowertrackingindex]); | |
b448b0cc | 1184 | RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n", |
20b7ec09 MK |
1185 | dm_tx_bb_gain[priv->rfc_txpowertrackingindex]); |
1186 | RT_TRACE(COMP_POWER_TRACKING, | |
1187 | "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n", | |
b448b0cc | 1188 | priv->rfc_txpowertrackingindex); |
20b7ec09 MK |
1189 | RT_TRACE(COMP_POWER_TRACKING, |
1190 | "Reset Recovery : RF C I/Q Amplify Gain is %d\n", | |
1191 | dm_tx_bb_gain_idx_to_amplify(priv->rfc_txpowertrackingindex)); | |
94a79942 LF |
1192 | } |
1193 | ||
25c01ec3 | 1194 | void rtl92e_dm_restore_state(struct net_device *dev) |
94a79942 LF |
1195 | { |
1196 | struct r8192_priv *priv = rtllib_priv(dev); | |
1197 | u32 reg_ratr = priv->rate_adaptive.last_ratr; | |
b448b0cc | 1198 | u32 ratr_value; |
94a79942 | 1199 | |
5dc42962 | 1200 | if (!priv->up) { |
35e33b04 | 1201 | RT_TRACE(COMP_RATE, |
25c01ec3 | 1202 | "<---- rtl92e_dm_restore_state(): driver is going to unload\n"); |
94a79942 LF |
1203 | return; |
1204 | } | |
1205 | ||
1206 | if (priv->rate_adaptive.rate_adaptive_disabled) | |
1207 | return; | |
b448b0cc LF |
1208 | if (!(priv->rtllib->mode == WIRELESS_MODE_N_24G || |
1209 | priv->rtllib->mode == WIRELESS_MODE_N_5G)) | |
1210 | return; | |
1211 | ratr_value = reg_ratr; | |
1212 | if (priv->rf_type == RF_1T2R) | |
1213 | ratr_value &= ~(RATE_ALL_OFDM_2SS); | |
8ea54100 | 1214 | rtl92e_writel(dev, RATR0, ratr_value); |
d8ae1967 | 1215 | rtl92e_writeb(dev, UFWP, 1); |
b448b0cc | 1216 | if (priv->btxpower_trackingInit && priv->btxpower_tracking) |
94a79942 | 1217 | dm_txpower_reset_recovery(dev); |
94a79942 LF |
1218 | |
1219 | dm_bb_initialgain_restore(dev); | |
1220 | ||
1221 | } | |
1222 | ||
1223 | static void dm_bb_initialgain_restore(struct net_device *dev) | |
1224 | { | |
1225 | struct r8192_priv *priv = rtllib_priv(dev); | |
1226 | u32 bit_mask = 0x7f; | |
1227 | ||
1228 | if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) | |
1229 | return; | |
1230 | ||
153f9ddb MK |
1231 | rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8); |
1232 | rtl92e_set_bb_reg(dev, rOFDM0_XAAGCCore1, bit_mask, | |
1233 | (u32)priv->initgain_backup.xaagccore1); | |
1234 | rtl92e_set_bb_reg(dev, rOFDM0_XBAGCCore1, bit_mask, | |
1235 | (u32)priv->initgain_backup.xbagccore1); | |
1236 | rtl92e_set_bb_reg(dev, rOFDM0_XCAGCCore1, bit_mask, | |
1237 | (u32)priv->initgain_backup.xcagccore1); | |
1238 | rtl92e_set_bb_reg(dev, rOFDM0_XDAGCCore1, bit_mask, | |
1239 | (u32)priv->initgain_backup.xdagccore1); | |
94a79942 | 1240 | bit_mask = bMaskByte2; |
153f9ddb MK |
1241 | rtl92e_set_bb_reg(dev, rCCK0_CCA, bit_mask, |
1242 | (u32)priv->initgain_backup.cca); | |
d9c1fff5 MK |
1243 | |
1244 | RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n", | |
1245 | priv->initgain_backup.xaagccore1); | |
1246 | RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n", | |
1247 | priv->initgain_backup.xbagccore1); | |
1248 | RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n", | |
1249 | priv->initgain_backup.xcagccore1); | |
1250 | RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n", | |
1251 | priv->initgain_backup.xdagccore1); | |
1252 | RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n", | |
1253 | priv->initgain_backup.cca); | |
153f9ddb | 1254 | rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x1); |
94a79942 LF |
1255 | |
1256 | } | |
1257 | ||
1258 | ||
090e8a4d | 1259 | void rtl92e_dm_backup_state(struct net_device *dev) |
94a79942 LF |
1260 | { |
1261 | struct r8192_priv *priv = rtllib_priv(dev); | |
1262 | ||
1263 | priv->bswitch_fsync = false; | |
1264 | priv->bfsync_processing = false; | |
1265 | dm_bb_initialgain_backup(dev); | |
1266 | ||
1267 | } | |
1268 | ||
1269 | ||
1270 | static void dm_bb_initialgain_backup(struct net_device *dev) | |
1271 | { | |
1272 | struct r8192_priv *priv = rtllib_priv(dev); | |
1273 | u32 bit_mask = bMaskByte0; | |
1274 | ||
1275 | if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) | |
1276 | return; | |
1277 | ||
153f9ddb | 1278 | rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8); |
3c351fec MK |
1279 | priv->initgain_backup.xaagccore1 = (u8)rtl92e_get_bb_reg(dev, rOFDM0_XAAGCCore1, bit_mask); |
1280 | priv->initgain_backup.xbagccore1 = (u8)rtl92e_get_bb_reg(dev, rOFDM0_XBAGCCore1, bit_mask); | |
1281 | priv->initgain_backup.xcagccore1 = (u8)rtl92e_get_bb_reg(dev, rOFDM0_XCAGCCore1, bit_mask); | |
1282 | priv->initgain_backup.xdagccore1 = (u8)rtl92e_get_bb_reg(dev, rOFDM0_XDAGCCore1, bit_mask); | |
94a79942 | 1283 | bit_mask = bMaskByte2; |
3c351fec | 1284 | priv->initgain_backup.cca = (u8)rtl92e_get_bb_reg(dev, rCCK0_CCA, bit_mask); |
94a79942 | 1285 | |
d9c1fff5 MK |
1286 | RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n", |
1287 | priv->initgain_backup.xaagccore1); | |
1288 | RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n", | |
1289 | priv->initgain_backup.xbagccore1); | |
1290 | RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n", | |
1291 | priv->initgain_backup.xcagccore1); | |
1292 | RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n", | |
1293 | priv->initgain_backup.xdagccore1); | |
1294 | RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n", | |
1295 | priv->initgain_backup.cca); | |
94a79942 LF |
1296 | |
1297 | } | |
1298 | ||
94a79942 LF |
1299 | static void dm_dig_init(struct net_device *dev) |
1300 | { | |
1301 | struct r8192_priv *priv = rtllib_priv(dev); | |
3a6b70c3 | 1302 | |
94a79942 | 1303 | dm_digtable.dig_enable_flag = true; |
94a79942 | 1304 | |
94a79942 | 1305 | dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI; |
94a79942 | 1306 | |
94a79942 LF |
1307 | dm_digtable.dig_algorithm_switch = 0; |
1308 | ||
1309 | dm_digtable.dig_state = DM_STA_DIG_MAX; | |
1310 | dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX; | |
35e33b04 MK |
1311 | dm_digtable.CurSTAConnectState = DIG_STA_DISCONNECT; |
1312 | dm_digtable.PreSTAConnectState = DIG_STA_DISCONNECT; | |
94a79942 LF |
1313 | |
1314 | dm_digtable.rssi_low_thresh = DM_DIG_THRESH_LOW; | |
1315 | dm_digtable.rssi_high_thresh = DM_DIG_THRESH_HIGH; | |
1316 | ||
94a79942 LF |
1317 | dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW; |
1318 | dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH; | |
1319 | ||
1320 | dm_digtable.rssi_val = 50; | |
1321 | dm_digtable.backoff_val = DM_DIG_BACKOFF; | |
1322 | dm_digtable.rx_gain_range_max = DM_DIG_MAX; | |
1323 | if (priv->CustomerID == RT_CID_819x_Netcore) | |
1324 | dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore; | |
1325 | else | |
1326 | dm_digtable.rx_gain_range_min = DM_DIG_MIN; | |
94a79942 LF |
1327 | } |
1328 | ||
94a79942 LF |
1329 | static void dm_ctrl_initgain_byrssi(struct net_device *dev) |
1330 | { | |
1331 | ||
1332 | if (dm_digtable.dig_enable_flag == false) | |
1333 | return; | |
1334 | ||
1335 | if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM) | |
1336 | dm_ctrl_initgain_byrssi_by_fwfalse_alarm(dev); | |
1337 | else if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) | |
1338 | dm_ctrl_initgain_byrssi_by_driverrssi(dev); | |
94a79942 LF |
1339 | else |
1340 | return; | |
1341 | } | |
1342 | ||
94a79942 LF |
1343 | /*----------------------------------------------------------------------------- |
1344 | * Function: dm_CtrlInitGainBeforeConnectByRssiAndFalseAlarm() | |
1345 | * | |
1346 | * Overview: Driver monitor RSSI and False Alarm to change initial gain. | |
1347 | Only change initial gain during link in progress. | |
1348 | * | |
1349 | * Input: IN PADAPTER pAdapter | |
1350 | * | |
1351 | * Output: NONE | |
1352 | * | |
1353 | * Return: NONE | |
1354 | * | |
1355 | * Revised History: | |
1356 | * When Who Remark | |
1357 | * 03/04/2009 hpfan Create Version 0. | |
1358 | * | |
1359 | *---------------------------------------------------------------------------*/ | |
1360 | ||
94a79942 LF |
1361 | static void dm_ctrl_initgain_byrssi_by_driverrssi( |
1362 | struct net_device *dev) | |
1363 | { | |
1364 | struct r8192_priv *priv = rtllib_priv(dev); | |
1365 | u8 i; | |
b448b0cc | 1366 | static u8 fw_dig; |
94a79942 LF |
1367 | |
1368 | if (dm_digtable.dig_enable_flag == false) | |
1369 | return; | |
1370 | ||
1371 | if (dm_digtable.dig_algorithm_switch) | |
1372 | fw_dig = 0; | |
b448b0cc LF |
1373 | if (fw_dig <= 3) { |
1374 | for (i = 0; i < 3; i++) | |
153f9ddb | 1375 | rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8); |
94a79942 LF |
1376 | fw_dig++; |
1377 | dm_digtable.dig_state = DM_STA_DIG_OFF; | |
1378 | } | |
1379 | ||
1380 | if (priv->rtllib->state == RTLLIB_LINKED) | |
1381 | dm_digtable.CurSTAConnectState = DIG_STA_CONNECT; | |
1382 | else | |
1383 | dm_digtable.CurSTAConnectState = DIG_STA_DISCONNECT; | |
1384 | ||
1385 | ||
32215eaa | 1386 | dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb; |
94a79942 LF |
1387 | dm_initial_gain(dev); |
1388 | dm_pd_th(dev); | |
1389 | dm_cs_ratio(dev); | |
1390 | if (dm_digtable.dig_algorithm_switch) | |
1391 | dm_digtable.dig_algorithm_switch = 0; | |
1392 | dm_digtable.PreSTAConnectState = dm_digtable.CurSTAConnectState; | |
1393 | ||
1394 | } | |
1395 | ||
1396 | static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( | |
1397 | struct net_device *dev) | |
1398 | { | |
1399 | struct r8192_priv *priv = rtllib_priv(dev); | |
b448b0cc | 1400 | static u32 reset_cnt; |
94a79942 LF |
1401 | u8 i; |
1402 | ||
1403 | if (dm_digtable.dig_enable_flag == false) | |
1404 | return; | |
1405 | ||
b448b0cc | 1406 | if (dm_digtable.dig_algorithm_switch) { |
94a79942 | 1407 | dm_digtable.dig_state = DM_STA_DIG_MAX; |
b448b0cc | 1408 | for (i = 0; i < 3; i++) |
153f9ddb | 1409 | rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x1); |
94a79942 LF |
1410 | dm_digtable.dig_algorithm_switch = 0; |
1411 | } | |
1412 | ||
1413 | if (priv->rtllib->state != RTLLIB_LINKED) | |
1414 | return; | |
1415 | ||
1416 | if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) && | |
1417 | (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh)) | |
94a79942 | 1418 | return; |
025b8bbe | 1419 | if (priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh) { |
94a79942 LF |
1420 | if (dm_digtable.dig_state == DM_STA_DIG_OFF && |
1421 | (priv->reset_count == reset_cnt)) | |
94a79942 | 1422 | return; |
285b7c00 | 1423 | reset_cnt = priv->reset_count; |
94a79942 LF |
1424 | |
1425 | dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX; | |
1426 | dm_digtable.dig_state = DM_STA_DIG_OFF; | |
1427 | ||
153f9ddb | 1428 | rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8); |
94a79942 | 1429 | |
d8ae1967 MK |
1430 | rtl92e_writeb(dev, rOFDM0_XAAGCCore1, 0x17); |
1431 | rtl92e_writeb(dev, rOFDM0_XBAGCCore1, 0x17); | |
1432 | rtl92e_writeb(dev, rOFDM0_XCAGCCore1, 0x17); | |
1433 | rtl92e_writeb(dev, rOFDM0_XDAGCCore1, 0x17); | |
94a79942 LF |
1434 | |
1435 | if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) | |
d8ae1967 | 1436 | rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x00); |
94a79942 | 1437 | else |
d8ae1967 | 1438 | rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x42); |
94a79942 | 1439 | |
d8ae1967 | 1440 | rtl92e_writeb(dev, 0xa0a, 0x08); |
94a79942 LF |
1441 | |
1442 | return; | |
94a79942 LF |
1443 | } |
1444 | ||
025b8bbe | 1445 | if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) { |
94a79942 LF |
1446 | u8 reset_flag = 0; |
1447 | ||
1448 | if (dm_digtable.dig_state == DM_STA_DIG_ON && | |
b448b0cc | 1449 | (priv->reset_count == reset_cnt)) { |
94a79942 LF |
1450 | dm_ctrl_initgain_byrssi_highpwr(dev); |
1451 | return; | |
94a79942 | 1452 | } |
285b7c00 MK |
1453 | if (priv->reset_count != reset_cnt) |
1454 | reset_flag = 1; | |
1455 | ||
1456 | reset_cnt = priv->reset_count; | |
94a79942 LF |
1457 | |
1458 | dm_digtable.dig_state = DM_STA_DIG_ON; | |
1459 | ||
b448b0cc | 1460 | if (reset_flag == 1) { |
d8ae1967 MK |
1461 | rtl92e_writeb(dev, rOFDM0_XAAGCCore1, 0x2c); |
1462 | rtl92e_writeb(dev, rOFDM0_XBAGCCore1, 0x2c); | |
1463 | rtl92e_writeb(dev, rOFDM0_XCAGCCore1, 0x2c); | |
1464 | rtl92e_writeb(dev, rOFDM0_XDAGCCore1, 0x2c); | |
b448b0cc | 1465 | } else { |
d8ae1967 MK |
1466 | rtl92e_writeb(dev, rOFDM0_XAAGCCore1, 0x20); |
1467 | rtl92e_writeb(dev, rOFDM0_XBAGCCore1, 0x20); | |
1468 | rtl92e_writeb(dev, rOFDM0_XCAGCCore1, 0x20); | |
1469 | rtl92e_writeb(dev, rOFDM0_XDAGCCore1, 0x20); | |
94a79942 LF |
1470 | } |
1471 | ||
1472 | if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) | |
d8ae1967 | 1473 | rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x20); |
94a79942 | 1474 | else |
d8ae1967 | 1475 | rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x44); |
94a79942 | 1476 | |
d8ae1967 | 1477 | rtl92e_writeb(dev, 0xa0a, 0xcd); |
94a79942 | 1478 | |
153f9ddb | 1479 | rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x1); |
94a79942 | 1480 | } |
94a79942 | 1481 | dm_ctrl_initgain_byrssi_highpwr(dev); |
94a79942 LF |
1482 | } |
1483 | ||
1484 | ||
b448b0cc | 1485 | static void dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev) |
94a79942 LF |
1486 | { |
1487 | struct r8192_priv *priv = rtllib_priv(dev); | |
b448b0cc | 1488 | static u32 reset_cnt_highpwr; |
94a79942 | 1489 | |
35e33b04 MK |
1490 | if ((priv->undecorated_smoothed_pwdb > |
1491 | dm_digtable.rssi_high_power_lowthresh) && | |
1492 | (priv->undecorated_smoothed_pwdb < | |
1493 | dm_digtable.rssi_high_power_highthresh)) | |
94a79942 | 1494 | return; |
94a79942 | 1495 | |
35e33b04 MK |
1496 | if (priv->undecorated_smoothed_pwdb >= |
1497 | dm_digtable.rssi_high_power_highthresh) { | |
94a79942 LF |
1498 | if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON && |
1499 | (priv->reset_count == reset_cnt_highpwr)) | |
1500 | return; | |
285b7c00 | 1501 | dm_digtable.dig_highpwr_state = DM_STA_DIG_ON; |
94a79942 LF |
1502 | |
1503 | if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) | |
d8ae1967 | 1504 | rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x10); |
94a79942 | 1505 | else |
d8ae1967 | 1506 | rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x43); |
b448b0cc LF |
1507 | } else { |
1508 | if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF && | |
94a79942 LF |
1509 | (priv->reset_count == reset_cnt_highpwr)) |
1510 | return; | |
285b7c00 | 1511 | dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF; |
94a79942 | 1512 | |
35e33b04 MK |
1513 | if ((priv->undecorated_smoothed_pwdb < |
1514 | dm_digtable.rssi_high_power_lowthresh) && | |
1515 | (priv->undecorated_smoothed_pwdb >= | |
1516 | dm_digtable.rssi_high_thresh)) { | |
94a79942 | 1517 | if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) |
d8ae1967 | 1518 | rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x20); |
94a79942 | 1519 | else |
d8ae1967 | 1520 | rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x44); |
94a79942 LF |
1521 | } |
1522 | } | |
94a79942 | 1523 | reset_cnt_highpwr = priv->reset_count; |
94a79942 LF |
1524 | } |
1525 | ||
b448b0cc | 1526 | static void dm_initial_gain(struct net_device *dev) |
94a79942 LF |
1527 | { |
1528 | struct r8192_priv *priv = rtllib_priv(dev); | |
b448b0cc LF |
1529 | u8 initial_gain = 0; |
1530 | static u8 initialized, force_write; | |
1531 | static u32 reset_cnt; | |
94a79942 | 1532 | |
b448b0cc | 1533 | if (dm_digtable.dig_algorithm_switch) { |
94a79942 LF |
1534 | initialized = 0; |
1535 | reset_cnt = 0; | |
1536 | } | |
1537 | ||
b448b0cc | 1538 | if (rtllib_act_scanning(priv->rtllib, true) == true) { |
94a79942 LF |
1539 | force_write = 1; |
1540 | return; | |
1541 | } | |
1542 | ||
b448b0cc LF |
1543 | if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) { |
1544 | if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) { | |
35e33b04 MK |
1545 | long gain_range = dm_digtable.rssi_val + 10 - |
1546 | dm_digtable.backoff_val; | |
1547 | gain_range = clamp_t(long, gain_range, | |
1548 | dm_digtable.rx_gain_range_min, | |
1549 | dm_digtable.rx_gain_range_max); | |
1550 | dm_digtable.cur_ig_value = gain_range; | |
b448b0cc | 1551 | } else { |
94a79942 LF |
1552 | if (dm_digtable.cur_ig_value == 0) |
1553 | dm_digtable.cur_ig_value = priv->DefaultInitialGain[0]; | |
1554 | else | |
1555 | dm_digtable.cur_ig_value = dm_digtable.pre_ig_value; | |
1556 | } | |
b448b0cc | 1557 | } else { |
94a79942 LF |
1558 | dm_digtable.cur_ig_value = priv->DefaultInitialGain[0]; |
1559 | dm_digtable.pre_ig_value = 0; | |
1560 | } | |
1561 | ||
b448b0cc | 1562 | if (priv->reset_count != reset_cnt) { |
94a79942 LF |
1563 | force_write = 1; |
1564 | reset_cnt = priv->reset_count; | |
1565 | } | |
1566 | ||
b59a4ca3 | 1567 | if (dm_digtable.pre_ig_value != rtl92e_readb(dev, rOFDM0_XAAGCCore1)) |
94a79942 LF |
1568 | force_write = 1; |
1569 | ||
b448b0cc LF |
1570 | if ((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value) |
1571 | || !initialized || force_write) { | |
1572 | initial_gain = (u8)dm_digtable.cur_ig_value; | |
d8ae1967 MK |
1573 | rtl92e_writeb(dev, rOFDM0_XAAGCCore1, initial_gain); |
1574 | rtl92e_writeb(dev, rOFDM0_XBAGCCore1, initial_gain); | |
1575 | rtl92e_writeb(dev, rOFDM0_XCAGCCore1, initial_gain); | |
1576 | rtl92e_writeb(dev, rOFDM0_XDAGCCore1, initial_gain); | |
b448b0cc LF |
1577 | dm_digtable.pre_ig_value = dm_digtable.cur_ig_value; |
1578 | initialized = 1; | |
1579 | force_write = 0; | |
94a79942 LF |
1580 | } |
1581 | } | |
1582 | ||
b448b0cc | 1583 | static void dm_pd_th(struct net_device *dev) |
94a79942 LF |
1584 | { |
1585 | struct r8192_priv *priv = rtllib_priv(dev); | |
b448b0cc LF |
1586 | static u8 initialized, force_write; |
1587 | static u32 reset_cnt; | |
94a79942 | 1588 | |
b448b0cc | 1589 | if (dm_digtable.dig_algorithm_switch) { |
94a79942 LF |
1590 | initialized = 0; |
1591 | reset_cnt = 0; | |
1592 | } | |
1593 | ||
b448b0cc LF |
1594 | if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) { |
1595 | if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) { | |
35e33b04 MK |
1596 | if (dm_digtable.rssi_val >= |
1597 | dm_digtable.rssi_high_power_highthresh) | |
1598 | dm_digtable.curpd_thstate = | |
1599 | DIG_PD_AT_HIGH_POWER; | |
1600 | else if (dm_digtable.rssi_val <= | |
1601 | dm_digtable.rssi_low_thresh) | |
1602 | dm_digtable.curpd_thstate = | |
1603 | DIG_PD_AT_LOW_POWER; | |
1604 | else if ((dm_digtable.rssi_val >= | |
1605 | dm_digtable.rssi_high_thresh) && | |
1606 | (dm_digtable.rssi_val < | |
1607 | dm_digtable.rssi_high_power_lowthresh)) | |
1608 | dm_digtable.curpd_thstate = | |
1609 | DIG_PD_AT_NORMAL_POWER; | |
94a79942 | 1610 | else |
35e33b04 MK |
1611 | dm_digtable.curpd_thstate = |
1612 | dm_digtable.prepd_thstate; | |
b448b0cc | 1613 | } else { |
94a79942 LF |
1614 | dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; |
1615 | } | |
b448b0cc | 1616 | } else { |
94a79942 LF |
1617 | dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; |
1618 | } | |
1619 | ||
b448b0cc | 1620 | if (priv->reset_count != reset_cnt) { |
94a79942 LF |
1621 | force_write = 1; |
1622 | reset_cnt = priv->reset_count; | |
1623 | } | |
1624 | ||
b448b0cc LF |
1625 | if ((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) || |
1626 | (initialized <= 3) || force_write) { | |
1627 | if (dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) { | |
1628 | if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) | |
d8ae1967 | 1629 | rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x00); |
b448b0cc | 1630 | else |
d8ae1967 | 1631 | rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x42); |
35e33b04 MK |
1632 | } else if (dm_digtable.curpd_thstate == |
1633 | DIG_PD_AT_NORMAL_POWER) { | |
b448b0cc | 1634 | if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) |
d8ae1967 | 1635 | rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x20); |
b448b0cc | 1636 | else |
d8ae1967 | 1637 | rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x44); |
b448b0cc LF |
1638 | } else if (dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) { |
1639 | if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) | |
d8ae1967 | 1640 | rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x10); |
b448b0cc | 1641 | else |
d8ae1967 | 1642 | rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x43); |
94a79942 | 1643 | } |
b448b0cc LF |
1644 | dm_digtable.prepd_thstate = dm_digtable.curpd_thstate; |
1645 | if (initialized <= 3) | |
1646 | initialized++; | |
1647 | force_write = 0; | |
94a79942 LF |
1648 | } |
1649 | } | |
1650 | ||
b448b0cc | 1651 | static void dm_cs_ratio(struct net_device *dev) |
94a79942 LF |
1652 | { |
1653 | struct r8192_priv *priv = rtllib_priv(dev); | |
b448b0cc LF |
1654 | static u8 initialized, force_write; |
1655 | static u32 reset_cnt; | |
94a79942 | 1656 | |
b448b0cc | 1657 | if (dm_digtable.dig_algorithm_switch) { |
94a79942 LF |
1658 | initialized = 0; |
1659 | reset_cnt = 0; | |
1660 | } | |
1661 | ||
b448b0cc LF |
1662 | if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) { |
1663 | if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) { | |
025b8bbe | 1664 | if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh) |
94a79942 | 1665 | dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; |
025b8bbe | 1666 | else if (dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) |
94a79942 LF |
1667 | dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER; |
1668 | else | |
1669 | dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state; | |
b448b0cc | 1670 | } else { |
94a79942 LF |
1671 | dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; |
1672 | } | |
b448b0cc | 1673 | } else { |
94a79942 LF |
1674 | dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; |
1675 | } | |
1676 | ||
b448b0cc | 1677 | if (priv->reset_count != reset_cnt) { |
94a79942 LF |
1678 | force_write = 1; |
1679 | reset_cnt = priv->reset_count; | |
1680 | } | |
1681 | ||
1682 | ||
b448b0cc LF |
1683 | if ((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) || |
1684 | !initialized || force_write) { | |
1685 | if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER) | |
d8ae1967 | 1686 | rtl92e_writeb(dev, 0xa0a, 0x08); |
b448b0cc | 1687 | else if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER) |
d8ae1967 | 1688 | rtl92e_writeb(dev, 0xa0a, 0xcd); |
b448b0cc LF |
1689 | dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state; |
1690 | initialized = 1; | |
1691 | force_write = 0; | |
94a79942 LF |
1692 | } |
1693 | } | |
1694 | ||
7842c2d5 | 1695 | void rtl92e_dm_init_edca_turbo(struct net_device *dev) |
94a79942 LF |
1696 | { |
1697 | struct r8192_priv *priv = rtllib_priv(dev); | |
1698 | ||
1699 | priv->bcurrent_turbo_EDCA = false; | |
1700 | priv->rtllib->bis_any_nonbepkts = false; | |
1701 | priv->bis_cur_rdlstate = false; | |
1702 | } | |
1703 | ||
b448b0cc | 1704 | static void dm_check_edca_turbo(struct net_device *dev) |
94a79942 LF |
1705 | { |
1706 | struct r8192_priv *priv = rtllib_priv(dev); | |
7796d93e | 1707 | struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo; |
94a79942 | 1708 | |
b448b0cc LF |
1709 | static unsigned long lastTxOkCnt; |
1710 | static unsigned long lastRxOkCnt; | |
1711 | unsigned long curTxOkCnt = 0; | |
1712 | unsigned long curRxOkCnt = 0; | |
94a79942 LF |
1713 | |
1714 | if (priv->rtllib->iw_mode == IW_MODE_ADHOC) | |
94a79942 | 1715 | goto dm_CheckEdcaTurbo_EXIT; |
94a79942 | 1716 | if (priv->rtllib->state != RTLLIB_LINKED) |
94a79942 | 1717 | goto dm_CheckEdcaTurbo_EXIT; |
94a79942 | 1718 | if (priv->rtllib->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO) |
94a79942 | 1719 | goto dm_CheckEdcaTurbo_EXIT; |
94a79942 LF |
1720 | |
1721 | { | |
b448b0cc LF |
1722 | u8 *peername[11] = { |
1723 | "unknown", "realtek_90", "realtek_92se", "broadcom", | |
1724 | "ralink", "atheros", "cisco", "marvell", "92u_softap", | |
1725 | "self_softap" | |
1726 | }; | |
1727 | static int wb_tmp; | |
3a6b70c3 | 1728 | |
b448b0cc | 1729 | if (wb_tmp == 0) { |
d69d2054 MK |
1730 | netdev_info(dev, |
1731 | "%s():iot peer is %s, bssid: %pM\n", | |
1732 | __func__, peername[pHTInfo->IOTPeer], | |
1733 | priv->rtllib->current_network.bssid); | |
94a79942 LF |
1734 | wb_tmp = 1; |
1735 | } | |
1736 | } | |
b448b0cc | 1737 | if (!priv->rtllib->bis_any_nonbepkts) { |
94a79942 LF |
1738 | curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt; |
1739 | curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt; | |
b448b0cc LF |
1740 | if (pHTInfo->IOTAction & HT_IOT_ACT_EDCA_BIAS_ON_RX) { |
1741 | if (curTxOkCnt > 4*curRxOkCnt) { | |
1742 | if (priv->bis_cur_rdlstate || | |
1743 | !priv->bcurrent_turbo_EDCA) { | |
8ea54100 MK |
1744 | rtl92e_writel(dev, EDCAPARA_BE, |
1745 | edca_setting_UL[pHTInfo->IOTPeer]); | |
94a79942 LF |
1746 | priv->bis_cur_rdlstate = false; |
1747 | } | |
b448b0cc LF |
1748 | } else { |
1749 | if (!priv->bis_cur_rdlstate || | |
1750 | !priv->bcurrent_turbo_EDCA) { | |
94a79942 | 1751 | if (priv->rtllib->mode == WIRELESS_MODE_G) |
8ea54100 MK |
1752 | rtl92e_writel(dev, EDCAPARA_BE, |
1753 | edca_setting_DL_GMode[pHTInfo->IOTPeer]); | |
94a79942 | 1754 | else |
8ea54100 MK |
1755 | rtl92e_writel(dev, EDCAPARA_BE, |
1756 | edca_setting_DL[pHTInfo->IOTPeer]); | |
94a79942 LF |
1757 | priv->bis_cur_rdlstate = true; |
1758 | } | |
1759 | } | |
1760 | priv->bcurrent_turbo_EDCA = true; | |
b448b0cc LF |
1761 | } else { |
1762 | if (curRxOkCnt > 4*curTxOkCnt) { | |
d9c1fff5 MK |
1763 | if (!priv->bis_cur_rdlstate || |
1764 | !priv->bcurrent_turbo_EDCA) { | |
b448b0cc | 1765 | if (priv->rtllib->mode == WIRELESS_MODE_G) |
8ea54100 MK |
1766 | rtl92e_writel(dev, EDCAPARA_BE, |
1767 | edca_setting_DL_GMode[pHTInfo->IOTPeer]); | |
b448b0cc | 1768 | else |
8ea54100 MK |
1769 | rtl92e_writel(dev, EDCAPARA_BE, |
1770 | edca_setting_DL[pHTInfo->IOTPeer]); | |
b448b0cc LF |
1771 | priv->bis_cur_rdlstate = true; |
1772 | } | |
1773 | } else { | |
1774 | if (priv->bis_cur_rdlstate || | |
1775 | !priv->bcurrent_turbo_EDCA) { | |
8ea54100 MK |
1776 | rtl92e_writel(dev, EDCAPARA_BE, |
1777 | edca_setting_UL[pHTInfo->IOTPeer]); | |
b448b0cc LF |
1778 | priv->bis_cur_rdlstate = false; |
1779 | } | |
1780 | ||
94a79942 LF |
1781 | } |
1782 | ||
b448b0cc | 1783 | priv->bcurrent_turbo_EDCA = true; |
94a79942 | 1784 | } |
b448b0cc LF |
1785 | } else { |
1786 | if (priv->bcurrent_turbo_EDCA) { | |
1787 | u8 tmp = AC0_BE; | |
3a6b70c3 | 1788 | |
35e33b04 MK |
1789 | priv->rtllib->SetHwRegHandler(dev, HW_VAR_AC_PARAM, |
1790 | (u8 *)(&tmp)); | |
94a79942 LF |
1791 | priv->bcurrent_turbo_EDCA = false; |
1792 | } | |
1793 | } | |
1794 | ||
1795 | ||
1796 | dm_CheckEdcaTurbo_EXIT: | |
1797 | priv->rtllib->bis_any_nonbepkts = false; | |
1798 | lastTxOkCnt = priv->stats.txbytesunicast; | |
1799 | lastRxOkCnt = priv->stats.rxbytesunicast; | |
1800 | } | |
94a79942 | 1801 | |
b448b0cc | 1802 | static void dm_init_ctstoself(struct net_device *dev) |
94a79942 LF |
1803 | { |
1804 | struct r8192_priv *priv = rtllib_priv((struct net_device *)dev); | |
1805 | ||
1806 | priv->rtllib->bCTSToSelfEnable = true; | |
94a79942 LF |
1807 | } |
1808 | ||
1809 | static void dm_ctstoself(struct net_device *dev) | |
1810 | { | |
1811 | struct r8192_priv *priv = rtllib_priv((struct net_device *)dev); | |
7796d93e | 1812 | struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo; |
b448b0cc LF |
1813 | static unsigned long lastTxOkCnt; |
1814 | static unsigned long lastRxOkCnt; | |
1815 | unsigned long curTxOkCnt = 0; | |
1816 | unsigned long curRxOkCnt = 0; | |
94a79942 | 1817 | |
b448b0cc | 1818 | if (priv->rtllib->bCTSToSelfEnable != true) { |
94a79942 LF |
1819 | pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF; |
1820 | return; | |
1821 | } | |
b448b0cc | 1822 | if (pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) { |
94a79942 LF |
1823 | curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt; |
1824 | curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt; | |
1825 | if (curRxOkCnt > 4*curTxOkCnt) | |
94a79942 | 1826 | pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF; |
94a79942 | 1827 | else |
94a79942 | 1828 | pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF; |
94a79942 LF |
1829 | |
1830 | lastTxOkCnt = priv->stats.txbytesunicast; | |
1831 | lastRxOkCnt = priv->stats.rxbytesunicast; | |
1832 | } | |
1833 | } | |
1834 | ||
1835 | ||
b448b0cc | 1836 | static void dm_Init_WA_Broadcom_IOT(struct net_device *dev) |
94a79942 LF |
1837 | { |
1838 | struct r8192_priv *priv = rtllib_priv((struct net_device *)dev); | |
7796d93e | 1839 | struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo; |
94a79942 LF |
1840 | |
1841 | pHTInfo->bWAIotBroadcom = false; | |
1842 | pHTInfo->WAIotTH = WAIotTHVal; | |
1843 | } | |
1844 | ||
94a79942 LF |
1845 | static void dm_check_pbc_gpio(struct net_device *dev) |
1846 | { | |
94a79942 LF |
1847 | } |
1848 | ||
735b7861 | 1849 | static void dm_CheckRfCtrlGPIO(void *data) |
94a79942 | 1850 | { |
b448b0cc LF |
1851 | struct r8192_priv *priv = container_of_dwork_rsl(data, |
1852 | struct r8192_priv, gpio_change_rf_wq); | |
1853 | struct net_device *dev = priv->rtllib->dev; | |
94a79942 | 1854 | u8 tmp1byte; |
de7c885a | 1855 | enum rt_rf_power_state eRfPowerStateToSet; |
94a79942 | 1856 | bool bActuallySet = false; |
94a79942 LF |
1857 | char *argv[3]; |
1858 | static char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh"; | |
35e33b04 MK |
1859 | static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", |
1860 | NULL}; | |
94a79942 | 1861 | |
b448b0cc | 1862 | bActuallySet = false; |
94a79942 LF |
1863 | |
1864 | if ((priv->up_first_time == 1) || (priv->being_init_adapter)) | |
94a79942 | 1865 | return; |
94a79942 | 1866 | |
b448b0cc | 1867 | if (priv->bfirst_after_down) { |
014e4c27 | 1868 | priv->bfirst_after_down = true; |
94a79942 LF |
1869 | return; |
1870 | } | |
1871 | ||
b59a4ca3 | 1872 | tmp1byte = rtl92e_readb(dev, GPI); |
94a79942 | 1873 | |
b448b0cc | 1874 | eRfPowerStateToSet = (tmp1byte&BIT1) ? eRfOn : eRfOff; |
94a79942 | 1875 | |
4bb01423 | 1876 | if (priv->bHwRadioOff && (eRfPowerStateToSet == eRfOn)) { |
b448b0cc | 1877 | RT_TRACE(COMP_RF, "gpiochangeRF - HW Radio ON\n"); |
1f921b9f | 1878 | netdev_info(dev, "gpiochangeRF - HW Radio ON\n"); |
b448b0cc LF |
1879 | priv->bHwRadioOff = false; |
1880 | bActuallySet = true; | |
4bb01423 | 1881 | } else if (!priv->bHwRadioOff && (eRfPowerStateToSet == eRfOff)) { |
b448b0cc | 1882 | RT_TRACE(COMP_RF, "gpiochangeRF - HW Radio OFF\n"); |
1f921b9f | 1883 | netdev_info(dev, "gpiochangeRF - HW Radio OFF\n"); |
b448b0cc LF |
1884 | priv->bHwRadioOff = true; |
1885 | bActuallySet = true; | |
1886 | } | |
94a79942 | 1887 | |
b448b0cc LF |
1888 | if (bActuallySet) { |
1889 | mdelay(1000); | |
1890 | priv->bHwRfOffAction = 1; | |
2937a5d2 | 1891 | rtl92e_set_rf_state(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW); |
4bb01423 | 1892 | if (priv->bHwRadioOff) |
b448b0cc LF |
1893 | argv[1] = "RFOFF"; |
1894 | else | |
1895 | argv[1] = "RFON"; | |
94a79942 | 1896 | |
b448b0cc LF |
1897 | argv[0] = RadioPowerPath; |
1898 | argv[2] = NULL; | |
70834d30 | 1899 | call_usermodehelper(RadioPowerPath, argv, envp, UMH_WAIT_PROC); |
94a79942 | 1900 | } |
94a79942 | 1901 | } |
f8f3b8a5 | 1902 | |
3cd4db70 | 1903 | void rtl92e_dm_rf_pathcheck_wq(void *data) |
94a79942 | 1904 | { |
b448b0cc LF |
1905 | struct r8192_priv *priv = container_of_dwork_rsl(data, |
1906 | struct r8192_priv, | |
1907 | rfpath_check_wq); | |
1908 | struct net_device *dev = priv->rtllib->dev; | |
94a79942 LF |
1909 | u8 rfpath = 0, i; |
1910 | ||
b59a4ca3 | 1911 | rfpath = rtl92e_readb(dev, 0xc04); |
94a79942 | 1912 | |
cb762154 | 1913 | for (i = 0; i < RF90_PATH_MAX; i++) { |
94a79942 | 1914 | if (rfpath & (0x01<<i)) |
014e4c27 | 1915 | priv->brfpath_rxenable[i] = true; |
94a79942 | 1916 | else |
014e4c27 | 1917 | priv->brfpath_rxenable[i] = false; |
94a79942 LF |
1918 | } |
1919 | if (!DM_RxPathSelTable.Enable) | |
1920 | return; | |
1921 | ||
1922 | dm_rxpath_sel_byrssi(dev); | |
1923 | } | |
1924 | ||
b448b0cc | 1925 | static void dm_init_rxpath_selection(struct net_device *dev) |
94a79942 LF |
1926 | { |
1927 | u8 i; | |
1928 | struct r8192_priv *priv = rtllib_priv(dev); | |
b448b0cc | 1929 | |
94a79942 LF |
1930 | DM_RxPathSelTable.Enable = 1; |
1931 | DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low; | |
1932 | DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH; | |
1933 | if (priv->CustomerID == RT_CID_819x_Netcore) | |
1934 | DM_RxPathSelTable.cck_method = CCK_Rx_Version_2; | |
1935 | else | |
1936 | DM_RxPathSelTable.cck_method = CCK_Rx_Version_1; | |
94a79942 | 1937 | DM_RxPathSelTable.disabledRF = 0; |
b448b0cc | 1938 | for (i = 0; i < 4; i++) { |
94a79942 LF |
1939 | DM_RxPathSelTable.rf_rssi[i] = 50; |
1940 | DM_RxPathSelTable.cck_pwdb_sta[i] = -64; | |
1941 | DM_RxPathSelTable.rf_enable_rssi_th[i] = 100; | |
1942 | } | |
1943 | } | |
1944 | ||
b448b0cc LF |
1945 | #define PWDB_IN_RANGE ((cur_cck_pwdb < tmp_cck_max_pwdb) && \ |
1946 | (cur_cck_pwdb > tmp_cck_sec_pwdb)) | |
1947 | ||
1948 | static void dm_rxpath_sel_byrssi(struct net_device *dev) | |
94a79942 LF |
1949 | { |
1950 | struct r8192_priv *priv = rtllib_priv(dev); | |
b448b0cc LF |
1951 | u8 i, max_rssi_index = 0, min_rssi_index = 0; |
1952 | u8 sec_rssi_index = 0, rf_num = 0; | |
1953 | u8 tmp_max_rssi = 0, tmp_min_rssi = 0, tmp_sec_rssi = 0; | |
1954 | u8 cck_default_Rx = 0x2; | |
1955 | u8 cck_optional_Rx = 0x3; | |
1956 | long tmp_cck_max_pwdb = 0, tmp_cck_min_pwdb = 0, tmp_cck_sec_pwdb = 0; | |
1957 | u8 cck_rx_ver2_max_index = 0, cck_rx_ver2_min_index = 0; | |
1958 | u8 cck_rx_ver2_sec_index = 0; | |
1959 | u8 cur_rf_rssi; | |
1960 | long cur_cck_pwdb; | |
1961 | static u8 disabled_rf_cnt, cck_Rx_Path_initialized; | |
1962 | u8 update_cck_rx_path; | |
94a79942 LF |
1963 | |
1964 | if (priv->rf_type != RF_2T4R) | |
1965 | return; | |
1966 | ||
b448b0cc | 1967 | if (!cck_Rx_Path_initialized) { |
b59a4ca3 | 1968 | DM_RxPathSelTable.cck_Rx_path = (rtl92e_readb(dev, 0xa07)&0xf); |
94a79942 LF |
1969 | cck_Rx_Path_initialized = 1; |
1970 | } | |
1971 | ||
1972 | DM_RxPathSelTable.disabledRF = 0xf; | |
b59a4ca3 | 1973 | DM_RxPathSelTable.disabledRF &= ~(rtl92e_readb(dev, 0xc04)); |
94a79942 LF |
1974 | |
1975 | if (priv->rtllib->mode == WIRELESS_MODE_B) | |
94a79942 | 1976 | DM_RxPathSelTable.cck_method = CCK_Rx_Version_2; |
94a79942 | 1977 | |
b448b0cc | 1978 | for (i = 0; i < RF90_PATH_MAX; i++) { |
32215eaa | 1979 | DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i]; |
94a79942 | 1980 | |
b448b0cc | 1981 | if (priv->brfpath_rxenable[i]) { |
94a79942 LF |
1982 | rf_num++; |
1983 | cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i]; | |
1984 | ||
b448b0cc | 1985 | if (rf_num == 1) { |
94a79942 LF |
1986 | max_rssi_index = min_rssi_index = sec_rssi_index = i; |
1987 | tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi; | |
b448b0cc LF |
1988 | } else if (rf_num == 2) { |
1989 | if (cur_rf_rssi >= tmp_max_rssi) { | |
94a79942 LF |
1990 | tmp_max_rssi = cur_rf_rssi; |
1991 | max_rssi_index = i; | |
b448b0cc | 1992 | } else { |
94a79942 LF |
1993 | tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi; |
1994 | sec_rssi_index = min_rssi_index = i; | |
1995 | } | |
b448b0cc LF |
1996 | } else { |
1997 | if (cur_rf_rssi > tmp_max_rssi) { | |
94a79942 LF |
1998 | tmp_sec_rssi = tmp_max_rssi; |
1999 | sec_rssi_index = max_rssi_index; | |
2000 | tmp_max_rssi = cur_rf_rssi; | |
2001 | max_rssi_index = i; | |
b448b0cc | 2002 | } else if (cur_rf_rssi == tmp_max_rssi) { |
94a79942 LF |
2003 | tmp_sec_rssi = cur_rf_rssi; |
2004 | sec_rssi_index = i; | |
b448b0cc LF |
2005 | } else if ((cur_rf_rssi < tmp_max_rssi) && |
2006 | (cur_rf_rssi > tmp_sec_rssi)) { | |
94a79942 LF |
2007 | tmp_sec_rssi = cur_rf_rssi; |
2008 | sec_rssi_index = i; | |
b448b0cc LF |
2009 | } else if (cur_rf_rssi == tmp_sec_rssi) { |
2010 | if (tmp_sec_rssi == tmp_min_rssi) { | |
94a79942 LF |
2011 | tmp_sec_rssi = cur_rf_rssi; |
2012 | sec_rssi_index = i; | |
2013 | } | |
b448b0cc LF |
2014 | } else if ((cur_rf_rssi < tmp_sec_rssi) && |
2015 | (cur_rf_rssi > tmp_min_rssi)) { | |
2016 | ; | |
2017 | } else if (cur_rf_rssi == tmp_min_rssi) { | |
2018 | if (tmp_sec_rssi == tmp_min_rssi) { | |
94a79942 LF |
2019 | tmp_min_rssi = cur_rf_rssi; |
2020 | min_rssi_index = i; | |
2021 | } | |
b448b0cc | 2022 | } else if (cur_rf_rssi < tmp_min_rssi) { |
94a79942 LF |
2023 | tmp_min_rssi = cur_rf_rssi; |
2024 | min_rssi_index = i; | |
2025 | } | |
2026 | } | |
2027 | } | |
2028 | } | |
2029 | ||
2030 | rf_num = 0; | |
b448b0cc LF |
2031 | if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) { |
2032 | for (i = 0; i < RF90_PATH_MAX; i++) { | |
2033 | if (priv->brfpath_rxenable[i]) { | |
94a79942 | 2034 | rf_num++; |
b448b0cc LF |
2035 | cur_cck_pwdb = |
2036 | DM_RxPathSelTable.cck_pwdb_sta[i]; | |
2037 | ||
2038 | if (rf_num == 1) { | |
2039 | cck_rx_ver2_max_index = i; | |
2040 | cck_rx_ver2_min_index = i; | |
2041 | cck_rx_ver2_sec_index = i; | |
2042 | tmp_cck_max_pwdb = cur_cck_pwdb; | |
2043 | tmp_cck_min_pwdb = cur_cck_pwdb; | |
2044 | tmp_cck_sec_pwdb = cur_cck_pwdb; | |
2045 | } else if (rf_num == 2) { | |
2046 | if (cur_cck_pwdb >= tmp_cck_max_pwdb) { | |
94a79942 LF |
2047 | tmp_cck_max_pwdb = cur_cck_pwdb; |
2048 | cck_rx_ver2_max_index = i; | |
b448b0cc LF |
2049 | } else { |
2050 | tmp_cck_sec_pwdb = cur_cck_pwdb; | |
2051 | tmp_cck_min_pwdb = cur_cck_pwdb; | |
2052 | cck_rx_ver2_sec_index = i; | |
2053 | cck_rx_ver2_min_index = i; | |
94a79942 | 2054 | } |
b448b0cc LF |
2055 | } else { |
2056 | if (cur_cck_pwdb > tmp_cck_max_pwdb) { | |
2057 | tmp_cck_sec_pwdb = | |
2058 | tmp_cck_max_pwdb; | |
2059 | cck_rx_ver2_sec_index = | |
2060 | cck_rx_ver2_max_index; | |
94a79942 LF |
2061 | tmp_cck_max_pwdb = cur_cck_pwdb; |
2062 | cck_rx_ver2_max_index = i; | |
b448b0cc LF |
2063 | } else if (cur_cck_pwdb == |
2064 | tmp_cck_max_pwdb) { | |
94a79942 LF |
2065 | tmp_cck_sec_pwdb = cur_cck_pwdb; |
2066 | cck_rx_ver2_sec_index = i; | |
b448b0cc | 2067 | } else if (PWDB_IN_RANGE) { |
94a79942 LF |
2068 | tmp_cck_sec_pwdb = cur_cck_pwdb; |
2069 | cck_rx_ver2_sec_index = i; | |
b448b0cc LF |
2070 | } else if (cur_cck_pwdb == |
2071 | tmp_cck_sec_pwdb) { | |
2072 | if (tmp_cck_sec_pwdb == | |
2073 | tmp_cck_min_pwdb) { | |
2074 | tmp_cck_sec_pwdb = | |
2075 | cur_cck_pwdb; | |
2076 | cck_rx_ver2_sec_index = | |
2077 | i; | |
94a79942 | 2078 | } |
b448b0cc LF |
2079 | } else if ((cur_cck_pwdb < tmp_cck_sec_pwdb) && |
2080 | (cur_cck_pwdb > tmp_cck_min_pwdb)) { | |
2081 | ; | |
2082 | } else if (cur_cck_pwdb == tmp_cck_min_pwdb) { | |
2083 | if (tmp_cck_sec_pwdb == tmp_cck_min_pwdb) { | |
94a79942 LF |
2084 | tmp_cck_min_pwdb = cur_cck_pwdb; |
2085 | cck_rx_ver2_min_index = i; | |
2086 | } | |
b448b0cc | 2087 | } else if (cur_cck_pwdb < tmp_cck_min_pwdb) { |
94a79942 LF |
2088 | tmp_cck_min_pwdb = cur_cck_pwdb; |
2089 | cck_rx_ver2_min_index = i; | |
2090 | } | |
2091 | } | |
2092 | ||
2093 | } | |
2094 | } | |
2095 | } | |
2096 | ||
94a79942 | 2097 | update_cck_rx_path = 0; |
b448b0cc | 2098 | if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) { |
94a79942 LF |
2099 | cck_default_Rx = cck_rx_ver2_max_index; |
2100 | cck_optional_Rx = cck_rx_ver2_sec_index; | |
2101 | if (tmp_cck_max_pwdb != -64) | |
2102 | update_cck_rx_path = 1; | |
2103 | } | |
2104 | ||
b448b0cc LF |
2105 | if (tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2) { |
2106 | if ((tmp_max_rssi - tmp_min_rssi) >= | |
2107 | DM_RxPathSelTable.diff_TH) { | |
2108 | DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] = | |
2109 | tmp_max_rssi+5; | |
153f9ddb MK |
2110 | rtl92e_set_bb_reg(dev, rOFDM0_TRxPathEnable, |
2111 | 0x1<<min_rssi_index, 0x0); | |
2112 | rtl92e_set_bb_reg(dev, rOFDM1_TRxPathEnable, | |
2113 | 0x1<<min_rssi_index, 0x0); | |
94a79942 LF |
2114 | disabled_rf_cnt++; |
2115 | } | |
b448b0cc | 2116 | if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_1) { |
94a79942 LF |
2117 | cck_default_Rx = max_rssi_index; |
2118 | cck_optional_Rx = sec_rssi_index; | |
2119 | if (tmp_max_rssi) | |
2120 | update_cck_rx_path = 1; | |
2121 | } | |
2122 | } | |
2123 | ||
b448b0cc LF |
2124 | if (update_cck_rx_path) { |
2125 | DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2) | | |
2126 | (cck_optional_Rx); | |
153f9ddb MK |
2127 | rtl92e_set_bb_reg(dev, rCCK0_AFESetting, 0x0f000000, |
2128 | DM_RxPathSelTable.cck_Rx_path); | |
94a79942 LF |
2129 | } |
2130 | ||
b448b0cc LF |
2131 | if (DM_RxPathSelTable.disabledRF) { |
2132 | for (i = 0; i < 4; i++) { | |
2133 | if ((DM_RxPathSelTable.disabledRF>>i) & 0x1) { | |
2134 | if (tmp_max_rssi >= | |
2135 | DM_RxPathSelTable.rf_enable_rssi_th[i]) { | |
153f9ddb MK |
2136 | rtl92e_set_bb_reg(dev, |
2137 | rOFDM0_TRxPathEnable, | |
2138 | 0x1 << i, 0x1); | |
2139 | rtl92e_set_bb_reg(dev, | |
2140 | rOFDM1_TRxPathEnable, | |
2141 | 0x1 << i, 0x1); | |
b448b0cc LF |
2142 | DM_RxPathSelTable.rf_enable_rssi_th[i] |
2143 | = 100; | |
94a79942 LF |
2144 | disabled_rf_cnt--; |
2145 | } | |
2146 | } | |
2147 | } | |
2148 | } | |
2149 | } | |
2150 | ||
2151 | static void dm_check_rx_path_selection(struct net_device *dev) | |
2152 | { | |
2153 | struct r8192_priv *priv = rtllib_priv(dev); | |
b448b0cc LF |
2154 | |
2155 | queue_delayed_work_rsl(priv->priv_wq, &priv->rfpath_check_wq, 0); | |
94a79942 LF |
2156 | } |
2157 | ||
2158 | ||
b448b0cc | 2159 | static void dm_init_fsync(struct net_device *dev) |
94a79942 LF |
2160 | { |
2161 | struct r8192_priv *priv = rtllib_priv(dev); | |
2162 | ||
2163 | priv->rtllib->fsync_time_interval = 500; | |
2164 | priv->rtllib->fsync_rate_bitmap = 0x0f000800; | |
2165 | priv->rtllib->fsync_rssi_threshold = 30; | |
94a79942 | 2166 | priv->rtllib->bfsync_enable = false; |
94a79942 | 2167 | priv->rtllib->fsync_multiple_timeinterval = 3; |
b448b0cc LF |
2168 | priv->rtllib->fsync_firstdiff_ratethreshold = 100; |
2169 | priv->rtllib->fsync_seconddiff_ratethreshold = 200; | |
94a79942 | 2170 | priv->rtllib->fsync_state = Default_Fsync; |
94a79942 | 2171 | priv->framesyncMonitor = 1; |
94a79942 | 2172 | |
b448b0cc LF |
2173 | setup_timer(&priv->fsync_timer, dm_fsync_timer_callback, |
2174 | (unsigned long) dev); | |
94a79942 LF |
2175 | } |
2176 | ||
2177 | ||
2178 | static void dm_deInit_fsync(struct net_device *dev) | |
2179 | { | |
2180 | struct r8192_priv *priv = rtllib_priv(dev); | |
3a6b70c3 | 2181 | |
94a79942 LF |
2182 | del_timer_sync(&priv->fsync_timer); |
2183 | } | |
2184 | ||
735b7861 | 2185 | static void dm_fsync_timer_callback(unsigned long data) |
94a79942 LF |
2186 | { |
2187 | struct net_device *dev = (struct net_device *)data; | |
2188 | struct r8192_priv *priv = rtllib_priv((struct net_device *)data); | |
b448b0cc | 2189 | u32 rate_index, rate_count = 0, rate_count_diff = 0; |
94a79942 LF |
2190 | bool bSwitchFromCountDiff = false; |
2191 | bool bDoubleTimeInterval = false; | |
2192 | ||
b448b0cc LF |
2193 | if (priv->rtllib->state == RTLLIB_LINKED && |
2194 | priv->rtllib->bfsync_enable && | |
2195 | (priv->rtllib->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) { | |
94a79942 | 2196 | u32 rate_bitmap; |
3a6b70c3 | 2197 | |
b448b0cc | 2198 | for (rate_index = 0; rate_index <= 27; rate_index++) { |
94a79942 LF |
2199 | rate_bitmap = 1 << rate_index; |
2200 | if (priv->rtllib->fsync_rate_bitmap & rate_bitmap) | |
b448b0cc LF |
2201 | rate_count += |
2202 | priv->stats.received_rate_histogram[1] | |
2203 | [rate_index]; | |
94a79942 LF |
2204 | } |
2205 | ||
2206 | if (rate_count < priv->rate_record) | |
b448b0cc LF |
2207 | rate_count_diff = 0xffffffff - rate_count + |
2208 | priv->rate_record; | |
94a79942 LF |
2209 | else |
2210 | rate_count_diff = rate_count - priv->rate_record; | |
b448b0cc | 2211 | if (rate_count_diff < priv->rateCountDiffRecord) { |
94a79942 | 2212 | |
b448b0cc LF |
2213 | u32 DiffNum = priv->rateCountDiffRecord - |
2214 | rate_count_diff; | |
2215 | if (DiffNum >= | |
2216 | priv->rtllib->fsync_seconddiff_ratethreshold) | |
4c234ebc | 2217 | priv->ContinueDiffCount++; |
94a79942 | 2218 | else |
4c234ebc | 2219 | priv->ContinueDiffCount = 0; |
94a79942 | 2220 | |
4c234ebc | 2221 | if (priv->ContinueDiffCount >= 2) { |
94a79942 | 2222 | bSwitchFromCountDiff = true; |
4c234ebc | 2223 | priv->ContinueDiffCount = 0; |
94a79942 | 2224 | } |
b448b0cc | 2225 | } else { |
4c234ebc | 2226 | priv->ContinueDiffCount = 0; |
94a79942 LF |
2227 | } |
2228 | ||
b448b0cc LF |
2229 | if (rate_count_diff <= |
2230 | priv->rtllib->fsync_firstdiff_ratethreshold) { | |
94a79942 | 2231 | bSwitchFromCountDiff = true; |
4c234ebc | 2232 | priv->ContinueDiffCount = 0; |
94a79942 LF |
2233 | } |
2234 | priv->rate_record = rate_count; | |
2235 | priv->rateCountDiffRecord = rate_count_diff; | |
0822339b MK |
2236 | RT_TRACE(COMP_HALDM, |
2237 | "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", | |
2238 | priv->rate_record, rate_count, rate_count_diff, | |
2239 | priv->bswitch_fsync); | |
b448b0cc LF |
2240 | if (priv->undecorated_smoothed_pwdb > |
2241 | priv->rtllib->fsync_rssi_threshold && | |
2242 | bSwitchFromCountDiff) { | |
94a79942 LF |
2243 | bDoubleTimeInterval = true; |
2244 | priv->bswitch_fsync = !priv->bswitch_fsync; | |
b448b0cc | 2245 | if (priv->bswitch_fsync) { |
d8ae1967 MK |
2246 | rtl92e_writeb(dev, 0xC36, 0x1c); |
2247 | rtl92e_writeb(dev, 0xC3e, 0x90); | |
b448b0cc | 2248 | } else { |
d8ae1967 MK |
2249 | rtl92e_writeb(dev, 0xC36, 0x5c); |
2250 | rtl92e_writeb(dev, 0xC3e, 0x96); | |
94a79942 | 2251 | } |
b448b0cc LF |
2252 | } else if (priv->undecorated_smoothed_pwdb <= |
2253 | priv->rtllib->fsync_rssi_threshold) { | |
2254 | if (priv->bswitch_fsync) { | |
94a79942 | 2255 | priv->bswitch_fsync = false; |
d8ae1967 MK |
2256 | rtl92e_writeb(dev, 0xC36, 0x5c); |
2257 | rtl92e_writeb(dev, 0xC3e, 0x96); | |
94a79942 LF |
2258 | } |
2259 | } | |
b448b0cc | 2260 | if (bDoubleTimeInterval) { |
94a79942 LF |
2261 | if (timer_pending(&priv->fsync_timer)) |
2262 | del_timer_sync(&priv->fsync_timer); | |
b448b0cc | 2263 | priv->fsync_timer.expires = jiffies + |
8b9733c1 | 2264 | msecs_to_jiffies(priv->rtllib->fsync_time_interval * |
b448b0cc | 2265 | priv->rtllib->fsync_multiple_timeinterval); |
94a79942 | 2266 | add_timer(&priv->fsync_timer); |
b448b0cc | 2267 | } else { |
94a79942 LF |
2268 | if (timer_pending(&priv->fsync_timer)) |
2269 | del_timer_sync(&priv->fsync_timer); | |
b448b0cc | 2270 | priv->fsync_timer.expires = jiffies + |
8b9733c1 | 2271 | msecs_to_jiffies(priv->rtllib->fsync_time_interval); |
94a79942 LF |
2272 | add_timer(&priv->fsync_timer); |
2273 | } | |
b448b0cc LF |
2274 | } else { |
2275 | if (priv->bswitch_fsync) { | |
94a79942 | 2276 | priv->bswitch_fsync = false; |
d8ae1967 MK |
2277 | rtl92e_writeb(dev, 0xC36, 0x5c); |
2278 | rtl92e_writeb(dev, 0xC3e, 0x96); | |
94a79942 | 2279 | } |
4c234ebc | 2280 | priv->ContinueDiffCount = 0; |
8ea54100 | 2281 | rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c52cd); |
94a79942 | 2282 | } |
4c234ebc | 2283 | RT_TRACE(COMP_HALDM, "ContinueDiffCount %d\n", priv->ContinueDiffCount); |
0822339b MK |
2284 | RT_TRACE(COMP_HALDM, |
2285 | "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", | |
2286 | priv->rate_record, rate_count, rate_count_diff, | |
2287 | priv->bswitch_fsync); | |
94a79942 LF |
2288 | } |
2289 | ||
2290 | static void dm_StartHWFsync(struct net_device *dev) | |
2291 | { | |
94a79942 LF |
2292 | u8 rf_timing = 0x77; |
2293 | struct r8192_priv *priv = rtllib_priv(dev); | |
3a6b70c3 | 2294 | |
94a79942 | 2295 | RT_TRACE(COMP_HALDM, "%s\n", __func__); |
8ea54100 | 2296 | rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c12cf); |
b448b0cc LF |
2297 | priv->rtllib->SetHwRegHandler(dev, HW_VAR_RF_TIMING, |
2298 | (u8 *)(&rf_timing)); | |
d8ae1967 | 2299 | rtl92e_writeb(dev, 0xc3b, 0x41); |
94a79942 LF |
2300 | } |
2301 | ||
2302 | static void dm_EndHWFsync(struct net_device *dev) | |
2303 | { | |
94a79942 LF |
2304 | u8 rf_timing = 0xaa; |
2305 | struct r8192_priv *priv = rtllib_priv(dev); | |
3a6b70c3 | 2306 | |
b448b0cc | 2307 | RT_TRACE(COMP_HALDM, "%s\n", __func__); |
8ea54100 | 2308 | rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c52cd); |
b448b0cc LF |
2309 | priv->rtllib->SetHwRegHandler(dev, HW_VAR_RF_TIMING, (u8 *) |
2310 | (&rf_timing)); | |
d8ae1967 | 2311 | rtl92e_writeb(dev, 0xc3b, 0x49); |
94a79942 LF |
2312 | } |
2313 | ||
2314 | static void dm_EndSWFsync(struct net_device *dev) | |
2315 | { | |
2316 | struct r8192_priv *priv = rtllib_priv(dev); | |
2317 | ||
2318 | RT_TRACE(COMP_HALDM, "%s\n", __func__); | |
2319 | del_timer_sync(&(priv->fsync_timer)); | |
2320 | ||
b448b0cc | 2321 | if (priv->bswitch_fsync) { |
94a79942 LF |
2322 | priv->bswitch_fsync = false; |
2323 | ||
d8ae1967 | 2324 | rtl92e_writeb(dev, 0xC36, 0x5c); |
94a79942 | 2325 | |
d8ae1967 | 2326 | rtl92e_writeb(dev, 0xC3e, 0x96); |
94a79942 LF |
2327 | } |
2328 | ||
4c234ebc | 2329 | priv->ContinueDiffCount = 0; |
8ea54100 | 2330 | rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c52cd); |
94a79942 LF |
2331 | } |
2332 | ||
2333 | static void dm_StartSWFsync(struct net_device *dev) | |
2334 | { | |
2335 | struct r8192_priv *priv = rtllib_priv(dev); | |
2336 | u32 rateIndex; | |
2337 | u32 rateBitmap; | |
2338 | ||
b448b0cc | 2339 | RT_TRACE(COMP_HALDM, "%s\n", __func__); |
94a79942 | 2340 | priv->rate_record = 0; |
4c234ebc | 2341 | priv->ContinueDiffCount = 0; |
94a79942 LF |
2342 | priv->rateCountDiffRecord = 0; |
2343 | priv->bswitch_fsync = false; | |
2344 | ||
b448b0cc LF |
2345 | if (priv->rtllib->mode == WIRELESS_MODE_N_24G) { |
2346 | priv->rtllib->fsync_firstdiff_ratethreshold = 600; | |
94a79942 | 2347 | priv->rtllib->fsync_seconddiff_ratethreshold = 0xffff; |
b448b0cc LF |
2348 | } else { |
2349 | priv->rtllib->fsync_firstdiff_ratethreshold = 200; | |
94a79942 LF |
2350 | priv->rtllib->fsync_seconddiff_ratethreshold = 200; |
2351 | } | |
b448b0cc | 2352 | for (rateIndex = 0; rateIndex <= 27; rateIndex++) { |
94a79942 | 2353 | rateBitmap = 1 << rateIndex; |
b448b0cc LF |
2354 | if (priv->rtllib->fsync_rate_bitmap & rateBitmap) |
2355 | priv->rate_record += | |
2356 | priv->stats.received_rate_histogram[1] | |
2357 | [rateIndex]; | |
94a79942 LF |
2358 | } |
2359 | if (timer_pending(&priv->fsync_timer)) | |
2360 | del_timer_sync(&priv->fsync_timer); | |
b448b0cc | 2361 | priv->fsync_timer.expires = jiffies + |
8b9733c1 | 2362 | msecs_to_jiffies(priv->rtllib->fsync_time_interval); |
94a79942 LF |
2363 | add_timer(&priv->fsync_timer); |
2364 | ||
8ea54100 | 2365 | rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c12cd); |
94a79942 LF |
2366 | |
2367 | } | |
2368 | ||
735b7861 | 2369 | static void dm_check_fsync(struct net_device *dev) |
94a79942 | 2370 | { |
b448b0cc | 2371 | #define RegC38_Default 0 |
94a79942 LF |
2372 | #define RegC38_NonFsync_Other_AP 1 |
2373 | #define RegC38_Fsync_AP_BCM 2 | |
2374 | struct r8192_priv *priv = rtllib_priv(dev); | |
b448b0cc LF |
2375 | static u8 reg_c38_State = RegC38_Default; |
2376 | static u32 reset_cnt; | |
2377 | ||
0822339b MK |
2378 | RT_TRACE(COMP_HALDM, |
2379 | "RSSI %d TimeInterval %d MultipleTimeInterval %d\n", | |
2380 | priv->rtllib->fsync_rssi_threshold, | |
b448b0cc LF |
2381 | priv->rtllib->fsync_time_interval, |
2382 | priv->rtllib->fsync_multiple_timeinterval); | |
0822339b MK |
2383 | RT_TRACE(COMP_HALDM, |
2384 | "RateBitmap 0x%x FirstDiffRateThreshold %d SecondDiffRateThreshold %d\n", | |
2385 | priv->rtllib->fsync_rate_bitmap, | |
b448b0cc LF |
2386 | priv->rtllib->fsync_firstdiff_ratethreshold, |
2387 | priv->rtllib->fsync_seconddiff_ratethreshold); | |
2388 | ||
2389 | if (priv->rtllib->state == RTLLIB_LINKED && | |
2390 | priv->rtllib->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) { | |
2391 | if (priv->rtllib->bfsync_enable == 0) { | |
2392 | switch (priv->rtllib->fsync_state) { | |
2393 | case Default_Fsync: | |
2394 | dm_StartHWFsync(dev); | |
2395 | priv->rtllib->fsync_state = HW_Fsync; | |
2396 | break; | |
2397 | case SW_Fsync: | |
2398 | dm_EndSWFsync(dev); | |
2399 | dm_StartHWFsync(dev); | |
2400 | priv->rtllib->fsync_state = HW_Fsync; | |
2401 | break; | |
2402 | case HW_Fsync: | |
2403 | default: | |
2404 | break; | |
94a79942 | 2405 | } |
b448b0cc LF |
2406 | } else { |
2407 | switch (priv->rtllib->fsync_state) { | |
2408 | case Default_Fsync: | |
2409 | dm_StartSWFsync(dev); | |
2410 | priv->rtllib->fsync_state = SW_Fsync; | |
2411 | break; | |
2412 | case HW_Fsync: | |
2413 | dm_EndHWFsync(dev); | |
2414 | dm_StartSWFsync(dev); | |
2415 | priv->rtllib->fsync_state = SW_Fsync; | |
2416 | break; | |
2417 | case SW_Fsync: | |
2418 | default: | |
2419 | break; | |
94a79942 LF |
2420 | |
2421 | } | |
2422 | } | |
b448b0cc LF |
2423 | if (priv->framesyncMonitor) { |
2424 | if (reg_c38_State != RegC38_Fsync_AP_BCM) { | |
d8ae1967 | 2425 | rtl92e_writeb(dev, rOFDM0_RxDetector3, 0x95); |
94a79942 LF |
2426 | |
2427 | reg_c38_State = RegC38_Fsync_AP_BCM; | |
2428 | } | |
2429 | } | |
2430 | } else { | |
2431 | switch (priv->rtllib->fsync_state) { | |
2432 | case HW_Fsync: | |
2433 | dm_EndHWFsync(dev); | |
2434 | priv->rtllib->fsync_state = Default_Fsync; | |
2435 | break; | |
2436 | case SW_Fsync: | |
2437 | dm_EndSWFsync(dev); | |
2438 | priv->rtllib->fsync_state = Default_Fsync; | |
2439 | break; | |
2440 | case Default_Fsync: | |
2441 | default: | |
2442 | break; | |
2443 | } | |
2444 | ||
2445 | if (priv->framesyncMonitor) { | |
2446 | if (priv->rtllib->state == RTLLIB_LINKED) { | |
b448b0cc LF |
2447 | if (priv->undecorated_smoothed_pwdb <= |
2448 | RegC38_TH) { | |
2449 | if (reg_c38_State != | |
2450 | RegC38_NonFsync_Other_AP) { | |
d8ae1967 | 2451 | rtl92e_writeb(dev, |
b448b0cc LF |
2452 | rOFDM0_RxDetector3, |
2453 | 0x90); | |
2454 | ||
2455 | reg_c38_State = | |
2456 | RegC38_NonFsync_Other_AP; | |
94a79942 | 2457 | } |
b448b0cc LF |
2458 | } else if (priv->undecorated_smoothed_pwdb >= |
2459 | (RegC38_TH+5)) { | |
94a79942 | 2460 | if (reg_c38_State) { |
d8ae1967 | 2461 | rtl92e_writeb(dev, |
b448b0cc LF |
2462 | rOFDM0_RxDetector3, |
2463 | priv->framesync); | |
94a79942 LF |
2464 | reg_c38_State = RegC38_Default; |
2465 | } | |
2466 | } | |
2467 | } else { | |
2468 | if (reg_c38_State) { | |
d8ae1967 MK |
2469 | rtl92e_writeb(dev, rOFDM0_RxDetector3, |
2470 | priv->framesync); | |
94a79942 LF |
2471 | reg_c38_State = RegC38_Default; |
2472 | } | |
2473 | } | |
2474 | } | |
2475 | } | |
2476 | if (priv->framesyncMonitor) { | |
2477 | if (priv->reset_count != reset_cnt) { | |
d8ae1967 | 2478 | rtl92e_writeb(dev, rOFDM0_RxDetector3, |
b448b0cc | 2479 | priv->framesync); |
94a79942 LF |
2480 | reg_c38_State = RegC38_Default; |
2481 | reset_cnt = priv->reset_count; | |
2482 | } | |
2483 | } else { | |
2484 | if (reg_c38_State) { | |
d8ae1967 | 2485 | rtl92e_writeb(dev, rOFDM0_RxDetector3, |
b448b0cc | 2486 | priv->framesync); |
94a79942 LF |
2487 | reg_c38_State = RegC38_Default; |
2488 | } | |
2489 | } | |
2490 | } | |
2491 | ||
94a79942 LF |
2492 | /*---------------------------Define function prototype------------------------*/ |
2493 | static void dm_init_dynamic_txpower(struct net_device *dev) | |
2494 | { | |
2495 | struct r8192_priv *priv = rtllib_priv(dev); | |
2496 | ||
2497 | priv->rtllib->bdynamic_txpower_enable = true; | |
2498 | priv->bLastDTPFlag_High = false; | |
2499 | priv->bLastDTPFlag_Low = false; | |
2500 | priv->bDynamicTxHighPower = false; | |
2501 | priv->bDynamicTxLowPower = false; | |
2502 | } | |
2503 | ||
2504 | static void dm_dynamic_txpower(struct net_device *dev) | |
2505 | { | |
2506 | struct r8192_priv *priv = rtllib_priv(dev); | |
b448b0cc LF |
2507 | unsigned int txhipower_threshhold = 0; |
2508 | unsigned int txlowpower_threshold = 0; | |
3a6b70c3 | 2509 | |
b448b0cc | 2510 | if (priv->rtllib->bdynamic_txpower_enable != true) { |
94a79942 LF |
2511 | priv->bDynamicTxHighPower = false; |
2512 | priv->bDynamicTxLowPower = false; | |
2513 | return; | |
2514 | } | |
b448b0cc LF |
2515 | if ((priv->rtllib->pHTInfo->IOTPeer == HT_IOT_PEER_ATHEROS) && |
2516 | (priv->rtllib->mode == IEEE_G)) { | |
94a79942 LF |
2517 | txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH; |
2518 | txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW; | |
b448b0cc | 2519 | } else { |
94a79942 LF |
2520 | txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH; |
2521 | txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW; | |
2522 | } | |
2523 | ||
b448b0cc LF |
2524 | RT_TRACE(COMP_TXAGC, "priv->undecorated_smoothed_pwdb = %ld\n", |
2525 | priv->undecorated_smoothed_pwdb); | |
94a79942 | 2526 | |
b448b0cc LF |
2527 | if (priv->rtllib->state == RTLLIB_LINKED) { |
2528 | if (priv->undecorated_smoothed_pwdb >= txhipower_threshhold) { | |
94a79942 LF |
2529 | priv->bDynamicTxHighPower = true; |
2530 | priv->bDynamicTxLowPower = false; | |
b448b0cc LF |
2531 | } else { |
2532 | if (priv->undecorated_smoothed_pwdb < | |
4bb01423 | 2533 | txlowpower_threshold && priv->bDynamicTxHighPower) |
94a79942 | 2534 | priv->bDynamicTxHighPower = false; |
94a79942 | 2535 | if (priv->undecorated_smoothed_pwdb < 35) |
94a79942 | 2536 | priv->bDynamicTxLowPower = true; |
94a79942 | 2537 | else if (priv->undecorated_smoothed_pwdb >= 40) |
94a79942 | 2538 | priv->bDynamicTxLowPower = false; |
94a79942 | 2539 | } |
b448b0cc | 2540 | } else { |
94a79942 LF |
2541 | priv->bDynamicTxHighPower = false; |
2542 | priv->bDynamicTxLowPower = false; | |
2543 | } | |
2544 | ||
b448b0cc LF |
2545 | if ((priv->bDynamicTxHighPower != priv->bLastDTPFlag_High) || |
2546 | (priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low)) { | |
2547 | RT_TRACE(COMP_TXAGC, "SetTxPowerLevel8190() channel = %d\n", | |
2548 | priv->rtllib->current_network.channel); | |
94a79942 | 2549 | |
5aa1b9ca | 2550 | rtl92e_set_tx_power(dev, priv->rtllib->current_network.channel); |
94a79942 LF |
2551 | } |
2552 | priv->bLastDTPFlag_High = priv->bDynamicTxHighPower; | |
2553 | priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower; | |
2554 | ||
2555 | } | |
2556 | ||
b448b0cc | 2557 | static void dm_check_txrateandretrycount(struct net_device *dev) |
94a79942 LF |
2558 | { |
2559 | struct r8192_priv *priv = rtllib_priv(dev); | |
b448b0cc | 2560 | struct rtllib_device *ieee = priv->rtllib; |
94a79942 | 2561 | |
b59a4ca3 | 2562 | ieee->softmac_stats.CurrentShowTxate = rtl92e_readb(dev, |
b448b0cc | 2563 | Current_Tx_Rate_Reg); |
94a79942 | 2564 | |
b59a4ca3 | 2565 | ieee->softmac_stats.last_packet_rate = rtl92e_readb(dev, |
b448b0cc | 2566 | Initial_Tx_Rate_Reg); |
94a79942 | 2567 | |
99aa47e0 | 2568 | ieee->softmac_stats.txretrycount = rtl92e_readl(dev, |
b448b0cc | 2569 | Tx_Retry_Count_Reg); |
94a79942 LF |
2570 | } |
2571 | ||
2572 | static void dm_send_rssi_tofw(struct net_device *dev) | |
2573 | { | |
94a79942 LF |
2574 | struct r8192_priv *priv = rtllib_priv(dev); |
2575 | ||
d8ae1967 | 2576 | rtl92e_writeb(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb); |
94a79942 | 2577 | } |