Linux-libre 3.4.9-gnu1
[librecmc/linux-libre.git] / drivers / staging / rtl8192e / rtl8192e / rtl_dm.c
1 /******************************************************************************
2  * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
3  *
4  * This program is distributed in the hope that it will be useful, but WITHOUT
5  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
7  * more details.
8  *
9  * You should have received a copy of the GNU General Public License along with
10  * this program; if not, write to the Free Software Foundation, Inc.,
11  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
12  *
13  * The full GNU General Public License is included in this distribution in the
14  * file called LICENSE.
15  *
16  * Contact Information:
17  * wlanfae <wlanfae@realtek.com>
18 ******************************************************************************/
19 #include "rtl_core.h"
20 #include "rtl_dm.h"
21 #include "r8192E_hw.h"
22 #include "r8192E_phy.h"
23 #include "r8192E_phyreg.h"
24 #include "r8190P_rtl8256.h"
25 #include "r8192E_cmdpkt.h"
26
27 /*---------------------------Define Local Constant---------------------------*/
28 static u32 edca_setting_DL[HT_IOT_PEER_MAX] = {
29         0x5e4322,
30         0x5e4322,
31         0x5ea44f,
32         0x5e4322,
33         0x604322,
34         0xa44f,
35         0x5e4322,
36         0x5e4332
37 };
38
39 static u32 edca_setting_DL_GMode[HT_IOT_PEER_MAX] = {
40         0x5e4322,
41         0x5e4322,
42         0x5e4322,
43         0x5e4322,
44         0x604322,
45         0xa44f,
46         0x5e4322,
47         0x5e4322
48 };
49
50 static u32 edca_setting_UL[HT_IOT_PEER_MAX] = {
51         0x5e4322,
52         0xa44f,
53         0x5ea44f,
54         0x5e4322,
55         0x604322,
56         0x5e4322,
57         0x5e4322,
58         0x5e4332
59 };
60
61 #define RTK_UL_EDCA 0xa44f
62 #define RTK_DL_EDCA 0x5e4322
63 /*---------------------------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         priv->DM_Type = DM_Type_ByDriver;
141
142         priv->undecorated_smoothed_pwdb = -1;
143
144         dm_init_dynamic_txpower(dev);
145
146         init_rate_adaptive(dev);
147
148         dm_dig_init(dev);
149         dm_init_edca_turbo(dev);
150         dm_init_bandwidth_autoswitch(dev);
151         dm_init_fsync(dev);
152         dm_init_rxpath_selection(dev);
153         dm_init_ctstoself(dev);
154         if (IS_HARDWARE_TYPE_8192SE(dev))
155                 dm_Init_WA_Broadcom_IOT(dev);
156
157         INIT_DELAYED_WORK_RSL(&priv->gpio_change_rf_wq, (void *)dm_CheckRfCtrlGPIO, dev);
158 }
159
160 void deinit_hal_dm(struct net_device *dev)
161 {
162
163         dm_deInit_fsync(dev);
164
165 }
166
167 void hal_dm_watchdog(struct net_device *dev)
168 {
169         struct r8192_priv *priv = rtllib_priv(dev);
170         if (priv->being_init_adapter)
171                 return;
172
173         dm_check_ac_dc_power(dev);
174
175         dm_check_pbc_gpio(dev);
176         dm_check_txrateandretrycount(dev);
177         dm_check_edca_turbo(dev);
178
179         dm_check_rate_adaptive(dev);
180         dm_dynamic_txpower(dev);
181         dm_check_txpower_tracking(dev);
182
183         dm_ctrl_initgain_byrssi(dev);
184         dm_bandwidth_autoswitch(dev);
185
186         dm_check_rx_path_selection(dev);
187         dm_check_fsync(dev);
188
189         dm_send_rssi_tofw(dev);
190         dm_ctstoself(dev);
191 }
192
193 static void dm_check_ac_dc_power(struct net_device *dev)
194 {
195         struct r8192_priv *priv = rtllib_priv(dev);
196         static char *ac_dc_check_script_path = "/etc/acpi/wireless-rtl-ac-dc-power.sh";
197         char *argv[] = {ac_dc_check_script_path, DRV_NAME, NULL};
198         static char *envp[] = {"HOME=/",
199                         "TERM=linux",
200                         "PATH=/usr/bin:/bin",
201                          NULL};
202
203         if (priv->ResetProgress == RESET_TYPE_SILENT) {
204                 RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF),
205                          "GPIOChangeRFWorkItemCallBack(): Silent Reseting!!!!!!!\n");
206                 return;
207         }
208
209         if (priv->rtllib->state != RTLLIB_LINKED)
210                 return;
211         call_usermodehelper(ac_dc_check_script_path, argv, envp, UMH_WAIT_PROC);
212
213         return;
214 };
215
216
217 void init_rate_adaptive(struct net_device *dev)
218 {
219
220         struct r8192_priv *priv = rtllib_priv(dev);
221         struct rate_adaptive *pra = (struct rate_adaptive *)&priv->rate_adaptive;
222
223         pra->ratr_state = DM_RATR_STA_MAX;
224         pra->high2low_rssi_thresh_for_ra = RateAdaptiveTH_High;
225         pra->low2high_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M+5;
226         pra->low2high_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M+5;
227
228         pra->high_rssi_thresh_for_ra = RateAdaptiveTH_High+5;
229         pra->low_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M;
230         pra->low_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M;
231
232         if (priv->CustomerID == RT_CID_819x_Netcore)
233                 pra->ping_rssi_enable = 1;
234         else
235                 pra->ping_rssi_enable = 0;
236         pra->ping_rssi_thresh_for_ra = 15;
237
238
239         if (priv->rf_type == RF_2T4R) {
240                 pra->upper_rssi_threshold_ratr          =       0x8f0f0000;
241                 pra->middle_rssi_threshold_ratr         =       0x8f0ff000;
242                 pra->low_rssi_threshold_ratr            =       0x8f0ff001;
243                 pra->low_rssi_threshold_ratr_40M        =       0x8f0ff005;
244                 pra->low_rssi_threshold_ratr_20M        =       0x8f0ff001;
245                 pra->ping_rssi_ratr     =       0x0000000d;
246         } else if (priv->rf_type == RF_1T2R) {
247                 pra->upper_rssi_threshold_ratr          =       0x000fc000;
248                 pra->middle_rssi_threshold_ratr         =       0x000ff000;
249                 pra->low_rssi_threshold_ratr            =       0x000ff001;
250                 pra->low_rssi_threshold_ratr_40M        =       0x000ff005;
251                 pra->low_rssi_threshold_ratr_20M        =       0x000ff001;
252                 pra->ping_rssi_ratr     =       0x0000000d;
253         }
254
255 }
256
257
258 static void dm_check_rate_adaptive(struct net_device *dev)
259 {
260         struct r8192_priv *priv = rtllib_priv(dev);
261         struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
262         struct rate_adaptive *pra = (struct rate_adaptive *)&priv->rate_adaptive;
263         u32 currentRATR, targetRATR = 0;
264         u32 LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0;
265         bool bshort_gi_enabled = false;
266         static u8 ping_rssi_state;
267
268         if (IS_NIC_DOWN(priv)) {
269                 RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n");
270                 return;
271         }
272
273         if (pra->rate_adaptive_disabled)
274                 return;
275
276         if (!(priv->rtllib->mode == WIRELESS_MODE_N_24G ||
277             priv->rtllib->mode == WIRELESS_MODE_N_5G))
278                 return;
279
280         if (priv->rtllib->state == RTLLIB_LINKED) {
281
282                 bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) ||
283                         (!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz);
284
285
286                 pra->upper_rssi_threshold_ratr =
287                                 (pra->upper_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0);
288
289                 pra->middle_rssi_threshold_ratr =
290                                 (pra->middle_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0);
291
292                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
293                         pra->low_rssi_threshold_ratr =
294                                 (pra->low_rssi_threshold_ratr_40M & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0);
295                 } else {
296                         pra->low_rssi_threshold_ratr =
297                         (pra->low_rssi_threshold_ratr_20M & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0);
298                 }
299                 pra->ping_rssi_ratr =
300                                 (pra->ping_rssi_ratr & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0);
301
302                 if (pra->ratr_state == DM_RATR_STA_HIGH) {
303                         HighRSSIThreshForRA     = pra->high2low_rssi_thresh_for_ra;
304                         LowRSSIThreshForRA      = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
305                                         (pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M);
306                 } else if (pra->ratr_state == DM_RATR_STA_LOW) {
307                         HighRSSIThreshForRA     = pra->high_rssi_thresh_for_ra;
308                         LowRSSIThreshForRA      = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
309                                         (pra->low2high_rssi_thresh_for_ra40M) : (pra->low2high_rssi_thresh_for_ra20M);
310                 } else {
311                         HighRSSIThreshForRA     = pra->high_rssi_thresh_for_ra;
312                         LowRSSIThreshForRA      = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
313                                         (pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M);
314                 }
315
316                 if (priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA) {
317                         pra->ratr_state = DM_RATR_STA_HIGH;
318                         targetRATR = pra->upper_rssi_threshold_ratr;
319                 } else if (priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA) {
320                         pra->ratr_state = DM_RATR_STA_MIDDLE;
321                         targetRATR = pra->middle_rssi_threshold_ratr;
322                 } else {
323                         pra->ratr_state = DM_RATR_STA_LOW;
324                         targetRATR = pra->low_rssi_threshold_ratr;
325                 }
326
327                 if (pra->ping_rssi_enable) {
328                         if (priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5)) {
329                                 if ((priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) ||
330                                     ping_rssi_state) {
331                                         pra->ratr_state = DM_RATR_STA_LOW;
332                                         targetRATR = pra->ping_rssi_ratr;
333                                         ping_rssi_state = 1;
334                                 }
335                         } else {
336                                 ping_rssi_state = 0;
337                         }
338                 }
339
340                 if (priv->rtllib->GetHalfNmodeSupportByAPsHandler(dev))
341                         targetRATR &=  0xf00fffff;
342
343                 currentRATR = read_nic_dword(dev, RATR0);
344                 if (targetRATR !=  currentRATR) {
345                         u32 ratr_value;
346                         ratr_value = targetRATR;
347                         RT_TRACE(COMP_RATE,
348                                  "currentRATR = %x, targetRATR = %x\n",
349                                  currentRATR, targetRATR);
350                         if (priv->rf_type == RF_1T2R)
351                                 ratr_value &= ~(RATE_ALL_OFDM_2SS);
352                         write_nic_dword(dev, RATR0, ratr_value);
353                         write_nic_byte(dev, UFWP, 1);
354
355                         pra->last_ratr = targetRATR;
356                 }
357
358         } else {
359                 pra->ratr_state = DM_RATR_STA_MAX;
360         }
361 }
362
363 static void dm_init_bandwidth_autoswitch(struct net_device *dev)
364 {
365         struct r8192_priv *priv = rtllib_priv(dev);
366
367         priv->rtllib->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH;
368         priv->rtllib->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW;
369         priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = false;
370         priv->rtllib->bandwidth_auto_switch.bautoswitch_enable = false;
371 }
372
373 static void dm_bandwidth_autoswitch(struct net_device *dev)
374 {
375         struct r8192_priv *priv = rtllib_priv(dev);
376
377         if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ||
378            !priv->rtllib->bandwidth_auto_switch.bautoswitch_enable) {
379                 return;
380         } else {
381                 if (priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz == false) {
382                         if (priv->undecorated_smoothed_pwdb <=
383                             priv->rtllib->bandwidth_auto_switch.threshold_40Mhzto20Mhz)
384                                 priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = true;
385                 } else {
386                         if (priv->undecorated_smoothed_pwdb >=
387                             priv->rtllib->bandwidth_auto_switch.threshold_20Mhzto40Mhz)
388                                 priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = false;
389
390                 }
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 slient 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 == true) {
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                         } else {
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, "Initial reg0x%x"
758                                          " = 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, "Record_CCK_20Mindex / Record_CCK_40"
804                  "Mindex = %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         if (priv->IC_Cut >= IC_VersionCut_D)
1366                 dm_InitializeTXPowerTracking_TSSI(dev);
1367         else
1368                 dm_InitializeTXPowerTracking_ThermalMeter(dev);
1369 }
1370
1371 static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev)
1372 {
1373         struct r8192_priv *priv = rtllib_priv(dev);
1374         static u32 tx_power_track_counter;
1375         RT_TRACE(COMP_POWER_TRACKING, "%s()\n", __func__);
1376         if (read_nic_byte(dev, 0x11e) == 1)
1377                 return;
1378         if (!priv->btxpower_tracking)
1379                 return;
1380         tx_power_track_counter++;
1381
1382
1383          if (tx_power_track_counter >= 180) {
1384                 queue_delayed_work_rsl(priv->priv_wq, &priv->txpower_tracking_wq, 0);
1385                 tx_power_track_counter = 0;
1386         }
1387
1388 }
1389 static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev)
1390 {
1391         struct r8192_priv *priv = rtllib_priv(dev);
1392         static u8       TM_Trigger;
1393         u8              TxPowerCheckCnt = 0;
1394
1395         if (IS_HARDWARE_TYPE_8192SE(dev))
1396                 TxPowerCheckCnt = 5;
1397         else
1398                 TxPowerCheckCnt = 2;
1399         if (!priv->btxpower_tracking) {
1400                 return;
1401         } else {
1402                 if (priv->txpower_count  <= TxPowerCheckCnt) {
1403                         priv->txpower_count++;
1404                         return;
1405                 }
1406         }
1407
1408         if (!TM_Trigger) {
1409                 {
1410                 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1411                 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1412                 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1413                 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1414                 }
1415                 TM_Trigger = 1;
1416                 return;
1417         } else {
1418             printk(KERN_INFO "===============>Schedule TxPowerTrackingWorkItem\n");
1419
1420                 queue_delayed_work_rsl(priv->priv_wq, &priv->txpower_tracking_wq, 0);
1421                 TM_Trigger = 0;
1422                 }
1423
1424         }
1425
1426 static void dm_check_txpower_tracking(struct net_device *dev)
1427 {
1428         struct r8192_priv *priv = rtllib_priv(dev);
1429
1430         if (priv->IC_Cut >= IC_VersionCut_D)
1431                 dm_CheckTXPowerTracking_TSSI(dev);
1432         else
1433                 dm_CheckTXPowerTracking_ThermalMeter(dev);
1434 }
1435
1436 static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool  bInCH14)
1437 {
1438         u32 TempVal;
1439         struct r8192_priv *priv = rtllib_priv(dev);
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 = 0;
1447                 TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] +
1448                           (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) +
1449                           (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16)+
1450                           (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24));
1451                 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1452                 TempVal = 0;
1453                 TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] +
1454                           (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ;
1455
1456                 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1457         } else {
1458                 TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[0] +
1459                           (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ;
1460
1461                 rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1462                 TempVal = 0;
1463                 TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] +
1464                           (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) +
1465                           (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16)+
1466                           (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24));
1467                 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1468                 TempVal = 0;
1469                 TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] +
1470                           (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ;
1471
1472                 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1473         }
1474
1475
1476 }
1477
1478 static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev,    bool  bInCH14)
1479 {
1480         u32 TempVal;
1481         struct r8192_priv *priv = rtllib_priv(dev);
1482
1483         TempVal = 0;
1484         if (!bInCH14) {
1485                 TempVal =       CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] +
1486                                         (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8) ;
1487                 rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1488                 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1489                         rCCK0_TxFilter1, TempVal);
1490                 TempVal = 0;
1491                 TempVal =       CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] +
1492                                         (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) +
1493                                         (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16)+
1494                                         (CCKSwingTable_Ch1_Ch13[priv->CCK_index][5]<<24);
1495                 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1496                 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1497                         rCCK0_TxFilter2, TempVal);
1498                 TempVal = 0;
1499                 TempVal =       CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] +
1500                                         (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8) ;
1501
1502                 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1503                 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1504                         rCCK0_DebugPort, TempVal);
1505         } else {
1506                 TempVal =       CCKSwingTable_Ch14[priv->CCK_index][0] +
1507                                         (CCKSwingTable_Ch14[priv->CCK_index][1]<<8) ;
1508
1509                 rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1510                 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1511                         rCCK0_TxFilter1, TempVal);
1512                 TempVal = 0;
1513                 TempVal =       CCKSwingTable_Ch14[priv->CCK_index][2] +
1514                                         (CCKSwingTable_Ch14[priv->CCK_index][3]<<8) +
1515                                         (CCKSwingTable_Ch14[priv->CCK_index][4]<<16)+
1516                                         (CCKSwingTable_Ch14[priv->CCK_index][5]<<24);
1517                 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1518                 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1519                         rCCK0_TxFilter2, TempVal);
1520                 TempVal = 0;
1521                 TempVal =       CCKSwingTable_Ch14[priv->CCK_index][6] +
1522                                         (CCKSwingTable_Ch14[priv->CCK_index][7]<<8) ;
1523
1524                 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1525                 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1526                         rCCK0_DebugPort, TempVal);
1527         }
1528         }
1529
1530 void dm_cck_txpower_adjust(struct net_device *dev, bool  binch14)
1531 {
1532         struct r8192_priv *priv = rtllib_priv(dev);
1533         if (priv->IC_Cut >= IC_VersionCut_D)
1534                 dm_CCKTxPowerAdjust_TSSI(dev, binch14);
1535         else
1536                 dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14);
1537 }
1538
1539 static void dm_txpower_reset_recovery(struct net_device *dev)
1540 {
1541         struct r8192_priv *priv = rtllib_priv(dev);
1542
1543         RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n");
1544         rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord,
1545                          priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
1546         RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n",
1547                  priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
1548         RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n",
1549                  priv->rfa_txpowertrackingindex);
1550         RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF A I/Q Amplify Gain is %ld\n",
1551                  priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbb_iq_amplifygain);
1552         RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: CCK Attenuation is %d dB\n",
1553                  priv->CCKPresentAttentuation);
1554         dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
1555
1556         rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord,
1557                          priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
1558         RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n",
1559                  priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
1560         RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n",
1561                  priv->rfc_txpowertrackingindex);
1562         RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF C I/Q Amplify Gain is %ld\n",
1563                  priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbb_iq_amplifygain);
1564
1565 }
1566
1567 void dm_restore_dynamic_mechanism_state(struct net_device *dev)
1568 {
1569         struct r8192_priv *priv = rtllib_priv(dev);
1570         u32     reg_ratr = priv->rate_adaptive.last_ratr;
1571         u32 ratr_value;
1572
1573         if (IS_NIC_DOWN(priv)) {
1574                 RT_TRACE(COMP_RATE, "<---- dm_restore_dynamic_mechanism_state(): driver is going to unload\n");
1575                 return;
1576         }
1577
1578         if (priv->rate_adaptive.rate_adaptive_disabled)
1579                 return;
1580         if (!(priv->rtllib->mode == WIRELESS_MODE_N_24G ||
1581               priv->rtllib->mode == WIRELESS_MODE_N_5G))
1582                 return;
1583         ratr_value = reg_ratr;
1584         if (priv->rf_type == RF_1T2R)
1585                 ratr_value &= ~(RATE_ALL_OFDM_2SS);
1586         write_nic_dword(dev, RATR0, ratr_value);
1587         write_nic_byte(dev, UFWP, 1);
1588         if (priv->btxpower_trackingInit && priv->btxpower_tracking)
1589                 dm_txpower_reset_recovery(dev);
1590
1591         dm_bb_initialgain_restore(dev);
1592
1593 }
1594
1595 static void dm_bb_initialgain_restore(struct net_device *dev)
1596 {
1597         struct r8192_priv *priv = rtllib_priv(dev);
1598         u32 bit_mask = 0x7f;
1599
1600         if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1601                 return;
1602
1603         rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);
1604         rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bit_mask, (u32)priv->initgain_backup.xaagccore1);
1605         rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bit_mask, (u32)priv->initgain_backup.xbagccore1);
1606         rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bit_mask, (u32)priv->initgain_backup.xcagccore1);
1607         rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, bit_mask, (u32)priv->initgain_backup.xdagccore1);
1608         bit_mask  = bMaskByte2;
1609         rtl8192_setBBreg(dev, rCCK0_CCA, bit_mask, (u32)priv->initgain_backup.cca);
1610
1611         RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n", priv->initgain_backup.xaagccore1);
1612         RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n", priv->initgain_backup.xbagccore1);
1613         RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n", priv->initgain_backup.xcagccore1);
1614         RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n", priv->initgain_backup.xdagccore1);
1615         RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n", priv->initgain_backup.cca);
1616         rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);
1617
1618 }
1619
1620
1621 void dm_backup_dynamic_mechanism_state(struct net_device *dev)
1622 {
1623         struct r8192_priv *priv = rtllib_priv(dev);
1624
1625         priv->bswitch_fsync  = false;
1626         priv->bfsync_processing = false;
1627         dm_bb_initialgain_backup(dev);
1628
1629 }
1630
1631
1632 static void dm_bb_initialgain_backup(struct net_device *dev)
1633 {
1634         struct r8192_priv *priv = rtllib_priv(dev);
1635         u32 bit_mask = bMaskByte0;
1636
1637         if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1638                 return;
1639
1640         rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);
1641         priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bit_mask);
1642         priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bit_mask);
1643         priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bit_mask);
1644         priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, bit_mask);
1645         bit_mask  = bMaskByte2;
1646         priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bit_mask);
1647
1648         RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n", priv->initgain_backup.xaagccore1);
1649         RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n", priv->initgain_backup.xbagccore1);
1650         RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n", priv->initgain_backup.xcagccore1);
1651         RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n", priv->initgain_backup.xdagccore1);
1652         RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n", priv->initgain_backup.cca);
1653
1654 }
1655
1656 void dm_change_dynamic_initgain_thresh(struct net_device *dev,
1657                                        u32 dm_type, u32 dm_value)
1658 {
1659         if (dm_type == DIG_TYPE_THRESH_HIGH) {
1660                 dm_digtable.rssi_high_thresh = dm_value;
1661         } else if (dm_type == DIG_TYPE_THRESH_LOW) {
1662                 dm_digtable.rssi_low_thresh = dm_value;
1663         } else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) {
1664                 dm_digtable.rssi_high_power_highthresh = dm_value;
1665         } else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) {
1666                 dm_digtable.rssi_high_power_highthresh = dm_value;
1667         } else if (dm_type == DIG_TYPE_ENABLE) {
1668                 dm_digtable.dig_state           = DM_STA_DIG_MAX;
1669                 dm_digtable.dig_enable_flag     = true;
1670         } else if (dm_type == DIG_TYPE_DISABLE) {
1671                 dm_digtable.dig_state           = DM_STA_DIG_MAX;
1672                 dm_digtable.dig_enable_flag     = false;
1673         } else if (dm_type == DIG_TYPE_DBG_MODE) {
1674                 if (dm_value >= DM_DBG_MAX)
1675                         dm_value = DM_DBG_OFF;
1676                 dm_digtable.dbg_mode            = (u8)dm_value;
1677         } else if (dm_type == DIG_TYPE_RSSI) {
1678                 if (dm_value > 100)
1679                         dm_value = 30;
1680                 dm_digtable.rssi_val                    = (long)dm_value;
1681         } else if (dm_type == DIG_TYPE_ALGORITHM) {
1682                 if (dm_value >= DIG_ALGO_MAX)
1683                         dm_value = DIG_ALGO_BY_FALSE_ALARM;
1684                 if (dm_digtable.dig_algorithm != (u8)dm_value)
1685                         dm_digtable.dig_algorithm_switch = 1;
1686                 dm_digtable.dig_algorithm       = (u8)dm_value;
1687         } else if (dm_type == DIG_TYPE_BACKOFF) {
1688                 if (dm_value > 30)
1689                         dm_value = 30;
1690                 dm_digtable.backoff_val         = (u8)dm_value;
1691         } else if (dm_type == DIG_TYPE_RX_GAIN_MIN) {
1692                 if (dm_value == 0)
1693                         dm_value = 0x1;
1694                 dm_digtable.rx_gain_range_min = (u8)dm_value;
1695         } else if (dm_type == DIG_TYPE_RX_GAIN_MAX) {
1696                 if (dm_value > 0x50)
1697                         dm_value = 0x50;
1698                 dm_digtable.rx_gain_range_max = (u8)dm_value;
1699         }
1700 }
1701
1702 static void dm_dig_init(struct net_device *dev)
1703 {
1704         struct r8192_priv *priv = rtllib_priv(dev);
1705         dm_digtable.dig_enable_flag     = true;
1706         dm_digtable.Backoff_Enable_Flag = true;
1707
1708         dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI;
1709
1710         dm_digtable.Dig_TwoPort_Algorithm = DIG_TWO_PORT_ALGO_RSSI;
1711         dm_digtable.Dig_Ext_Port_Stage = DIG_EXT_PORT_STAGE_MAX;
1712         dm_digtable.dbg_mode = DM_DBG_OFF;
1713         dm_digtable.dig_algorithm_switch = 0;
1714
1715         dm_digtable.dig_state           = DM_STA_DIG_MAX;
1716         dm_digtable.dig_highpwr_state   = DM_STA_DIG_MAX;
1717         dm_digtable.CurSTAConnectState = dm_digtable.PreSTAConnectState = DIG_STA_DISCONNECT;
1718         dm_digtable.CurAPConnectState = dm_digtable.PreAPConnectState = DIG_AP_DISCONNECT;
1719         dm_digtable.initialgain_lowerbound_state = false;
1720
1721         dm_digtable.rssi_low_thresh     = DM_DIG_THRESH_LOW;
1722         dm_digtable.rssi_high_thresh    = DM_DIG_THRESH_HIGH;
1723
1724         dm_digtable.FALowThresh = DM_FALSEALARM_THRESH_LOW;
1725         dm_digtable.FAHighThresh        = DM_FALSEALARM_THRESH_HIGH;
1726
1727         dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
1728         dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
1729
1730         dm_digtable.rssi_val = 50;
1731         dm_digtable.backoff_val = DM_DIG_BACKOFF;
1732         dm_digtable.rx_gain_range_max = DM_DIG_MAX;
1733         if (priv->CustomerID == RT_CID_819x_Netcore)
1734                 dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore;
1735         else
1736                 dm_digtable.rx_gain_range_min = DM_DIG_MIN;
1737
1738         dm_digtable.BackoffVal_range_max = DM_DIG_BACKOFF_MAX;
1739         dm_digtable.BackoffVal_range_min = DM_DIG_BACKOFF_MIN;
1740 }
1741
1742 static void dm_ctrl_initgain_byrssi(struct net_device *dev)
1743 {
1744
1745         if (dm_digtable.dig_enable_flag == false)
1746                 return;
1747
1748         if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
1749                 dm_ctrl_initgain_byrssi_by_fwfalse_alarm(dev);
1750         else if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1751                 dm_ctrl_initgain_byrssi_by_driverrssi(dev);
1752         else
1753                 return;
1754 }
1755
1756 /*-----------------------------------------------------------------------------
1757  * Function:    dm_CtrlInitGainBeforeConnectByRssiAndFalseAlarm()
1758  *
1759  * Overview:    Driver monitor RSSI and False Alarm to change initial gain.
1760                         Only change initial gain during link in progress.
1761  *
1762  * Input:               IN      PADAPTER        pAdapter
1763  *
1764  * Output:              NONE
1765  *
1766  * Return:              NONE
1767  *
1768  * Revised History:
1769  *      When            Who             Remark
1770  *      03/04/2009      hpfan   Create Version 0.
1771  *
1772  *---------------------------------------------------------------------------*/
1773
1774 static void dm_ctrl_initgain_byrssi_by_driverrssi(
1775         struct net_device *dev)
1776 {
1777         struct r8192_priv *priv = rtllib_priv(dev);
1778         u8 i;
1779         static u8       fw_dig;
1780
1781         if (dm_digtable.dig_enable_flag == false)
1782                 return;
1783
1784         if (dm_digtable.dig_algorithm_switch)
1785                 fw_dig = 0;
1786         if (fw_dig <= 3) {
1787                 for (i = 0; i < 3; i++)
1788                         rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);
1789                 fw_dig++;
1790                 dm_digtable.dig_state = DM_STA_DIG_OFF;
1791         }
1792
1793         if (priv->rtllib->state == RTLLIB_LINKED)
1794                 dm_digtable.CurSTAConnectState = DIG_STA_CONNECT;
1795         else
1796                 dm_digtable.CurSTAConnectState = DIG_STA_DISCONNECT;
1797
1798
1799         if (dm_digtable.dbg_mode == DM_DBG_OFF)
1800                 dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
1801         dm_initial_gain(dev);
1802         dm_pd_th(dev);
1803         dm_cs_ratio(dev);
1804         if (dm_digtable.dig_algorithm_switch)
1805                 dm_digtable.dig_algorithm_switch = 0;
1806         dm_digtable.PreSTAConnectState = dm_digtable.CurSTAConnectState;
1807
1808 }
1809
1810 static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
1811         struct net_device *dev)
1812 {
1813         struct r8192_priv *priv = rtllib_priv(dev);
1814         static u32 reset_cnt;
1815         u8 i;
1816
1817         if (dm_digtable.dig_enable_flag == false)
1818                 return;
1819
1820         if (dm_digtable.dig_algorithm_switch) {
1821                 dm_digtable.dig_state = DM_STA_DIG_MAX;
1822                 for (i = 0; i < 3; i++)
1823                         rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);
1824                 dm_digtable.dig_algorithm_switch = 0;
1825         }
1826
1827         if (priv->rtllib->state != RTLLIB_LINKED)
1828                 return;
1829
1830         if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) &&
1831                 (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh))
1832                 return;
1833         if ((priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh)) {
1834                 if (dm_digtable.dig_state == DM_STA_DIG_OFF &&
1835                         (priv->reset_count == reset_cnt))
1836                         return;
1837                 else
1838                         reset_cnt = priv->reset_count;
1839
1840                 dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
1841                 dm_digtable.dig_state = DM_STA_DIG_OFF;
1842
1843                 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);
1844
1845                 write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x17);
1846                 write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x17);
1847                 write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x17);
1848                 write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x17);
1849
1850                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1851                         write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
1852                 else
1853                         write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
1854
1855                 write_nic_byte(dev, 0xa0a, 0x08);
1856
1857                 return;
1858         }
1859
1860         if ((priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh)) {
1861                 u8 reset_flag = 0;
1862
1863                 if (dm_digtable.dig_state == DM_STA_DIG_ON &&
1864                     (priv->reset_count == reset_cnt)) {
1865                         dm_ctrl_initgain_byrssi_highpwr(dev);
1866                         return;
1867                 } else {
1868                         if (priv->reset_count != reset_cnt)
1869                                 reset_flag = 1;
1870
1871                         reset_cnt = priv->reset_count;
1872                 }
1873
1874                 dm_digtable.dig_state = DM_STA_DIG_ON;
1875
1876                 if (reset_flag == 1) {
1877                         write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x2c);
1878                         write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x2c);
1879                         write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x2c);
1880                         write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x2c);
1881                 } else {
1882                         write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x20);
1883                         write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x20);
1884                         write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x20);
1885                         write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x20);
1886                 }
1887
1888                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1889                         write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
1890                 else
1891                         write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
1892
1893                 write_nic_byte(dev, 0xa0a, 0xcd);
1894
1895                 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);
1896         }
1897         dm_ctrl_initgain_byrssi_highpwr(dev);
1898 }
1899
1900
1901 static void dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev)
1902 {
1903         struct r8192_priv *priv = rtllib_priv(dev);
1904         static u32 reset_cnt_highpwr;
1905
1906         if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) &&
1907                 (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh))
1908                 return;
1909
1910         if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh) {
1911                 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON &&
1912                         (priv->reset_count == reset_cnt_highpwr))
1913                         return;
1914                 else
1915                         dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
1916
1917                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1918                                 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
1919                 else
1920                         write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
1921         } else {
1922                 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF &&
1923                         (priv->reset_count == reset_cnt_highpwr))
1924                         return;
1925                 else
1926                         dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
1927
1928                 if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh &&
1929                          priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) {
1930                         if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1931                                 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
1932                         else
1933                                 write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
1934                 }
1935         }
1936         reset_cnt_highpwr = priv->reset_count;
1937 }
1938
1939 static void dm_initial_gain(struct net_device *dev)
1940 {
1941         struct r8192_priv *priv = rtllib_priv(dev);
1942         u8 initial_gain = 0;
1943         static u8 initialized, force_write;
1944         static u32 reset_cnt;
1945
1946         if (dm_digtable.dig_algorithm_switch) {
1947                 initialized = 0;
1948                 reset_cnt = 0;
1949         }
1950
1951         if (rtllib_act_scanning(priv->rtllib, true) == true) {
1952                 force_write = 1;
1953                 return;
1954         }
1955
1956         if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) {
1957                 if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) {
1958                         if ((dm_digtable.rssi_val+10-dm_digtable.backoff_val) > dm_digtable.rx_gain_range_max)
1959                                 dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_max;
1960                         else if ((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
1961                                 dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min;
1962                         else
1963                                 dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val;
1964                 } else {
1965                         if (dm_digtable.cur_ig_value == 0)
1966                                 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1967                         else
1968                                 dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
1969                 }
1970         } else {
1971                 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1972                 dm_digtable.pre_ig_value = 0;
1973         }
1974
1975         if (priv->reset_count != reset_cnt) {
1976                 force_write = 1;
1977                 reset_cnt = priv->reset_count;
1978         }
1979
1980         if (dm_digtable.pre_ig_value != read_nic_byte(dev, rOFDM0_XAAGCCore1))
1981                 force_write = 1;
1982
1983         if ((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
1984             || !initialized || force_write) {
1985                 initial_gain = (u8)dm_digtable.cur_ig_value;
1986                 write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
1987                 write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
1988                 write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
1989                 write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
1990                 dm_digtable.pre_ig_value = dm_digtable.cur_ig_value;
1991                 initialized = 1;
1992                 force_write = 0;
1993         }
1994 }
1995
1996 static void dm_pd_th(struct net_device *dev)
1997 {
1998         struct r8192_priv *priv = rtllib_priv(dev);
1999         static u8 initialized, force_write;
2000         static u32 reset_cnt;
2001
2002         if (dm_digtable.dig_algorithm_switch) {
2003                 initialized = 0;
2004                 reset_cnt = 0;
2005         }
2006
2007         if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) {
2008                 if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) {
2009                         if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh)
2010                                 dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER;
2011                         else if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
2012                                 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2013                         else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) &&
2014                                         (dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh))
2015                                 dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER;
2016                         else
2017                                 dm_digtable.curpd_thstate = dm_digtable.prepd_thstate;
2018                 } else {
2019                         dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2020                 }
2021         } else {
2022                 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2023         }
2024
2025         if (priv->reset_count != reset_cnt) {
2026                 force_write = 1;
2027                 reset_cnt = priv->reset_count;
2028         }
2029
2030         if ((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
2031             (initialized <= 3) || force_write) {
2032                 if (dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) {
2033                         if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2034                                 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
2035                         else
2036                                 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2037                 } else if (dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER) {
2038                         if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2039                                 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
2040                         else
2041                                 write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
2042                 } else if (dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) {
2043                         if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2044                                 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
2045                         else
2046                                 write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
2047                 }
2048                 dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
2049                 if (initialized <= 3)
2050                         initialized++;
2051                 force_write = 0;
2052         }
2053 }
2054
2055 static  void dm_cs_ratio(struct net_device *dev)
2056 {
2057         struct r8192_priv *priv = rtllib_priv(dev);
2058         static u8 initialized, force_write;
2059         static u32 reset_cnt;
2060
2061         if (dm_digtable.dig_algorithm_switch) {
2062                 initialized = 0;
2063                 reset_cnt = 0;
2064         }
2065
2066         if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) {
2067                 if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) {
2068                         if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
2069                                 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2070                         else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh))
2071                                 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
2072                         else
2073                                 dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
2074                 } else {
2075                         dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2076                 }
2077         } else {
2078                 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2079         }
2080
2081         if (priv->reset_count != reset_cnt) {
2082                 force_write = 1;
2083                 reset_cnt = priv->reset_count;
2084         }
2085
2086
2087         if ((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
2088             !initialized || force_write) {
2089                 if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
2090                         write_nic_byte(dev, 0xa0a, 0x08);
2091                 else if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER)
2092                         write_nic_byte(dev, 0xa0a, 0xcd);
2093                 dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
2094                 initialized = 1;
2095                 force_write = 0;
2096         }
2097 }
2098
2099 void dm_init_edca_turbo(struct net_device *dev)
2100 {
2101         struct r8192_priv *priv = rtllib_priv(dev);
2102
2103         priv->bcurrent_turbo_EDCA = false;
2104         priv->rtllib->bis_any_nonbepkts = false;
2105         priv->bis_cur_rdlstate = false;
2106 }
2107
2108 static void dm_check_edca_turbo(struct net_device *dev)
2109 {
2110         struct r8192_priv *priv = rtllib_priv(dev);
2111         struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
2112
2113         static unsigned long lastTxOkCnt;
2114         static unsigned long lastRxOkCnt;
2115         unsigned long curTxOkCnt = 0;
2116         unsigned long curRxOkCnt = 0;
2117
2118         if (priv->rtllib->iw_mode == IW_MODE_ADHOC)
2119                 goto dm_CheckEdcaTurbo_EXIT;
2120         if (priv->rtllib->state != RTLLIB_LINKED)
2121                 goto dm_CheckEdcaTurbo_EXIT;
2122         if (priv->rtllib->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
2123                 goto dm_CheckEdcaTurbo_EXIT;
2124
2125         {
2126                 u8 *peername[11] = {
2127                         "unknown", "realtek_90", "realtek_92se", "broadcom",
2128                         "ralink", "atheros", "cisco", "marvell", "92u_softap",
2129                         "self_softap"
2130                 };
2131                 static int wb_tmp;
2132                 if (wb_tmp == 0) {
2133                         printk(KERN_INFO "%s():iot peer is %s, bssid:"
2134                                " %pM\n", __func__,
2135                                peername[pHTInfo->IOTPeer],
2136                                priv->rtllib->current_network.bssid);
2137                         wb_tmp = 1;
2138                 }
2139         }
2140         if (!priv->rtllib->bis_any_nonbepkts) {
2141                 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
2142                 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
2143                 if (pHTInfo->IOTAction & HT_IOT_ACT_EDCA_BIAS_ON_RX) {
2144                         if (curTxOkCnt > 4*curRxOkCnt) {
2145                                 if (priv->bis_cur_rdlstate ||
2146                                     !priv->bcurrent_turbo_EDCA) {
2147                                         write_nic_dword(dev, EDCAPARA_BE,
2148                                                  edca_setting_UL[pHTInfo->IOTPeer]);
2149                                         priv->bis_cur_rdlstate = false;
2150                                 }
2151                         } else {
2152                                 if (!priv->bis_cur_rdlstate ||
2153                                     !priv->bcurrent_turbo_EDCA) {
2154                                         if (priv->rtllib->mode == WIRELESS_MODE_G)
2155                                                 write_nic_dword(dev, EDCAPARA_BE,
2156                                                          edca_setting_DL_GMode[pHTInfo->IOTPeer]);
2157                                         else
2158                                                 write_nic_dword(dev, EDCAPARA_BE,
2159                                                          edca_setting_DL[pHTInfo->IOTPeer]);
2160                                         priv->bis_cur_rdlstate = true;
2161                                 }
2162                         }
2163                         priv->bcurrent_turbo_EDCA = true;
2164                 } else {
2165                         if (curRxOkCnt > 4*curTxOkCnt) {
2166                                 if (!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) {
2167                                         if (priv->rtllib->mode == WIRELESS_MODE_G)
2168                                                 write_nic_dword(dev, EDCAPARA_BE,
2169                                                          edca_setting_DL_GMode[pHTInfo->IOTPeer]);
2170                                         else
2171                                                 write_nic_dword(dev, EDCAPARA_BE,
2172                                                          edca_setting_DL[pHTInfo->IOTPeer]);
2173                                         priv->bis_cur_rdlstate = true;
2174                                 }
2175                         } else {
2176                                 if (priv->bis_cur_rdlstate ||
2177                                     !priv->bcurrent_turbo_EDCA) {
2178                                         write_nic_dword(dev, EDCAPARA_BE,
2179                                                         edca_setting_UL[pHTInfo->IOTPeer]);
2180                                         priv->bis_cur_rdlstate = false;
2181                                 }
2182
2183                         }
2184
2185                         priv->bcurrent_turbo_EDCA = true;
2186                 }
2187         } else {
2188                  if (priv->bcurrent_turbo_EDCA) {
2189                         u8 tmp = AC0_BE;
2190                         priv->rtllib->SetHwRegHandler(dev, HW_VAR_AC_PARAM, (u8 *)(&tmp));
2191                         priv->bcurrent_turbo_EDCA = false;
2192                 }
2193         }
2194
2195
2196 dm_CheckEdcaTurbo_EXIT:
2197         priv->rtllib->bis_any_nonbepkts = false;
2198         lastTxOkCnt = priv->stats.txbytesunicast;
2199         lastRxOkCnt = priv->stats.rxbytesunicast;
2200 }
2201
2202 static void dm_init_ctstoself(struct net_device *dev)
2203 {
2204         struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
2205
2206         priv->rtllib->bCTSToSelfEnable = true;
2207         priv->rtllib->CTSToSelfTH = CTSToSelfTHVal;
2208 }
2209
2210 static void dm_ctstoself(struct net_device *dev)
2211 {
2212         struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
2213         struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
2214         static unsigned long lastTxOkCnt;
2215         static unsigned long lastRxOkCnt;
2216         unsigned long curTxOkCnt = 0;
2217         unsigned long curRxOkCnt = 0;
2218
2219         if (priv->rtllib->bCTSToSelfEnable != true) {
2220                 pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
2221                 return;
2222         }
2223         if (pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) {
2224                 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
2225                 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
2226                 if (curRxOkCnt > 4*curTxOkCnt)
2227                         pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
2228                 else
2229                         pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
2230
2231                 lastTxOkCnt = priv->stats.txbytesunicast;
2232                 lastRxOkCnt = priv->stats.rxbytesunicast;
2233         }
2234 }
2235
2236
2237 static  void dm_Init_WA_Broadcom_IOT(struct net_device *dev)
2238 {
2239         struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
2240         struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
2241
2242         pHTInfo->bWAIotBroadcom = false;
2243         pHTInfo->WAIotTH = WAIotTHVal;
2244 }
2245
2246 static  void    dm_check_pbc_gpio(struct net_device *dev)
2247 {
2248 }
2249
2250 void dm_CheckRfCtrlGPIO(void *data)
2251 {
2252         struct r8192_priv *priv = container_of_dwork_rsl(data,
2253                                   struct r8192_priv, gpio_change_rf_wq);
2254         struct net_device *dev = priv->rtllib->dev;
2255         u8 tmp1byte;
2256         enum rt_rf_power_state eRfPowerStateToSet;
2257         bool bActuallySet = false;
2258         char *argv[3];
2259         static char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh";
2260         static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL};
2261
2262         bActuallySet = false;
2263
2264         if ((priv->up_first_time == 1) || (priv->being_init_adapter))
2265                 return;
2266
2267         if (priv->bfirst_after_down) {
2268                 priv->bfirst_after_down = 1;
2269                 return;
2270         }
2271
2272         tmp1byte = read_nic_byte(dev, GPI);
2273
2274         eRfPowerStateToSet = (tmp1byte&BIT1) ?  eRfOn : eRfOff;
2275
2276         if ((priv->bHwRadioOff == true) && (eRfPowerStateToSet == eRfOn)) {
2277                 RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio ON\n");
2278                 printk(KERN_INFO "gpiochangeRF  - HW Radio ON\n");
2279                 priv->bHwRadioOff = false;
2280                 bActuallySet = true;
2281         } else if ((priv->bHwRadioOff == false) && (eRfPowerStateToSet == eRfOff)) {
2282                 RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio OFF\n");
2283                 printk(KERN_INFO "gpiochangeRF  - HW Radio OFF\n");
2284                 priv->bHwRadioOff = true;
2285                 bActuallySet = true;
2286         }
2287
2288         if (bActuallySet) {
2289                 mdelay(1000);
2290                 priv->bHwRfOffAction = 1;
2291                 MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW, true);
2292                 if (priv->bHwRadioOff == true)
2293                         argv[1] = "RFOFF";
2294                 else
2295                         argv[1] = "RFON";
2296
2297                 argv[0] = RadioPowerPath;
2298                 argv[2] = NULL;
2299                 call_usermodehelper(RadioPowerPath, argv, envp, UMH_WAIT_PROC);
2300         }
2301 }
2302
2303 void    dm_rf_pathcheck_workitemcallback(void *data)
2304 {
2305         struct r8192_priv *priv = container_of_dwork_rsl(data,
2306                                   struct r8192_priv,
2307                                   rfpath_check_wq);
2308         struct net_device *dev = priv->rtllib->dev;
2309         u8 rfpath = 0, i;
2310
2311         rfpath = read_nic_byte(dev, 0xc04);
2312
2313         for (i = 0; i < RF90_PATH_MAX; i++) {
2314                 if (rfpath & (0x01<<i))
2315                         priv->brfpath_rxenable[i] = 1;
2316                 else
2317                         priv->brfpath_rxenable[i] = 0;
2318         }
2319         if (!DM_RxPathSelTable.Enable)
2320                 return;
2321
2322         dm_rxpath_sel_byrssi(dev);
2323 }
2324
2325 static void dm_init_rxpath_selection(struct net_device *dev)
2326 {
2327         u8 i;
2328         struct r8192_priv *priv = rtllib_priv(dev);
2329
2330         DM_RxPathSelTable.Enable = 1;
2331         DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low;
2332         DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH;
2333         if (priv->CustomerID == RT_CID_819x_Netcore)
2334                 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
2335         else
2336                 DM_RxPathSelTable.cck_method = CCK_Rx_Version_1;
2337         DM_RxPathSelTable.DbgMode = DM_DBG_OFF;
2338         DM_RxPathSelTable.disabledRF = 0;
2339         for (i = 0; i < 4; i++) {
2340                 DM_RxPathSelTable.rf_rssi[i] = 50;
2341                 DM_RxPathSelTable.cck_pwdb_sta[i] = -64;
2342                 DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
2343         }
2344 }
2345
2346 #define PWDB_IN_RANGE   ((cur_cck_pwdb < tmp_cck_max_pwdb) &&   \
2347                         (cur_cck_pwdb > tmp_cck_sec_pwdb))
2348
2349 static void dm_rxpath_sel_byrssi(struct net_device *dev)
2350 {
2351         struct r8192_priv *priv = rtllib_priv(dev);
2352         u8 i, max_rssi_index = 0, min_rssi_index = 0;
2353         u8 sec_rssi_index = 0, rf_num = 0;
2354         u8 tmp_max_rssi = 0, tmp_min_rssi = 0, tmp_sec_rssi = 0;
2355         u8 cck_default_Rx = 0x2;
2356         u8 cck_optional_Rx = 0x3;
2357         long tmp_cck_max_pwdb = 0, tmp_cck_min_pwdb = 0, tmp_cck_sec_pwdb = 0;
2358         u8 cck_rx_ver2_max_index = 0, cck_rx_ver2_min_index = 0;
2359         u8 cck_rx_ver2_sec_index = 0;
2360         u8 cur_rf_rssi;
2361         long cur_cck_pwdb;
2362         static u8 disabled_rf_cnt, cck_Rx_Path_initialized;
2363         u8 update_cck_rx_path;
2364
2365         if (priv->rf_type != RF_2T4R)
2366                 return;
2367
2368         if (!cck_Rx_Path_initialized) {
2369                 DM_RxPathSelTable.cck_Rx_path = (read_nic_byte(dev, 0xa07)&0xf);
2370                 cck_Rx_Path_initialized = 1;
2371         }
2372
2373         DM_RxPathSelTable.disabledRF = 0xf;
2374         DM_RxPathSelTable.disabledRF &= ~(read_nic_byte(dev, 0xc04));
2375
2376         if (priv->rtllib->mode == WIRELESS_MODE_B)
2377                 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
2378
2379         for (i = 0; i < RF90_PATH_MAX; i++) {
2380                 if (!DM_RxPathSelTable.DbgMode)
2381                         DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
2382
2383                 if (priv->brfpath_rxenable[i]) {
2384                         rf_num++;
2385                         cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i];
2386
2387                         if (rf_num == 1) {
2388                                 max_rssi_index = min_rssi_index = sec_rssi_index = i;
2389                                 tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
2390                         } else if (rf_num == 2) {
2391                                 if (cur_rf_rssi >= tmp_max_rssi) {
2392                                         tmp_max_rssi = cur_rf_rssi;
2393                                         max_rssi_index = i;
2394                                 } else {
2395                                         tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
2396                                         sec_rssi_index = min_rssi_index = i;
2397                                 }
2398                         } else {
2399                                 if (cur_rf_rssi > tmp_max_rssi) {
2400                                         tmp_sec_rssi = tmp_max_rssi;
2401                                         sec_rssi_index = max_rssi_index;
2402                                         tmp_max_rssi = cur_rf_rssi;
2403                                         max_rssi_index = i;
2404                                 } else if (cur_rf_rssi == tmp_max_rssi) {
2405                                         tmp_sec_rssi = cur_rf_rssi;
2406                                         sec_rssi_index = i;
2407                                 } else if ((cur_rf_rssi < tmp_max_rssi) &&
2408                                            (cur_rf_rssi > tmp_sec_rssi)) {
2409                                         tmp_sec_rssi = cur_rf_rssi;
2410                                         sec_rssi_index = i;
2411                                 } else if (cur_rf_rssi == tmp_sec_rssi) {
2412                                         if (tmp_sec_rssi == tmp_min_rssi) {
2413                                                 tmp_sec_rssi = cur_rf_rssi;
2414                                                 sec_rssi_index = i;
2415                                         }
2416                                 } else if ((cur_rf_rssi < tmp_sec_rssi) &&
2417                                            (cur_rf_rssi > tmp_min_rssi)) {
2418                                         ;
2419                                 } else if (cur_rf_rssi == tmp_min_rssi) {
2420                                         if (tmp_sec_rssi == tmp_min_rssi) {
2421                                                 tmp_min_rssi = cur_rf_rssi;
2422                                                 min_rssi_index = i;
2423                                         }
2424                                 } else if (cur_rf_rssi < tmp_min_rssi) {
2425                                         tmp_min_rssi = cur_rf_rssi;
2426                                         min_rssi_index = i;
2427                                 }
2428                         }
2429                 }
2430         }
2431
2432         rf_num = 0;
2433         if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) {
2434                 for (i = 0; i < RF90_PATH_MAX; i++) {
2435                         if (priv->brfpath_rxenable[i]) {
2436                                 rf_num++;
2437                                 cur_cck_pwdb =
2438                                          DM_RxPathSelTable.cck_pwdb_sta[i];
2439
2440                                 if (rf_num == 1) {
2441                                         cck_rx_ver2_max_index = i;
2442                                         cck_rx_ver2_min_index = i;
2443                                         cck_rx_ver2_sec_index = i;
2444                                         tmp_cck_max_pwdb = cur_cck_pwdb;
2445                                         tmp_cck_min_pwdb = cur_cck_pwdb;
2446                                         tmp_cck_sec_pwdb = cur_cck_pwdb;
2447                                 } else if (rf_num == 2) {
2448                                         if (cur_cck_pwdb >= tmp_cck_max_pwdb) {
2449                                                 tmp_cck_max_pwdb = cur_cck_pwdb;
2450                                                 cck_rx_ver2_max_index = i;
2451                                         } else {
2452                                                 tmp_cck_sec_pwdb = cur_cck_pwdb;
2453                                                 tmp_cck_min_pwdb = cur_cck_pwdb;
2454                                                 cck_rx_ver2_sec_index = i;
2455                                                 cck_rx_ver2_min_index = i;
2456                                         }
2457                                 } else {
2458                                         if (cur_cck_pwdb > tmp_cck_max_pwdb) {
2459                                                 tmp_cck_sec_pwdb =
2460                                                          tmp_cck_max_pwdb;
2461                                                 cck_rx_ver2_sec_index =
2462                                                          cck_rx_ver2_max_index;
2463                                                 tmp_cck_max_pwdb = cur_cck_pwdb;
2464                                                 cck_rx_ver2_max_index = i;
2465                                         } else if (cur_cck_pwdb ==
2466                                                    tmp_cck_max_pwdb) {
2467                                                 tmp_cck_sec_pwdb = cur_cck_pwdb;
2468                                                 cck_rx_ver2_sec_index = i;
2469                                         } else if (PWDB_IN_RANGE) {
2470                                                 tmp_cck_sec_pwdb = cur_cck_pwdb;
2471                                                 cck_rx_ver2_sec_index = i;
2472                                         } else if (cur_cck_pwdb ==
2473                                                    tmp_cck_sec_pwdb) {
2474                                                 if (tmp_cck_sec_pwdb ==
2475                                                     tmp_cck_min_pwdb) {
2476                                                         tmp_cck_sec_pwdb =
2477                                                                  cur_cck_pwdb;
2478                                                         cck_rx_ver2_sec_index =
2479                                                                  i;
2480                                                 }
2481                                         } else if ((cur_cck_pwdb < tmp_cck_sec_pwdb) &&
2482                                                    (cur_cck_pwdb > tmp_cck_min_pwdb)) {
2483                                                 ;
2484                                         } else if (cur_cck_pwdb == tmp_cck_min_pwdb) {
2485                                                 if (tmp_cck_sec_pwdb == tmp_cck_min_pwdb) {
2486                                                         tmp_cck_min_pwdb = cur_cck_pwdb;
2487                                                         cck_rx_ver2_min_index = i;
2488                                                 }
2489                                         } else if (cur_cck_pwdb < tmp_cck_min_pwdb) {
2490                                                 tmp_cck_min_pwdb = cur_cck_pwdb;
2491                                                 cck_rx_ver2_min_index = i;
2492                                         }
2493                                 }
2494
2495                         }
2496                 }
2497         }
2498
2499         update_cck_rx_path = 0;
2500         if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) {
2501                 cck_default_Rx = cck_rx_ver2_max_index;
2502                 cck_optional_Rx = cck_rx_ver2_sec_index;
2503                 if (tmp_cck_max_pwdb != -64)
2504                         update_cck_rx_path = 1;
2505         }
2506
2507         if (tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2) {
2508                 if ((tmp_max_rssi - tmp_min_rssi) >=
2509                      DM_RxPathSelTable.diff_TH) {
2510                         DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] =
2511                                  tmp_max_rssi+5;
2512                         rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable,
2513                                  0x1<<min_rssi_index, 0x0);
2514                         rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable,
2515                                  0x1<<min_rssi_index, 0x0);
2516                         disabled_rf_cnt++;
2517                 }
2518                 if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_1) {
2519                         cck_default_Rx = max_rssi_index;
2520                         cck_optional_Rx = sec_rssi_index;
2521                         if (tmp_max_rssi)
2522                                 update_cck_rx_path = 1;
2523                 }
2524         }
2525
2526         if (update_cck_rx_path) {
2527                 DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2) |
2528                                                 (cck_optional_Rx);
2529                 rtl8192_setBBreg(dev, rCCK0_AFESetting, 0x0f000000,
2530                                  DM_RxPathSelTable.cck_Rx_path);
2531         }
2532
2533         if (DM_RxPathSelTable.disabledRF) {
2534                 for (i = 0; i < 4; i++) {
2535                         if ((DM_RxPathSelTable.disabledRF>>i) & 0x1) {
2536                                 if (tmp_max_rssi >=
2537                                     DM_RxPathSelTable.rf_enable_rssi_th[i]) {
2538                                         rtl8192_setBBreg(dev,
2539                                                  rOFDM0_TRxPathEnable, 0x1 << i,
2540                                                  0x1);
2541                                         rtl8192_setBBreg(dev,
2542                                                  rOFDM1_TRxPathEnable,
2543                                                  0x1 << i, 0x1);
2544                                         DM_RxPathSelTable.rf_enable_rssi_th[i]
2545                                                  = 100;
2546                                         disabled_rf_cnt--;
2547                                 }
2548                         }
2549                 }
2550         }
2551 }
2552
2553 static  void    dm_check_rx_path_selection(struct net_device *dev)
2554 {
2555         struct r8192_priv *priv = rtllib_priv(dev);
2556
2557         queue_delayed_work_rsl(priv->priv_wq, &priv->rfpath_check_wq, 0);
2558 }
2559
2560
2561 static void dm_init_fsync(struct net_device *dev)
2562 {
2563         struct r8192_priv *priv = rtllib_priv(dev);
2564
2565         priv->rtllib->fsync_time_interval = 500;
2566         priv->rtllib->fsync_rate_bitmap = 0x0f000800;
2567         priv->rtllib->fsync_rssi_threshold = 30;
2568         priv->rtllib->bfsync_enable = false;
2569         priv->rtllib->fsync_multiple_timeinterval = 3;
2570         priv->rtllib->fsync_firstdiff_ratethreshold = 100;
2571         priv->rtllib->fsync_seconddiff_ratethreshold = 200;
2572         priv->rtllib->fsync_state = Default_Fsync;
2573         priv->framesyncMonitor = 1;
2574
2575         init_timer(&priv->fsync_timer);
2576         setup_timer(&priv->fsync_timer, dm_fsync_timer_callback,
2577                    (unsigned long) dev);
2578 }
2579
2580
2581 static void dm_deInit_fsync(struct net_device *dev)
2582 {
2583         struct r8192_priv *priv = rtllib_priv(dev);
2584         del_timer_sync(&priv->fsync_timer);
2585 }
2586
2587 void dm_fsync_timer_callback(unsigned long data)
2588 {
2589         struct net_device *dev = (struct net_device *)data;
2590         struct r8192_priv *priv = rtllib_priv((struct net_device *)data);
2591         u32 rate_index, rate_count = 0, rate_count_diff = 0;
2592         bool            bSwitchFromCountDiff = false;
2593         bool            bDoubleTimeInterval = false;
2594
2595         if (priv->rtllib->state == RTLLIB_LINKED &&
2596             priv->rtllib->bfsync_enable &&
2597             (priv->rtllib->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) {
2598                 u32 rate_bitmap;
2599                 for (rate_index = 0; rate_index <= 27; rate_index++) {
2600                         rate_bitmap  = 1 << rate_index;
2601                         if (priv->rtllib->fsync_rate_bitmap &  rate_bitmap)
2602                                 rate_count +=
2603                                    priv->stats.received_rate_histogram[1]
2604                                    [rate_index];
2605                 }
2606
2607                 if (rate_count < priv->rate_record)
2608                         rate_count_diff = 0xffffffff - rate_count +
2609                                           priv->rate_record;
2610                 else
2611                         rate_count_diff = rate_count - priv->rate_record;
2612                 if (rate_count_diff < priv->rateCountDiffRecord) {
2613
2614                         u32 DiffNum = priv->rateCountDiffRecord -
2615                                       rate_count_diff;
2616                         if (DiffNum >=
2617                             priv->rtllib->fsync_seconddiff_ratethreshold)
2618                                 priv->ContiuneDiffCount++;
2619                         else
2620                                 priv->ContiuneDiffCount = 0;
2621
2622                         if (priv->ContiuneDiffCount >= 2) {
2623                                 bSwitchFromCountDiff = true;
2624                                 priv->ContiuneDiffCount = 0;
2625                         }
2626                 } else {
2627                         priv->ContiuneDiffCount = 0;
2628                 }
2629
2630                 if (rate_count_diff <=
2631                     priv->rtllib->fsync_firstdiff_ratethreshold) {
2632                         bSwitchFromCountDiff = true;
2633                         priv->ContiuneDiffCount = 0;
2634                 }
2635                 priv->rate_record = rate_count;
2636                 priv->rateCountDiffRecord = rate_count_diff;
2637                 RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rate"
2638                          "Countdiff %d bSwitchFsync %d\n", priv->rate_record,
2639                          rate_count, rate_count_diff, priv->bswitch_fsync);
2640                 if (priv->undecorated_smoothed_pwdb >
2641                     priv->rtllib->fsync_rssi_threshold &&
2642                     bSwitchFromCountDiff) {
2643                         bDoubleTimeInterval = true;
2644                         priv->bswitch_fsync = !priv->bswitch_fsync;
2645                         if (priv->bswitch_fsync) {
2646                                 write_nic_byte(dev, 0xC36, 0x1c);
2647                                 write_nic_byte(dev, 0xC3e, 0x90);
2648                         } else {
2649                                 write_nic_byte(dev, 0xC36, 0x5c);
2650                                 write_nic_byte(dev, 0xC3e, 0x96);
2651                         }
2652                 } else if (priv->undecorated_smoothed_pwdb <=
2653                            priv->rtllib->fsync_rssi_threshold) {
2654                         if (priv->bswitch_fsync) {
2655                                 priv->bswitch_fsync  = false;
2656                                 write_nic_byte(dev, 0xC36, 0x5c);
2657                                 write_nic_byte(dev, 0xC3e, 0x96);
2658                         }
2659                 }
2660                 if (bDoubleTimeInterval) {
2661                         if (timer_pending(&priv->fsync_timer))
2662                                 del_timer_sync(&priv->fsync_timer);
2663                         priv->fsync_timer.expires = jiffies +
2664                                  MSECS(priv->rtllib->fsync_time_interval *
2665                                  priv->rtllib->fsync_multiple_timeinterval);
2666                         add_timer(&priv->fsync_timer);
2667                 } else {
2668                         if (timer_pending(&priv->fsync_timer))
2669                                 del_timer_sync(&priv->fsync_timer);
2670                         priv->fsync_timer.expires = jiffies +
2671                                  MSECS(priv->rtllib->fsync_time_interval);
2672                         add_timer(&priv->fsync_timer);
2673                 }
2674         } else {
2675                 if (priv->bswitch_fsync) {
2676                         priv->bswitch_fsync  = false;
2677                         write_nic_byte(dev, 0xC36, 0x5c);
2678                         write_nic_byte(dev, 0xC3e, 0x96);
2679                 }
2680                 priv->ContiuneDiffCount = 0;
2681                 write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
2682         }
2683         RT_TRACE(COMP_HALDM, "ContiuneDiffCount %d\n", priv->ContiuneDiffCount);
2684         RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d "
2685                  "bSwitchFsync %d\n", priv->rate_record, rate_count,
2686                  rate_count_diff, priv->bswitch_fsync);
2687 }
2688
2689 static void dm_StartHWFsync(struct net_device *dev)
2690 {
2691         u8 rf_timing = 0x77;
2692         struct r8192_priv *priv = rtllib_priv(dev);
2693         RT_TRACE(COMP_HALDM, "%s\n", __func__);
2694         write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cf);
2695         priv->rtllib->SetHwRegHandler(dev, HW_VAR_RF_TIMING,
2696                                       (u8 *)(&rf_timing));
2697         write_nic_byte(dev, 0xc3b, 0x41);
2698 }
2699
2700 static void dm_EndHWFsync(struct net_device *dev)
2701 {
2702         u8 rf_timing = 0xaa;
2703         struct r8192_priv *priv = rtllib_priv(dev);
2704         RT_TRACE(COMP_HALDM, "%s\n", __func__);
2705         write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
2706         priv->rtllib->SetHwRegHandler(dev, HW_VAR_RF_TIMING, (u8 *)
2707                                      (&rf_timing));
2708         write_nic_byte(dev, 0xc3b, 0x49);
2709 }
2710
2711 static void dm_EndSWFsync(struct net_device *dev)
2712 {
2713         struct r8192_priv *priv = rtllib_priv(dev);
2714
2715         RT_TRACE(COMP_HALDM, "%s\n", __func__);
2716         del_timer_sync(&(priv->fsync_timer));
2717
2718         if (priv->bswitch_fsync) {
2719                 priv->bswitch_fsync  = false;
2720
2721                 write_nic_byte(dev, 0xC36, 0x5c);
2722
2723                 write_nic_byte(dev, 0xC3e, 0x96);
2724         }
2725
2726         priv->ContiuneDiffCount = 0;
2727         write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
2728 }
2729
2730 static void dm_StartSWFsync(struct net_device *dev)
2731 {
2732         struct r8192_priv *priv = rtllib_priv(dev);
2733         u32                     rateIndex;
2734         u32                     rateBitmap;
2735
2736         RT_TRACE(COMP_HALDM, "%s\n", __func__);
2737         priv->rate_record = 0;
2738         priv->ContiuneDiffCount = 0;
2739         priv->rateCountDiffRecord = 0;
2740         priv->bswitch_fsync  = false;
2741
2742         if (priv->rtllib->mode == WIRELESS_MODE_N_24G) {
2743                 priv->rtllib->fsync_firstdiff_ratethreshold = 600;
2744                 priv->rtllib->fsync_seconddiff_ratethreshold = 0xffff;
2745         } else {
2746                 priv->rtllib->fsync_firstdiff_ratethreshold = 200;
2747                 priv->rtllib->fsync_seconddiff_ratethreshold = 200;
2748         }
2749         for (rateIndex = 0; rateIndex <= 27; rateIndex++) {
2750                 rateBitmap  = 1 << rateIndex;
2751                 if (priv->rtllib->fsync_rate_bitmap & rateBitmap)
2752                         priv->rate_record +=
2753                                  priv->stats.received_rate_histogram[1]
2754                                 [rateIndex];
2755         }
2756         if (timer_pending(&priv->fsync_timer))
2757                 del_timer_sync(&priv->fsync_timer);
2758         priv->fsync_timer.expires = jiffies +
2759                                     MSECS(priv->rtllib->fsync_time_interval);
2760         add_timer(&priv->fsync_timer);
2761
2762         write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd);
2763
2764 }
2765
2766 void dm_check_fsync(struct net_device *dev)
2767 {
2768 #define RegC38_Default                  0
2769 #define RegC38_NonFsync_Other_AP        1
2770 #define RegC38_Fsync_AP_BCM             2
2771         struct r8192_priv *priv = rtllib_priv(dev);
2772         static u8 reg_c38_State = RegC38_Default;
2773         static u32 reset_cnt;
2774
2775         RT_TRACE(COMP_HALDM, "RSSI %d TimeInterval %d MultipleTimeInterval "
2776                  "%d\n", priv->rtllib->fsync_rssi_threshold,
2777                  priv->rtllib->fsync_time_interval,
2778                  priv->rtllib->fsync_multiple_timeinterval);
2779         RT_TRACE(COMP_HALDM, "RateBitmap 0x%x FirstDiffRateThreshold %d Second"
2780                  "DiffRateThreshold %d\n", 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         if (priv->rtllib->bdynamic_txpower_enable != true) {
2927                 priv->bDynamicTxHighPower = false;
2928                 priv->bDynamicTxLowPower = false;
2929                 return;
2930         }
2931         if ((priv->rtllib->pHTInfo->IOTPeer == HT_IOT_PEER_ATHEROS) &&
2932             (priv->rtllib->mode == IEEE_G)) {
2933                 txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH;
2934                 txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
2935         } else {
2936                 txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
2937                 txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
2938         }
2939
2940         RT_TRACE(COMP_TXAGC, "priv->undecorated_smoothed_pwdb = %ld\n",
2941                  priv->undecorated_smoothed_pwdb);
2942
2943         if (priv->rtllib->state == RTLLIB_LINKED) {
2944                 if (priv->undecorated_smoothed_pwdb >= txhipower_threshhold) {
2945                         priv->bDynamicTxHighPower = true;
2946                         priv->bDynamicTxLowPower = false;
2947                 } else {
2948                         if (priv->undecorated_smoothed_pwdb <
2949                             txlowpower_threshold &&
2950                             priv->bDynamicTxHighPower == true)
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 }