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