GNU Linux-libre 4.9.326-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(unsigned long data);
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 *ac_dc_script = "/etc/acpi/wireless-rtl-ac-dc-power.sh";
272         char *argv[] = {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 = tmpCCK20Mindex = 0;
892                 else
893                         tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval;
894                 tmpCCK40Mindex = 0;
895         }
896         if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
897                 tmpCCKindex = tmpCCK40Mindex;
898         else
899                 tmpCCKindex = tmpCCK20Mindex;
900
901         priv->Record_CCK_20Mindex = tmpCCK20Mindex;
902         priv->Record_CCK_40Mindex = tmpCCK40Mindex;
903         RT_TRACE(COMP_POWER_TRACKING,
904                  "Record_CCK_20Mindex / Record_CCK_40Mindex = %d / %d.\n",
905                  priv->Record_CCK_20Mindex, priv->Record_CCK_40Mindex);
906
907         if (priv->rtllib->current_network.channel == 14 &&
908             !priv->bcck_in_ch14) {
909                 priv->bcck_in_ch14 = true;
910                 CCKSwingNeedUpdate = 1;
911         } else if (priv->rtllib->current_network.channel != 14 &&
912                    priv->bcck_in_ch14) {
913                 priv->bcck_in_ch14 = false;
914                 CCKSwingNeedUpdate = 1;
915         }
916
917         if (priv->CCK_index != tmpCCKindex) {
918                 priv->CCK_index = tmpCCKindex;
919                 CCKSwingNeedUpdate = 1;
920         }
921
922         if (CCKSwingNeedUpdate)
923                 rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
924         if (priv->OFDM_index[0] != tmpOFDMindex) {
925                 priv->OFDM_index[0] = tmpOFDMindex;
926                 rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, bMaskDWord,
927                                   OFDMSwingTable[priv->OFDM_index[0]]);
928                 RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n",
929                          priv->OFDM_index[0],
930                          OFDMSwingTable[priv->OFDM_index[0]]);
931         }
932         priv->txpower_count = 0;
933 }
934
935 void rtl92e_dm_txpower_tracking_wq(void *data)
936 {
937         struct r8192_priv *priv = container_of_dwork_rsl(data,
938                                   struct r8192_priv, txpower_tracking_wq);
939         struct net_device *dev = priv->rtllib->dev;
940
941         if (priv->IC_Cut >= IC_VersionCut_D)
942                 _rtl92e_dm_tx_power_tracking_callback_tssi(dev);
943         else
944                 _rtl92e_dm_tx_power_tracking_cb_thermal(dev);
945 }
946
947 static void _rtl92e_dm_initialize_tx_power_tracking_tssi(struct net_device *dev)
948 {
949
950         struct r8192_priv *priv = rtllib_priv(dev);
951
952         priv->btxpower_tracking = true;
953         priv->txpower_count       = 0;
954         priv->btxpower_trackingInit = false;
955
956 }
957
958 static void _rtl92e_dm_init_tx_power_tracking_thermal(struct net_device *dev)
959 {
960         struct r8192_priv *priv = rtllib_priv(dev);
961
962
963         if (priv->rtllib->FwRWRF)
964                 priv->btxpower_tracking = true;
965         else
966                 priv->btxpower_tracking = false;
967         priv->txpower_count       = 0;
968         priv->btxpower_trackingInit = false;
969         RT_TRACE(COMP_POWER_TRACKING, "pMgntInfo->bTXPowerTracking = %d\n",
970                  priv->btxpower_tracking);
971 }
972
973 void rtl92e_dm_init_txpower_tracking(struct net_device *dev)
974 {
975         struct r8192_priv *priv = rtllib_priv(dev);
976
977         if (priv->IC_Cut >= IC_VersionCut_D)
978                 _rtl92e_dm_initialize_tx_power_tracking_tssi(dev);
979         else
980                 _rtl92e_dm_init_tx_power_tracking_thermal(dev);
981 }
982
983 static void _rtl92e_dm_check_tx_power_tracking_tssi(struct net_device *dev)
984 {
985         struct r8192_priv *priv = rtllib_priv(dev);
986         static u32 tx_power_track_counter;
987
988         RT_TRACE(COMP_POWER_TRACKING, "%s()\n", __func__);
989         if (rtl92e_readb(dev, 0x11e) == 1)
990                 return;
991         if (!priv->btxpower_tracking)
992                 return;
993         tx_power_track_counter++;
994
995
996          if (tx_power_track_counter >= 180) {
997                 schedule_delayed_work(&priv->txpower_tracking_wq, 0);
998                 tx_power_track_counter = 0;
999         }
1000
1001 }
1002
1003 static void _rtl92e_dm_check_tx_power_tracking_thermal(struct net_device *dev)
1004 {
1005         struct r8192_priv *priv = rtllib_priv(dev);
1006         static u8       TM_Trigger;
1007         u8              TxPowerCheckCnt = 0;
1008
1009         if (IS_HARDWARE_TYPE_8192SE(dev))
1010                 TxPowerCheckCnt = 5;
1011         else
1012                 TxPowerCheckCnt = 2;
1013         if (!priv->btxpower_tracking)
1014                 return;
1015
1016         if (priv->txpower_count  <= TxPowerCheckCnt) {
1017                 priv->txpower_count++;
1018                 return;
1019         }
1020
1021         if (!TM_Trigger) {
1022                 rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1023                 rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1024                 rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1025                 rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1026                 TM_Trigger = 1;
1027                 return;
1028         }
1029         netdev_info(dev, "===============>Schedule TxPowerTrackingWorkItem\n");
1030         schedule_delayed_work(&priv->txpower_tracking_wq, 0);
1031         TM_Trigger = 0;
1032
1033 }
1034
1035 static void _rtl92e_dm_check_tx_power_tracking(struct net_device *dev)
1036 {
1037         struct r8192_priv *priv = rtllib_priv(dev);
1038
1039         if (priv->IC_Cut >= IC_VersionCut_D)
1040                 _rtl92e_dm_check_tx_power_tracking_tssi(dev);
1041         else
1042                 _rtl92e_dm_check_tx_power_tracking_thermal(dev);
1043 }
1044
1045 static void _rtl92e_dm_cck_tx_power_adjust_tssi(struct net_device *dev,
1046                                                 bool bInCH14)
1047 {
1048         u32 TempVal;
1049         struct r8192_priv *priv = rtllib_priv(dev);
1050         u8 attenuation = (u8)priv->CCKPresentAttentuation;
1051
1052         TempVal = 0;
1053         if (!bInCH14) {
1054                 TempVal = (u32)(dm_cck_tx_bb_gain[attenuation][0] +
1055                           (dm_cck_tx_bb_gain[attenuation][1] << 8));
1056
1057                 rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1058                 TempVal = (u32)((dm_cck_tx_bb_gain[attenuation][2]) +
1059                           (dm_cck_tx_bb_gain[attenuation][3] << 8) +
1060                           (dm_cck_tx_bb_gain[attenuation][4] << 16)+
1061                           (dm_cck_tx_bb_gain[attenuation][5] << 24));
1062                 rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1063                 TempVal = (u32)(dm_cck_tx_bb_gain[attenuation][6] +
1064                           (dm_cck_tx_bb_gain[attenuation][7] << 8));
1065
1066                 rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1067         } else {
1068                 TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][0]) +
1069                           (dm_cck_tx_bb_gain_ch14[attenuation][1] << 8));
1070
1071                 rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1072                 TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][2]) +
1073                           (dm_cck_tx_bb_gain_ch14[attenuation][3] << 8) +
1074                           (dm_cck_tx_bb_gain_ch14[attenuation][4] << 16)+
1075                           (dm_cck_tx_bb_gain_ch14[attenuation][5] << 24));
1076                 rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1077                 TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][6]) +
1078                           (dm_cck_tx_bb_gain_ch14[attenuation][7] << 8));
1079
1080                 rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1081         }
1082 }
1083
1084 static void _rtl92e_dm_cck_tx_power_adjust_thermal_meter(struct net_device *dev,
1085                                                          bool bInCH14)
1086 {
1087         u32 TempVal;
1088         struct r8192_priv *priv = rtllib_priv(dev);
1089
1090         TempVal = 0;
1091         if (!bInCH14) {
1092                 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] +
1093                           (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1] << 8);
1094                 rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1095                 RT_TRACE(COMP_POWER_TRACKING,
1096                          "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter1,
1097                          TempVal);
1098                 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] +
1099                           (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3] << 8) +
1100                           (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4] << 16)+
1101                           (CCKSwingTable_Ch1_Ch13[priv->CCK_index][5] << 24);
1102                 rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1103                 RT_TRACE(COMP_POWER_TRACKING,
1104                          "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter2,
1105                          TempVal);
1106                 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] +
1107                           (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7] << 8);
1108
1109                 rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1110                 RT_TRACE(COMP_POWER_TRACKING,
1111                          "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_DebugPort,
1112                          TempVal);
1113         } else {
1114                 TempVal = CCKSwingTable_Ch14[priv->CCK_index][0] +
1115                           (CCKSwingTable_Ch14[priv->CCK_index][1] << 8);
1116
1117                 rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1118                 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1119                         rCCK0_TxFilter1, TempVal);
1120                 TempVal = CCKSwingTable_Ch14[priv->CCK_index][2] +
1121                           (CCKSwingTable_Ch14[priv->CCK_index][3] << 8) +
1122                           (CCKSwingTable_Ch14[priv->CCK_index][4] << 16)+
1123                           (CCKSwingTable_Ch14[priv->CCK_index][5] << 24);
1124                 rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1125                 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1126                         rCCK0_TxFilter2, TempVal);
1127                 TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] +
1128                           (CCKSwingTable_Ch14[priv->CCK_index][7]<<8);
1129
1130                 rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1131                 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1132                         rCCK0_DebugPort, TempVal);
1133         }
1134 }
1135
1136 void rtl92e_dm_cck_txpower_adjust(struct net_device *dev, bool binch14)
1137 {
1138         struct r8192_priv *priv = rtllib_priv(dev);
1139
1140         if (priv->IC_Cut >= IC_VersionCut_D)
1141                 _rtl92e_dm_cck_tx_power_adjust_tssi(dev, binch14);
1142         else
1143                 _rtl92e_dm_cck_tx_power_adjust_thermal_meter(dev, binch14);
1144 }
1145
1146 static void _rtl92e_dm_tx_power_reset_recovery(struct net_device *dev)
1147 {
1148         struct r8192_priv *priv = rtllib_priv(dev);
1149
1150         RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n");
1151         rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, bMaskDWord,
1152                           dm_tx_bb_gain[priv->rfa_txpowertrackingindex]);
1153         RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n",
1154                  dm_tx_bb_gain[priv->rfa_txpowertrackingindex]);
1155         RT_TRACE(COMP_POWER_TRACKING,
1156                  "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n",
1157                  priv->rfa_txpowertrackingindex);
1158         RT_TRACE(COMP_POWER_TRACKING,
1159                  "Reset Recovery : RF A I/Q Amplify Gain is %d\n",
1160                  dm_tx_bb_gain_idx_to_amplify(priv->rfa_txpowertrackingindex));
1161         RT_TRACE(COMP_POWER_TRACKING,
1162                  "Reset Recovery: CCK Attenuation is %d dB\n",
1163                  priv->CCKPresentAttentuation);
1164         rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
1165
1166         rtl92e_set_bb_reg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord,
1167                           dm_tx_bb_gain[priv->rfc_txpowertrackingindex]);
1168         RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n",
1169                  dm_tx_bb_gain[priv->rfc_txpowertrackingindex]);
1170         RT_TRACE(COMP_POWER_TRACKING,
1171                  "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n",
1172                  priv->rfc_txpowertrackingindex);
1173         RT_TRACE(COMP_POWER_TRACKING,
1174                  "Reset Recovery : RF C I/Q Amplify Gain is %d\n",
1175                  dm_tx_bb_gain_idx_to_amplify(priv->rfc_txpowertrackingindex));
1176 }
1177
1178 void rtl92e_dm_restore_state(struct net_device *dev)
1179 {
1180         struct r8192_priv *priv = rtllib_priv(dev);
1181         u32     reg_ratr = priv->rate_adaptive.last_ratr;
1182         u32 ratr_value;
1183
1184         if (!priv->up) {
1185                 RT_TRACE(COMP_RATE,
1186                          "<---- rtl92e_dm_restore_state(): driver is going to unload\n");
1187                 return;
1188         }
1189
1190         if (priv->rate_adaptive.rate_adaptive_disabled)
1191                 return;
1192         if (!(priv->rtllib->mode == WIRELESS_MODE_N_24G ||
1193               priv->rtllib->mode == WIRELESS_MODE_N_5G))
1194                 return;
1195         ratr_value = reg_ratr;
1196         if (priv->rf_type == RF_1T2R)
1197                 ratr_value &= ~(RATE_ALL_OFDM_2SS);
1198         rtl92e_writel(dev, RATR0, ratr_value);
1199         rtl92e_writeb(dev, UFWP, 1);
1200         if (priv->btxpower_trackingInit && priv->btxpower_tracking)
1201                 _rtl92e_dm_tx_power_reset_recovery(dev);
1202
1203         _rtl92e_dm_bb_initialgain_restore(dev);
1204
1205 }
1206
1207 static void _rtl92e_dm_bb_initialgain_restore(struct net_device *dev)
1208 {
1209         struct r8192_priv *priv = rtllib_priv(dev);
1210         u32 bit_mask = 0x7f;
1211
1212         if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1213                 return;
1214
1215         rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8);
1216         rtl92e_set_bb_reg(dev, rOFDM0_XAAGCCore1, bit_mask,
1217                           (u32)priv->initgain_backup.xaagccore1);
1218         rtl92e_set_bb_reg(dev, rOFDM0_XBAGCCore1, bit_mask,
1219                           (u32)priv->initgain_backup.xbagccore1);
1220         rtl92e_set_bb_reg(dev, rOFDM0_XCAGCCore1, bit_mask,
1221                           (u32)priv->initgain_backup.xcagccore1);
1222         rtl92e_set_bb_reg(dev, rOFDM0_XDAGCCore1, bit_mask,
1223                           (u32)priv->initgain_backup.xdagccore1);
1224         bit_mask  = bMaskByte2;
1225         rtl92e_set_bb_reg(dev, rCCK0_CCA, bit_mask,
1226                           (u32)priv->initgain_backup.cca);
1227
1228         RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n",
1229                  priv->initgain_backup.xaagccore1);
1230         RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n",
1231                  priv->initgain_backup.xbagccore1);
1232         RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n",
1233                  priv->initgain_backup.xcagccore1);
1234         RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n",
1235                  priv->initgain_backup.xdagccore1);
1236         RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n",
1237                  priv->initgain_backup.cca);
1238         rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x1);
1239
1240 }
1241
1242 void rtl92e_dm_backup_state(struct net_device *dev)
1243 {
1244         struct r8192_priv *priv = rtllib_priv(dev);
1245         u32 bit_mask = bMaskByte0;
1246
1247         priv->bswitch_fsync  = false;
1248         priv->bfsync_processing = false;
1249
1250         if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1251                 return;
1252
1253         rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8);
1254         priv->initgain_backup.xaagccore1 = (u8)rtl92e_get_bb_reg(dev, rOFDM0_XAAGCCore1, bit_mask);
1255         priv->initgain_backup.xbagccore1 = (u8)rtl92e_get_bb_reg(dev, rOFDM0_XBAGCCore1, bit_mask);
1256         priv->initgain_backup.xcagccore1 = (u8)rtl92e_get_bb_reg(dev, rOFDM0_XCAGCCore1, bit_mask);
1257         priv->initgain_backup.xdagccore1 = (u8)rtl92e_get_bb_reg(dev, rOFDM0_XDAGCCore1, bit_mask);
1258         bit_mask  = bMaskByte2;
1259         priv->initgain_backup.cca = (u8)rtl92e_get_bb_reg(dev, rCCK0_CCA, bit_mask);
1260
1261         RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n",
1262                  priv->initgain_backup.xaagccore1);
1263         RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n",
1264                  priv->initgain_backup.xbagccore1);
1265         RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n",
1266                  priv->initgain_backup.xcagccore1);
1267         RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n",
1268                  priv->initgain_backup.xdagccore1);
1269         RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n",
1270                  priv->initgain_backup.cca);
1271 }
1272
1273 static void _rtl92e_dm_dig_init(struct net_device *dev)
1274 {
1275         struct r8192_priv *priv = rtllib_priv(dev);
1276
1277         dm_digtable.dig_enable_flag     = true;
1278
1279         dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI;
1280
1281         dm_digtable.dig_algorithm_switch = 0;
1282
1283         dm_digtable.dig_state           = DM_STA_DIG_MAX;
1284         dm_digtable.dig_highpwr_state   = DM_STA_DIG_MAX;
1285         dm_digtable.CurSTAConnectState = DIG_STA_DISCONNECT;
1286         dm_digtable.PreSTAConnectState = DIG_STA_DISCONNECT;
1287
1288         dm_digtable.rssi_low_thresh     = DM_DIG_THRESH_LOW;
1289         dm_digtable.rssi_high_thresh    = DM_DIG_THRESH_HIGH;
1290
1291         dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
1292         dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
1293
1294         dm_digtable.rssi_val = 50;
1295         dm_digtable.backoff_val = DM_DIG_BACKOFF;
1296         dm_digtable.rx_gain_range_max = DM_DIG_MAX;
1297         if (priv->CustomerID == RT_CID_819x_Netcore)
1298                 dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore;
1299         else
1300                 dm_digtable.rx_gain_range_min = DM_DIG_MIN;
1301 }
1302
1303 static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev)
1304 {
1305
1306         if (dm_digtable.dig_enable_flag == false)
1307                 return;
1308
1309         if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
1310                 _rtl92e_dm_ctrl_initgain_byrssi_false_alarm(dev);
1311         else if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1312                 _rtl92e_dm_ctrl_initgain_byrssi_driver(dev);
1313         else
1314                 return;
1315 }
1316
1317 /*-----------------------------------------------------------------------------
1318  * Function:    dm_CtrlInitGainBeforeConnectByRssiAndFalseAlarm()
1319  *
1320  * Overview:    Driver monitor RSSI and False Alarm to change initial gain.
1321                         Only change initial gain during link in progress.
1322  *
1323  * Input:               IN      PADAPTER        pAdapter
1324  *
1325  * Output:              NONE
1326  *
1327  * Return:              NONE
1328  *
1329  * Revised History:
1330  *      When            Who             Remark
1331  *      03/04/2009      hpfan   Create Version 0.
1332  *
1333  *---------------------------------------------------------------------------*/
1334
1335 static void _rtl92e_dm_ctrl_initgain_byrssi_driver(struct net_device *dev)
1336 {
1337         struct r8192_priv *priv = rtllib_priv(dev);
1338         u8 i;
1339         static u8       fw_dig;
1340
1341         if (dm_digtable.dig_enable_flag == false)
1342                 return;
1343
1344         if (dm_digtable.dig_algorithm_switch)
1345                 fw_dig = 0;
1346         if (fw_dig <= 3) {
1347                 for (i = 0; i < 3; i++)
1348                         rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8);
1349                 fw_dig++;
1350                 dm_digtable.dig_state = DM_STA_DIG_OFF;
1351         }
1352
1353         if (priv->rtllib->state == RTLLIB_LINKED)
1354                 dm_digtable.CurSTAConnectState = DIG_STA_CONNECT;
1355         else
1356                 dm_digtable.CurSTAConnectState = DIG_STA_DISCONNECT;
1357
1358
1359         dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
1360         _rtl92e_dm_initial_gain(dev);
1361         _rtl92e_dm_pd_th(dev);
1362         _rtl92e_dm_cs_ratio(dev);
1363         if (dm_digtable.dig_algorithm_switch)
1364                 dm_digtable.dig_algorithm_switch = 0;
1365         dm_digtable.PreSTAConnectState = dm_digtable.CurSTAConnectState;
1366
1367 }
1368
1369 static void _rtl92e_dm_ctrl_initgain_byrssi_false_alarm(struct net_device *dev)
1370 {
1371         struct r8192_priv *priv = rtllib_priv(dev);
1372         static u32 reset_cnt;
1373         u8 i;
1374
1375         if (dm_digtable.dig_enable_flag == false)
1376                 return;
1377
1378         if (dm_digtable.dig_algorithm_switch) {
1379                 dm_digtable.dig_state = DM_STA_DIG_MAX;
1380                 for (i = 0; i < 3; i++)
1381                         rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x1);
1382                 dm_digtable.dig_algorithm_switch = 0;
1383         }
1384
1385         if (priv->rtllib->state != RTLLIB_LINKED)
1386                 return;
1387
1388         if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) &&
1389                 (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh))
1390                 return;
1391         if (priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh) {
1392                 if (dm_digtable.dig_state == DM_STA_DIG_OFF &&
1393                         (priv->reset_count == reset_cnt))
1394                         return;
1395                 reset_cnt = priv->reset_count;
1396
1397                 dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
1398                 dm_digtable.dig_state = DM_STA_DIG_OFF;
1399
1400                 rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8);
1401
1402                 rtl92e_writeb(dev, rOFDM0_XAAGCCore1, 0x17);
1403                 rtl92e_writeb(dev, rOFDM0_XBAGCCore1, 0x17);
1404                 rtl92e_writeb(dev, rOFDM0_XCAGCCore1, 0x17);
1405                 rtl92e_writeb(dev, rOFDM0_XDAGCCore1, 0x17);
1406
1407                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1408                         rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x00);
1409                 else
1410                         rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x42);
1411
1412                 rtl92e_writeb(dev, 0xa0a, 0x08);
1413
1414                 return;
1415         }
1416
1417         if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) {
1418                 u8 reset_flag = 0;
1419
1420                 if (dm_digtable.dig_state == DM_STA_DIG_ON &&
1421                     (priv->reset_count == reset_cnt)) {
1422                         _rtl92e_dm_ctrl_initgain_byrssi_highpwr(dev);
1423                         return;
1424                 }
1425                 if (priv->reset_count != reset_cnt)
1426                         reset_flag = 1;
1427
1428                 reset_cnt = priv->reset_count;
1429
1430                 dm_digtable.dig_state = DM_STA_DIG_ON;
1431
1432                 if (reset_flag == 1) {
1433                         rtl92e_writeb(dev, rOFDM0_XAAGCCore1, 0x2c);
1434                         rtl92e_writeb(dev, rOFDM0_XBAGCCore1, 0x2c);
1435                         rtl92e_writeb(dev, rOFDM0_XCAGCCore1, 0x2c);
1436                         rtl92e_writeb(dev, rOFDM0_XDAGCCore1, 0x2c);
1437                 } else {
1438                         rtl92e_writeb(dev, rOFDM0_XAAGCCore1, 0x20);
1439                         rtl92e_writeb(dev, rOFDM0_XBAGCCore1, 0x20);
1440                         rtl92e_writeb(dev, rOFDM0_XCAGCCore1, 0x20);
1441                         rtl92e_writeb(dev, rOFDM0_XDAGCCore1, 0x20);
1442                 }
1443
1444                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1445                         rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x20);
1446                 else
1447                         rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x44);
1448
1449                 rtl92e_writeb(dev, 0xa0a, 0xcd);
1450
1451                 rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x1);
1452         }
1453         _rtl92e_dm_ctrl_initgain_byrssi_highpwr(dev);
1454 }
1455
1456
1457 static void _rtl92e_dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev)
1458 {
1459         struct r8192_priv *priv = rtllib_priv(dev);
1460         static u32 reset_cnt_highpwr;
1461
1462         if ((priv->undecorated_smoothed_pwdb >
1463              dm_digtable.rssi_high_power_lowthresh) &&
1464             (priv->undecorated_smoothed_pwdb <
1465              dm_digtable.rssi_high_power_highthresh))
1466                 return;
1467
1468         if (priv->undecorated_smoothed_pwdb >=
1469             dm_digtable.rssi_high_power_highthresh) {
1470                 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON &&
1471                         (priv->reset_count == reset_cnt_highpwr))
1472                         return;
1473                 dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
1474
1475                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1476                         rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x10);
1477                 else
1478                         rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x43);
1479         } else {
1480                 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF &&
1481                         (priv->reset_count == reset_cnt_highpwr))
1482                         return;
1483                 dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
1484
1485                 if ((priv->undecorated_smoothed_pwdb <
1486                      dm_digtable.rssi_high_power_lowthresh) &&
1487                     (priv->undecorated_smoothed_pwdb >=
1488                     dm_digtable.rssi_high_thresh)) {
1489                         if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1490                                 rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x20);
1491                         else
1492                                 rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x44);
1493                 }
1494         }
1495         reset_cnt_highpwr = priv->reset_count;
1496 }
1497
1498 static void _rtl92e_dm_initial_gain(struct net_device *dev)
1499 {
1500         struct r8192_priv *priv = rtllib_priv(dev);
1501         u8 initial_gain = 0;
1502         static u8 initialized, force_write;
1503         static u32 reset_cnt;
1504
1505         if (dm_digtable.dig_algorithm_switch) {
1506                 initialized = 0;
1507                 reset_cnt = 0;
1508         }
1509
1510         if (rtllib_act_scanning(priv->rtllib, true) == true) {
1511                 force_write = 1;
1512                 return;
1513         }
1514
1515         if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) {
1516                 if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) {
1517                         long gain_range = dm_digtable.rssi_val + 10 -
1518                                           dm_digtable.backoff_val;
1519                         gain_range = clamp_t(long, gain_range,
1520                                              dm_digtable.rx_gain_range_min,
1521                                              dm_digtable.rx_gain_range_max);
1522                         dm_digtable.cur_ig_value = gain_range;
1523                 } else {
1524                         if (dm_digtable.cur_ig_value == 0)
1525                                 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1526                         else
1527                                 dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
1528                 }
1529         } else {
1530                 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1531                 dm_digtable.pre_ig_value = 0;
1532         }
1533
1534         if (priv->reset_count != reset_cnt) {
1535                 force_write = 1;
1536                 reset_cnt = priv->reset_count;
1537         }
1538
1539         if (dm_digtable.pre_ig_value != rtl92e_readb(dev, rOFDM0_XAAGCCore1))
1540                 force_write = 1;
1541
1542         if ((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
1543             || !initialized || force_write) {
1544                 initial_gain = (u8)dm_digtable.cur_ig_value;
1545                 rtl92e_writeb(dev, rOFDM0_XAAGCCore1, initial_gain);
1546                 rtl92e_writeb(dev, rOFDM0_XBAGCCore1, initial_gain);
1547                 rtl92e_writeb(dev, rOFDM0_XCAGCCore1, initial_gain);
1548                 rtl92e_writeb(dev, rOFDM0_XDAGCCore1, initial_gain);
1549                 dm_digtable.pre_ig_value = dm_digtable.cur_ig_value;
1550                 initialized = 1;
1551                 force_write = 0;
1552         }
1553 }
1554
1555 static void _rtl92e_dm_pd_th(struct net_device *dev)
1556 {
1557         struct r8192_priv *priv = rtllib_priv(dev);
1558         static u8 initialized, force_write;
1559         static u32 reset_cnt;
1560
1561         if (dm_digtable.dig_algorithm_switch) {
1562                 initialized = 0;
1563                 reset_cnt = 0;
1564         }
1565
1566         if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) {
1567                 if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) {
1568                         if (dm_digtable.rssi_val >=
1569                             dm_digtable.rssi_high_power_highthresh)
1570                                 dm_digtable.curpd_thstate =
1571                                                         DIG_PD_AT_HIGH_POWER;
1572                         else if (dm_digtable.rssi_val <=
1573                                  dm_digtable.rssi_low_thresh)
1574                                 dm_digtable.curpd_thstate =
1575                                                         DIG_PD_AT_LOW_POWER;
1576                         else if ((dm_digtable.rssi_val >=
1577                                   dm_digtable.rssi_high_thresh) &&
1578                                  (dm_digtable.rssi_val <
1579                                   dm_digtable.rssi_high_power_lowthresh))
1580                                 dm_digtable.curpd_thstate =
1581                                                         DIG_PD_AT_NORMAL_POWER;
1582                         else
1583                                 dm_digtable.curpd_thstate =
1584                                                 dm_digtable.prepd_thstate;
1585                 } else {
1586                         dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1587                 }
1588         } else {
1589                 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1590         }
1591
1592         if (priv->reset_count != reset_cnt) {
1593                 force_write = 1;
1594                 reset_cnt = priv->reset_count;
1595         }
1596
1597         if ((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
1598             (initialized <= 3) || force_write) {
1599                 if (dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) {
1600                         if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1601                                 rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x00);
1602                         else
1603                                 rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x42);
1604                 } else if (dm_digtable.curpd_thstate ==
1605                            DIG_PD_AT_NORMAL_POWER) {
1606                         if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1607                                 rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x20);
1608                         else
1609                                 rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x44);
1610                 } else if (dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) {
1611                         if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1612                                 rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x10);
1613                         else
1614                                 rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x43);
1615                 }
1616                 dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
1617                 if (initialized <= 3)
1618                         initialized++;
1619                 force_write = 0;
1620         }
1621 }
1622
1623 static void _rtl92e_dm_cs_ratio(struct net_device *dev)
1624 {
1625         struct r8192_priv *priv = rtllib_priv(dev);
1626         static u8 initialized, force_write;
1627         static u32 reset_cnt;
1628
1629         if (dm_digtable.dig_algorithm_switch) {
1630                 initialized = 0;
1631                 reset_cnt = 0;
1632         }
1633
1634         if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) {
1635                 if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) {
1636                         if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)
1637                                 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1638                         else if (dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh)
1639                                 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
1640                         else
1641                                 dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
1642                 } else {
1643                         dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1644                 }
1645         } else {
1646                 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1647         }
1648
1649         if (priv->reset_count != reset_cnt) {
1650                 force_write = 1;
1651                 reset_cnt = priv->reset_count;
1652         }
1653
1654
1655         if ((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
1656             !initialized || force_write) {
1657                 if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
1658                         rtl92e_writeb(dev, 0xa0a, 0x08);
1659                 else if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER)
1660                         rtl92e_writeb(dev, 0xa0a, 0xcd);
1661                 dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
1662                 initialized = 1;
1663                 force_write = 0;
1664         }
1665 }
1666
1667 void rtl92e_dm_init_edca_turbo(struct net_device *dev)
1668 {
1669         struct r8192_priv *priv = rtllib_priv(dev);
1670
1671         priv->bcurrent_turbo_EDCA = false;
1672         priv->rtllib->bis_any_nonbepkts = false;
1673         priv->bis_cur_rdlstate = false;
1674 }
1675
1676 static void _rtl92e_dm_check_edca_turbo(struct net_device *dev)
1677 {
1678         struct r8192_priv *priv = rtllib_priv(dev);
1679         struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
1680
1681         static unsigned long lastTxOkCnt;
1682         static unsigned long lastRxOkCnt;
1683         unsigned long curTxOkCnt = 0;
1684         unsigned long curRxOkCnt = 0;
1685
1686         if (priv->rtllib->iw_mode == IW_MODE_ADHOC)
1687                 goto dm_CheckEdcaTurbo_EXIT;
1688         if (priv->rtllib->state != RTLLIB_LINKED)
1689                 goto dm_CheckEdcaTurbo_EXIT;
1690         if (priv->rtllib->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
1691                 goto dm_CheckEdcaTurbo_EXIT;
1692
1693         {
1694                 u8 *peername[11] = {
1695                         "unknown", "realtek_90", "realtek_92se", "broadcom",
1696                         "ralink", "atheros", "cisco", "marvell", "92u_softap",
1697                         "self_softap"
1698                 };
1699                 static int wb_tmp;
1700
1701                 if (wb_tmp == 0) {
1702                         netdev_info(dev,
1703                                     "%s():iot peer is %s, bssid: %pM\n",
1704                                     __func__, peername[pHTInfo->IOTPeer],
1705                                     priv->rtllib->current_network.bssid);
1706                         wb_tmp = 1;
1707                 }
1708         }
1709         if (!priv->rtllib->bis_any_nonbepkts) {
1710                 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
1711                 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
1712                 if (pHTInfo->IOTAction & HT_IOT_ACT_EDCA_BIAS_ON_RX) {
1713                         if (curTxOkCnt > 4*curRxOkCnt) {
1714                                 if (priv->bis_cur_rdlstate ||
1715                                     !priv->bcurrent_turbo_EDCA) {
1716                                         rtl92e_writel(dev, EDCAPARA_BE,
1717                                                       edca_setting_UL[pHTInfo->IOTPeer]);
1718                                         priv->bis_cur_rdlstate = false;
1719                                 }
1720                         } else {
1721                                 if (!priv->bis_cur_rdlstate ||
1722                                     !priv->bcurrent_turbo_EDCA) {
1723                                         if (priv->rtllib->mode == WIRELESS_MODE_G)
1724                                                 rtl92e_writel(dev, EDCAPARA_BE,
1725                                                               edca_setting_DL_GMode[pHTInfo->IOTPeer]);
1726                                         else
1727                                                 rtl92e_writel(dev, EDCAPARA_BE,
1728                                                               edca_setting_DL[pHTInfo->IOTPeer]);
1729                                         priv->bis_cur_rdlstate = true;
1730                                 }
1731                         }
1732                         priv->bcurrent_turbo_EDCA = true;
1733                 } else {
1734                         if (curRxOkCnt > 4*curTxOkCnt) {
1735                                 if (!priv->bis_cur_rdlstate ||
1736                                     !priv->bcurrent_turbo_EDCA) {
1737                                         if (priv->rtllib->mode == WIRELESS_MODE_G)
1738                                                 rtl92e_writel(dev, EDCAPARA_BE,
1739                                                               edca_setting_DL_GMode[pHTInfo->IOTPeer]);
1740                                         else
1741                                                 rtl92e_writel(dev, EDCAPARA_BE,
1742                                                               edca_setting_DL[pHTInfo->IOTPeer]);
1743                                         priv->bis_cur_rdlstate = true;
1744                                 }
1745                         } else {
1746                                 if (priv->bis_cur_rdlstate ||
1747                                     !priv->bcurrent_turbo_EDCA) {
1748                                         rtl92e_writel(dev, EDCAPARA_BE,
1749                                                       edca_setting_UL[pHTInfo->IOTPeer]);
1750                                         priv->bis_cur_rdlstate = false;
1751                                 }
1752
1753                         }
1754
1755                         priv->bcurrent_turbo_EDCA = true;
1756                 }
1757         } else {
1758                  if (priv->bcurrent_turbo_EDCA) {
1759                         u8 tmp = AC0_BE;
1760
1761                         priv->rtllib->SetHwRegHandler(dev, HW_VAR_AC_PARAM,
1762                                                       (u8 *)(&tmp));
1763                         priv->bcurrent_turbo_EDCA = false;
1764                 }
1765         }
1766
1767
1768 dm_CheckEdcaTurbo_EXIT:
1769         priv->rtllib->bis_any_nonbepkts = false;
1770         lastTxOkCnt = priv->stats.txbytesunicast;
1771         lastRxOkCnt = priv->stats.rxbytesunicast;
1772 }
1773
1774 static void _rtl92e_dm_init_cts_to_self(struct net_device *dev)
1775 {
1776         struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
1777
1778         priv->rtllib->bCTSToSelfEnable = true;
1779 }
1780
1781 static void _rtl92e_dm_cts_to_self(struct net_device *dev)
1782 {
1783         struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
1784         struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
1785         static unsigned long lastTxOkCnt;
1786         static unsigned long lastRxOkCnt;
1787         unsigned long curTxOkCnt = 0;
1788         unsigned long curRxOkCnt = 0;
1789
1790         if (priv->rtllib->bCTSToSelfEnable != true) {
1791                 pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
1792                 return;
1793         }
1794         if (pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) {
1795                 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
1796                 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
1797                 if (curRxOkCnt > 4*curTxOkCnt)
1798                         pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
1799                 else
1800                         pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
1801
1802                 lastTxOkCnt = priv->stats.txbytesunicast;
1803                 lastRxOkCnt = priv->stats.rxbytesunicast;
1804         }
1805 }
1806
1807
1808 static void _rtl92e_dm_init_wa_broadcom_iot(struct net_device *dev)
1809 {
1810         struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
1811         struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
1812
1813         pHTInfo->bWAIotBroadcom = false;
1814         pHTInfo->WAIotTH = WAIotTHVal;
1815 }
1816
1817 static void _rtl92e_dm_check_rf_ctrl_gpio(void *data)
1818 {
1819         struct r8192_priv *priv = container_of_dwork_rsl(data,
1820                                   struct r8192_priv, gpio_change_rf_wq);
1821         struct net_device *dev = priv->rtllib->dev;
1822         u8 tmp1byte;
1823         enum rt_rf_power_state eRfPowerStateToSet;
1824         bool bActuallySet = false;
1825         char *argv[3];
1826         static char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh";
1827         static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin",
1828                                NULL};
1829
1830         bActuallySet = false;
1831
1832         if ((priv->up_first_time == 1) || (priv->being_init_adapter))
1833                 return;
1834
1835         if (priv->bfirst_after_down) {
1836                 priv->bfirst_after_down = true;
1837                 return;
1838         }
1839
1840         tmp1byte = rtl92e_readb(dev, GPI);
1841
1842         eRfPowerStateToSet = (tmp1byte&BIT1) ?  eRfOn : eRfOff;
1843
1844         if (priv->bHwRadioOff && (eRfPowerStateToSet == eRfOn)) {
1845                 RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio ON\n");
1846                 netdev_info(dev, "gpiochangeRF  - HW Radio ON\n");
1847                 priv->bHwRadioOff = false;
1848                 bActuallySet = true;
1849         } else if (!priv->bHwRadioOff && (eRfPowerStateToSet == eRfOff)) {
1850                 RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio OFF\n");
1851                 netdev_info(dev, "gpiochangeRF  - HW Radio OFF\n");
1852                 priv->bHwRadioOff = true;
1853                 bActuallySet = true;
1854         }
1855
1856         if (bActuallySet) {
1857                 mdelay(1000);
1858                 priv->bHwRfOffAction = 1;
1859                 rtl92e_set_rf_state(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
1860                 if (priv->bHwRadioOff)
1861                         argv[1] = "RFOFF";
1862                 else
1863                         argv[1] = "RFON";
1864
1865                 argv[0] = RadioPowerPath;
1866                 argv[2] = NULL;
1867                 call_usermodehelper(RadioPowerPath, argv, envp, UMH_WAIT_PROC);
1868         }
1869 }
1870
1871 void rtl92e_dm_rf_pathcheck_wq(void *data)
1872 {
1873         struct r8192_priv *priv = container_of_dwork_rsl(data,
1874                                   struct r8192_priv,
1875                                   rfpath_check_wq);
1876         struct net_device *dev = priv->rtllib->dev;
1877         u8 rfpath, i;
1878
1879         rfpath = rtl92e_readb(dev, 0xc04);
1880
1881         for (i = 0; i < RF90_PATH_MAX; i++) {
1882                 if (rfpath & (0x01<<i))
1883                         priv->brfpath_rxenable[i] = true;
1884                 else
1885                         priv->brfpath_rxenable[i] = false;
1886         }
1887         if (!DM_RxPathSelTable.Enable)
1888                 return;
1889
1890         _rtl92e_dm_rx_path_sel_byrssi(dev);
1891 }
1892
1893 static void _rtl92e_dm_init_rx_path_selection(struct net_device *dev)
1894 {
1895         u8 i;
1896         struct r8192_priv *priv = rtllib_priv(dev);
1897
1898         DM_RxPathSelTable.Enable = 1;
1899         DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low;
1900         DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH;
1901         if (priv->CustomerID == RT_CID_819x_Netcore)
1902                 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
1903         else
1904                 DM_RxPathSelTable.cck_method = CCK_Rx_Version_1;
1905         DM_RxPathSelTable.disabledRF = 0;
1906         for (i = 0; i < 4; i++) {
1907                 DM_RxPathSelTable.rf_rssi[i] = 50;
1908                 DM_RxPathSelTable.cck_pwdb_sta[i] = -64;
1909                 DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
1910         }
1911 }
1912
1913 #define PWDB_IN_RANGE   ((cur_cck_pwdb < tmp_cck_max_pwdb) &&   \
1914                         (cur_cck_pwdb > tmp_cck_sec_pwdb))
1915
1916 static void _rtl92e_dm_rx_path_sel_byrssi(struct net_device *dev)
1917 {
1918         struct r8192_priv *priv = rtllib_priv(dev);
1919         u8 i, max_rssi_index = 0, min_rssi_index = 0;
1920         u8 sec_rssi_index = 0, rf_num = 0;
1921         u8 tmp_max_rssi = 0, tmp_min_rssi = 0, tmp_sec_rssi = 0;
1922         u8 cck_default_Rx = 0x2;
1923         u8 cck_optional_Rx = 0x3;
1924         long tmp_cck_max_pwdb = 0, tmp_cck_min_pwdb = 0, tmp_cck_sec_pwdb = 0;
1925         u8 cck_rx_ver2_max_index = 0, cck_rx_ver2_min_index = 0;
1926         u8 cck_rx_ver2_sec_index = 0;
1927         u8 cur_rf_rssi;
1928         long cur_cck_pwdb;
1929         static u8 disabled_rf_cnt, cck_Rx_Path_initialized;
1930         u8 update_cck_rx_path;
1931
1932         if (priv->rf_type != RF_2T4R)
1933                 return;
1934
1935         if (!cck_Rx_Path_initialized) {
1936                 DM_RxPathSelTable.cck_Rx_path = (rtl92e_readb(dev, 0xa07)&0xf);
1937                 cck_Rx_Path_initialized = 1;
1938         }
1939
1940         DM_RxPathSelTable.disabledRF = 0xf;
1941         DM_RxPathSelTable.disabledRF &= ~(rtl92e_readb(dev, 0xc04));
1942
1943         if (priv->rtllib->mode == WIRELESS_MODE_B)
1944                 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
1945
1946         for (i = 0; i < RF90_PATH_MAX; i++) {
1947                 DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
1948
1949                 if (priv->brfpath_rxenable[i]) {
1950                         rf_num++;
1951                         cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i];
1952
1953                         if (rf_num == 1) {
1954                                 max_rssi_index = min_rssi_index = sec_rssi_index = i;
1955                                 tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
1956                         } else if (rf_num == 2) {
1957                                 if (cur_rf_rssi >= tmp_max_rssi) {
1958                                         tmp_max_rssi = cur_rf_rssi;
1959                                         max_rssi_index = i;
1960                                 } else {
1961                                         tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
1962                                         sec_rssi_index = min_rssi_index = i;
1963                                 }
1964                         } else {
1965                                 if (cur_rf_rssi > tmp_max_rssi) {
1966                                         tmp_sec_rssi = tmp_max_rssi;
1967                                         sec_rssi_index = max_rssi_index;
1968                                         tmp_max_rssi = cur_rf_rssi;
1969                                         max_rssi_index = i;
1970                                 } else if (cur_rf_rssi == tmp_max_rssi) {
1971                                         tmp_sec_rssi = cur_rf_rssi;
1972                                         sec_rssi_index = i;
1973                                 } else if ((cur_rf_rssi < tmp_max_rssi) &&
1974                                            (cur_rf_rssi > tmp_sec_rssi)) {
1975                                         tmp_sec_rssi = cur_rf_rssi;
1976                                         sec_rssi_index = i;
1977                                 } else if (cur_rf_rssi == tmp_sec_rssi) {
1978                                         if (tmp_sec_rssi == tmp_min_rssi) {
1979                                                 tmp_sec_rssi = cur_rf_rssi;
1980                                                 sec_rssi_index = i;
1981                                         }
1982                                 } else if ((cur_rf_rssi < tmp_sec_rssi) &&
1983                                            (cur_rf_rssi > tmp_min_rssi)) {
1984                                         ;
1985                                 } else if (cur_rf_rssi == tmp_min_rssi) {
1986                                         if (tmp_sec_rssi == tmp_min_rssi) {
1987                                                 tmp_min_rssi = cur_rf_rssi;
1988                                                 min_rssi_index = i;
1989                                         }
1990                                 } else if (cur_rf_rssi < tmp_min_rssi) {
1991                                         tmp_min_rssi = cur_rf_rssi;
1992                                         min_rssi_index = i;
1993                                 }
1994                         }
1995                 }
1996         }
1997
1998         rf_num = 0;
1999         if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) {
2000                 for (i = 0; i < RF90_PATH_MAX; i++) {
2001                         if (priv->brfpath_rxenable[i]) {
2002                                 rf_num++;
2003                                 cur_cck_pwdb =
2004                                          DM_RxPathSelTable.cck_pwdb_sta[i];
2005
2006                                 if (rf_num == 1) {
2007                                         cck_rx_ver2_max_index = i;
2008                                         cck_rx_ver2_min_index = i;
2009                                         cck_rx_ver2_sec_index = i;
2010                                         tmp_cck_max_pwdb = cur_cck_pwdb;
2011                                         tmp_cck_min_pwdb = cur_cck_pwdb;
2012                                         tmp_cck_sec_pwdb = cur_cck_pwdb;
2013                                 } else if (rf_num == 2) {
2014                                         if (cur_cck_pwdb >= tmp_cck_max_pwdb) {
2015                                                 tmp_cck_max_pwdb = cur_cck_pwdb;
2016                                                 cck_rx_ver2_max_index = i;
2017                                         } else {
2018                                                 tmp_cck_sec_pwdb = cur_cck_pwdb;
2019                                                 tmp_cck_min_pwdb = cur_cck_pwdb;
2020                                                 cck_rx_ver2_sec_index = i;
2021                                                 cck_rx_ver2_min_index = i;
2022                                         }
2023                                 } else {
2024                                         if (cur_cck_pwdb > tmp_cck_max_pwdb) {
2025                                                 tmp_cck_sec_pwdb =
2026                                                          tmp_cck_max_pwdb;
2027                                                 cck_rx_ver2_sec_index =
2028                                                          cck_rx_ver2_max_index;
2029                                                 tmp_cck_max_pwdb = cur_cck_pwdb;
2030                                                 cck_rx_ver2_max_index = i;
2031                                         } else if (cur_cck_pwdb ==
2032                                                    tmp_cck_max_pwdb) {
2033                                                 tmp_cck_sec_pwdb = cur_cck_pwdb;
2034                                                 cck_rx_ver2_sec_index = i;
2035                                         } else if (PWDB_IN_RANGE) {
2036                                                 tmp_cck_sec_pwdb = cur_cck_pwdb;
2037                                                 cck_rx_ver2_sec_index = i;
2038                                         } else if (cur_cck_pwdb ==
2039                                                    tmp_cck_sec_pwdb) {
2040                                                 if (tmp_cck_sec_pwdb ==
2041                                                     tmp_cck_min_pwdb) {
2042                                                         tmp_cck_sec_pwdb =
2043                                                                  cur_cck_pwdb;
2044                                                         cck_rx_ver2_sec_index =
2045                                                                  i;
2046                                                 }
2047                                         } else if ((cur_cck_pwdb < tmp_cck_sec_pwdb) &&
2048                                                    (cur_cck_pwdb > tmp_cck_min_pwdb)) {
2049                                                 ;
2050                                         } else if (cur_cck_pwdb == tmp_cck_min_pwdb) {
2051                                                 if (tmp_cck_sec_pwdb == tmp_cck_min_pwdb) {
2052                                                         tmp_cck_min_pwdb = cur_cck_pwdb;
2053                                                         cck_rx_ver2_min_index = i;
2054                                                 }
2055                                         } else if (cur_cck_pwdb < tmp_cck_min_pwdb) {
2056                                                 tmp_cck_min_pwdb = cur_cck_pwdb;
2057                                                 cck_rx_ver2_min_index = i;
2058                                         }
2059                                 }
2060
2061                         }
2062                 }
2063         }
2064
2065         update_cck_rx_path = 0;
2066         if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) {
2067                 cck_default_Rx = cck_rx_ver2_max_index;
2068                 cck_optional_Rx = cck_rx_ver2_sec_index;
2069                 if (tmp_cck_max_pwdb != -64)
2070                         update_cck_rx_path = 1;
2071         }
2072
2073         if (tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2) {
2074                 if ((tmp_max_rssi - tmp_min_rssi) >=
2075                      DM_RxPathSelTable.diff_TH) {
2076                         DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] =
2077                                  tmp_max_rssi+5;
2078                         rtl92e_set_bb_reg(dev, rOFDM0_TRxPathEnable,
2079                                           0x1<<min_rssi_index, 0x0);
2080                         rtl92e_set_bb_reg(dev, rOFDM1_TRxPathEnable,
2081                                           0x1<<min_rssi_index, 0x0);
2082                         disabled_rf_cnt++;
2083                 }
2084                 if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_1) {
2085                         cck_default_Rx = max_rssi_index;
2086                         cck_optional_Rx = sec_rssi_index;
2087                         if (tmp_max_rssi)
2088                                 update_cck_rx_path = 1;
2089                 }
2090         }
2091
2092         if (update_cck_rx_path) {
2093                 DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2) |
2094                                                 (cck_optional_Rx);
2095                 rtl92e_set_bb_reg(dev, rCCK0_AFESetting, 0x0f000000,
2096                                   DM_RxPathSelTable.cck_Rx_path);
2097         }
2098
2099         if (DM_RxPathSelTable.disabledRF) {
2100                 for (i = 0; i < 4; i++) {
2101                         if ((DM_RxPathSelTable.disabledRF>>i) & 0x1) {
2102                                 if (tmp_max_rssi >=
2103                                     DM_RxPathSelTable.rf_enable_rssi_th[i]) {
2104                                         rtl92e_set_bb_reg(dev,
2105                                                           rOFDM0_TRxPathEnable,
2106                                                           0x1 << i, 0x1);
2107                                         rtl92e_set_bb_reg(dev,
2108                                                           rOFDM1_TRxPathEnable,
2109                                                           0x1 << i, 0x1);
2110                                         DM_RxPathSelTable.rf_enable_rssi_th[i]
2111                                                  = 100;
2112                                         disabled_rf_cnt--;
2113                                 }
2114                         }
2115                 }
2116         }
2117 }
2118
2119 static void _rtl92e_dm_check_rx_path_selection(struct net_device *dev)
2120 {
2121         struct r8192_priv *priv = rtllib_priv(dev);
2122
2123         schedule_delayed_work(&priv->rfpath_check_wq, 0);
2124 }
2125
2126
2127 static void _rtl92e_dm_init_fsync(struct net_device *dev)
2128 {
2129         struct r8192_priv *priv = rtllib_priv(dev);
2130
2131         priv->rtllib->fsync_time_interval = 500;
2132         priv->rtllib->fsync_rate_bitmap = 0x0f000800;
2133         priv->rtllib->fsync_rssi_threshold = 30;
2134         priv->rtllib->bfsync_enable = false;
2135         priv->rtllib->fsync_multiple_timeinterval = 3;
2136         priv->rtllib->fsync_firstdiff_ratethreshold = 100;
2137         priv->rtllib->fsync_seconddiff_ratethreshold = 200;
2138         priv->rtllib->fsync_state = Default_Fsync;
2139         priv->framesyncMonitor = 1;
2140
2141         setup_timer(&priv->fsync_timer, _rtl92e_dm_fsync_timer_callback,
2142                     (unsigned long)dev);
2143 }
2144
2145
2146 static void _rtl92e_dm_deinit_fsync(struct net_device *dev)
2147 {
2148         struct r8192_priv *priv = rtllib_priv(dev);
2149
2150         del_timer_sync(&priv->fsync_timer);
2151 }
2152
2153 static void _rtl92e_dm_fsync_timer_callback(unsigned long data)
2154 {
2155         struct net_device *dev = (struct net_device *)data;
2156         struct r8192_priv *priv = rtllib_priv((struct net_device *)data);
2157         u32 rate_index, rate_count = 0, rate_count_diff = 0;
2158         bool            bSwitchFromCountDiff = false;
2159         bool            bDoubleTimeInterval = false;
2160
2161         if (priv->rtllib->state == RTLLIB_LINKED &&
2162             priv->rtllib->bfsync_enable &&
2163             (priv->rtllib->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) {
2164                 u32 rate_bitmap;
2165
2166                 for (rate_index = 0; rate_index <= 27; rate_index++) {
2167                         rate_bitmap  = 1 << rate_index;
2168                         if (priv->rtllib->fsync_rate_bitmap &  rate_bitmap)
2169                                 rate_count +=
2170                                    priv->stats.received_rate_histogram[1]
2171                                    [rate_index];
2172                 }
2173
2174                 if (rate_count < priv->rate_record)
2175                         rate_count_diff = 0xffffffff - rate_count +
2176                                           priv->rate_record;
2177                 else
2178                         rate_count_diff = rate_count - priv->rate_record;
2179                 if (rate_count_diff < priv->rateCountDiffRecord) {
2180
2181                         u32 DiffNum = priv->rateCountDiffRecord -
2182                                       rate_count_diff;
2183                         if (DiffNum >=
2184                             priv->rtllib->fsync_seconddiff_ratethreshold)
2185                                 priv->ContinueDiffCount++;
2186                         else
2187                                 priv->ContinueDiffCount = 0;
2188
2189                         if (priv->ContinueDiffCount >= 2) {
2190                                 bSwitchFromCountDiff = true;
2191                                 priv->ContinueDiffCount = 0;
2192                         }
2193                 } else {
2194                         priv->ContinueDiffCount = 0;
2195                 }
2196
2197                 if (rate_count_diff <=
2198                     priv->rtllib->fsync_firstdiff_ratethreshold) {
2199                         bSwitchFromCountDiff = true;
2200                         priv->ContinueDiffCount = 0;
2201                 }
2202                 priv->rate_record = rate_count;
2203                 priv->rateCountDiffRecord = rate_count_diff;
2204                 RT_TRACE(COMP_HALDM,
2205                          "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n",
2206                          priv->rate_record, rate_count, rate_count_diff,
2207                          priv->bswitch_fsync);
2208                 if (priv->undecorated_smoothed_pwdb >
2209                     priv->rtllib->fsync_rssi_threshold &&
2210                     bSwitchFromCountDiff) {
2211                         bDoubleTimeInterval = true;
2212                         priv->bswitch_fsync = !priv->bswitch_fsync;
2213                         if (priv->bswitch_fsync) {
2214                                 rtl92e_writeb(dev, 0xC36, 0x1c);
2215                                 rtl92e_writeb(dev, 0xC3e, 0x90);
2216                         } else {
2217                                 rtl92e_writeb(dev, 0xC36, 0x5c);
2218                                 rtl92e_writeb(dev, 0xC3e, 0x96);
2219                         }
2220                 } else if (priv->undecorated_smoothed_pwdb <=
2221                            priv->rtllib->fsync_rssi_threshold) {
2222                         if (priv->bswitch_fsync) {
2223                                 priv->bswitch_fsync  = false;
2224                                 rtl92e_writeb(dev, 0xC36, 0x5c);
2225                                 rtl92e_writeb(dev, 0xC3e, 0x96);
2226                         }
2227                 }
2228                 if (bDoubleTimeInterval) {
2229                         if (timer_pending(&priv->fsync_timer))
2230                                 del_timer_sync(&priv->fsync_timer);
2231                         priv->fsync_timer.expires = jiffies +
2232                                  msecs_to_jiffies(priv->rtllib->fsync_time_interval *
2233                                  priv->rtllib->fsync_multiple_timeinterval);
2234                         add_timer(&priv->fsync_timer);
2235                 } else {
2236                         if (timer_pending(&priv->fsync_timer))
2237                                 del_timer_sync(&priv->fsync_timer);
2238                         priv->fsync_timer.expires = jiffies +
2239                                  msecs_to_jiffies(priv->rtllib->fsync_time_interval);
2240                         add_timer(&priv->fsync_timer);
2241                 }
2242         } else {
2243                 if (priv->bswitch_fsync) {
2244                         priv->bswitch_fsync  = false;
2245                         rtl92e_writeb(dev, 0xC36, 0x5c);
2246                         rtl92e_writeb(dev, 0xC3e, 0x96);
2247                 }
2248                 priv->ContinueDiffCount = 0;
2249                 rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c52cd);
2250         }
2251         RT_TRACE(COMP_HALDM, "ContinueDiffCount %d\n", priv->ContinueDiffCount);
2252         RT_TRACE(COMP_HALDM,
2253                  "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n",
2254                  priv->rate_record, rate_count, rate_count_diff,
2255                  priv->bswitch_fsync);
2256 }
2257
2258 static void _rtl92e_dm_start_hw_fsync(struct net_device *dev)
2259 {
2260         u8 rf_timing = 0x77;
2261         struct r8192_priv *priv = rtllib_priv(dev);
2262
2263         RT_TRACE(COMP_HALDM, "%s\n", __func__);
2264         rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c12cf);
2265         priv->rtllib->SetHwRegHandler(dev, HW_VAR_RF_TIMING,
2266                                       (u8 *)(&rf_timing));
2267         rtl92e_writeb(dev, 0xc3b, 0x41);
2268 }
2269
2270 static void _rtl92e_dm_end_hw_fsync(struct net_device *dev)
2271 {
2272         u8 rf_timing = 0xaa;
2273         struct r8192_priv *priv = rtllib_priv(dev);
2274
2275         RT_TRACE(COMP_HALDM, "%s\n", __func__);
2276         rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c52cd);
2277         priv->rtllib->SetHwRegHandler(dev, HW_VAR_RF_TIMING, (u8 *)
2278                                      (&rf_timing));
2279         rtl92e_writeb(dev, 0xc3b, 0x49);
2280 }
2281
2282 static void _rtl92e_dm_end_sw_fsync(struct net_device *dev)
2283 {
2284         struct r8192_priv *priv = rtllib_priv(dev);
2285
2286         RT_TRACE(COMP_HALDM, "%s\n", __func__);
2287         del_timer_sync(&(priv->fsync_timer));
2288
2289         if (priv->bswitch_fsync) {
2290                 priv->bswitch_fsync  = false;
2291
2292                 rtl92e_writeb(dev, 0xC36, 0x5c);
2293
2294                 rtl92e_writeb(dev, 0xC3e, 0x96);
2295         }
2296
2297         priv->ContinueDiffCount = 0;
2298         rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c52cd);
2299 }
2300
2301 static void _rtl92e_dm_start_sw_fsync(struct net_device *dev)
2302 {
2303         struct r8192_priv *priv = rtllib_priv(dev);
2304         u32                     rateIndex;
2305         u32                     rateBitmap;
2306
2307         RT_TRACE(COMP_HALDM, "%s\n", __func__);
2308         priv->rate_record = 0;
2309         priv->ContinueDiffCount = 0;
2310         priv->rateCountDiffRecord = 0;
2311         priv->bswitch_fsync  = false;
2312
2313         if (priv->rtllib->mode == WIRELESS_MODE_N_24G) {
2314                 priv->rtllib->fsync_firstdiff_ratethreshold = 600;
2315                 priv->rtllib->fsync_seconddiff_ratethreshold = 0xffff;
2316         } else {
2317                 priv->rtllib->fsync_firstdiff_ratethreshold = 200;
2318                 priv->rtllib->fsync_seconddiff_ratethreshold = 200;
2319         }
2320         for (rateIndex = 0; rateIndex <= 27; rateIndex++) {
2321                 rateBitmap  = 1 << rateIndex;
2322                 if (priv->rtllib->fsync_rate_bitmap & rateBitmap)
2323                         priv->rate_record +=
2324                                  priv->stats.received_rate_histogram[1]
2325                                 [rateIndex];
2326         }
2327         if (timer_pending(&priv->fsync_timer))
2328                 del_timer_sync(&priv->fsync_timer);
2329         priv->fsync_timer.expires = jiffies +
2330                                     msecs_to_jiffies(priv->rtllib->fsync_time_interval);
2331         add_timer(&priv->fsync_timer);
2332
2333         rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c12cd);
2334
2335 }
2336
2337 static void _rtl92e_dm_check_fsync(struct net_device *dev)
2338 {
2339 #define RegC38_Default                  0
2340 #define RegC38_NonFsync_Other_AP        1
2341 #define RegC38_Fsync_AP_BCM             2
2342         struct r8192_priv *priv = rtllib_priv(dev);
2343         static u8 reg_c38_State = RegC38_Default;
2344         static u32 reset_cnt;
2345
2346         RT_TRACE(COMP_HALDM,
2347                  "RSSI %d TimeInterval %d MultipleTimeInterval %d\n",
2348                  priv->rtllib->fsync_rssi_threshold,
2349                  priv->rtllib->fsync_time_interval,
2350                  priv->rtllib->fsync_multiple_timeinterval);
2351         RT_TRACE(COMP_HALDM,
2352                  "RateBitmap 0x%x FirstDiffRateThreshold %d SecondDiffRateThreshold %d\n",
2353                  priv->rtllib->fsync_rate_bitmap,
2354                  priv->rtllib->fsync_firstdiff_ratethreshold,
2355                  priv->rtllib->fsync_seconddiff_ratethreshold);
2356
2357         if (priv->rtllib->state == RTLLIB_LINKED &&
2358             priv->rtllib->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) {
2359                 if (priv->rtllib->bfsync_enable == 0) {
2360                         switch (priv->rtllib->fsync_state) {
2361                         case Default_Fsync:
2362                                 _rtl92e_dm_start_hw_fsync(dev);
2363                                 priv->rtllib->fsync_state = HW_Fsync;
2364                                 break;
2365                         case SW_Fsync:
2366                                 _rtl92e_dm_end_sw_fsync(dev);
2367                                 _rtl92e_dm_start_hw_fsync(dev);
2368                                 priv->rtllib->fsync_state = HW_Fsync;
2369                                 break;
2370                         case HW_Fsync:
2371                         default:
2372                                 break;
2373                         }
2374                 } else {
2375                         switch (priv->rtllib->fsync_state) {
2376                         case Default_Fsync:
2377                                 _rtl92e_dm_start_sw_fsync(dev);
2378                                 priv->rtllib->fsync_state = SW_Fsync;
2379                                 break;
2380                         case HW_Fsync:
2381                                 _rtl92e_dm_end_hw_fsync(dev);
2382                                 _rtl92e_dm_start_sw_fsync(dev);
2383                                 priv->rtllib->fsync_state = SW_Fsync;
2384                                 break;
2385                         case SW_Fsync:
2386                         default:
2387                                 break;
2388
2389                         }
2390                 }
2391                 if (priv->framesyncMonitor) {
2392                         if (reg_c38_State != RegC38_Fsync_AP_BCM) {
2393                                 rtl92e_writeb(dev, rOFDM0_RxDetector3, 0x95);
2394
2395                                 reg_c38_State = RegC38_Fsync_AP_BCM;
2396                         }
2397                 }
2398         } else {
2399                 switch (priv->rtllib->fsync_state) {
2400                 case HW_Fsync:
2401                         _rtl92e_dm_end_hw_fsync(dev);
2402                         priv->rtllib->fsync_state = Default_Fsync;
2403                         break;
2404                 case SW_Fsync:
2405                         _rtl92e_dm_end_sw_fsync(dev);
2406                         priv->rtllib->fsync_state = Default_Fsync;
2407                         break;
2408                 case Default_Fsync:
2409                 default:
2410                         break;
2411                 }
2412
2413                 if (priv->framesyncMonitor) {
2414                         if (priv->rtllib->state == RTLLIB_LINKED) {
2415                                 if (priv->undecorated_smoothed_pwdb <=
2416                                     RegC38_TH) {
2417                                         if (reg_c38_State !=
2418                                             RegC38_NonFsync_Other_AP) {
2419                                                 rtl92e_writeb(dev,
2420                                                               rOFDM0_RxDetector3,
2421                                                               0x90);
2422
2423                                                 reg_c38_State =
2424                                                      RegC38_NonFsync_Other_AP;
2425                                         }
2426                                 } else if (priv->undecorated_smoothed_pwdb >=
2427                                            (RegC38_TH+5)) {
2428                                         if (reg_c38_State) {
2429                                                 rtl92e_writeb(dev,
2430                                                         rOFDM0_RxDetector3,
2431                                                         priv->framesync);
2432                                                 reg_c38_State = RegC38_Default;
2433                                         }
2434                                 }
2435                         } else {
2436                                 if (reg_c38_State) {
2437                                         rtl92e_writeb(dev, rOFDM0_RxDetector3,
2438                                                       priv->framesync);
2439                                         reg_c38_State = RegC38_Default;
2440                                 }
2441                         }
2442                 }
2443         }
2444         if (priv->framesyncMonitor) {
2445                 if (priv->reset_count != reset_cnt) {
2446                         rtl92e_writeb(dev, rOFDM0_RxDetector3,
2447                                        priv->framesync);
2448                         reg_c38_State = RegC38_Default;
2449                         reset_cnt = priv->reset_count;
2450                 }
2451         } else {
2452                 if (reg_c38_State) {
2453                         rtl92e_writeb(dev, rOFDM0_RxDetector3,
2454                                        priv->framesync);
2455                         reg_c38_State = RegC38_Default;
2456                 }
2457         }
2458 }
2459
2460 /*---------------------------Define function prototype------------------------*/
2461 static void _rtl92e_dm_init_dynamic_tx_power(struct net_device *dev)
2462 {
2463         struct r8192_priv *priv = rtllib_priv(dev);
2464
2465         priv->rtllib->bdynamic_txpower_enable = true;
2466         priv->bLastDTPFlag_High = false;
2467         priv->bLastDTPFlag_Low = false;
2468         priv->bDynamicTxHighPower = false;
2469         priv->bDynamicTxLowPower = false;
2470 }
2471
2472 static void _rtl92e_dm_dynamic_tx_power(struct net_device *dev)
2473 {
2474         struct r8192_priv *priv = rtllib_priv(dev);
2475         unsigned int txhipower_threshhold = 0;
2476         unsigned int txlowpower_threshold = 0;
2477
2478         if (priv->rtllib->bdynamic_txpower_enable != true) {
2479                 priv->bDynamicTxHighPower = false;
2480                 priv->bDynamicTxLowPower = false;
2481                 return;
2482         }
2483         if ((priv->rtllib->pHTInfo->IOTPeer == HT_IOT_PEER_ATHEROS) &&
2484             (priv->rtllib->mode == IEEE_G)) {
2485                 txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH;
2486                 txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
2487         } else {
2488                 txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
2489                 txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
2490         }
2491
2492         RT_TRACE(COMP_TXAGC, "priv->undecorated_smoothed_pwdb = %ld\n",
2493                  priv->undecorated_smoothed_pwdb);
2494
2495         if (priv->rtllib->state == RTLLIB_LINKED) {
2496                 if (priv->undecorated_smoothed_pwdb >= txhipower_threshhold) {
2497                         priv->bDynamicTxHighPower = true;
2498                         priv->bDynamicTxLowPower = false;
2499                 } else {
2500                         if (priv->undecorated_smoothed_pwdb <
2501                             txlowpower_threshold && priv->bDynamicTxHighPower)
2502                                 priv->bDynamicTxHighPower = false;
2503                         if (priv->undecorated_smoothed_pwdb < 35)
2504                                 priv->bDynamicTxLowPower = true;
2505                         else if (priv->undecorated_smoothed_pwdb >= 40)
2506                                 priv->bDynamicTxLowPower = false;
2507                 }
2508         } else {
2509                 priv->bDynamicTxHighPower = false;
2510                 priv->bDynamicTxLowPower = false;
2511         }
2512
2513         if ((priv->bDynamicTxHighPower != priv->bLastDTPFlag_High) ||
2514             (priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low)) {
2515                 RT_TRACE(COMP_TXAGC, "SetTxPowerLevel8190()  channel = %d\n",
2516                          priv->rtllib->current_network.channel);
2517
2518                 rtl92e_set_tx_power(dev, priv->rtllib->current_network.channel);
2519         }
2520         priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
2521         priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
2522
2523 }
2524
2525 static void _rtl92e_dm_check_txrateandretrycount(struct net_device *dev)
2526 {
2527         struct r8192_priv *priv = rtllib_priv(dev);
2528         struct rtllib_device *ieee = priv->rtllib;
2529
2530         ieee->softmac_stats.CurrentShowTxate = rtl92e_readb(dev,
2531                                                  Current_Tx_Rate_Reg);
2532
2533         ieee->softmac_stats.last_packet_rate = rtl92e_readb(dev,
2534                                                  Initial_Tx_Rate_Reg);
2535
2536         ieee->softmac_stats.txretrycount = rtl92e_readl(dev,
2537                                                  Tx_Retry_Count_Reg);
2538 }
2539
2540 static void _rtl92e_dm_send_rssi_to_fw(struct net_device *dev)
2541 {
2542         struct r8192_priv *priv = rtllib_priv(dev);
2543
2544         rtl92e_writeb(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb);
2545 }