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