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