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