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