]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blame - drivers/staging/rtl8192e/rtl8192e/rtl_dm.c
Merge tag 'armsoc-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
[mirror_ubuntu-eoan-kernel.git] / drivers / staging / rtl8192e / rtl8192e / rtl_dm.c
CommitLineData
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
28static 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
39static 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
50static 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
61const 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
101const 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
127const 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 157struct dig_t dm_digtable;
b448b0cc 158
8e8b90c6 159struct 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-----------------------*/
169static void dm_check_rate_adaptive(struct net_device *dev);
170
b448b0cc
LF
171static void dm_init_bandwidth_autoswitch(struct net_device *dev);
172static void dm_bandwidth_autoswitch(struct net_device *dev);
94a79942
LF
173
174
175static void dm_check_txpower_tracking(struct net_device *dev);
176
177
178
179
180
94a79942
LF
181static void dm_bb_initialgain_restore(struct net_device *dev);
182
183
184static void dm_bb_initialgain_backup(struct net_device *dev);
94a79942
LF
185
186static void dm_dig_init(struct net_device *dev);
187static void dm_ctrl_initgain_byrssi(struct net_device *dev);
188static void dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev);
b448b0cc 189static void dm_ctrl_initgain_byrssi_by_driverrssi(struct net_device *dev);
94a79942
LF
190static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct net_device *dev);
191static void dm_initial_gain(struct net_device *dev);
192static void dm_pd_th(struct net_device *dev);
193static void dm_cs_ratio(struct net_device *dev);
194
195static void dm_init_ctstoself(struct net_device *dev);
196static void dm_Init_WA_Broadcom_IOT(struct net_device *dev);
94a79942
LF
197
198static void dm_check_edca_turbo(struct net_device *dev);
199
94a79942
LF
200static void dm_check_pbc_gpio(struct net_device *dev);
201
202
203static void dm_check_rx_path_selection(struct net_device *dev);
204static void dm_init_rxpath_selection(struct net_device *dev);
205static void dm_rxpath_sel_byrssi(struct net_device *dev);
206
207
208static void dm_init_fsync(struct net_device *dev);
209static void dm_deInit_fsync(struct net_device *dev);
210
211static void dm_check_txrateandretrycount(struct net_device *dev);
212static void dm_check_ac_dc_power(struct net_device *dev);
735b7861
MK
213static void dm_check_fsync(struct net_device *dev);
214static void dm_CheckRfCtrlGPIO(void *data);
215static void dm_fsync_timer_callback(unsigned long data);
94a79942
LF
216
217/*---------------------Define local function prototype-----------------------*/
218
219static void dm_init_dynamic_txpower(struct net_device *dev);
220static void dm_dynamic_txpower(struct net_device *dev);
221
222
223static void dm_send_rssi_tofw(struct net_device *dev);
224static void dm_ctstoself(struct net_device *dev);
94a79942
LF
225/*---------------------------Define function prototype------------------------*/
226
ab743598 227void 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 252void rtl92e_dm_deinit(struct net_device *dev)
94a79942
LF
253{
254
255 dm_deInit_fsync(dev);
256
257}
258
8e1e64bb 259void 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 286static 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 310void 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 351static 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 468static 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 478static 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
496static 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
518static 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
533static 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
554static 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
602static 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
642static 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 847static 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 950void 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
962static 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
973static 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 988void 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
998static 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
1018static 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
1052static 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
1062static 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
1100static 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 1152void 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 1162static 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 1194void 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
1223static 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 1259void 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
1270static 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
1299static 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
1329static 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
1361static 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
1396static 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 1485static 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 1526static 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 1583static 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 1651static 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 1695void 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 1704static 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
1796dm_CheckEdcaTurbo_EXIT:
1797 priv->rtllib->bis_any_nonbepkts = false;
1798 lastTxOkCnt = priv->stats.txbytesunicast;
1799 lastRxOkCnt = priv->stats.rxbytesunicast;
1800}
94a79942 1801
b448b0cc 1802static 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
1809static 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 1836static 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
1845static void dm_check_pbc_gpio(struct net_device *dev)
1846{
94a79942
LF
1847}
1848
735b7861 1849static 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 1903void 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 1925static 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
1948static 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
2151static 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 2159static 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
2178static 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 2185static 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
2290static 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
2302static 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
2314static 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
2333static 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 2369static 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------------------------*/
2493static 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
2504static 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 2557static 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
2572static 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}