Merge branches 'pm-domains' and 'pm-cpufreq'
[deliverable/linux.git] / drivers / staging / rtl8192u / r8192U_dm.c
CommitLineData
8fc8598e
JC
1/*++
2Copyright-c Realtek Semiconductor Corp. All rights reserved.
3
4Module Name:
5 r8192U_dm.c
6
7Abstract:
8 HW dynamic mechanism.
9
10Major Change History:
35997ff0 11 When Who What
8fc8598e
JC
12 ---------- --------------- -------------------------------
13 2008-05-14 amy create version 0 porting from windows code.
14
15--*/
16#include "r8192U.h"
17#include "r8192U_dm.h"
18#include "r8192U_hw.h"
19#include "r819xU_phy.h"
20#include "r819xU_phyreg.h"
21#include "r8190_rtl8256.h"
22#include "r819xU_cmdpkt.h"
23/*---------------------------Define Local Constant---------------------------*/
e1da1d57 24/* Indicate different AP vendor for IOT issue. */
04d695d7
LS
25static u32 edca_setting_DL[HT_IOT_PEER_MAX] = {
26 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0x00a44f, 0x5ea44f
27};
28static u32 edca_setting_UL[HT_IOT_PEER_MAX] = {
29 0x5e4322, 0x00a44f, 0x5e4322, 0x604322, 0x5ea44f, 0x5ea44f
30};
8fc8598e
JC
31
32#define RTK_UL_EDCA 0xa44f
33#define RTK_DL_EDCA 0x5e4322
34/*---------------------------Define Local Constant---------------------------*/
35
36
37/*------------------------Define global variable-----------------------------*/
e1da1d57 38/* Debug variable ? */
70dada1a 39struct dig dm_digtable;
e1da1d57 40/* Store current software write register content for MAC PHY. */
04d695d7 41u8 dm_shadow[16][256] = { {0} };
e1da1d57 42/* For Dynamic Rx Path Selection by Signal Strength */
3962d2af 43struct dynamic_rx_path_sel DM_RxPathSelTable;
70dada1a 44
8fc8598e
JC
45/*------------------------Define global variable-----------------------------*/
46
47
48/*------------------------Define local variable------------------------------*/
49/*------------------------Define local variable------------------------------*/
50
51
52/*--------------------Define export function prototype-----------------------*/
8fc8598e 53extern void dm_check_fsync(struct net_device *dev);
8fc8598e
JC
54
55/*--------------------Define export function prototype-----------------------*/
56
57
58/*---------------------Define local function prototype-----------------------*/
e1da1d57 59/* DM --> Rate Adaptive */
8fc8598e
JC
60static void dm_check_rate_adaptive(struct net_device *dev);
61
e1da1d57 62/* DM --> Bandwidth switch */
8fc8598e 63static void dm_init_bandwidth_autoswitch(struct net_device *dev);
0009631b 64static void dm_bandwidth_autoswitch(struct net_device *dev);
8fc8598e 65
e1da1d57
LS
66/* DM --> TX power control */
67/*static void dm_initialize_txpower_tracking(struct net_device *dev);*/
8fc8598e
JC
68
69static void dm_check_txpower_tracking(struct net_device *dev);
70
e1da1d57 71/*static void dm_txpower_reset_recovery(struct net_device *dev);*/
8fc8598e 72
e1da1d57 73/* DM --> Dynamic Init Gain by RSSI */
8fc8598e
JC
74static void dm_dig_init(struct net_device *dev);
75static void dm_ctrl_initgain_byrssi(struct net_device *dev);
76static void dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev);
0009631b 77static void dm_ctrl_initgain_byrssi_by_driverrssi(struct net_device *dev);
8fc8598e
JC
78static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct net_device *dev);
79static void dm_initial_gain(struct net_device *dev);
80static void dm_pd_th(struct net_device *dev);
81static void dm_cs_ratio(struct net_device *dev);
82
83static void dm_init_ctstoself(struct net_device *dev);
e1da1d57 84/* DM --> EDCA turbo mode control */
8fc8598e
JC
85static void dm_check_edca_turbo(struct net_device *dev);
86
e1da1d57
LS
87/*static void dm_gpio_change_rf(struct net_device *dev);*/
88/* DM --> Check PBC */
8fc8598e
JC
89static void dm_check_pbc_gpio(struct net_device *dev);
90
e1da1d57 91/* DM --> Check current RX RF path state */
8fc8598e 92static void dm_check_rx_path_selection(struct net_device *dev);
35997ff0 93static void dm_init_rxpath_selection(struct net_device *dev);
8fc8598e
JC
94static void dm_rxpath_sel_byrssi(struct net_device *dev);
95
e1da1d57 96/* DM --> Fsync for broadcom ap */
8fc8598e
JC
97static void dm_init_fsync(struct net_device *dev);
98static void dm_deInit_fsync(struct net_device *dev);
99
e1da1d57 100/* Added by vivi, 20080522 */
8fc8598e
JC
101static void dm_check_txrateandretrycount(struct net_device *dev);
102
103/*---------------------Define local function prototype-----------------------*/
104
e1da1d57 105/*---------------------Define of Tx Power Control For Near/Far Range --------*/ /*Add by Jacken 2008/02/18 */
8fc8598e
JC
106static void dm_init_dynamic_txpower(struct net_device *dev);
107static void dm_dynamic_txpower(struct net_device *dev);
108
e1da1d57 109/* DM --> For rate adaptive and DIG, we must send RSSI to firmware */
8fc8598e
JC
110static void dm_send_rssi_tofw(struct net_device *dev);
111static void dm_ctstoself(struct net_device *dev);
112/*---------------------------Define function prototype------------------------*/
e1da1d57
LS
113/*
114 * ================================================================================
115 * HW Dynamic mechanism interface.
116 * ================================================================================
117 *
118 *
119 * Description:
120 * Prepare SW resource for HW dynamic mechanism.
121 *
122 * Assumption:
69e98df7 123 * This function is only invoked at driver initialization once.
e1da1d57 124 */
bf316434 125void init_hal_dm(struct net_device *dev)
8fc8598e
JC
126{
127 struct r8192_priv *priv = ieee80211_priv(dev);
128
e1da1d57 129 /* Undecorated Smoothed Signal Strength, it can utilized to dynamic mechanism. */
8fc8598e
JC
130 priv->undecorated_smoothed_pwdb = -1;
131
e1da1d57 132 /* Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code. */
8fc8598e
JC
133 dm_init_dynamic_txpower(dev);
134 init_rate_adaptive(dev);
e1da1d57 135 /*dm_initialize_txpower_tracking(dev);*/
8fc8598e
JC
136 dm_dig_init(dev);
137 dm_init_edca_turbo(dev);
138 dm_init_bandwidth_autoswitch(dev);
139 dm_init_fsync(dev);
140 dm_init_rxpath_selection(dev);
141 dm_init_ctstoself(dev);
142
e1da1d57 143} /* InitHalDm */
8fc8598e 144
c541fa87 145void deinit_hal_dm(struct net_device *dev)
8fc8598e 146{
8fc8598e 147 dm_deInit_fsync(dev);
8fc8598e
JC
148}
149
8fc8598e 150#ifdef USB_RX_AGGREGATION_SUPPORT
04d695d7
LS
151void dm_CheckRxAggregation(struct net_device *dev)
152{
8fc8598e
JC
153 struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
154 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
de13a3da
SH
155 static unsigned long lastTxOkCnt;
156 static unsigned long lastRxOkCnt;
8fc8598e
JC
157 unsigned long curTxOkCnt = 0;
158 unsigned long curRxOkCnt = 0;
159
160/*
161 if (pHalData->bForcedUsbRxAggr) {
162 if (pHalData->ForcedUsbRxAggrInfo == 0) {
163 if (pHalData->bCurrentRxAggrEnable) {
164 Adapter->HalFunc.HalUsbRxAggrHandler(Adapter, FALSE);
165 }
166 } else {
167 if (!pHalData->bCurrentRxAggrEnable || (pHalData->ForcedUsbRxAggrInfo != pHalData->LastUsbRxAggrInfoSetting)) {
168 Adapter->HalFunc.HalUsbRxAggrHandler(Adapter, TRUE);
169 }
170 }
171 return;
172 }
173
174*/
175 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
176 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
177
2930d0b9 178 if ((curTxOkCnt + curRxOkCnt) < 15000000)
8fc8598e 179 return;
8fc8598e 180
04d695d7 181 if (curTxOkCnt > 4*curRxOkCnt) {
8fc8598e
JC
182 if (priv->bCurrentRxAggrEnable) {
183 write_nic_dword(dev, 0x1a8, 0);
184 priv->bCurrentRxAggrEnable = false;
185 }
04d695d7 186 } else {
8fc8598e
JC
187 if (!priv->bCurrentRxAggrEnable && !pHTInfo->bCurrentRT2RTAggregation) {
188 u32 ulValue;
04d695d7 189
8fc8598e
JC
190 ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
191 (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
192 /*
193 * If usb rx firmware aggregation is enabled,
194 * when anyone of three threshold conditions above is reached,
195 * firmware will send aggregated packet to driver.
196 */
197 write_nic_dword(dev, 0x1a8, ulValue);
198 priv->bCurrentRxAggrEnable = true;
199 }
200 }
201
202 lastTxOkCnt = priv->stats.txbytesunicast;
203 lastRxOkCnt = priv->stats.rxbytesunicast;
e1da1d57 204} /* dm_CheckEdcaTurbo */
8fc8598e
JC
205#endif
206
bf316434 207void hal_dm_watchdog(struct net_device *dev)
8fc8598e 208{
e1da1d57 209 /*struct r8192_priv *priv = ieee80211_priv(dev);*/
8fc8598e 210
e1da1d57 211 /*static u8 previous_bssid[6] ={0};*/
8fc8598e
JC
212
213 /*Add by amy 2008/05/15 ,porting from windows code.*/
214 dm_check_rate_adaptive(dev);
215 dm_dynamic_txpower(dev);
216 dm_check_txrateandretrycount(dev);
217 dm_check_txpower_tracking(dev);
218 dm_ctrl_initgain_byrssi(dev);
219 dm_check_edca_turbo(dev);
220 dm_bandwidth_autoswitch(dev);
8fc8598e
JC
221 dm_check_rx_path_selection(dev);
222 dm_check_fsync(dev);
223
e1da1d57 224 /* Add by amy 2008-05-15 porting from windows code. */
8fc8598e
JC
225 dm_check_pbc_gpio(dev);
226 dm_send_rssi_tofw(dev);
227 dm_ctstoself(dev);
228#ifdef USB_RX_AGGREGATION_SUPPORT
229 dm_CheckRxAggregation(dev);
230#endif
e1da1d57 231} /* HalDmWatchDog */
8fc8598e 232
8fc8598e 233/*
e1da1d57
LS
234 * Decide Rate Adaptive Set according to distance (signal strength)
235 * 01/11/2008 MHC Modify input arguments and RATR table level.
236 * 01/16/2008 MHC RF_Type is assigned in ReadAdapterInfo(). We must call
237 * the function after making sure RF_Type.
238 */
c541fa87 239void init_rate_adaptive(struct net_device *dev)
8fc8598e 240{
8fc8598e
JC
241 struct r8192_priv *priv = ieee80211_priv(dev);
242 prate_adaptive pra = (prate_adaptive)&priv->rate_adaptive;
243
244 pra->ratr_state = DM_RATR_STA_MAX;
245 pra->high2low_rssi_thresh_for_ra = RateAdaptiveTH_High;
246 pra->low2high_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M+5;
247 pra->low2high_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M+5;
248
249 pra->high_rssi_thresh_for_ra = RateAdaptiveTH_High+5;
250 pra->low_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M;
251 pra->low_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M;
252
04d695d7 253 if (priv->CustomerID == RT_CID_819x_Netcore)
8fc8598e
JC
254 pra->ping_rssi_enable = 1;
255 else
256 pra->ping_rssi_enable = 0;
257 pra->ping_rssi_thresh_for_ra = 15;
258
04d695d7 259 if (priv->rf_type == RF_2T4R) {
e1da1d57
LS
260 /*
261 * 07/10/08 MH Modify for RA smooth scheme.
262 * 2008/01/11 MH Modify 2T RATR table for different RSSI. 080515 porting by amy from windows code.
263 */
35997ff0
SH
264 pra->upper_rssi_threshold_ratr = 0x8f0f0000;
265 pra->middle_rssi_threshold_ratr = 0x8f0ff000;
266 pra->low_rssi_threshold_ratr = 0x8f0ff001;
267 pra->low_rssi_threshold_ratr_40M = 0x8f0ff005;
268 pra->low_rssi_threshold_ratr_20M = 0x8f0ff001;
e1da1d57 269 pra->ping_rssi_ratr = 0x0000000d;/* cosa add for test */
04d695d7 270 } else if (priv->rf_type == RF_1T2R) {
35997ff0
SH
271 pra->upper_rssi_threshold_ratr = 0x000f0000;
272 pra->middle_rssi_threshold_ratr = 0x000ff000;
273 pra->low_rssi_threshold_ratr = 0x000ff001;
274 pra->low_rssi_threshold_ratr_40M = 0x000ff005;
275 pra->low_rssi_threshold_ratr_20M = 0x000ff001;
e1da1d57 276 pra->ping_rssi_ratr = 0x0000000d;/* cosa add for test */
8fc8598e
JC
277 }
278
e1da1d57 279} /* InitRateAdaptive */
8fc8598e 280
8fc8598e
JC
281/*-----------------------------------------------------------------------------
282 * Function: dm_check_rate_adaptive()
283 *
284 * Overview:
285 *
286 * Input: NONE
287 *
288 * Output: NONE
289 *
290 * Return: NONE
291 *
292 * Revised History:
293 * When Who Remark
35997ff0 294 * 05/26/08 amy Create version 0 porting from windows code.
8fc8598e
JC
295 *
296 *---------------------------------------------------------------------------*/
999d594b 297static void dm_check_rate_adaptive(struct net_device *dev)
8fc8598e
JC
298{
299 struct r8192_priv *priv = ieee80211_priv(dev);
300 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
301 prate_adaptive pra = (prate_adaptive)&priv->rate_adaptive;
302 u32 currentRATR, targetRATR = 0;
303 u32 LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0;
304 bool bshort_gi_enabled = false;
de13a3da 305 static u8 ping_rssi_state;
8fc8598e 306
04d695d7 307 if (!priv->up) {
8fc8598e
JC
308 RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n");
309 return;
310 }
311
04d695d7 312 if (pra->rate_adaptive_disabled) /* this variable is set by ioctl. */
8fc8598e
JC
313 return;
314
e1da1d57 315 /* TODO: Only 11n mode is implemented currently, */
04d695d7
LS
316 if (!(priv->ieee80211->mode == WIRELESS_MODE_N_24G ||
317 priv->ieee80211->mode == WIRELESS_MODE_N_5G))
318 return;
8fc8598e 319
04d695d7 320 if (priv->ieee80211->state == IEEE80211_LINKED) {
e1da1d57 321 /*RT_TRACE(COMP_RATE, "dm_CheckRateAdaptive(): \t");*/
8fc8598e 322
e1da1d57 323 /* Check whether Short GI is enabled */
8fc8598e
JC
324 bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) ||
325 (!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz);
326
8fc8598e 327 pra->upper_rssi_threshold_ratr =
56b3152e
AB
328 (pra->upper_rssi_threshold_ratr & (~BIT(31))) |
329 ((bshort_gi_enabled) ? BIT(31) : 0);
8fc8598e
JC
330
331 pra->middle_rssi_threshold_ratr =
56b3152e
AB
332 (pra->middle_rssi_threshold_ratr & (~BIT(31))) |
333 ((bshort_gi_enabled) ? BIT(31) : 0);
8fc8598e 334
04d695d7 335 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
8fc8598e 336 pra->low_rssi_threshold_ratr =
56b3152e
AB
337 (pra->low_rssi_threshold_ratr_40M & (~BIT(31))) |
338 ((bshort_gi_enabled) ? BIT(31) : 0);
04d695d7 339 } else {
8fc8598e 340 pra->low_rssi_threshold_ratr =
56b3152e
AB
341 (pra->low_rssi_threshold_ratr_20M & (~BIT(31))) |
342 ((bshort_gi_enabled) ? BIT(31) : 0);
8fc8598e 343 }
e1da1d57 344 /* cosa add for test */
8fc8598e 345 pra->ping_rssi_ratr =
56b3152e
AB
346 (pra->ping_rssi_ratr & (~BIT(31))) |
347 ((bshort_gi_enabled) ? BIT(31) : 0);
8fc8598e
JC
348
349 /* 2007/10/08 MH We support RA smooth scheme now. When it is the first
350 time to link with AP. We will not change upper/lower threshold. If
351 STA stay in high or low level, we must change two different threshold
352 to prevent jumping frequently. */
04d695d7 353 if (pra->ratr_state == DM_RATR_STA_HIGH) {
35997ff0 354 HighRSSIThreshForRA = pra->high2low_rssi_thresh_for_ra;
04d695d7 355 LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
8fc8598e 356 (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
04d695d7 357 } else if (pra->ratr_state == DM_RATR_STA_LOW) {
8fc8598e 358 HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra;
04d695d7 359 LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
8fc8598e 360 (pra->low2high_rssi_thresh_for_ra40M):(pra->low2high_rssi_thresh_for_ra20M);
04d695d7 361 } else {
8fc8598e 362 HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra;
04d695d7 363 LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
8fc8598e
JC
364 (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
365 }
366
e1da1d57 367 /*DbgPrint("[DM] THresh H/L=%d/%d\n\r", RATR.HighRSSIThreshForRA, RATR.LowRSSIThreshForRA);*/
04d695d7 368 if (priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA) {
e1da1d57 369 /*DbgPrint("[DM] RSSI=%d STA=HIGH\n\r", pHalData->UndecoratedSmoothedPWDB);*/
8fc8598e
JC
370 pra->ratr_state = DM_RATR_STA_HIGH;
371 targetRATR = pra->upper_rssi_threshold_ratr;
04d695d7 372 } else if (priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA) {
e1da1d57 373 /*DbgPrint("[DM] RSSI=%d STA=Middle\n\r", pHalData->UndecoratedSmoothedPWDB);*/
8fc8598e
JC
374 pra->ratr_state = DM_RATR_STA_MIDDLE;
375 targetRATR = pra->middle_rssi_threshold_ratr;
04d695d7 376 } else {
e1da1d57 377 /*DbgPrint("[DM] RSSI=%d STA=LOW\n\r", pHalData->UndecoratedSmoothedPWDB);*/
8fc8598e
JC
378 pra->ratr_state = DM_RATR_STA_LOW;
379 targetRATR = pra->low_rssi_threshold_ratr;
380 }
381
e1da1d57 382 /* cosa add for test */
04d695d7 383 if (pra->ping_rssi_enable) {
e1da1d57 384 /*pHalData->UndecoratedSmoothedPWDB = 19;*/
04d695d7
LS
385 if (priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5)) {
386 if ((priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) ||
387 ping_rssi_state) {
388 /*DbgPrint("TestRSSI = %d, set RATR to 0x%x\n", pHalData->UndecoratedSmoothedPWDB, pRA->TestRSSIRATR);*/
8fc8598e
JC
389 pra->ratr_state = DM_RATR_STA_LOW;
390 targetRATR = pra->ping_rssi_ratr;
391 ping_rssi_state = 1;
392 }
e1da1d57 393 /*else
04d695d7
LS
394 DbgPrint("TestRSSI is between the range.\n");*/
395 } else {
396 /*DbgPrint("TestRSSI Recover to 0x%x\n", targetRATR);*/
8fc8598e
JC
397 ping_rssi_state = 0;
398 }
399 }
400
e1da1d57
LS
401 /*
402 * 2008.04.01
403 * For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7.
404 */
04d695d7
LS
405 if (priv->ieee80211->GetHalfNmodeSupportByAPsHandler(dev))
406 targetRATR &= 0xf00fffff;
8fc8598e 407
e1da1d57 408 /* Check whether updating of RATR0 is required */
b3d42bf1 409 read_nic_dword(dev, RATR0, &currentRATR);
04d695d7 410 if (targetRATR != currentRATR) {
8fc8598e 411 u32 ratr_value;
04d695d7 412
8fc8598e 413 ratr_value = targetRATR;
04d695d7 414 RT_TRACE(COMP_RATE, "currentRATR = %x, targetRATR = %x\n", currentRATR, targetRATR);
16da7808 415 if (priv->rf_type == RF_1T2R)
8fc8598e 416 ratr_value &= ~(RATE_ALL_OFDM_2SS);
8fc8598e
JC
417 write_nic_dword(dev, RATR0, ratr_value);
418 write_nic_byte(dev, UFWP, 1);
419
420 pra->last_ratr = targetRATR;
421 }
422
04d695d7 423 } else {
8fc8598e
JC
424 pra->ratr_state = DM_RATR_STA_MAX;
425 }
426
e1da1d57 427} /* dm_CheckRateAdaptive */
8fc8598e 428
999d594b 429static void dm_init_bandwidth_autoswitch(struct net_device *dev)
8fc8598e
JC
430{
431 struct r8192_priv *priv = ieee80211_priv(dev);
432
433 priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH;
434 priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW;
435 priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
436 priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable = false;
437
e1da1d57 438} /* dm_init_bandwidth_autoswitch */
8fc8598e 439
999d594b 440static void dm_bandwidth_autoswitch(struct net_device *dev)
8fc8598e
JC
441{
442 struct r8192_priv *priv = ieee80211_priv(dev);
443
16da7808 444 if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 || !priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable)
8fc8598e 445 return;
f9bd549a 446 if (!priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz) { /* If send packets in 40 Mhz in 20/40 */
04d695d7 447 if (priv->undecorated_smoothed_pwdb <= priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz)
2fd8feab 448 priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = true;
04d695d7
LS
449 } else { /* in force send packets in 20 Mhz in 20/40 */
450 if (priv->undecorated_smoothed_pwdb >= priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz)
2fd8feab 451 priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
8fc8598e 452 }
e1da1d57 453} /* dm_BandwidthAutoSwitch */
8fc8598e 454
e1da1d57 455/* OFDM default at 0db, index=6. */
8fc8598e 456static u32 OFDMSwingTable[OFDM_Table_Length] = {
e1da1d57
LS
457 0x7f8001fe, /* 0, +6db */
458 0x71c001c7, /* 1, +5db */
459 0x65400195, /* 2, +4db */
460 0x5a400169, /* 3, +3db */
461 0x50800142, /* 4, +2db */
462 0x47c0011f, /* 5, +1db */
463 0x40000100, /* 6, +0db ===> default, upper for higher temperature, lower for low temperature */
464 0x390000e4, /* 7, -1db */
465 0x32c000cb, /* 8, -2db */
466 0x2d4000b5, /* 9, -3db */
467 0x288000a2, /* 10, -4db */
468 0x24000090, /* 11, -5db */
469 0x20000080, /* 12, -6db */
470 0x1c800072, /* 13, -7db */
471 0x19800066, /* 14, -8db */
472 0x26c0005b, /* 15, -9db */
473 0x24400051, /* 16, -10db */
474 0x12000048, /* 17, -11db */
475 0x10000040 /* 18, -12db */
8fc8598e
JC
476};
477
478static u8 CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = {
e1da1d57
LS
479 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, /* 0, +0db ===> CCK40M default */
480 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 1, -1db */
481 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 2, -2db */
482 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 3, -3db */
483 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 4, -4db */
484 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 5, -5db */
485 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 6, -6db ===> CCK20M default */
486 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 7, -7db */
487 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 8, -8db */
488 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 9, -9db */
489 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 10, -10db */
490 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01} /* 11, -11db */
8fc8598e
JC
491};
492
493static u8 CCKSwingTable_Ch14[CCK_Table_length][8] = {
e1da1d57
LS
494 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, /* 0, +0db ===> CCK40M default */
495 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 1, -1db */
496 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 2, -2db */
497 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 3, -3db */
498 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 4, -4db */
499 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 5, -5db */
500 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 6, -6db ===> CCK20M default */
501 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 7, -7db */
502 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 8, -8db */
503 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 9, -9db */
504 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 10, -10db */
505 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00} /* 11, -11db */
8fc8598e
JC
506};
507
999d594b 508static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
8fc8598e
JC
509{
510 struct r8192_priv *priv = ieee80211_priv(dev);
4b2faf80 511 bool bHighpowerstate, viviflag = false;
8fc8598e
JC
512 DCMD_TXCMD_T tx_cmd;
513 u8 powerlevelOFDM24G;
04d695d7
LS
514 int i = 0, j = 0, k = 0;
515 u8 RF_Type, tmp_report[5] = {0, 0, 0, 0, 0};
8fc8598e
JC
516 u32 Value;
517 u8 Pwr_Flag;
04d695d7 518 u16 Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver = 0;
e1da1d57 519 /*RT_STATUS rtStatus = RT_STATUS_SUCCESS;*/
8fc8598e 520 bool rtStatus = true;
04d695d7 521 u32 delta = 0;
8fc8598e
JC
522
523 write_nic_byte(dev, 0x1ba, 0);
524
525 priv->ieee80211->bdynamic_txpower_enable = false;
526 bHighpowerstate = priv->bDynamicTxHighPower;
527
528 powerlevelOFDM24G = (u8)(priv->Pwr_Track>>24);
529 RF_Type = priv->rf_type;
530 Value = (RF_Type<<8) | powerlevelOFDM24G;
531
532 RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n", powerlevelOFDM24G);
533
04d695d7
LS
534 for (j = 0; j <= 30; j++) { /* fill tx_cmd */
535 tx_cmd.Op = TXCMD_SET_TX_PWR_TRACKING;
536 tx_cmd.Length = 4;
537 tx_cmd.Value = Value;
538 rtStatus = SendTxCommandPacket(dev, &tx_cmd, 12);
16da7808 539 if (rtStatus == RT_STATUS_FAILURE)
04d695d7 540 RT_TRACE(COMP_POWER_TRACKING, "Set configuration with tx cmd queue fail!\n");
04d695d7
LS
541 mdelay(1);
542 /*DbgPrint("hi, vivi, strange\n");*/
543 for (i = 0; i <= 30; i++) {
544 read_nic_byte(dev, 0x1ba, &Pwr_Flag);
545
546 if (Pwr_Flag == 0) {
547 mdelay(1);
548 continue;
549 }
550 read_nic_word(dev, 0x13c, &Avg_TSSI_Meas);
551 if (Avg_TSSI_Meas == 0) {
552 write_nic_byte(dev, 0x1ba, 0);
8fc8598e
JC
553 break;
554 }
8fc8598e 555
04d695d7
LS
556 for (k = 0; k < 5; k++) {
557 if (k != 4)
558 read_nic_byte(dev, 0x134+k, &tmp_report[k]);
559 else
560 read_nic_byte(dev, 0x13e, &tmp_report[k]);
561 RT_TRACE(COMP_POWER_TRACKING, "TSSI_report_value = %d\n", tmp_report[k]);
562 }
8fc8598e 563
04d695d7
LS
564 /* check if the report value is right */
565 for (k = 0; k < 5; k++) {
566 if (tmp_report[k] <= 20) {
4b2faf80 567 viviflag = true;
04d695d7 568 break;
8fc8598e
JC
569 }
570 }
c40753b5 571 if (viviflag) {
04d695d7 572 write_nic_byte(dev, 0x1ba, 0);
4b2faf80 573 viviflag = false;
04d695d7
LS
574 RT_TRACE(COMP_POWER_TRACKING, "we filtered the data\n");
575 for (k = 0; k < 5; k++)
576 tmp_report[k] = 0;
577 break;
578 }
8fc8598e 579
16da7808 580 for (k = 0; k < 5; k++)
04d695d7 581 Avg_TSSI_Meas_from_driver += tmp_report[k];
8fc8598e 582
04d695d7
LS
583 Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5;
584 RT_TRACE(COMP_POWER_TRACKING, "Avg_TSSI_Meas_from_driver = %d\n", Avg_TSSI_Meas_from_driver);
585 TSSI_13dBm = priv->TSSI_13dBm;
586 RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm);
587
588 /*if (abs(Avg_TSSI_Meas_from_driver - TSSI_13dBm) <= E_FOR_TX_POWER_TRACK)*/
589 /* For MacOS-compatible */
590 if (Avg_TSSI_Meas_from_driver > TSSI_13dBm)
591 delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm;
8fc8598e 592 else
04d695d7
LS
593 delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver;
594
595 if (delta <= E_FOR_TX_POWER_TRACK) {
4b2faf80 596 priv->ieee80211->bdynamic_txpower_enable = true;
04d695d7
LS
597 write_nic_byte(dev, 0x1ba, 0);
598 RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n");
599 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
600 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
601 RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation_difference = %d\n", priv->cck_present_attentuation_difference);
602 RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation = %d\n", priv->cck_present_attentuation);
603 return;
16da7808
LS
604 }
605 if (Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK) {
606 if (priv->rfa_txpowertrackingindex > 0) {
607 priv->rfa_txpowertrackingindex--;
608 if (priv->rfa_txpowertrackingindex_real > 4) {
609 priv->rfa_txpowertrackingindex_real--;
04d695d7 610 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
04d695d7 611 }
8fc8598e 612 }
16da7808
LS
613 } else {
614 if (priv->rfa_txpowertrackingindex < 36) {
615 priv->rfa_txpowertrackingindex++;
616 priv->rfa_txpowertrackingindex_real++;
617 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
04d695d7 618
04d695d7 619 }
16da7808
LS
620 }
621 priv->cck_present_attentuation_difference
622 = priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default;
04d695d7 623
16da7808
LS
624 if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
625 priv->cck_present_attentuation
626 = priv->cck_present_attentuation_20Mdefault + priv->cck_present_attentuation_difference;
627 else
628 priv->cck_present_attentuation
629 = priv->cck_present_attentuation_40Mdefault + priv->cck_present_attentuation_difference;
630
631 if (priv->cck_present_attentuation > -1 && priv->cck_present_attentuation < 23) {
632 if (priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) {
4b2faf80 633 priv->bcck_in_ch14 = true;
16da7808
LS
634 dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
635 } else if (priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) {
4b2faf80 636 priv->bcck_in_ch14 = false;
16da7808
LS
637 dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
638 } else
639 dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
640 }
641 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
642 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
643 RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation_difference = %d\n", priv->cck_present_attentuation_difference);
644 RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation = %d\n", priv->cck_present_attentuation);
04d695d7 645
16da7808 646 if (priv->cck_present_attentuation_difference <= -12 || priv->cck_present_attentuation_difference >= 24) {
4b2faf80 647 priv->ieee80211->bdynamic_txpower_enable = true;
16da7808
LS
648 write_nic_byte(dev, 0x1ba, 0);
649 RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n");
650 return;
8fc8598e 651 }
16da7808 652
8fc8598e 653 write_nic_byte(dev, 0x1ba, 0);
04d695d7
LS
654 Avg_TSSI_Meas_from_driver = 0;
655 for (k = 0; k < 5; k++)
656 tmp_report[k] = 0;
657 break;
8fc8598e 658 }
8fc8598e 659 }
4b2faf80 660 priv->ieee80211->bdynamic_txpower_enable = true;
04d695d7 661 write_nic_byte(dev, 0x1ba, 0);
8fc8598e
JC
662}
663
999d594b 664static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device *dev)
8fc8598e
JC
665{
666#define ThermalMeterVal 9
667 struct r8192_priv *priv = ieee80211_priv(dev);
668 u32 tmpRegA, TempCCk;
669 u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval;
04d695d7 670 int i = 0, CCKSwingNeedUpdate = 0;
8fc8598e 671
04d695d7 672 if (!priv->btxpower_trackingInit) {
e1da1d57 673 /* Query OFDM default setting */
04d695d7
LS
674 tmpRegA = rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord);
675 for (i = 0; i < OFDM_Table_Length; i++) { /* find the index */
676 if (tmpRegA == OFDMSwingTable[i]) {
677 priv->OFDM_index = (u8)i;
8fc8598e
JC
678 RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, OFDM_index=0x%x\n",
679 rOFDM0_XATxIQImbalance, tmpRegA, priv->OFDM_index);
680 }
681 }
682
e1da1d57 683 /* Query CCK default setting From 0xa22 */
8fc8598e 684 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
04d695d7
LS
685 for (i = 0; i < CCK_Table_length; i++) {
686 if (TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0]) {
687 priv->CCK_index = (u8) i;
8fc8598e
JC
688 RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, CCK_index=0x%x\n",
689 rCCK0_TxFilter1, TempCCk, priv->CCK_index);
690 break;
691 }
692 }
4b2faf80 693 priv->btxpower_trackingInit = true;
e1da1d57 694 /*pHalData->TXPowercount = 0;*/
8fc8598e
JC
695 return;
696 }
697
e1da1d57
LS
698 /*
699 * ==========================
700 * this is only for test, should be masked
701 * ==========================
702 */
8fc8598e 703
e1da1d57
LS
704 /* read and filter out unreasonable value */
705 tmpRegA = rtl8192_phy_QueryRFReg(dev, RF90_PATH_A, 0x12, 0x078); /* 0x12: RF Reg[10:7] */
04d695d7
LS
706 RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d\n", tmpRegA);
707 if (tmpRegA < 3 || tmpRegA > 13)
8fc8598e 708 return;
04d695d7 709 if (tmpRegA >= 12) /* if over 12, TP will be bad when high temperature */
8fc8598e 710 tmpRegA = 12;
04d695d7 711 RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d\n", tmpRegA);
e1da1d57
LS
712 priv->ThermalMeter[0] = ThermalMeterVal; /* We use fixed value by Bryant's suggestion */
713 priv->ThermalMeter[1] = ThermalMeterVal; /* We use fixed value by Bryant's suggestion */
8fc8598e 714
e1da1d57 715 /* Get current RF-A temperature index */
04d695d7 716 if (priv->ThermalMeter[0] >= (u8)tmpRegA) { /* lower temperature */
8fc8598e
JC
717 tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0]-(u8)tmpRegA);
718 tmpCCK40Mindex = tmpCCK20Mindex - 6;
04d695d7 719 if (tmpOFDMindex >= OFDM_Table_Length)
8fc8598e 720 tmpOFDMindex = OFDM_Table_Length-1;
04d695d7 721 if (tmpCCK20Mindex >= CCK_Table_length)
8fc8598e 722 tmpCCK20Mindex = CCK_Table_length-1;
04d695d7 723 if (tmpCCK40Mindex >= CCK_Table_length)
8fc8598e 724 tmpCCK40Mindex = CCK_Table_length-1;
04d695d7 725 } else {
2060f31a 726 tmpval = (u8)tmpRegA - priv->ThermalMeter[0];
04d695d7
LS
727
728 if (tmpval >= 6) /* higher temperature */
729 tmpOFDMindex = tmpCCK20Mindex = 0; /* max to +6dB */
8fc8598e
JC
730 else
731 tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval;
732 tmpCCK40Mindex = 0;
733 }
e1da1d57
LS
734 /*DbgPrint("%ddb, tmpOFDMindex = %d, tmpCCK20Mindex = %d, tmpCCK40Mindex = %d",
735 ((u1Byte)tmpRegA - pHalData->ThermalMeter[0]),
736 tmpOFDMindex, tmpCCK20Mindex, tmpCCK40Mindex);*/
04d695d7 737 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) /* 40M */
8fc8598e
JC
738 tmpCCKindex = tmpCCK40Mindex;
739 else
740 tmpCCKindex = tmpCCK20Mindex;
741
04d695d7 742 if (priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) {
4b2faf80 743 priv->bcck_in_ch14 = true;
8fc8598e 744 CCKSwingNeedUpdate = 1;
04d695d7 745 } else if (priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) {
4b2faf80 746 priv->bcck_in_ch14 = false;
8fc8598e
JC
747 CCKSwingNeedUpdate = 1;
748 }
749
04d695d7 750 if (priv->CCK_index != tmpCCKindex) {
8fc8598e
JC
751 priv->CCK_index = tmpCCKindex;
752 CCKSwingNeedUpdate = 1;
753 }
754
04d695d7 755 if (CCKSwingNeedUpdate) {
e1da1d57 756 /*DbgPrint("Update CCK Swing, CCK_index = %d\n", pHalData->CCK_index);*/
8fc8598e
JC
757 dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
758 }
04d695d7 759 if (priv->OFDM_index != tmpOFDMindex) {
8fc8598e
JC
760 priv->OFDM_index = tmpOFDMindex;
761 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable[priv->OFDM_index]);
762 RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n",
763 priv->OFDM_index, OFDMSwingTable[priv->OFDM_index]);
764 }
765 priv->txpower_count = 0;
766}
767
bf316434 768void dm_txpower_trackingcallback(struct work_struct *work)
8fc8598e 769{
04d695d7
LS
770 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
771 struct r8192_priv *priv = container_of(dwork, struct r8192_priv, txpower_tracking_wq);
772 struct net_device *dev = priv->ieee80211->dev;
8fc8598e 773
c40753b5 774 if (priv->bDcut)
8fc8598e
JC
775 dm_TXPowerTrackingCallback_TSSI(dev);
776 else
777 dm_TXPowerTrackingCallback_ThermalMeter(dev);
8fc8598e
JC
778}
779
8fc8598e
JC
780static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev)
781{
8fc8598e
JC
782 struct r8192_priv *priv = ieee80211_priv(dev);
783
e1da1d57 784 /* Initial the Tx BB index and mapping value */
35997ff0 785 priv->txbbgain_table[0].txbb_iq_amplifygain = 12;
04d695d7 786 priv->txbbgain_table[0].txbbgain_value = 0x7f8001fe;
35997ff0 787 priv->txbbgain_table[1].txbb_iq_amplifygain = 11;
04d695d7 788 priv->txbbgain_table[1].txbbgain_value = 0x788001e2;
35997ff0 789 priv->txbbgain_table[2].txbb_iq_amplifygain = 10;
04d695d7 790 priv->txbbgain_table[2].txbbgain_value = 0x71c001c7;
35997ff0 791 priv->txbbgain_table[3].txbb_iq_amplifygain = 9;
04d695d7 792 priv->txbbgain_table[3].txbbgain_value = 0x6b8001ae;
35997ff0 793 priv->txbbgain_table[4].txbb_iq_amplifygain = 8;
04d695d7 794 priv->txbbgain_table[4].txbbgain_value = 0x65400195;
35997ff0 795 priv->txbbgain_table[5].txbb_iq_amplifygain = 7;
04d695d7 796 priv->txbbgain_table[5].txbbgain_value = 0x5fc0017f;
35997ff0 797 priv->txbbgain_table[6].txbb_iq_amplifygain = 6;
04d695d7 798 priv->txbbgain_table[6].txbbgain_value = 0x5a400169;
35997ff0 799 priv->txbbgain_table[7].txbb_iq_amplifygain = 5;
04d695d7 800 priv->txbbgain_table[7].txbbgain_value = 0x55400155;
35997ff0 801 priv->txbbgain_table[8].txbb_iq_amplifygain = 4;
04d695d7 802 priv->txbbgain_table[8].txbbgain_value = 0x50800142;
35997ff0 803 priv->txbbgain_table[9].txbb_iq_amplifygain = 3;
04d695d7 804 priv->txbbgain_table[9].txbbgain_value = 0x4c000130;
35997ff0 805 priv->txbbgain_table[10].txbb_iq_amplifygain = 2;
04d695d7 806 priv->txbbgain_table[10].txbbgain_value = 0x47c0011f;
35997ff0 807 priv->txbbgain_table[11].txbb_iq_amplifygain = 1;
04d695d7 808 priv->txbbgain_table[11].txbbgain_value = 0x43c0010f;
35997ff0 809 priv->txbbgain_table[12].txbb_iq_amplifygain = 0;
04d695d7 810 priv->txbbgain_table[12].txbbgain_value = 0x40000100;
35997ff0 811 priv->txbbgain_table[13].txbb_iq_amplifygain = -1;
04d695d7 812 priv->txbbgain_table[13].txbbgain_value = 0x3c8000f2;
35997ff0 813 priv->txbbgain_table[14].txbb_iq_amplifygain = -2;
04d695d7 814 priv->txbbgain_table[14].txbbgain_value = 0x390000e4;
35997ff0 815 priv->txbbgain_table[15].txbb_iq_amplifygain = -3;
04d695d7 816 priv->txbbgain_table[15].txbbgain_value = 0x35c000d7;
35997ff0 817 priv->txbbgain_table[16].txbb_iq_amplifygain = -4;
04d695d7 818 priv->txbbgain_table[16].txbbgain_value = 0x32c000cb;
35997ff0 819 priv->txbbgain_table[17].txbb_iq_amplifygain = -5;
04d695d7 820 priv->txbbgain_table[17].txbbgain_value = 0x300000c0;
35997ff0 821 priv->txbbgain_table[18].txbb_iq_amplifygain = -6;
04d695d7 822 priv->txbbgain_table[18].txbbgain_value = 0x2d4000b5;
35997ff0 823 priv->txbbgain_table[19].txbb_iq_amplifygain = -7;
04d695d7 824 priv->txbbgain_table[19].txbbgain_value = 0x2ac000ab;
35997ff0 825 priv->txbbgain_table[20].txbb_iq_amplifygain = -8;
04d695d7 826 priv->txbbgain_table[20].txbbgain_value = 0x288000a2;
35997ff0 827 priv->txbbgain_table[21].txbb_iq_amplifygain = -9;
04d695d7 828 priv->txbbgain_table[21].txbbgain_value = 0x26000098;
35997ff0 829 priv->txbbgain_table[22].txbb_iq_amplifygain = -10;
04d695d7 830 priv->txbbgain_table[22].txbbgain_value = 0x24000090;
35997ff0 831 priv->txbbgain_table[23].txbb_iq_amplifygain = -11;
04d695d7 832 priv->txbbgain_table[23].txbbgain_value = 0x22000088;
35997ff0 833 priv->txbbgain_table[24].txbb_iq_amplifygain = -12;
04d695d7 834 priv->txbbgain_table[24].txbbgain_value = 0x20000080;
35997ff0 835 priv->txbbgain_table[25].txbb_iq_amplifygain = -13;
04d695d7 836 priv->txbbgain_table[25].txbbgain_value = 0x1a00006c;
35997ff0 837 priv->txbbgain_table[26].txbb_iq_amplifygain = -14;
04d695d7 838 priv->txbbgain_table[26].txbbgain_value = 0x1c800072;
35997ff0 839 priv->txbbgain_table[27].txbb_iq_amplifygain = -15;
04d695d7 840 priv->txbbgain_table[27].txbbgain_value = 0x18000060;
35997ff0 841 priv->txbbgain_table[28].txbb_iq_amplifygain = -16;
04d695d7 842 priv->txbbgain_table[28].txbbgain_value = 0x19800066;
35997ff0 843 priv->txbbgain_table[29].txbb_iq_amplifygain = -17;
04d695d7 844 priv->txbbgain_table[29].txbbgain_value = 0x15800056;
35997ff0 845 priv->txbbgain_table[30].txbb_iq_amplifygain = -18;
04d695d7 846 priv->txbbgain_table[30].txbbgain_value = 0x26c0005b;
35997ff0 847 priv->txbbgain_table[31].txbb_iq_amplifygain = -19;
04d695d7 848 priv->txbbgain_table[31].txbbgain_value = 0x14400051;
35997ff0 849 priv->txbbgain_table[32].txbb_iq_amplifygain = -20;
04d695d7 850 priv->txbbgain_table[32].txbbgain_value = 0x24400051;
35997ff0 851 priv->txbbgain_table[33].txbb_iq_amplifygain = -21;
04d695d7 852 priv->txbbgain_table[33].txbbgain_value = 0x1300004c;
35997ff0 853 priv->txbbgain_table[34].txbb_iq_amplifygain = -22;
04d695d7 854 priv->txbbgain_table[34].txbbgain_value = 0x12000048;
35997ff0 855 priv->txbbgain_table[35].txbb_iq_amplifygain = -23;
04d695d7 856 priv->txbbgain_table[35].txbbgain_value = 0x11000044;
35997ff0 857 priv->txbbgain_table[36].txbb_iq_amplifygain = -24;
04d695d7 858 priv->txbbgain_table[36].txbbgain_value = 0x10000040;
8fc8598e 859
e1da1d57
LS
860 /*
861 * ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
862 * This Table is for CH1~CH13
863 */
8fc8598e
JC
864 priv->cck_txbbgain_table[0].ccktxbb_valuearray[0] = 0x36;
865 priv->cck_txbbgain_table[0].ccktxbb_valuearray[1] = 0x35;
866 priv->cck_txbbgain_table[0].ccktxbb_valuearray[2] = 0x2e;
867 priv->cck_txbbgain_table[0].ccktxbb_valuearray[3] = 0x25;
868 priv->cck_txbbgain_table[0].ccktxbb_valuearray[4] = 0x1c;
869 priv->cck_txbbgain_table[0].ccktxbb_valuearray[5] = 0x12;
870 priv->cck_txbbgain_table[0].ccktxbb_valuearray[6] = 0x09;
871 priv->cck_txbbgain_table[0].ccktxbb_valuearray[7] = 0x04;
872
873 priv->cck_txbbgain_table[1].ccktxbb_valuearray[0] = 0x33;
874 priv->cck_txbbgain_table[1].ccktxbb_valuearray[1] = 0x32;
875 priv->cck_txbbgain_table[1].ccktxbb_valuearray[2] = 0x2b;
876 priv->cck_txbbgain_table[1].ccktxbb_valuearray[3] = 0x23;
877 priv->cck_txbbgain_table[1].ccktxbb_valuearray[4] = 0x1a;
878 priv->cck_txbbgain_table[1].ccktxbb_valuearray[5] = 0x11;
879 priv->cck_txbbgain_table[1].ccktxbb_valuearray[6] = 0x08;
880 priv->cck_txbbgain_table[1].ccktxbb_valuearray[7] = 0x04;
881
882 priv->cck_txbbgain_table[2].ccktxbb_valuearray[0] = 0x30;
883 priv->cck_txbbgain_table[2].ccktxbb_valuearray[1] = 0x2f;
884 priv->cck_txbbgain_table[2].ccktxbb_valuearray[2] = 0x29;
885 priv->cck_txbbgain_table[2].ccktxbb_valuearray[3] = 0x21;
886 priv->cck_txbbgain_table[2].ccktxbb_valuearray[4] = 0x19;
887 priv->cck_txbbgain_table[2].ccktxbb_valuearray[5] = 0x10;
888 priv->cck_txbbgain_table[2].ccktxbb_valuearray[6] = 0x08;
889 priv->cck_txbbgain_table[2].ccktxbb_valuearray[7] = 0x03;
890
891 priv->cck_txbbgain_table[3].ccktxbb_valuearray[0] = 0x2d;
892 priv->cck_txbbgain_table[3].ccktxbb_valuearray[1] = 0x2d;
893 priv->cck_txbbgain_table[3].ccktxbb_valuearray[2] = 0x27;
894 priv->cck_txbbgain_table[3].ccktxbb_valuearray[3] = 0x1f;
895 priv->cck_txbbgain_table[3].ccktxbb_valuearray[4] = 0x18;
896 priv->cck_txbbgain_table[3].ccktxbb_valuearray[5] = 0x0f;
897 priv->cck_txbbgain_table[3].ccktxbb_valuearray[6] = 0x08;
898 priv->cck_txbbgain_table[3].ccktxbb_valuearray[7] = 0x03;
899
900 priv->cck_txbbgain_table[4].ccktxbb_valuearray[0] = 0x2b;
901 priv->cck_txbbgain_table[4].ccktxbb_valuearray[1] = 0x2a;
902 priv->cck_txbbgain_table[4].ccktxbb_valuearray[2] = 0x25;
903 priv->cck_txbbgain_table[4].ccktxbb_valuearray[3] = 0x1e;
904 priv->cck_txbbgain_table[4].ccktxbb_valuearray[4] = 0x16;
905 priv->cck_txbbgain_table[4].ccktxbb_valuearray[5] = 0x0e;
906 priv->cck_txbbgain_table[4].ccktxbb_valuearray[6] = 0x07;
907 priv->cck_txbbgain_table[4].ccktxbb_valuearray[7] = 0x03;
908
909 priv->cck_txbbgain_table[5].ccktxbb_valuearray[0] = 0x28;
910 priv->cck_txbbgain_table[5].ccktxbb_valuearray[1] = 0x28;
911 priv->cck_txbbgain_table[5].ccktxbb_valuearray[2] = 0x22;
912 priv->cck_txbbgain_table[5].ccktxbb_valuearray[3] = 0x1c;
913 priv->cck_txbbgain_table[5].ccktxbb_valuearray[4] = 0x15;
914 priv->cck_txbbgain_table[5].ccktxbb_valuearray[5] = 0x0d;
915 priv->cck_txbbgain_table[5].ccktxbb_valuearray[6] = 0x07;
916 priv->cck_txbbgain_table[5].ccktxbb_valuearray[7] = 0x03;
917
918 priv->cck_txbbgain_table[6].ccktxbb_valuearray[0] = 0x26;
919 priv->cck_txbbgain_table[6].ccktxbb_valuearray[1] = 0x25;
920 priv->cck_txbbgain_table[6].ccktxbb_valuearray[2] = 0x21;
921 priv->cck_txbbgain_table[6].ccktxbb_valuearray[3] = 0x1b;
922 priv->cck_txbbgain_table[6].ccktxbb_valuearray[4] = 0x14;
923 priv->cck_txbbgain_table[6].ccktxbb_valuearray[5] = 0x0d;
924 priv->cck_txbbgain_table[6].ccktxbb_valuearray[6] = 0x06;
925 priv->cck_txbbgain_table[6].ccktxbb_valuearray[7] = 0x03;
926
927 priv->cck_txbbgain_table[7].ccktxbb_valuearray[0] = 0x24;
928 priv->cck_txbbgain_table[7].ccktxbb_valuearray[1] = 0x23;
929 priv->cck_txbbgain_table[7].ccktxbb_valuearray[2] = 0x1f;
930 priv->cck_txbbgain_table[7].ccktxbb_valuearray[3] = 0x19;
931 priv->cck_txbbgain_table[7].ccktxbb_valuearray[4] = 0x13;
932 priv->cck_txbbgain_table[7].ccktxbb_valuearray[5] = 0x0c;
933 priv->cck_txbbgain_table[7].ccktxbb_valuearray[6] = 0x06;
934 priv->cck_txbbgain_table[7].ccktxbb_valuearray[7] = 0x03;
935
936 priv->cck_txbbgain_table[8].ccktxbb_valuearray[0] = 0x22;
937 priv->cck_txbbgain_table[8].ccktxbb_valuearray[1] = 0x21;
938 priv->cck_txbbgain_table[8].ccktxbb_valuearray[2] = 0x1d;
939 priv->cck_txbbgain_table[8].ccktxbb_valuearray[3] = 0x18;
940 priv->cck_txbbgain_table[8].ccktxbb_valuearray[4] = 0x11;
941 priv->cck_txbbgain_table[8].ccktxbb_valuearray[5] = 0x0b;
942 priv->cck_txbbgain_table[8].ccktxbb_valuearray[6] = 0x06;
943 priv->cck_txbbgain_table[8].ccktxbb_valuearray[7] = 0x02;
944
945 priv->cck_txbbgain_table[9].ccktxbb_valuearray[0] = 0x20;
946 priv->cck_txbbgain_table[9].ccktxbb_valuearray[1] = 0x20;
947 priv->cck_txbbgain_table[9].ccktxbb_valuearray[2] = 0x1b;
948 priv->cck_txbbgain_table[9].ccktxbb_valuearray[3] = 0x16;
949 priv->cck_txbbgain_table[9].ccktxbb_valuearray[4] = 0x11;
950 priv->cck_txbbgain_table[9].ccktxbb_valuearray[5] = 0x08;
951 priv->cck_txbbgain_table[9].ccktxbb_valuearray[6] = 0x05;
952 priv->cck_txbbgain_table[9].ccktxbb_valuearray[7] = 0x02;
953
954 priv->cck_txbbgain_table[10].ccktxbb_valuearray[0] = 0x1f;
955 priv->cck_txbbgain_table[10].ccktxbb_valuearray[1] = 0x1e;
956 priv->cck_txbbgain_table[10].ccktxbb_valuearray[2] = 0x1a;
957 priv->cck_txbbgain_table[10].ccktxbb_valuearray[3] = 0x15;
958 priv->cck_txbbgain_table[10].ccktxbb_valuearray[4] = 0x10;
959 priv->cck_txbbgain_table[10].ccktxbb_valuearray[5] = 0x0a;
960 priv->cck_txbbgain_table[10].ccktxbb_valuearray[6] = 0x05;
961 priv->cck_txbbgain_table[10].ccktxbb_valuearray[7] = 0x02;
962
963 priv->cck_txbbgain_table[11].ccktxbb_valuearray[0] = 0x1d;
964 priv->cck_txbbgain_table[11].ccktxbb_valuearray[1] = 0x1c;
965 priv->cck_txbbgain_table[11].ccktxbb_valuearray[2] = 0x18;
966 priv->cck_txbbgain_table[11].ccktxbb_valuearray[3] = 0x14;
967 priv->cck_txbbgain_table[11].ccktxbb_valuearray[4] = 0x0f;
968 priv->cck_txbbgain_table[11].ccktxbb_valuearray[5] = 0x0a;
969 priv->cck_txbbgain_table[11].ccktxbb_valuearray[6] = 0x05;
970 priv->cck_txbbgain_table[11].ccktxbb_valuearray[7] = 0x02;
971
972 priv->cck_txbbgain_table[12].ccktxbb_valuearray[0] = 0x1b;
973 priv->cck_txbbgain_table[12].ccktxbb_valuearray[1] = 0x1a;
974 priv->cck_txbbgain_table[12].ccktxbb_valuearray[2] = 0x17;
975 priv->cck_txbbgain_table[12].ccktxbb_valuearray[3] = 0x13;
976 priv->cck_txbbgain_table[12].ccktxbb_valuearray[4] = 0x0e;
977 priv->cck_txbbgain_table[12].ccktxbb_valuearray[5] = 0x09;
978 priv->cck_txbbgain_table[12].ccktxbb_valuearray[6] = 0x04;
979 priv->cck_txbbgain_table[12].ccktxbb_valuearray[7] = 0x02;
980
981 priv->cck_txbbgain_table[13].ccktxbb_valuearray[0] = 0x1a;
982 priv->cck_txbbgain_table[13].ccktxbb_valuearray[1] = 0x19;
983 priv->cck_txbbgain_table[13].ccktxbb_valuearray[2] = 0x16;
984 priv->cck_txbbgain_table[13].ccktxbb_valuearray[3] = 0x12;
985 priv->cck_txbbgain_table[13].ccktxbb_valuearray[4] = 0x0d;
986 priv->cck_txbbgain_table[13].ccktxbb_valuearray[5] = 0x09;
987 priv->cck_txbbgain_table[13].ccktxbb_valuearray[6] = 0x04;
988 priv->cck_txbbgain_table[13].ccktxbb_valuearray[7] = 0x02;
989
990 priv->cck_txbbgain_table[14].ccktxbb_valuearray[0] = 0x18;
991 priv->cck_txbbgain_table[14].ccktxbb_valuearray[1] = 0x17;
992 priv->cck_txbbgain_table[14].ccktxbb_valuearray[2] = 0x15;
993 priv->cck_txbbgain_table[14].ccktxbb_valuearray[3] = 0x11;
994 priv->cck_txbbgain_table[14].ccktxbb_valuearray[4] = 0x0c;
995 priv->cck_txbbgain_table[14].ccktxbb_valuearray[5] = 0x08;
996 priv->cck_txbbgain_table[14].ccktxbb_valuearray[6] = 0x04;
997 priv->cck_txbbgain_table[14].ccktxbb_valuearray[7] = 0x02;
998
999 priv->cck_txbbgain_table[15].ccktxbb_valuearray[0] = 0x17;
1000 priv->cck_txbbgain_table[15].ccktxbb_valuearray[1] = 0x16;
1001 priv->cck_txbbgain_table[15].ccktxbb_valuearray[2] = 0x13;
1002 priv->cck_txbbgain_table[15].ccktxbb_valuearray[3] = 0x10;
1003 priv->cck_txbbgain_table[15].ccktxbb_valuearray[4] = 0x0c;
1004 priv->cck_txbbgain_table[15].ccktxbb_valuearray[5] = 0x08;
1005 priv->cck_txbbgain_table[15].ccktxbb_valuearray[6] = 0x04;
1006 priv->cck_txbbgain_table[15].ccktxbb_valuearray[7] = 0x02;
1007
1008 priv->cck_txbbgain_table[16].ccktxbb_valuearray[0] = 0x16;
1009 priv->cck_txbbgain_table[16].ccktxbb_valuearray[1] = 0x15;
1010 priv->cck_txbbgain_table[16].ccktxbb_valuearray[2] = 0x12;
1011 priv->cck_txbbgain_table[16].ccktxbb_valuearray[3] = 0x0f;
1012 priv->cck_txbbgain_table[16].ccktxbb_valuearray[4] = 0x0b;
1013 priv->cck_txbbgain_table[16].ccktxbb_valuearray[5] = 0x07;
1014 priv->cck_txbbgain_table[16].ccktxbb_valuearray[6] = 0x04;
1015 priv->cck_txbbgain_table[16].ccktxbb_valuearray[7] = 0x01;
1016
1017 priv->cck_txbbgain_table[17].ccktxbb_valuearray[0] = 0x14;
1018 priv->cck_txbbgain_table[17].ccktxbb_valuearray[1] = 0x14;
1019 priv->cck_txbbgain_table[17].ccktxbb_valuearray[2] = 0x11;
1020 priv->cck_txbbgain_table[17].ccktxbb_valuearray[3] = 0x0e;
1021 priv->cck_txbbgain_table[17].ccktxbb_valuearray[4] = 0x0b;
1022 priv->cck_txbbgain_table[17].ccktxbb_valuearray[5] = 0x07;
1023 priv->cck_txbbgain_table[17].ccktxbb_valuearray[6] = 0x03;
1024 priv->cck_txbbgain_table[17].ccktxbb_valuearray[7] = 0x02;
1025
1026 priv->cck_txbbgain_table[18].ccktxbb_valuearray[0] = 0x13;
1027 priv->cck_txbbgain_table[18].ccktxbb_valuearray[1] = 0x13;
1028 priv->cck_txbbgain_table[18].ccktxbb_valuearray[2] = 0x10;
1029 priv->cck_txbbgain_table[18].ccktxbb_valuearray[3] = 0x0d;
1030 priv->cck_txbbgain_table[18].ccktxbb_valuearray[4] = 0x0a;
1031 priv->cck_txbbgain_table[18].ccktxbb_valuearray[5] = 0x06;
1032 priv->cck_txbbgain_table[18].ccktxbb_valuearray[6] = 0x03;
1033 priv->cck_txbbgain_table[18].ccktxbb_valuearray[7] = 0x01;
1034
1035 priv->cck_txbbgain_table[19].ccktxbb_valuearray[0] = 0x12;
1036 priv->cck_txbbgain_table[19].ccktxbb_valuearray[1] = 0x12;
1037 priv->cck_txbbgain_table[19].ccktxbb_valuearray[2] = 0x0f;
1038 priv->cck_txbbgain_table[19].ccktxbb_valuearray[3] = 0x0c;
1039 priv->cck_txbbgain_table[19].ccktxbb_valuearray[4] = 0x09;
1040 priv->cck_txbbgain_table[19].ccktxbb_valuearray[5] = 0x06;
1041 priv->cck_txbbgain_table[19].ccktxbb_valuearray[6] = 0x03;
1042 priv->cck_txbbgain_table[19].ccktxbb_valuearray[7] = 0x01;
1043
1044 priv->cck_txbbgain_table[20].ccktxbb_valuearray[0] = 0x11;
1045 priv->cck_txbbgain_table[20].ccktxbb_valuearray[1] = 0x11;
1046 priv->cck_txbbgain_table[20].ccktxbb_valuearray[2] = 0x0f;
1047 priv->cck_txbbgain_table[20].ccktxbb_valuearray[3] = 0x0c;
1048 priv->cck_txbbgain_table[20].ccktxbb_valuearray[4] = 0x09;
1049 priv->cck_txbbgain_table[20].ccktxbb_valuearray[5] = 0x06;
1050 priv->cck_txbbgain_table[20].ccktxbb_valuearray[6] = 0x03;
1051 priv->cck_txbbgain_table[20].ccktxbb_valuearray[7] = 0x01;
1052
1053 priv->cck_txbbgain_table[21].ccktxbb_valuearray[0] = 0x10;
1054 priv->cck_txbbgain_table[21].ccktxbb_valuearray[1] = 0x10;
1055 priv->cck_txbbgain_table[21].ccktxbb_valuearray[2] = 0x0e;
1056 priv->cck_txbbgain_table[21].ccktxbb_valuearray[3] = 0x0b;
1057 priv->cck_txbbgain_table[21].ccktxbb_valuearray[4] = 0x08;
1058 priv->cck_txbbgain_table[21].ccktxbb_valuearray[5] = 0x05;
1059 priv->cck_txbbgain_table[21].ccktxbb_valuearray[6] = 0x03;
1060 priv->cck_txbbgain_table[21].ccktxbb_valuearray[7] = 0x01;
1061
1062 priv->cck_txbbgain_table[22].ccktxbb_valuearray[0] = 0x0f;
1063 priv->cck_txbbgain_table[22].ccktxbb_valuearray[1] = 0x0f;
1064 priv->cck_txbbgain_table[22].ccktxbb_valuearray[2] = 0x0d;
1065 priv->cck_txbbgain_table[22].ccktxbb_valuearray[3] = 0x0b;
1066 priv->cck_txbbgain_table[22].ccktxbb_valuearray[4] = 0x08;
1067 priv->cck_txbbgain_table[22].ccktxbb_valuearray[5] = 0x05;
1068 priv->cck_txbbgain_table[22].ccktxbb_valuearray[6] = 0x03;
1069 priv->cck_txbbgain_table[22].ccktxbb_valuearray[7] = 0x01;
1070
e1da1d57
LS
1071 /*
1072 * ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
1073 * This Table is for CH14
1074 */
8fc8598e
JC
1075 priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[0] = 0x36;
1076 priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[1] = 0x35;
1077 priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[2] = 0x2e;
1078 priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[3] = 0x1b;
1079 priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[4] = 0x00;
1080 priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[5] = 0x00;
1081 priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[6] = 0x00;
1082 priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[7] = 0x00;
1083
1084 priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[0] = 0x33;
1085 priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[1] = 0x32;
1086 priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[2] = 0x2b;
1087 priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[3] = 0x19;
1088 priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[4] = 0x00;
1089 priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[5] = 0x00;
1090 priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[6] = 0x00;
1091 priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[7] = 0x00;
1092
1093 priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[0] = 0x30;
1094 priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[1] = 0x2f;
1095 priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[2] = 0x29;
1096 priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[3] = 0x18;
1097 priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[4] = 0x00;
1098 priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[5] = 0x00;
1099 priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[6] = 0x00;
1100 priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[7] = 0x00;
1101
1102 priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[0] = 0x2d;
1103 priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[1] = 0x2d;
1104 priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[2] = 0x27;
1105 priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[3] = 0x17;
1106 priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[4] = 0x00;
1107 priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[5] = 0x00;
1108 priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[6] = 0x00;
1109 priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[7] = 0x00;
1110
1111 priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[0] = 0x2b;
1112 priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[1] = 0x2a;
1113 priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[2] = 0x25;
1114 priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[3] = 0x15;
1115 priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[4] = 0x00;
1116 priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[5] = 0x00;
1117 priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[6] = 0x00;
1118 priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[7] = 0x00;
1119
1120 priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[0] = 0x28;
1121 priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[1] = 0x28;
1122 priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[2] = 0x22;
1123 priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[3] = 0x14;
1124 priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[4] = 0x00;
1125 priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[5] = 0x00;
1126 priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[6] = 0x00;
1127 priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[7] = 0x00;
1128
1129 priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[0] = 0x26;
1130 priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[1] = 0x25;
1131 priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[2] = 0x21;
1132 priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[3] = 0x13;
1133 priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[4] = 0x00;
1134 priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[5] = 0x00;
1135 priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[6] = 0x00;
1136 priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[7] = 0x00;
1137
1138 priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[0] = 0x24;
1139 priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[1] = 0x23;
1140 priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[2] = 0x1f;
1141 priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[3] = 0x12;
1142 priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[4] = 0x00;
1143 priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[5] = 0x00;
1144 priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[6] = 0x00;
1145 priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[7] = 0x00;
1146
1147 priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[0] = 0x22;
1148 priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[1] = 0x21;
1149 priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[2] = 0x1d;
1150 priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[3] = 0x11;
1151 priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[4] = 0x00;
1152 priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[5] = 0x00;
1153 priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[6] = 0x00;
1154 priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[7] = 0x00;
1155
1156 priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[0] = 0x20;
1157 priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[1] = 0x20;
1158 priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[2] = 0x1b;
1159 priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[3] = 0x10;
1160 priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[4] = 0x00;
1161 priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[5] = 0x00;
1162 priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[6] = 0x00;
1163 priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[7] = 0x00;
1164
1165 priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[0] = 0x1f;
1166 priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[1] = 0x1e;
1167 priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[2] = 0x1a;
1168 priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[3] = 0x0f;
1169 priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[4] = 0x00;
1170 priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[5] = 0x00;
1171 priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[6] = 0x00;
1172 priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[7] = 0x00;
1173
1174 priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[0] = 0x1d;
1175 priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[1] = 0x1c;
1176 priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[2] = 0x18;
1177 priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[3] = 0x0e;
1178 priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[4] = 0x00;
1179 priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[5] = 0x00;
1180 priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[6] = 0x00;
1181 priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[7] = 0x00;
1182
1183 priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[0] = 0x1b;
1184 priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[1] = 0x1a;
1185 priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[2] = 0x17;
1186 priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[3] = 0x0e;
1187 priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[4] = 0x00;
1188 priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[5] = 0x00;
1189 priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[6] = 0x00;
1190 priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[7] = 0x00;
1191
1192 priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[0] = 0x1a;
1193 priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[1] = 0x19;
1194 priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[2] = 0x16;
1195 priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[3] = 0x0d;
1196 priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[4] = 0x00;
1197 priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[5] = 0x00;
1198 priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[6] = 0x00;
1199 priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[7] = 0x00;
1200
1201 priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[0] = 0x18;
1202 priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[1] = 0x17;
1203 priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[2] = 0x15;
1204 priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[3] = 0x0c;
1205 priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[4] = 0x00;
1206 priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[5] = 0x00;
1207 priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[6] = 0x00;
1208 priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[7] = 0x00;
1209
1210 priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[0] = 0x17;
1211 priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[1] = 0x16;
1212 priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[2] = 0x13;
1213 priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[3] = 0x0b;
1214 priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[4] = 0x00;
1215 priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[5] = 0x00;
1216 priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[6] = 0x00;
1217 priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[7] = 0x00;
1218
1219 priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[0] = 0x16;
1220 priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[1] = 0x15;
1221 priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[2] = 0x12;
1222 priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[3] = 0x0b;
1223 priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[4] = 0x00;
1224 priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[5] = 0x00;
1225 priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[6] = 0x00;
1226 priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[7] = 0x00;
1227
1228 priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[0] = 0x14;
1229 priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[1] = 0x14;
1230 priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[2] = 0x11;
1231 priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[3] = 0x0a;
1232 priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[4] = 0x00;
1233 priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[5] = 0x00;
1234 priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[6] = 0x00;
1235 priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[7] = 0x00;
1236
1237 priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[0] = 0x13;
1238 priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[1] = 0x13;
1239 priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[2] = 0x10;
1240 priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[3] = 0x0a;
1241 priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[4] = 0x00;
1242 priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[5] = 0x00;
1243 priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[6] = 0x00;
1244 priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[7] = 0x00;
1245
1246 priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[0] = 0x12;
1247 priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[1] = 0x12;
1248 priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[2] = 0x0f;
1249 priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[3] = 0x09;
1250 priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[4] = 0x00;
1251 priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[5] = 0x00;
1252 priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[6] = 0x00;
1253 priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[7] = 0x00;
1254
1255 priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[0] = 0x11;
1256 priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[1] = 0x11;
1257 priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[2] = 0x0f;
1258 priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[3] = 0x09;
1259 priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[4] = 0x00;
1260 priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[5] = 0x00;
1261 priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[6] = 0x00;
1262 priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[7] = 0x00;
1263
1264 priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[0] = 0x10;
1265 priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[1] = 0x10;
1266 priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[2] = 0x0e;
1267 priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[3] = 0x08;
1268 priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[4] = 0x00;
1269 priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[5] = 0x00;
1270 priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[6] = 0x00;
1271 priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[7] = 0x00;
1272
1273 priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[0] = 0x0f;
1274 priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[1] = 0x0f;
1275 priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[2] = 0x0d;
1276 priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[3] = 0x08;
1277 priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[4] = 0x00;
1278 priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[5] = 0x00;
1279 priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[6] = 0x00;
1280 priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[7] = 0x00;
1281
4b2faf80 1282 priv->btxpower_tracking = true;
8fc8598e 1283 priv->txpower_count = 0;
4b2faf80 1284 priv->btxpower_trackingInit = false;
8fc8598e
JC
1285
1286}
1287
1288static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev)
1289{
1290 struct r8192_priv *priv = ieee80211_priv(dev);
1291
e1da1d57
LS
1292 /*
1293 * Tx Power tracking by Thermal Meter requires Firmware R/W 3-wire. This mechanism
1294 * can be enabled only when Firmware R/W 3-wire is enabled. Otherwise, frequent r/w
1295 * 3-wire by driver causes RF to go into a wrong state.
1296 */
04d695d7 1297 if (priv->ieee80211->FwRWRF)
4b2faf80 1298 priv->btxpower_tracking = true;
8fc8598e 1299 else
4b2faf80 1300 priv->btxpower_tracking = false;
8fc8598e 1301 priv->txpower_count = 0;
4b2faf80 1302 priv->btxpower_trackingInit = false;
8fc8598e
JC
1303}
1304
8fc8598e
JC
1305void dm_initialize_txpower_tracking(struct net_device *dev)
1306{
1307 struct r8192_priv *priv = ieee80211_priv(dev);
04d695d7 1308
c40753b5 1309 if (priv->bDcut)
8fc8598e
JC
1310 dm_InitializeTXPowerTracking_TSSI(dev);
1311 else
1312 dm_InitializeTXPowerTracking_ThermalMeter(dev);
e1da1d57 1313} /* dm_InitializeTXPowerTracking */
8fc8598e 1314
8fc8598e
JC
1315static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev)
1316{
1317 struct r8192_priv *priv = ieee80211_priv(dev);
de13a3da 1318 static u32 tx_power_track_counter;
8fc8598e 1319
04d695d7 1320 if (!priv->btxpower_tracking)
8fc8598e 1321 return;
16da7808
LS
1322 if ((tx_power_track_counter % 30 == 0) && (tx_power_track_counter != 0))
1323 queue_delayed_work(priv->priv_wq, &priv->txpower_tracking_wq, 0);
1324 tx_power_track_counter++;
8fc8598e
JC
1325}
1326
8fc8598e
JC
1327static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev)
1328{
1329 struct r8192_priv *priv = ieee80211_priv(dev);
de13a3da 1330 static u8 TM_Trigger;
04d695d7
LS
1331 /*DbgPrint("dm_CheckTXPowerTracking()\n");*/
1332 if (!priv->btxpower_tracking)
8fc8598e 1333 return;
16da7808
LS
1334 if (priv->txpower_count <= 2) {
1335 priv->txpower_count++;
1336 return;
8fc8598e
JC
1337 }
1338
04d695d7 1339 if (!TM_Trigger) {
e1da1d57
LS
1340 /*
1341 * Attention!! You have to write all 12bits of data to RF, or it may cause RF to crash
1342 * actually write reg0x02 bit1=0, then bit1=1.
1343 * DbgPrint("Trigger ThermalMeter, write RF reg0x2 = 0x4d to 0x4f\n");
1344 */
8fc8598e
JC
1345 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1346 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1347 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1348 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1349 TM_Trigger = 1;
1350 return;
8fc8598e 1351 }
16da7808
LS
1352 /*DbgPrint("Schedule TxPowerTrackingWorkItem\n");*/
1353 queue_delayed_work(priv->priv_wq, &priv->txpower_tracking_wq, 0);
1354 TM_Trigger = 0;
8fc8598e
JC
1355}
1356
8fc8598e
JC
1357static void dm_check_txpower_tracking(struct net_device *dev)
1358{
1359 struct r8192_priv *priv = ieee80211_priv(dev);
e1da1d57 1360 /*static u32 tx_power_track_counter = 0;*/
8fc8598e 1361
04d695d7 1362#ifdef RTL8190P
8fc8598e
JC
1363 dm_CheckTXPowerTracking_TSSI(dev);
1364#else
c40753b5 1365 if (priv->bDcut)
8fc8598e
JC
1366 dm_CheckTXPowerTracking_TSSI(dev);
1367 else
1368 dm_CheckTXPowerTracking_ThermalMeter(dev);
1369#endif
1370
e1da1d57 1371} /* dm_CheckTXPowerTracking */
8fc8598e 1372
8fc8598e
JC
1373static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14)
1374{
1375 u32 TempVal;
1376 struct r8192_priv *priv = ieee80211_priv(dev);
04d695d7 1377
e1da1d57 1378 /* Write 0xa22 0xa23 */
8fc8598e 1379 TempVal = 0;
04d695d7 1380 if (!bInCH14) {
e1da1d57 1381 /* Write 0xa22 0xa23 */
35997ff0 1382 TempVal = priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[0] +
04d695d7 1383 (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[1]<<8);
8fc8598e 1384
0b4ef0a6 1385 rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
e1da1d57 1386 /* Write 0xa24 ~ 0xa27 */
35997ff0 1387 TempVal = priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[2] +
8fc8598e 1388 (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[3]<<8) +
0009631b 1389 (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[4]<<16)+
8fc8598e 1390 (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[5]<<24);
0b4ef0a6 1391 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
e1da1d57 1392 /* Write 0xa28 0xa29 */
35997ff0 1393 TempVal = priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[6] +
04d695d7 1394 (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[7]<<8);
8fc8598e 1395
0b4ef0a6 1396 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
04d695d7 1397 } else {
35997ff0 1398 TempVal = priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[0] +
04d695d7 1399 (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[1]<<8);
8fc8598e 1400
0b4ef0a6 1401 rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
e1da1d57 1402 /* Write 0xa24 ~ 0xa27 */
35997ff0 1403 TempVal = priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[2] +
8fc8598e 1404 (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[3]<<8) +
0009631b 1405 (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[4]<<16)+
8fc8598e 1406 (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[5]<<24);
0b4ef0a6 1407 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
e1da1d57 1408 /* Write 0xa28 0xa29 */
35997ff0 1409 TempVal = priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[6] +
04d695d7 1410 (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[7]<<8);
8fc8598e 1411
0b4ef0a6 1412 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
8fc8598e 1413 }
8fc8598e
JC
1414}
1415
04d695d7 1416static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH14)
8fc8598e
JC
1417{
1418 u32 TempVal;
1419 struct r8192_priv *priv = ieee80211_priv(dev);
1420
1421 TempVal = 0;
04d695d7 1422 if (!bInCH14) {
e1da1d57 1423 /* Write 0xa22 0xa23 */
35997ff0 1424 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] +
04d695d7 1425 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8);
8fc8598e
JC
1426 rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1427 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1428 rCCK0_TxFilter1, TempVal);
e1da1d57 1429 /* Write 0xa24 ~ 0xa27 */
35997ff0 1430 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] +
8fc8598e 1431 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) +
0009631b 1432 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16)+
8fc8598e
JC
1433 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][5]<<24);
1434 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1435 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1436 rCCK0_TxFilter2, TempVal);
e1da1d57 1437 /* Write 0xa28 0xa29 */
35997ff0 1438 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] +
04d695d7 1439 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8);
8fc8598e
JC
1440
1441 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1442 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1443 rCCK0_DebugPort, TempVal);
04d695d7 1444 } else {
e1da1d57
LS
1445 /*priv->CCKTxPowerAdjustCntNotCh14++; cosa add for debug.*/
1446 /* Write 0xa22 0xa23 */
35997ff0 1447 TempVal = CCKSwingTable_Ch14[priv->CCK_index][0] +
04d695d7 1448 (CCKSwingTable_Ch14[priv->CCK_index][1]<<8);
8fc8598e
JC
1449
1450 rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1451 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1452 rCCK0_TxFilter1, TempVal);
e1da1d57 1453 /* Write 0xa24 ~ 0xa27 */
35997ff0 1454 TempVal = CCKSwingTable_Ch14[priv->CCK_index][2] +
8fc8598e 1455 (CCKSwingTable_Ch14[priv->CCK_index][3]<<8) +
0009631b 1456 (CCKSwingTable_Ch14[priv->CCK_index][4]<<16)+
8fc8598e
JC
1457 (CCKSwingTable_Ch14[priv->CCK_index][5]<<24);
1458 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1459 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1460 rCCK0_TxFilter2, TempVal);
e1da1d57 1461 /* Write 0xa28 0xa29 */
35997ff0 1462 TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] +
04d695d7 1463 (CCKSwingTable_Ch14[priv->CCK_index][7]<<8);
8fc8598e
JC
1464
1465 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
0b4ef0a6 1466 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
8fc8598e
JC
1467 rCCK0_DebugPort, TempVal);
1468 }
1469}
1470
bf316434 1471void dm_cck_txpower_adjust(struct net_device *dev, bool binch14)
e1da1d57 1472{ /* dm_CCKTxPowerAdjust */
8fc8598e 1473 struct r8192_priv *priv = ieee80211_priv(dev);
04d695d7 1474
c40753b5 1475 if (priv->bDcut)
8fc8598e
JC
1476 dm_CCKTxPowerAdjust_TSSI(dev, binch14);
1477 else
1478 dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14);
8fc8598e
JC
1479}
1480
04d695d7 1481#ifndef RTL8192U
8fc8598e
JC
1482static void dm_txpower_reset_recovery(
1483 struct net_device *dev
1484)
1485{
1486 struct r8192_priv *priv = ieee80211_priv(dev);
1487
1488 RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n");
1489 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
04d695d7
LS
1490 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n", priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
1491 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n", priv->rfa_txpowertrackingindex);
1492 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF A I/Q Amplify Gain is %ld\n", priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbb_iq_amplifygain);
1493 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: CCK Attenuation is %d dB\n", priv->cck_present_attentuation);
0b4ef0a6 1494 dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
8fc8598e
JC
1495
1496 rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
04d695d7
LS
1497 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n", priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
1498 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n", priv->rfc_txpowertrackingindex);
1499 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF C I/Q Amplify Gain is %ld\n", priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbb_iq_amplifygain);
8fc8598e 1500
e1da1d57 1501} /* dm_TXPowerResetRecovery */
8fc8598e 1502
bf316434 1503void dm_restore_dynamic_mechanism_state(struct net_device *dev)
8fc8598e
JC
1504{
1505 struct r8192_priv *priv = ieee80211_priv(dev);
35997ff0 1506 u32 reg_ratr = priv->rate_adaptive.last_ratr;
8fc8598e 1507
04d695d7 1508 if (!priv->up) {
8fc8598e
JC
1509 RT_TRACE(COMP_RATE, "<---- dm_restore_dynamic_mechanism_state(): driver is going to unload\n");
1510 return;
1511 }
1512
e1da1d57 1513 /* Restore previous state for rate adaptive */
04d695d7 1514 if (priv->rate_adaptive.rate_adaptive_disabled)
8fc8598e 1515 return;
e1da1d57 1516 /* TODO: Only 11n mode is implemented currently, */
04d695d7
LS
1517 if (!(priv->ieee80211->mode == WIRELESS_MODE_N_24G ||
1518 priv->ieee80211->mode == WIRELESS_MODE_N_5G))
1519 return;
1520
8fc8598e
JC
1521 {
1522 /* 2007/11/15 MH Copy from 8190PCI. */
1523 u32 ratr_value;
04d695d7 1524
8fc8598e 1525 ratr_value = reg_ratr;
04d695d7 1526 if (priv->rf_type == RF_1T2R) { /* 1T2R, Spatial Stream 2 should be disabled */
33c2aa14 1527 ratr_value &= ~(RATE_ALL_OFDM_2SS);
e1da1d57 1528 /*DbgPrint("HW_VAR_TATR_0 from 0x%x ==> 0x%x\n", ((pu4Byte)(val))[0], ratr_value);*/
8fc8598e 1529 }
e1da1d57
LS
1530 /*DbgPrint("set HW_VAR_TATR_0 = 0x%x\n", ratr_value);*/
1531 /*cosa PlatformEFIOWrite4Byte(Adapter, RATR0, ((pu4Byte)(val))[0]);*/
8fc8598e
JC
1532 write_nic_dword(dev, RATR0, ratr_value);
1533 write_nic_byte(dev, UFWP, 1);
8fc8598e 1534 }
e1da1d57 1535 /* Restore TX Power Tracking Index */
2930d0b9 1536 if (priv->btxpower_trackingInit && priv->btxpower_tracking)
8fc8598e 1537 dm_txpower_reset_recovery(dev);
8fc8598e 1538
e1da1d57 1539 /* Restore BB Initial Gain */
8fc8598e
JC
1540 dm_bb_initialgain_restore(dev);
1541
e1da1d57 1542} /* DM_RestoreDynamicMechanismState */
8fc8598e
JC
1543
1544static void dm_bb_initialgain_restore(struct net_device *dev)
1545{
1546 struct r8192_priv *priv = ieee80211_priv(dev);
e1da1d57 1547 u32 bit_mask = 0x7f; /* Bit0~ Bit6 */
8fc8598e 1548
04d695d7 1549 if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
8fc8598e
JC
1550 return;
1551
e1da1d57
LS
1552 /* Disable Initial Gain */
1553 /*PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);*/
1554 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); /* Only clear byte 1 and rewrite. */
8fc8598e
JC
1555 rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bit_mask, (u32)priv->initgain_backup.xaagccore1);
1556 rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bit_mask, (u32)priv->initgain_backup.xbagccore1);
1557 rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bit_mask, (u32)priv->initgain_backup.xcagccore1);
1558 rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, bit_mask, (u32)priv->initgain_backup.xdagccore1);
1559 bit_mask = bMaskByte2;
1560 rtl8192_setBBreg(dev, rCCK0_CCA, bit_mask, (u32)priv->initgain_backup.cca);
1561
04d695d7
LS
1562 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n", priv->initgain_backup.xaagccore1);
1563 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n", priv->initgain_backup.xbagccore1);
1564 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n", priv->initgain_backup.xcagccore1);
1565 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n", priv->initgain_backup.xdagccore1);
1566 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n", priv->initgain_backup.cca);
e1da1d57
LS
1567 /* Enable Initial Gain */
1568 /*PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x100);*/
1569 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); /* Only clear byte 1 and rewrite. */
8fc8598e 1570
e1da1d57 1571} /* dm_BBInitialGainRestore */
8fc8598e 1572
bf316434 1573void dm_backup_dynamic_mechanism_state(struct net_device *dev)
8fc8598e
JC
1574{
1575 struct r8192_priv *priv = ieee80211_priv(dev);
1576
e1da1d57 1577 /* Fsync to avoid reset */
8fc8598e
JC
1578 priv->bswitch_fsync = false;
1579 priv->bfsync_processing = false;
e1da1d57 1580 /* Backup BB InitialGain */
8fc8598e
JC
1581 dm_bb_initialgain_backup(dev);
1582
e1da1d57 1583} /* DM_BackupDynamicMechanismState */
8fc8598e 1584
8fc8598e
JC
1585static void dm_bb_initialgain_backup(struct net_device *dev)
1586{
1587 struct r8192_priv *priv = ieee80211_priv(dev);
e1da1d57 1588 u32 bit_mask = bMaskByte0; /* Bit0~ Bit6 */
8fc8598e 1589
04d695d7 1590 if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
8fc8598e
JC
1591 return;
1592
e1da1d57
LS
1593 /*PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);*/
1594 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); /* Only clear byte 1 and rewrite. */
8fc8598e
JC
1595 priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bit_mask);
1596 priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bit_mask);
1597 priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bit_mask);
1598 priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, bit_mask);
1599 bit_mask = bMaskByte2;
1600 priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bit_mask);
1601
04d695d7
LS
1602 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n", priv->initgain_backup.xaagccore1);
1603 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n", priv->initgain_backup.xbagccore1);
1604 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n", priv->initgain_backup.xcagccore1);
1605 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n", priv->initgain_backup.xdagccore1);
1606 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n", priv->initgain_backup.cca);
8fc8598e 1607
e1da1d57 1608} /* dm_BBInitialGainBakcup */
8fc8598e
JC
1609
1610#endif
1611/*-----------------------------------------------------------------------------
1612 * Function: dm_change_dynamic_initgain_thresh()
1613 *
1614 * Overview:
1615 *
1616 * Input: NONE
1617 *
1618 * Output: NONE
1619 *
1620 * Return: NONE
1621 *
1622 * Revised History:
1623 * When Who Remark
1624 * 05/29/2008 amy Create Version 0 porting from windows code.
1625 *
1626 *---------------------------------------------------------------------------*/
bf316434
AR
1627
1628void dm_change_dynamic_initgain_thresh(struct net_device *dev, u32 dm_type,
1629 u32 dm_value)
8fc8598e 1630{
04d695d7 1631 if (dm_type == DIG_TYPE_THRESH_HIGH) {
8fc8598e 1632 dm_digtable.rssi_high_thresh = dm_value;
04d695d7 1633 } else if (dm_type == DIG_TYPE_THRESH_LOW) {
8fc8598e 1634 dm_digtable.rssi_low_thresh = dm_value;
04d695d7 1635 } else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) {
8fc8598e 1636 dm_digtable.rssi_high_power_highthresh = dm_value;
c5c15efb
VT
1637 } else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_LOW) {
1638 dm_digtable.rssi_high_power_lowthresh = dm_value;
04d695d7 1639 } else if (dm_type == DIG_TYPE_ENABLE) {
8fc8598e
JC
1640 dm_digtable.dig_state = DM_STA_DIG_MAX;
1641 dm_digtable.dig_enable_flag = true;
04d695d7 1642 } else if (dm_type == DIG_TYPE_DISABLE) {
8fc8598e
JC
1643 dm_digtable.dig_state = DM_STA_DIG_MAX;
1644 dm_digtable.dig_enable_flag = false;
04d695d7
LS
1645 } else if (dm_type == DIG_TYPE_DBG_MODE) {
1646 if (dm_value >= DM_DBG_MAX)
8fc8598e
JC
1647 dm_value = DM_DBG_OFF;
1648 dm_digtable.dbg_mode = (u8)dm_value;
04d695d7
LS
1649 } else if (dm_type == DIG_TYPE_RSSI) {
1650 if (dm_value > 100)
8fc8598e
JC
1651 dm_value = 30;
1652 dm_digtable.rssi_val = (long)dm_value;
04d695d7 1653 } else if (dm_type == DIG_TYPE_ALGORITHM) {
8fc8598e
JC
1654 if (dm_value >= DIG_ALGO_MAX)
1655 dm_value = DIG_ALGO_BY_FALSE_ALARM;
04d695d7 1656 if (dm_digtable.dig_algorithm != (u8)dm_value)
8fc8598e
JC
1657 dm_digtable.dig_algorithm_switch = 1;
1658 dm_digtable.dig_algorithm = (u8)dm_value;
04d695d7
LS
1659 } else if (dm_type == DIG_TYPE_BACKOFF) {
1660 if (dm_value > 30)
8fc8598e
JC
1661 dm_value = 30;
1662 dm_digtable.backoff_val = (u8)dm_value;
04d695d7
LS
1663 } else if (dm_type == DIG_TYPE_RX_GAIN_MIN) {
1664 if (dm_value == 0)
8fc8598e
JC
1665 dm_value = 0x1;
1666 dm_digtable.rx_gain_range_min = (u8)dm_value;
04d695d7
LS
1667 } else if (dm_type == DIG_TYPE_RX_GAIN_MAX) {
1668 if (dm_value > 0x50)
8fc8598e
JC
1669 dm_value = 0x50;
1670 dm_digtable.rx_gain_range_max = (u8)dm_value;
1671 }
1672} /* DM_ChangeDynamicInitGainThresh */
8fc8598e 1673
8fc8598e
JC
1674/*-----------------------------------------------------------------------------
1675 * Function: dm_dig_init()
1676 *
1677 * Overview: Set DIG scheme init value.
1678 *
1679 * Input: NONE
1680 *
1681 * Output: NONE
1682 *
1683 * Return: NONE
1684 *
1685 * Revised History:
1686 * When Who Remark
1687 * 05/15/2008 amy Create Version 0 porting from windows code.
1688 *
1689 *---------------------------------------------------------------------------*/
1690static void dm_dig_init(struct net_device *dev)
1691{
1692 struct r8192_priv *priv = ieee80211_priv(dev);
1693 /* 2007/10/05 MH Disable DIG scheme now. Not tested. */
1694 dm_digtable.dig_enable_flag = true;
1695 dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI;
e1da1d57 1696 dm_digtable.dbg_mode = DM_DBG_OFF; /* off=by real rssi value, on=by DM_DigTable.Rssi_val for new dig */
8fc8598e
JC
1697 dm_digtable.dig_algorithm_switch = 0;
1698
589b3d06 1699 /* 2007/10/04 MH Define init gain threshold. */
8fc8598e
JC
1700 dm_digtable.dig_state = DM_STA_DIG_MAX;
1701 dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
1702 dm_digtable.initialgain_lowerbound_state = false;
1703
35997ff0
SH
1704 dm_digtable.rssi_low_thresh = DM_DIG_THRESH_LOW;
1705 dm_digtable.rssi_high_thresh = DM_DIG_THRESH_HIGH;
8fc8598e
JC
1706
1707 dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
1708 dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
1709
e1da1d57 1710 dm_digtable.rssi_val = 50; /* for new dig debug rssi value */
8fc8598e
JC
1711 dm_digtable.backoff_val = DM_DIG_BACKOFF;
1712 dm_digtable.rx_gain_range_max = DM_DIG_MAX;
04d695d7 1713 if (priv->CustomerID == RT_CID_819x_Netcore)
8fc8598e
JC
1714 dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore;
1715 else
1716 dm_digtable.rx_gain_range_min = DM_DIG_MIN;
1717
1718} /* dm_dig_init */
1719
8fc8598e
JC
1720/*-----------------------------------------------------------------------------
1721 * Function: dm_ctrl_initgain_byrssi()
1722 *
1723 * Overview: Driver must monitor RSSI and notify firmware to change initial
1724 * gain according to different threshold. BB team provide the
1725 * suggested solution.
1726 *
1727 * Input: struct net_device *dev
1728 *
1729 * Output: NONE
1730 *
1731 * Return: NONE
1732 *
1733 * Revised History:
1734 * When Who Remark
1735 * 05/27/2008 amy Create Version 0 porting from windows code.
1736 *---------------------------------------------------------------------------*/
1737static void dm_ctrl_initgain_byrssi(struct net_device *dev)
1738{
f9bd549a 1739 if (!dm_digtable.dig_enable_flag)
8fc8598e
JC
1740 return;
1741
04d695d7 1742 if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
8fc8598e 1743 dm_ctrl_initgain_byrssi_by_fwfalse_alarm(dev);
04d695d7 1744 else if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
8fc8598e 1745 dm_ctrl_initgain_byrssi_by_driverrssi(dev);
e1da1d57 1746 /* ; */
8fc8598e
JC
1747 else
1748 return;
1749}
1750
8fc8598e
JC
1751static void dm_ctrl_initgain_byrssi_by_driverrssi(
1752 struct net_device *dev)
1753{
1754 struct r8192_priv *priv = ieee80211_priv(dev);
1755 u8 i;
de13a3da 1756 static u8 fw_dig;
8fc8598e 1757
f9bd549a 1758 if (!dm_digtable.dig_enable_flag)
8fc8598e
JC
1759 return;
1760
04d695d7
LS
1761 /*DbgPrint("Dig by Sw Rssi\n");*/
1762 if (dm_digtable.dig_algorithm_switch) /* if switched algorithm, we have to disable FW Dig. */
8fc8598e 1763 fw_dig = 0;
04d695d7
LS
1764
1765 if (fw_dig <= 3) { /* execute several times to make sure the FW Dig is disabled */
e1da1d57 1766 /* FW DIG Off */
04d695d7 1767 for (i = 0; i < 3; i++)
e1da1d57 1768 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); /* Only clear byte 1 and rewrite. */
8fc8598e 1769 fw_dig++;
e1da1d57 1770 dm_digtable.dig_state = DM_STA_DIG_OFF; /* fw dig off. */
8fc8598e
JC
1771 }
1772
04d695d7 1773 if (priv->ieee80211->state == IEEE80211_LINKED)
8fc8598e
JC
1774 dm_digtable.cur_connect_state = DIG_CONNECT;
1775 else
1776 dm_digtable.cur_connect_state = DIG_DISCONNECT;
1777
04d695d7 1778 /*DbgPrint("DM_DigTable.PreConnectState = %d, DM_DigTable.CurConnectState = %d\n",
e1da1d57 1779 DM_DigTable.PreConnectState, DM_DigTable.CurConnectState);*/
8fc8598e 1780
04d695d7 1781 if (dm_digtable.dbg_mode == DM_DBG_OFF)
8fc8598e 1782 dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
04d695d7 1783 /*DbgPrint("DM_DigTable.Rssi_val = %d\n", DM_DigTable.Rssi_val);*/
8fc8598e
JC
1784 dm_initial_gain(dev);
1785 dm_pd_th(dev);
1786 dm_cs_ratio(dev);
04d695d7 1787 if (dm_digtable.dig_algorithm_switch)
8fc8598e
JC
1788 dm_digtable.dig_algorithm_switch = 0;
1789 dm_digtable.pre_connect_state = dm_digtable.cur_connect_state;
1790
1791} /* dm_CtrlInitGainByRssi */
1792
1793static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
1794 struct net_device *dev)
1795{
1796 struct r8192_priv *priv = ieee80211_priv(dev);
de13a3da 1797 static u32 reset_cnt;
8fc8598e
JC
1798 u8 i;
1799
f9bd549a 1800 if (!dm_digtable.dig_enable_flag)
8fc8598e
JC
1801 return;
1802
04d695d7 1803 if (dm_digtable.dig_algorithm_switch) {
8fc8598e 1804 dm_digtable.dig_state = DM_STA_DIG_MAX;
e1da1d57 1805 /* Fw DIG On. */
04d695d7 1806 for (i = 0; i < 3; i++)
e1da1d57 1807 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); /* Only clear byte 1 and rewrite.*/
8fc8598e
JC
1808 dm_digtable.dig_algorithm_switch = 0;
1809 }
1810
1811 if (priv->ieee80211->state != IEEE80211_LINKED)
1812 return;
1813
e1da1d57 1814 /* For smooth, we can not change DIG state. */
8fc8598e
JC
1815 if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) &&
1816 (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh))
8fc8598e 1817 return;
04d695d7 1818
e1da1d57
LS
1819 /*DbgPrint("Dig by Fw False Alarm\n");*/
1820 /*if (DM_DigTable.Dig_State == DM_STA_DIG_OFF)*/
8fc8598e
JC
1821 /*DbgPrint("DIG Check\n\r RSSI=%d LOW=%d HIGH=%d STATE=%d",
1822 pHalData->UndecoratedSmoothedPWDB, DM_DigTable.RssiLowThresh,
1823 DM_DigTable.RssiHighThresh, DM_DigTable.Dig_State);*/
589b3d06 1824 /* 1. When RSSI decrease, We have to judge if it is smaller than a threshold
8ef3a7ed 1825 and then execute the step below. */
16da7808 1826 if (priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh) {
8fc8598e
JC
1827 /* 2008/02/05 MH When we execute silent reset, the DIG PHY parameters
1828 will be reset to init value. We must prevent the condition. */
1829 if (dm_digtable.dig_state == DM_STA_DIG_OFF &&
04d695d7 1830 (priv->reset_count == reset_cnt)) {
8fc8598e 1831 return;
8fc8598e 1832 }
16da7808 1833 reset_cnt = priv->reset_count;
8fc8598e 1834
e1da1d57 1835 /* If DIG is off, DIG high power state must reset. */
8fc8598e
JC
1836 dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
1837 dm_digtable.dig_state = DM_STA_DIG_OFF;
1838
e1da1d57
LS
1839 /* 1.1 DIG Off. */
1840 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); /* Only clear byte 1 and rewrite. */
8fc8598e 1841
e1da1d57 1842 /* 1.2 Set initial gain. */
8fc8598e
JC
1843 write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x17);
1844 write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x17);
1845 write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x17);
1846 write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x17);
1847
e1da1d57 1848 /* 1.3 Lower PD_TH for OFDM. */
04d695d7 1849 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
e1da1d57
LS
1850 /*
1851 * 2008/01/11 MH 40MHZ 90/92 register are not the same.
1852 * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
1853 */
91e39f09 1854 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
8fc8598e
JC
1855 /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
1856 write_nic_byte(pAdapter, rOFDM0_RxDetector1, 0x40);
e1da1d57
LS
1857 else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
1858 else
1859 PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x40);
8fc8598e 1860 */
04d695d7 1861 } else
8fc8598e
JC
1862 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
1863
e1da1d57 1864 /* 1.4 Lower CS ratio for CCK. */
8fc8598e
JC
1865 write_nic_byte(dev, 0xa0a, 0x08);
1866
e1da1d57
LS
1867 /* 1.5 Higher EDCCA. */
1868 /*PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x325);*/
8fc8598e
JC
1869 return;
1870
1871 }
1872
589b3d06 1873 /* 2. When RSSI increase, We have to judge if it is larger than a threshold
8ef3a7ed 1874 and then execute the step below. */
16da7808 1875 if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) {
8fc8598e
JC
1876 u8 reset_flag = 0;
1877
1878 if (dm_digtable.dig_state == DM_STA_DIG_ON &&
04d695d7 1879 (priv->reset_count == reset_cnt)) {
8fc8598e
JC
1880 dm_ctrl_initgain_byrssi_highpwr(dev);
1881 return;
8fc8598e 1882 }
16da7808
LS
1883 if (priv->reset_count != reset_cnt)
1884 reset_flag = 1;
1885
1886 reset_cnt = priv->reset_count;
8fc8598e
JC
1887
1888 dm_digtable.dig_state = DM_STA_DIG_ON;
e1da1d57 1889 /*DbgPrint("DIG ON\n\r");*/
8fc8598e 1890
e1da1d57
LS
1891 /*
1892 * 2.1 Set initial gain.
1893 * 2008/02/26 MH SD3-Jerry suggest to prevent dirty environment.
1894 */
04d695d7 1895 if (reset_flag == 1) {
8fc8598e
JC
1896 write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x2c);
1897 write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x2c);
1898 write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x2c);
1899 write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x2c);
04d695d7 1900 } else {
8fc8598e
JC
1901 write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x20);
1902 write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x20);
1903 write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x20);
1904 write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x20);
1905 }
1906
e1da1d57 1907 /* 2.2 Higher PD_TH for OFDM. */
04d695d7 1908 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
e1da1d57
LS
1909 /*
1910 * 2008/01/11 MH 40MHZ 90/92 register are not the same.
1911 * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
1912 */
91e39f09 1913 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
8fc8598e
JC
1914 /*
1915 else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
1916 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
e1da1d57
LS
1917 else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
1918 else
1919 PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x42);
8fc8598e 1920 */
04d695d7 1921 } else
8fc8598e
JC
1922 write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
1923
e1da1d57 1924 /* 2.3 Higher CS ratio for CCK. */
8fc8598e
JC
1925 write_nic_byte(dev, 0xa0a, 0xcd);
1926
e1da1d57
LS
1927 /*
1928 * 2.4 Lower EDCCA.
1929 * 2008/01/11 MH 90/92 series are the same.
1930 */
1931 /*PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x346);*/
8fc8598e 1932
e1da1d57
LS
1933 /* 2.5 DIG On. */
1934 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); /* Only clear byte 1 and rewrite. */
8fc8598e
JC
1935
1936 }
1937
1938 dm_ctrl_initgain_byrssi_highpwr(dev);
1939
1940} /* dm_CtrlInitGainByRssi */
1941
8fc8598e
JC
1942/*-----------------------------------------------------------------------------
1943 * Function: dm_ctrl_initgain_byrssi_highpwr()
1944 *
1945 * Overview:
1946 *
1947 * Input: NONE
1948 *
1949 * Output: NONE
1950 *
1951 * Return: NONE
1952 *
1953 * Revised History:
1954 * When Who Remark
1955 * 05/28/2008 amy Create Version 0 porting from windows code.
1956 *
1957 *---------------------------------------------------------------------------*/
1958static void dm_ctrl_initgain_byrssi_highpwr(
999d594b 1959 struct net_device *dev)
8fc8598e
JC
1960{
1961 struct r8192_priv *priv = ieee80211_priv(dev);
de13a3da 1962 static u32 reset_cnt_highpwr;
8fc8598e 1963
e1da1d57 1964 /* For smooth, we can not change high power DIG state in the range. */
8fc8598e
JC
1965 if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) &&
1966 (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh))
8fc8598e 1967 return;
8fc8598e 1968
e1da1d57
LS
1969 /*
1970 * 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if
1971 * it is larger than a threshold and then execute the step below.
1972 *
1973 * 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue.
1974 */
04d695d7 1975 if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh) {
8fc8598e
JC
1976 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON &&
1977 (priv->reset_count == reset_cnt_highpwr))
1978 return;
16da7808 1979 dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
8fc8598e 1980
e1da1d57 1981 /* 3.1 Higher PD_TH for OFDM for high power state. */
04d695d7 1982 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
91e39f09 1983 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
8fc8598e
JC
1984
1985 /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
1986 write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
1987 */
1988
04d695d7 1989 } else
8fc8598e 1990 write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
04d695d7
LS
1991 } else {
1992 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF &&
8fc8598e
JC
1993 (priv->reset_count == reset_cnt_highpwr))
1994 return;
16da7808 1995 dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
8fc8598e
JC
1996
1997 if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh &&
04d695d7 1998 priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) {
e1da1d57 1999 /* 3.2 Recover PD_TH for OFDM for normal power region. */
04d695d7 2000 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
91e39f09 2001 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
8fc8598e
JC
2002 /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2003 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2004 */
2005
04d695d7 2006 } else
8fc8598e
JC
2007 write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
2008 }
2009 }
2010
2011 reset_cnt_highpwr = priv->reset_count;
2012
2013} /* dm_CtrlInitGainByRssiHighPwr */
2014
8fc8598e 2015static void dm_initial_gain(
999d594b 2016 struct net_device *dev)
8fc8598e
JC
2017{
2018 struct r8192_priv *priv = ieee80211_priv(dev);
04d695d7 2019 u8 initial_gain = 0;
de13a3da
SH
2020 static u8 initialized, force_write;
2021 static u32 reset_cnt;
b3d42bf1 2022 u8 tmp;
8fc8598e 2023
04d695d7 2024 if (dm_digtable.dig_algorithm_switch) {
8fc8598e
JC
2025 initialized = 0;
2026 reset_cnt = 0;
2027 }
2028
04d695d7
LS
2029 if (dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) {
2030 if (dm_digtable.cur_connect_state == DIG_CONNECT) {
2031 if ((dm_digtable.rssi_val+10-dm_digtable.backoff_val) > dm_digtable.rx_gain_range_max)
8fc8598e 2032 dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_max;
04d695d7 2033 else if ((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
8fc8598e
JC
2034 dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min;
2035 else
2036 dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val;
04d695d7
LS
2037 } else { /* current state is disconnected */
2038 if (dm_digtable.cur_ig_value == 0)
8fc8598e
JC
2039 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
2040 else
2041 dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
2042 }
04d695d7 2043 } else { /* disconnected -> connected or connected -> disconnected */
8fc8598e
JC
2044 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
2045 dm_digtable.pre_ig_value = 0;
2046 }
e1da1d57 2047 /*DbgPrint("DM_DigTable.CurIGValue = 0x%x, DM_DigTable.PreIGValue = 0x%x\n", DM_DigTable.CurIGValue, DM_DigTable.PreIGValue);*/
8fc8598e 2048
e1da1d57 2049 /* if silent reset happened, we should rewrite the values back */
04d695d7 2050 if (priv->reset_count != reset_cnt) {
8fc8598e
JC
2051 force_write = 1;
2052 reset_cnt = priv->reset_count;
2053 }
2054
b3d42bf1
XR
2055 read_nic_byte(dev, rOFDM0_XAAGCCore1, &tmp);
2056 if (dm_digtable.pre_ig_value != tmp)
8fc8598e
JC
2057 force_write = 1;
2058
2059 {
04d695d7
LS
2060 if ((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
2061 || !initialized || force_write) {
8fc8598e 2062 initial_gain = (u8)dm_digtable.cur_ig_value;
e1da1d57
LS
2063 /*DbgPrint("Write initial gain = 0x%x\n", initial_gain);*/
2064 /* Set initial gain. */
8fc8598e
JC
2065 write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
2066 write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
2067 write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
2068 write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
2069 dm_digtable.pre_ig_value = dm_digtable.cur_ig_value;
2070 initialized = 1;
2071 force_write = 0;
2072 }
2073 }
2074}
2075
2076static void dm_pd_th(
999d594b 2077 struct net_device *dev)
8fc8598e
JC
2078{
2079 struct r8192_priv *priv = ieee80211_priv(dev);
de13a3da
SH
2080 static u8 initialized, force_write;
2081 static u32 reset_cnt;
8fc8598e 2082
04d695d7 2083 if (dm_digtable.dig_algorithm_switch) {
8fc8598e
JC
2084 initialized = 0;
2085 reset_cnt = 0;
2086 }
2087
04d695d7
LS
2088 if (dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) {
2089 if (dm_digtable.cur_connect_state == DIG_CONNECT) {
8fc8598e
JC
2090 if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh)
2091 dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER;
16da7808 2092 else if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)
8fc8598e
JC
2093 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2094 else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) &&
2095 (dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh))
2096 dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER;
2097 else
2098 dm_digtable.curpd_thstate = dm_digtable.prepd_thstate;
04d695d7 2099 } else {
8fc8598e
JC
2100 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2101 }
04d695d7 2102 } else { /* disconnected -> connected or connected -> disconnected */
8fc8598e
JC
2103 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2104 }
2105
e1da1d57 2106 /* if silent reset happened, we should rewrite the values back */
04d695d7 2107 if (priv->reset_count != reset_cnt) {
8fc8598e
JC
2108 force_write = 1;
2109 reset_cnt = priv->reset_count;
2110 }
2111
2112 {
04d695d7
LS
2113 if ((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
2114 (initialized <= 3) || force_write) {
e1da1d57 2115 /*DbgPrint("Write PD_TH state = %d\n", DM_DigTable.CurPD_THState);*/
04d695d7 2116 if (dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) {
e1da1d57 2117 /* Lower PD_TH for OFDM. */
04d695d7 2118 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
e1da1d57
LS
2119 /*
2120 * 2008/01/11 MH 40MHZ 90/92 register are not the same.
2121 * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2122 */
91e39f09 2123 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
8fc8598e
JC
2124 /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2125 write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
2126 */
04d695d7 2127 } else
8fc8598e 2128 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
04d695d7 2129 } else if (dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER) {
e1da1d57 2130 /* Higher PD_TH for OFDM. */
04d695d7 2131 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
e1da1d57
LS
2132 /*
2133 * 2008/01/11 MH 40MHZ 90/92 register are not the same.
2134 * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2135 */
91e39f09 2136 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
8fc8598e
JC
2137 /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2138 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2139 */
04d695d7 2140 } else
8fc8598e 2141 write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
04d695d7 2142 } else if (dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) {
e1da1d57 2143 /* Higher PD_TH for OFDM for high power state. */
04d695d7 2144 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
91e39f09 2145 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
8fc8598e
JC
2146 /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2147 write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
2148 */
04d695d7 2149 } else
8fc8598e
JC
2150 write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
2151 }
2152 dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
04d695d7 2153 if (initialized <= 3)
8fc8598e
JC
2154 initialized++;
2155 force_write = 0;
2156 }
2157 }
2158}
2159
2160static void dm_cs_ratio(
999d594b 2161 struct net_device *dev)
8fc8598e
JC
2162{
2163 struct r8192_priv *priv = ieee80211_priv(dev);
0b4ef0a6 2164 static u8 initialized, force_write;
de13a3da 2165 static u32 reset_cnt;
8fc8598e 2166
04d695d7 2167 if (dm_digtable.dig_algorithm_switch) {
8fc8598e
JC
2168 initialized = 0;
2169 reset_cnt = 0;
2170 }
2171
04d695d7
LS
2172 if (dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) {
2173 if (dm_digtable.cur_connect_state == DIG_CONNECT) {
16da7808 2174 if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)
8fc8598e 2175 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
16da7808 2176 else if (dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh)
8fc8598e
JC
2177 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
2178 else
2179 dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
04d695d7 2180 } else {
8fc8598e
JC
2181 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2182 }
04d695d7 2183 } else /* disconnected -> connected or connected -> disconnected */
8fc8598e 2184 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
8fc8598e 2185
e1da1d57 2186 /* if silent reset happened, we should rewrite the values back */
04d695d7 2187 if (priv->reset_count != reset_cnt) {
8fc8598e
JC
2188 force_write = 1;
2189 reset_cnt = priv->reset_count;
2190 }
2191
8fc8598e 2192 {
04d695d7
LS
2193 if ((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
2194 !initialized || force_write) {
e1da1d57 2195 /*DbgPrint("Write CS_ratio state = %d\n", DM_DigTable.CurCS_ratioState);*/
04d695d7 2196 if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER) {
e1da1d57 2197 /* Lower CS ratio for CCK. */
8fc8598e 2198 write_nic_byte(dev, 0xa0a, 0x08);
04d695d7 2199 } else if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER) {
e1da1d57 2200 /* Higher CS ratio for CCK. */
8fc8598e
JC
2201 write_nic_byte(dev, 0xa0a, 0xcd);
2202 }
2203 dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
2204 initialized = 1;
2205 force_write = 0;
2206 }
2207 }
2208}
2209
c541fa87 2210void dm_init_edca_turbo(struct net_device *dev)
8fc8598e
JC
2211{
2212 struct r8192_priv *priv = ieee80211_priv(dev);
2213
2214 priv->bcurrent_turbo_EDCA = false;
2215 priv->ieee80211->bis_any_nonbepkts = false;
2216 priv->bis_cur_rdlstate = false;
e1da1d57 2217} /* dm_init_edca_turbo */
8fc8598e 2218
8fc8598e 2219static void dm_check_edca_turbo(
999d594b 2220 struct net_device *dev)
8fc8598e
JC
2221{
2222 struct r8192_priv *priv = ieee80211_priv(dev);
2223 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
e1da1d57 2224 /*PSTA_QOS pStaQos = pMgntInfo->pStaQos;*/
8fc8598e 2225
e1da1d57 2226 /* Keep past Tx/Rx packet count for RT-to-RT EDCA turbo. */
de13a3da
SH
2227 static unsigned long lastTxOkCnt;
2228 static unsigned long lastRxOkCnt;
8fc8598e
JC
2229 unsigned long curTxOkCnt = 0;
2230 unsigned long curRxOkCnt = 0;
2231
e1da1d57
LS
2232 /*
2233 * Do not be Turbo if it's under WiFi config and Qos Enabled, because the EDCA parameters
2234 * should follow the settings from QAP. By Bruce, 2007-12-07.
2235 */
04d695d7 2236 if (priv->ieee80211->state != IEEE80211_LINKED)
8fc8598e 2237 goto dm_CheckEdcaTurbo_EXIT;
e1da1d57 2238 /* We do not turn on EDCA turbo mode for some AP that has IOT issue */
04d695d7 2239 if (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
8fc8598e
JC
2240 goto dm_CheckEdcaTurbo_EXIT;
2241
04d695d7 2242 /*printk("========>%s():bis_any_nonbepkts is %d\n", __func__, priv->bis_any_nonbepkts);*/
e1da1d57 2243 /* Check the status for current condition. */
04d695d7 2244 if (!priv->ieee80211->bis_any_nonbepkts) {
8fc8598e
JC
2245 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
2246 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
e1da1d57 2247 /* For RT-AP, we needs to turn it on when Rx>Tx */
04d695d7 2248 if (curRxOkCnt > 4*curTxOkCnt) {
e1da1d57 2249 /*printk("%s():curRxOkCnt > 4*curTxOkCnt\n");*/
04d695d7 2250 if (!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) {
8fc8598e
JC
2251 write_nic_dword(dev, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]);
2252 priv->bis_cur_rdlstate = true;
2253 }
04d695d7 2254 } else {
e1da1d57 2255 /*printk("%s():curRxOkCnt < 4*curTxOkCnt\n");*/
04d695d7 2256 if (priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) {
8fc8598e
JC
2257 write_nic_dword(dev, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]);
2258 priv->bis_cur_rdlstate = false;
2259 }
2260
2261 }
2262
2263 priv->bcurrent_turbo_EDCA = true;
04d695d7 2264 } else {
e1da1d57
LS
2265 /*
2266 * Turn Off EDCA turbo here.
2267 * Restore original EDCA according to the declaration of AP.
2268 */
04d695d7 2269 if (priv->bcurrent_turbo_EDCA) {
8fc8598e
JC
2270 {
2271 u8 u1bAIFS;
2272 u32 u4bAcParam;
2273 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2274 u8 mode = priv->ieee80211->mode;
2275
e1da1d57 2276 /* For Each time updating EDCA parameter, reset EDCA turbo mode status. */
8fc8598e 2277 dm_init_edca_turbo(dev);
04d695d7 2278 u1bAIFS = qos_parameters->aifs[0] * ((mode&(IEEE_G|IEEE_N_24G)) ? 9 : 20) + aSifsTime;
2060f31a 2279 u4bAcParam = (((u32)(qos_parameters->tx_op_limit[0])) << AC_PARAM_TXOP_LIMIT_OFFSET)|
04d695d7
LS
2280 (((u32)(qos_parameters->cw_max[0])) << AC_PARAM_ECW_MAX_OFFSET)|
2281 (((u32)(qos_parameters->cw_min[0])) << AC_PARAM_ECW_MIN_OFFSET)|
2060f31a 2282 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET);
e1da1d57 2283 /*write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);*/
8fc8598e
JC
2284 write_nic_dword(dev, EDCAPARA_BE, u4bAcParam);
2285
e1da1d57
LS
2286 /*
2287 * Check ACM bit.
2288 * If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
2289 */
8fc8598e 2290 {
e1da1d57 2291 /* TODO: Modified this part and try to set acm control in only 1 IO processing!! */
8fc8598e
JC
2292
2293 PACI_AIFSN pAciAifsn = (PACI_AIFSN)&(qos_parameters->aifs[0]);
b3d42bf1 2294 u8 AcmCtrl;
04d695d7 2295
b3d42bf1 2296 read_nic_byte(dev, AcmHwCtrl, &AcmCtrl);
04d695d7
LS
2297
2298 if (pAciAifsn->f.ACM) { /* ACM bit is 1. */
8fc8598e 2299 AcmCtrl |= AcmHw_BeqEn;
04d695d7 2300 } else { /* ACM bit is 0. */
8fc8598e
JC
2301 AcmCtrl &= (~AcmHw_BeqEn);
2302 }
2303
04d695d7 2304 RT_TRACE(COMP_QOS, "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);
0009631b 2305 write_nic_byte(dev, AcmHwCtrl, AcmCtrl);
8fc8598e
JC
2306 }
2307 }
2308 priv->bcurrent_turbo_EDCA = false;
2309 }
2310 }
2311
8fc8598e 2312dm_CheckEdcaTurbo_EXIT:
e1da1d57 2313 /* Set variables for next time. */
8fc8598e
JC
2314 priv->ieee80211->bis_any_nonbepkts = false;
2315 lastTxOkCnt = priv->stats.txbytesunicast;
2316 lastRxOkCnt = priv->stats.rxbytesunicast;
e1da1d57 2317} /* dm_CheckEdcaTurbo */
8fc8598e 2318
999d594b 2319static void dm_init_ctstoself(struct net_device *dev)
8fc8598e
JC
2320{
2321 struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
2322
4b2faf80 2323 priv->ieee80211->bCTSToSelfEnable = true;
8fc8598e
JC
2324 priv->ieee80211->CTSToSelfTH = CTSToSelfTHVal;
2325}
2326
2327static void dm_ctstoself(struct net_device *dev)
2328{
2329 struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
2330 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
de13a3da
SH
2331 static unsigned long lastTxOkCnt;
2332 static unsigned long lastRxOkCnt;
8fc8598e
JC
2333 unsigned long curTxOkCnt = 0;
2334 unsigned long curRxOkCnt = 0;
2335
4b2faf80 2336 if (priv->ieee80211->bCTSToSelfEnable != true) {
8fc8598e
JC
2337 pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
2338 return;
2339 }
2340 /*
2341 1. Uplink
2342 2. Linksys350/Linksys300N
2343 3. <50 disable, >55 enable
2344 */
2345
04d695d7 2346 if (pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) {
8fc8598e
JC
2347 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
2348 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
04d695d7 2349 if (curRxOkCnt > 4*curTxOkCnt) { /* downlink, disable CTS to self */
8fc8598e 2350 pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
e1da1d57 2351 /*DbgPrint("dm_CTSToSelf() ==> CTS to self disabled -- downlink\n");*/
04d695d7 2352 } else { /* uplink */
8fc8598e 2353 pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
8fc8598e
JC
2354 }
2355
2356 lastTxOkCnt = priv->stats.txbytesunicast;
2357 lastRxOkCnt = priv->stats.rxbytesunicast;
2358 }
2359}
2360
8fc8598e
JC
2361/*-----------------------------------------------------------------------------
2362 * Function: dm_check_pbc_gpio()
2363 *
2364 * Overview: Check if PBC button is pressed.
2365 *
2366 * Input: NONE
2367 *
2368 * Output: NONE
2369 *
2370 * Return: NONE
2371 *
2372 * Revised History:
2373 * When Who Remark
35997ff0 2374 * 05/28/2008 amy Create Version 0 porting from windows code.
8fc8598e
JC
2375 *
2376 *---------------------------------------------------------------------------*/
2377static void dm_check_pbc_gpio(struct net_device *dev)
2378{
8fc8598e
JC
2379 struct r8192_priv *priv = ieee80211_priv(dev);
2380 u8 tmp1byte;
2381
b3d42bf1 2382 read_nic_byte(dev, GPI, &tmp1byte);
04d695d7 2383 if (tmp1byte == 0xff)
8fc8598e
JC
2384 return;
2385
56b3152e 2386 if (tmp1byte & BIT(6) || tmp1byte & BIT(0)) {
e1da1d57
LS
2387 /*
2388 * Here we only set bPbcPressed to TRUE
2389 * After trigger PBC, the variable will be set to FALSE
2390 */
8fc8598e
JC
2391 RT_TRACE(COMP_IO, "CheckPbcGPIO - PBC is pressed\n");
2392 priv->bpbc_pressed = true;
2393 }
8fc8598e
JC
2394
2395}
2396
8fc8598e
JC
2397/*-----------------------------------------------------------------------------
2398 * Function: DM_RFPathCheckWorkItemCallBack()
2399 *
2400 * Overview: Check if Current RF RX path is enabled
2401 *
2402 * Input: NONE
2403 *
2404 * Output: NONE
2405 *
2406 * Return: NONE
2407 *
2408 * Revised History:
2409 * When Who Remark
2410 * 01/30/2008 MHC Create Version 0.
2411 *
2412 *---------------------------------------------------------------------------*/
bf316434 2413void dm_rf_pathcheck_workitemcallback(struct work_struct *work)
8fc8598e 2414{
04d695d7
LS
2415 struct delayed_work *dwork = container_of(work, struct delayed_work, work);
2416 struct r8192_priv *priv = container_of(dwork, struct r8192_priv, rfpath_check_wq);
2417 struct net_device *dev = priv->ieee80211->dev;
2418 /*bool bactually_set = false;*/
8fc8598e
JC
2419 u8 rfpath = 0, i;
2420
8fc8598e
JC
2421 /* 2008/01/30 MH After discussing with SD3 Jerry, 0xc04/0xd04 register will
2422 always be the same. We only read 0xc04 now. */
b3d42bf1 2423 read_nic_byte(dev, 0xc04, &rfpath);
8fc8598e 2424
e1da1d57 2425 /* Check Bit 0-3, it means if RF A-D is enabled. */
04d695d7 2426 for (i = 0; i < RF90_PATH_MAX; i++) {
8fc8598e 2427 if (rfpath & (0x01<<i))
19cd2297 2428 priv->brfpath_rxenable[i] = true;
8fc8598e 2429 else
19cd2297 2430 priv->brfpath_rxenable[i] = false;
8fc8598e 2431 }
04d695d7 2432 if (!DM_RxPathSelTable.Enable)
8fc8598e
JC
2433 return;
2434
2435 dm_rxpath_sel_byrssi(dev);
2436} /* DM_RFPathCheckWorkItemCallBack */
2437
999d594b 2438static void dm_init_rxpath_selection(struct net_device *dev)
8fc8598e
JC
2439{
2440 u8 i;
2441 struct r8192_priv *priv = ieee80211_priv(dev);
04d695d7 2442
e1da1d57 2443 DM_RxPathSelTable.Enable = 1; /* default enabled */
8fc8598e
JC
2444 DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low;
2445 DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH;
04d695d7 2446 if (priv->CustomerID == RT_CID_819x_Netcore)
8fc8598e
JC
2447 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
2448 else
2449 DM_RxPathSelTable.cck_method = CCK_Rx_Version_1;
2450 DM_RxPathSelTable.DbgMode = DM_DBG_OFF;
2451 DM_RxPathSelTable.disabledRF = 0;
04d695d7 2452 for (i = 0; i < 4; i++) {
8fc8598e
JC
2453 DM_RxPathSelTable.rf_rssi[i] = 50;
2454 DM_RxPathSelTable.cck_pwdb_sta[i] = -64;
2455 DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
2456 }
2457}
2458
999d594b 2459static void dm_rxpath_sel_byrssi(struct net_device *dev)
8fc8598e
JC
2460{
2461 struct r8192_priv *priv = ieee80211_priv(dev);
04d695d7
LS
2462 u8 i, max_rssi_index = 0, min_rssi_index = 0, sec_rssi_index = 0, rf_num = 0;
2463 u8 tmp_max_rssi = 0, tmp_min_rssi = 0, tmp_sec_rssi = 0;
2464 u8 cck_default_Rx = 0x2; /* RF-C */
2465 u8 cck_optional_Rx = 0x3; /* RF-D */
2466 long tmp_cck_max_pwdb = 0, tmp_cck_min_pwdb = 0, tmp_cck_sec_pwdb = 0;
2467 u8 cck_rx_ver2_max_index = 0, cck_rx_ver2_min_index = 0, cck_rx_ver2_sec_index = 0;
8fc8598e
JC
2468 u8 cur_rf_rssi;
2469 long cur_cck_pwdb;
de13a3da 2470 static u8 disabled_rf_cnt, cck_Rx_Path_initialized;
8fc8598e
JC
2471 u8 update_cck_rx_path;
2472
04d695d7 2473 if (priv->rf_type != RF_2T4R)
8fc8598e
JC
2474 return;
2475
04d695d7 2476 if (!cck_Rx_Path_initialized) {
b3d42bf1
XR
2477 read_nic_byte(dev, 0xa07, &DM_RxPathSelTable.cck_Rx_path);
2478 DM_RxPathSelTable.cck_Rx_path &= 0xf;
8fc8598e
JC
2479 cck_Rx_Path_initialized = 1;
2480 }
2481
b3d42bf1
XR
2482 read_nic_byte(dev, 0xc04, &DM_RxPathSelTable.disabledRF);
2483 DM_RxPathSelTable.disabledRF = ~DM_RxPathSelTable.disabledRF & 0xf;
8fc8598e 2484
04d695d7 2485 if (priv->ieee80211->mode == WIRELESS_MODE_B) {
e1da1d57 2486 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2; /* pure B mode, fixed cck version2 */
04d695d7 2487 /*DbgPrint("Pure B mode, use cck rx version2\n");*/
8fc8598e
JC
2488 }
2489
e1da1d57 2490 /* decide max/sec/min rssi index */
04d695d7
LS
2491 for (i = 0; i < RF90_PATH_MAX; i++) {
2492 if (!DM_RxPathSelTable.DbgMode)
8fc8598e
JC
2493 DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
2494
04d695d7 2495 if (priv->brfpath_rxenable[i]) {
8fc8598e
JC
2496 rf_num++;
2497 cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i];
2498
04d695d7 2499 if (rf_num == 1) { /* find first enabled rf path and the rssi values */
e1da1d57 2500 /* initialize, set all rssi index to the same one */
8fc8598e
JC
2501 max_rssi_index = min_rssi_index = sec_rssi_index = i;
2502 tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
04d695d7
LS
2503 } else if (rf_num == 2) { /* we pick up the max index first, and let sec and min to be the same one */
2504 if (cur_rf_rssi >= tmp_max_rssi) {
8fc8598e
JC
2505 tmp_max_rssi = cur_rf_rssi;
2506 max_rssi_index = i;
04d695d7 2507 } else {
8fc8598e
JC
2508 tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
2509 sec_rssi_index = min_rssi_index = i;
2510 }
04d695d7
LS
2511 } else {
2512 if (cur_rf_rssi > tmp_max_rssi) {
8fc8598e
JC
2513 tmp_sec_rssi = tmp_max_rssi;
2514 sec_rssi_index = max_rssi_index;
2515 tmp_max_rssi = cur_rf_rssi;
2516 max_rssi_index = i;
04d695d7 2517 } else if (cur_rf_rssi == tmp_max_rssi) { /* let sec and min point to the different index */
8fc8598e
JC
2518 tmp_sec_rssi = cur_rf_rssi;
2519 sec_rssi_index = i;
04d695d7 2520 } else if ((cur_rf_rssi < tmp_max_rssi) && (cur_rf_rssi > tmp_sec_rssi)) {
8fc8598e
JC
2521 tmp_sec_rssi = cur_rf_rssi;
2522 sec_rssi_index = i;
04d695d7
LS
2523 } else if (cur_rf_rssi == tmp_sec_rssi) {
2524 if (tmp_sec_rssi == tmp_min_rssi) {
2525 /* let sec and min point to the different index */
8fc8598e
JC
2526 tmp_sec_rssi = cur_rf_rssi;
2527 sec_rssi_index = i;
04d695d7 2528 } else {
e1da1d57 2529 /* This case we don't need to set any index */
8fc8598e 2530 }
04d695d7 2531 } else if ((cur_rf_rssi < tmp_sec_rssi) && (cur_rf_rssi > tmp_min_rssi)) {
e1da1d57 2532 /* This case we don't need to set any index */
04d695d7
LS
2533 } else if (cur_rf_rssi == tmp_min_rssi) {
2534 if (tmp_sec_rssi == tmp_min_rssi) {
2535 /* let sec and min point to the different index */
8fc8598e
JC
2536 tmp_min_rssi = cur_rf_rssi;
2537 min_rssi_index = i;
04d695d7 2538 } else {
e1da1d57 2539 /* This case we don't need to set any index */
8fc8598e 2540 }
04d695d7 2541 } else if (cur_rf_rssi < tmp_min_rssi) {
8fc8598e
JC
2542 tmp_min_rssi = cur_rf_rssi;
2543 min_rssi_index = i;
2544 }
2545 }
2546 }
2547 }
2548
2549 rf_num = 0;
e1da1d57 2550 /* decide max/sec/min cck pwdb index */
04d695d7
LS
2551 if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) {
2552 for (i = 0; i < RF90_PATH_MAX; i++) {
2553 if (priv->brfpath_rxenable[i]) {
8fc8598e
JC
2554 rf_num++;
2555 cur_cck_pwdb = DM_RxPathSelTable.cck_pwdb_sta[i];
2556
04d695d7
LS
2557 if (rf_num == 1) { /* find first enabled rf path and the rssi values */
2558 /* initialize, set all rssi index to the same one */
8fc8598e
JC
2559 cck_rx_ver2_max_index = cck_rx_ver2_min_index = cck_rx_ver2_sec_index = i;
2560 tmp_cck_max_pwdb = tmp_cck_min_pwdb = tmp_cck_sec_pwdb = cur_cck_pwdb;
04d695d7
LS
2561 } else if (rf_num == 2) { /* we pick up the max index first, and let sec and min to be the same one */
2562 if (cur_cck_pwdb >= tmp_cck_max_pwdb) {
8fc8598e
JC
2563 tmp_cck_max_pwdb = cur_cck_pwdb;
2564 cck_rx_ver2_max_index = i;
04d695d7 2565 } else {
8fc8598e
JC
2566 tmp_cck_sec_pwdb = tmp_cck_min_pwdb = cur_cck_pwdb;
2567 cck_rx_ver2_sec_index = cck_rx_ver2_min_index = i;
2568 }
04d695d7
LS
2569 } else {
2570 if (cur_cck_pwdb > tmp_cck_max_pwdb) {
8fc8598e
JC
2571 tmp_cck_sec_pwdb = tmp_cck_max_pwdb;
2572 cck_rx_ver2_sec_index = cck_rx_ver2_max_index;
2573 tmp_cck_max_pwdb = cur_cck_pwdb;
2574 cck_rx_ver2_max_index = i;
f0e0f8cf
LS
2575 } else if (cur_cck_pwdb == tmp_cck_max_pwdb) {
2576 /* let sec and min point to the different index */
8fc8598e
JC
2577 tmp_cck_sec_pwdb = cur_cck_pwdb;
2578 cck_rx_ver2_sec_index = i;
04d695d7 2579 } else if ((cur_cck_pwdb < tmp_cck_max_pwdb) && (cur_cck_pwdb > tmp_cck_sec_pwdb)) {
8fc8598e
JC
2580 tmp_cck_sec_pwdb = cur_cck_pwdb;
2581 cck_rx_ver2_sec_index = i;
f0e0f8cf
LS
2582 } else if (cur_cck_pwdb == tmp_cck_sec_pwdb && tmp_cck_sec_pwdb == tmp_cck_min_pwdb) {
2583 /* let sec and min point to the different index */
2584 tmp_cck_sec_pwdb = cur_cck_pwdb;
2585 cck_rx_ver2_sec_index = i;
2586 /* otherwise we don't need to set any index */
04d695d7 2587 } else if ((cur_cck_pwdb < tmp_cck_sec_pwdb) && (cur_cck_pwdb > tmp_cck_min_pwdb)) {
e1da1d57 2588 /* This case we don't need to set any index */
f0e0f8cf
LS
2589 } else if (cur_cck_pwdb == tmp_cck_min_pwdb && tmp_cck_sec_pwdb == tmp_cck_min_pwdb) {
2590 /* let sec and min point to the different index */
2591 tmp_cck_min_pwdb = cur_cck_pwdb;
2592 cck_rx_ver2_min_index = i;
2593 /* otherwise we don't need to set any index */
04d695d7 2594 } else if (cur_cck_pwdb < tmp_cck_min_pwdb) {
8fc8598e
JC
2595 tmp_cck_min_pwdb = cur_cck_pwdb;
2596 cck_rx_ver2_min_index = i;
2597 }
2598 }
2599
2600 }
2601 }
2602 }
2603
e1da1d57
LS
2604 /*
2605 * Set CCK Rx path
2606 * reg0xA07[3:2]=cck default rx path, reg0xa07[1:0]=cck optional rx path.
2607 */
8fc8598e 2608 update_cck_rx_path = 0;
04d695d7 2609 if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) {
8fc8598e
JC
2610 cck_default_Rx = cck_rx_ver2_max_index;
2611 cck_optional_Rx = cck_rx_ver2_sec_index;
04d695d7 2612 if (tmp_cck_max_pwdb != -64)
8fc8598e
JC
2613 update_cck_rx_path = 1;
2614 }
2615
04d695d7
LS
2616 if (tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2) {
2617 if ((tmp_max_rssi - tmp_min_rssi) >= DM_RxPathSelTable.diff_TH) {
e1da1d57 2618 /* record the enabled rssi threshold */
8fc8598e 2619 DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] = tmp_max_rssi+5;
e1da1d57
LS
2620 /* disable the BB Rx path, OFDM */
2621 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<min_rssi_index, 0x0); /* 0xc04[3:0] */
2622 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<min_rssi_index, 0x0); /* 0xd04[3:0] */
8fc8598e
JC
2623 disabled_rf_cnt++;
2624 }
04d695d7 2625 if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_1) {
8fc8598e
JC
2626 cck_default_Rx = max_rssi_index;
2627 cck_optional_Rx = sec_rssi_index;
04d695d7 2628 if (tmp_max_rssi)
8fc8598e
JC
2629 update_cck_rx_path = 1;
2630 }
2631 }
2632
04d695d7 2633 if (update_cck_rx_path) {
8fc8598e
JC
2634 DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2)|(cck_optional_Rx);
2635 rtl8192_setBBreg(dev, rCCK0_AFESetting, 0x0f000000, DM_RxPathSelTable.cck_Rx_path);
2636 }
2637
04d695d7
LS
2638 if (DM_RxPathSelTable.disabledRF) {
2639 for (i = 0; i < 4; i++) {
2640 if ((DM_RxPathSelTable.disabledRF>>i) & 0x1) { /* disabled rf */
2641 if (tmp_max_rssi >= DM_RxPathSelTable.rf_enable_rssi_th[i]) {
e1da1d57 2642 /* enable the BB Rx path */
04d695d7 2643 /*DbgPrint("RF-%d is enabled.\n", 0x1<<i);*/
e1da1d57
LS
2644 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<i, 0x1); /* 0xc04[3:0] */
2645 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<i, 0x1); /* 0xd04[3:0] */
8fc8598e
JC
2646 DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
2647 disabled_rf_cnt--;
2648 }
2649 }
2650 }
2651 }
2652}
2653
2654/*-----------------------------------------------------------------------------
2655 * Function: dm_check_rx_path_selection()
2656 *
2657 * Overview: Call a workitem to check current RXRF path and Rx Path selection by RSSI.
2658 *
2659 * Input: NONE
2660 *
2661 * Output: NONE
2662 *
2663 * Return: NONE
2664 *
2665 * Revised History:
2666 * When Who Remark
2667 * 05/28/2008 amy Create Version 0 porting from windows code.
2668 *
2669 *---------------------------------------------------------------------------*/
04d695d7 2670static void dm_check_rx_path_selection(struct net_device *dev)
8fc8598e
JC
2671{
2672 struct r8192_priv *priv = ieee80211_priv(dev);
8fc8598e 2673
04d695d7
LS
2674 queue_delayed_work(priv->priv_wq, &priv->rfpath_check_wq, 0);
2675} /* dm_CheckRxRFPath */
8fc8598e 2676
04d695d7 2677static void dm_init_fsync(struct net_device *dev)
8fc8598e
JC
2678{
2679 struct r8192_priv *priv = ieee80211_priv(dev);
2680
2681 priv->ieee80211->fsync_time_interval = 500;
2682 priv->ieee80211->fsync_rate_bitmap = 0x0f000800;
2683 priv->ieee80211->fsync_rssi_threshold = 30;
8fc8598e 2684 priv->ieee80211->bfsync_enable = false;
8fc8598e 2685 priv->ieee80211->fsync_multiple_timeinterval = 3;
04d695d7
LS
2686 priv->ieee80211->fsync_firstdiff_ratethreshold = 100;
2687 priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
8fc8598e 2688 priv->ieee80211->fsync_state = Default_Fsync;
e1da1d57 2689 priv->framesyncMonitor = 1; /* current default 0xc38 monitor on */
acc6539f
SA
2690 setup_timer(&priv->fsync_timer, dm_fsync_timer_callback,
2691 (unsigned long)dev);
8fc8598e
JC
2692}
2693
8fc8598e
JC
2694static void dm_deInit_fsync(struct net_device *dev)
2695{
2696 struct r8192_priv *priv = ieee80211_priv(dev);
04d695d7 2697
8fc8598e
JC
2698 del_timer_sync(&priv->fsync_timer);
2699}
2700
c541fa87 2701void dm_fsync_timer_callback(unsigned long data)
8fc8598e
JC
2702{
2703 struct net_device *dev = (struct net_device *)data;
2704 struct r8192_priv *priv = ieee80211_priv((struct net_device *)data);
04d695d7 2705 u32 rate_index, rate_count = 0, rate_count_diff = 0;
8fc8598e
JC
2706 bool bSwitchFromCountDiff = false;
2707 bool bDoubleTimeInterval = false;
2708
04d695d7 2709 if (priv->ieee80211->state == IEEE80211_LINKED &&
8fc8598e 2710 priv->ieee80211->bfsync_enable &&
04d695d7 2711 (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) {
e1da1d57 2712 /* Count rate 54, MCS [7], [12, 13, 14, 15] */
8fc8598e 2713 u32 rate_bitmap;
04d695d7
LS
2714
2715 for (rate_index = 0; rate_index <= 27; rate_index++) {
8fc8598e 2716 rate_bitmap = 1 << rate_index;
04d695d7
LS
2717 if (priv->ieee80211->fsync_rate_bitmap & rate_bitmap)
2718 rate_count += priv->stats.received_rate_histogram[1][rate_index];
8fc8598e
JC
2719 }
2720
04d695d7 2721 if (rate_count < priv->rate_record)
8fc8598e
JC
2722 rate_count_diff = 0xffffffff - rate_count + priv->rate_record;
2723 else
2724 rate_count_diff = rate_count - priv->rate_record;
04d695d7 2725 if (rate_count_diff < priv->rateCountDiffRecord) {
8fc8598e 2726 u32 DiffNum = priv->rateCountDiffRecord - rate_count_diff;
e1da1d57 2727 /* Continue count */
04d695d7 2728 if (DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold)
4c234ebc 2729 priv->ContinueDiffCount++;
8fc8598e 2730 else
4c234ebc 2731 priv->ContinueDiffCount = 0;
8fc8598e 2732
e1da1d57 2733 /* Continue count over */
04d695d7 2734 if (priv->ContinueDiffCount >= 2) {
8fc8598e 2735 bSwitchFromCountDiff = true;
4c234ebc 2736 priv->ContinueDiffCount = 0;
8fc8598e 2737 }
04d695d7 2738 } else {
e1da1d57 2739 /* Stop the continued count */
4c234ebc 2740 priv->ContinueDiffCount = 0;
8fc8598e
JC
2741 }
2742
e1da1d57 2743 /* If Count diff <= FsyncRateCountThreshold */
04d695d7 2744 if (rate_count_diff <= priv->ieee80211->fsync_firstdiff_ratethreshold) {
8fc8598e 2745 bSwitchFromCountDiff = true;
4c234ebc 2746 priv->ContinueDiffCount = 0;
8fc8598e
JC
2747 }
2748 priv->rate_record = rate_count;
2749 priv->rateCountDiffRecord = rate_count_diff;
04d695d7 2750 RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff, priv->bswitch_fsync);
e1da1d57 2751 /* if we never receive those mcs rate and rssi > 30 % then switch fsyn */
04d695d7 2752 if (priv->undecorated_smoothed_pwdb > priv->ieee80211->fsync_rssi_threshold && bSwitchFromCountDiff) {
8fc8598e
JC
2753 bDoubleTimeInterval = true;
2754 priv->bswitch_fsync = !priv->bswitch_fsync;
04d695d7 2755 if (priv->bswitch_fsync) {
0b4ef0a6 2756 write_nic_byte(dev, 0xC36, 0x1c);
8fc8598e 2757 write_nic_byte(dev, 0xC3e, 0x90);
04d695d7 2758 } else {
8fc8598e 2759 write_nic_byte(dev, 0xC36, 0x5c);
8fc8598e
JC
2760 write_nic_byte(dev, 0xC3e, 0x96);
2761 }
04d695d7
LS
2762 } else if (priv->undecorated_smoothed_pwdb <= priv->ieee80211->fsync_rssi_threshold) {
2763 if (priv->bswitch_fsync) {
8fc8598e 2764 priv->bswitch_fsync = false;
8fc8598e 2765 write_nic_byte(dev, 0xC36, 0x5c);
8fc8598e
JC
2766 write_nic_byte(dev, 0xC3e, 0x96);
2767 }
2768 }
04d695d7
LS
2769 if (bDoubleTimeInterval) {
2770 if (timer_pending(&priv->fsync_timer))
8fc8598e
JC
2771 del_timer_sync(&priv->fsync_timer);
2772 priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval*priv->ieee80211->fsync_multiple_timeinterval);
2773 add_timer(&priv->fsync_timer);
04d695d7
LS
2774 } else {
2775 if (timer_pending(&priv->fsync_timer))
8fc8598e
JC
2776 del_timer_sync(&priv->fsync_timer);
2777 priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
2778 add_timer(&priv->fsync_timer);
2779 }
04d695d7 2780 } else {
e1da1d57 2781 /* Let Register return to default value; */
04d695d7 2782 if (priv->bswitch_fsync) {
8fc8598e 2783 priv->bswitch_fsync = false;
8fc8598e 2784 write_nic_byte(dev, 0xC36, 0x5c);
8fc8598e
JC
2785 write_nic_byte(dev, 0xC3e, 0x96);
2786 }
4c234ebc 2787 priv->ContinueDiffCount = 0;
8fc8598e 2788 write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
8fc8598e 2789 }
4c234ebc 2790 RT_TRACE(COMP_HALDM, "ContinueDiffCount %d\n", priv->ContinueDiffCount);
04d695d7 2791 RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff, priv->bswitch_fsync);
8fc8598e
JC
2792}
2793
2794static void dm_StartHWFsync(struct net_device *dev)
2795{
f8628a47 2796 RT_TRACE(COMP_HALDM, "%s\n", __func__);
8fc8598e
JC
2797 write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cf);
2798 write_nic_byte(dev, 0xc3b, 0x41);
2799}
2800
2801static void dm_EndSWFsync(struct net_device *dev)
2802{
2803 struct r8192_priv *priv = ieee80211_priv(dev);
2804
f8628a47 2805 RT_TRACE(COMP_HALDM, "%s\n", __func__);
8fc8598e
JC
2806 del_timer_sync(&(priv->fsync_timer));
2807
e1da1d57 2808 /* Let Register return to default value; */
04d695d7 2809 if (priv->bswitch_fsync) {
8fc8598e
JC
2810 priv->bswitch_fsync = false;
2811
91e39f09 2812 write_nic_byte(dev, 0xC36, 0x5c);
8fc8598e
JC
2813
2814 write_nic_byte(dev, 0xC3e, 0x96);
2815 }
2816
4c234ebc 2817 priv->ContinueDiffCount = 0;
8fc8598e 2818 write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
8fc8598e
JC
2819
2820}
2821
2822static void dm_StartSWFsync(struct net_device *dev)
2823{
2824 struct r8192_priv *priv = ieee80211_priv(dev);
35997ff0
SH
2825 u32 rateIndex;
2826 u32 rateBitmap;
8fc8598e 2827
0b4ef0a6 2828 RT_TRACE(COMP_HALDM, "%s\n", __func__);
e1da1d57 2829 /* Initial rate record to zero, start to record. */
8fc8598e 2830 priv->rate_record = 0;
e1da1d57 2831 /* Initialize continue diff count to zero, start to record. */
4c234ebc 2832 priv->ContinueDiffCount = 0;
8fc8598e
JC
2833 priv->rateCountDiffRecord = 0;
2834 priv->bswitch_fsync = false;
2835
04d695d7
LS
2836 if (priv->ieee80211->mode == WIRELESS_MODE_N_24G) {
2837 priv->ieee80211->fsync_firstdiff_ratethreshold = 600;
8fc8598e 2838 priv->ieee80211->fsync_seconddiff_ratethreshold = 0xffff;
04d695d7
LS
2839 } else {
2840 priv->ieee80211->fsync_firstdiff_ratethreshold = 200;
8fc8598e
JC
2841 priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
2842 }
04d695d7
LS
2843 for (rateIndex = 0; rateIndex <= 27; rateIndex++) {
2844 rateBitmap = 1 << rateIndex;
2845 if (priv->ieee80211->fsync_rate_bitmap & rateBitmap)
8fc8598e
JC
2846 priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex];
2847 }
04d695d7 2848 if (timer_pending(&priv->fsync_timer))
8fc8598e
JC
2849 del_timer_sync(&priv->fsync_timer);
2850 priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
2851 add_timer(&priv->fsync_timer);
2852
8fc8598e 2853 write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd);
8fc8598e
JC
2854
2855}
2856
2857static void dm_EndHWFsync(struct net_device *dev)
2858{
0b4ef0a6 2859 RT_TRACE(COMP_HALDM, "%s\n", __func__);
8fc8598e
JC
2860 write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
2861 write_nic_byte(dev, 0xc3b, 0x49);
2862
2863}
2864
2865void dm_check_fsync(struct net_device *dev)
2866{
2867#define RegC38_Default 0
04d695d7
LS
2868#define RegC38_NonFsync_Other_AP 1
2869#define RegC38_Fsync_AP_BCM 2
8fc8598e 2870 struct r8192_priv *priv = ieee80211_priv(dev);
e1da1d57 2871 /*u32 framesyncC34;*/
04d695d7 2872 static u8 reg_c38_State = RegC38_Default;
de13a3da 2873 static u32 reset_cnt;
8fc8598e
JC
2874
2875 RT_TRACE(COMP_HALDM, "RSSI %d TimeInterval %d MultipleTimeInterval %d\n", priv->ieee80211->fsync_rssi_threshold, priv->ieee80211->fsync_time_interval, priv->ieee80211->fsync_multiple_timeinterval);
2876 RT_TRACE(COMP_HALDM, "RateBitmap 0x%x FirstDiffRateThreshold %d SecondDiffRateThreshold %d\n", priv->ieee80211->fsync_rate_bitmap, priv->ieee80211->fsync_firstdiff_ratethreshold, priv->ieee80211->fsync_seconddiff_ratethreshold);
2877
04d695d7
LS
2878 if (priv->ieee80211->state == IEEE80211_LINKED &&
2879 (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) {
2880 if (priv->ieee80211->bfsync_enable == 0) {
2881 switch (priv->ieee80211->fsync_state) {
2882 case Default_Fsync:
2883 dm_StartHWFsync(dev);
2884 priv->ieee80211->fsync_state = HW_Fsync;
2885 break;
2886 case SW_Fsync:
2887 dm_EndSWFsync(dev);
2888 dm_StartHWFsync(dev);
2889 priv->ieee80211->fsync_state = HW_Fsync;
2890 break;
2891 case HW_Fsync:
2892 default:
2893 break;
8fc8598e 2894 }
04d695d7
LS
2895 } else {
2896 switch (priv->ieee80211->fsync_state) {
2897 case Default_Fsync:
2898 dm_StartSWFsync(dev);
2899 priv->ieee80211->fsync_state = SW_Fsync;
2900 break;
2901 case HW_Fsync:
2902 dm_EndHWFsync(dev);
2903 dm_StartSWFsync(dev);
2904 priv->ieee80211->fsync_state = SW_Fsync;
2905 break;
2906 case SW_Fsync:
2907 default:
2908 break;
8fc8598e
JC
2909 }
2910 }
04d695d7
LS
2911 if (priv->framesyncMonitor) {
2912 if (reg_c38_State != RegC38_Fsync_AP_BCM) {
2913 /* For broadcom AP we write different default value */
91e39f09 2914 write_nic_byte(dev, rOFDM0_RxDetector3, 0x95);
8fc8598e
JC
2915
2916 reg_c38_State = RegC38_Fsync_AP_BCM;
2917 }
2918 }
04d695d7
LS
2919 } else {
2920 switch (priv->ieee80211->fsync_state) {
2921 case HW_Fsync:
2922 dm_EndHWFsync(dev);
2923 priv->ieee80211->fsync_state = Default_Fsync;
2924 break;
2925 case SW_Fsync:
2926 dm_EndSWFsync(dev);
2927 priv->ieee80211->fsync_state = Default_Fsync;
2928 break;
2929 case Default_Fsync:
2930 default:
2931 break;
8fc8598e
JC
2932 }
2933
04d695d7
LS
2934 if (priv->framesyncMonitor) {
2935 if (priv->ieee80211->state == IEEE80211_LINKED) {
2936 if (priv->undecorated_smoothed_pwdb <= RegC38_TH) {
2937 if (reg_c38_State != RegC38_NonFsync_Other_AP) {
91e39f09 2938 write_nic_byte(dev, rOFDM0_RxDetector3, 0x90);
8fc8598e
JC
2939
2940 reg_c38_State = RegC38_NonFsync_Other_AP;
8fc8598e 2941 }
04d695d7
LS
2942 } else if (priv->undecorated_smoothed_pwdb >= (RegC38_TH+5)) {
2943 if (reg_c38_State) {
8fc8598e
JC
2944 write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
2945 reg_c38_State = RegC38_Default;
04d695d7 2946 /*DbgPrint("Fsync is idle, rssi>=40, write 0xc38 = 0x%x\n", pHalData->framesync);*/
8fc8598e
JC
2947 }
2948 }
04d695d7
LS
2949 } else {
2950 if (reg_c38_State) {
8fc8598e
JC
2951 write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
2952 reg_c38_State = RegC38_Default;
04d695d7 2953 /*DbgPrint("Fsync is idle, not connected, write 0xc38 = 0x%x\n", pHalData->framesync);*/
8fc8598e
JC
2954 }
2955 }
2956 }
2957 }
04d695d7
LS
2958 if (priv->framesyncMonitor) {
2959 if (priv->reset_count != reset_cnt) { /* After silent reset, the reg_c38_State will be returned to default value */
8fc8598e
JC
2960 write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
2961 reg_c38_State = RegC38_Default;
2962 reset_cnt = priv->reset_count;
04d695d7 2963 /*DbgPrint("reg_c38_State = 0 for silent reset.\n");*/
8fc8598e 2964 }
04d695d7
LS
2965 } else {
2966 if (reg_c38_State) {
8fc8598e
JC
2967 write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
2968 reg_c38_State = RegC38_Default;
04d695d7 2969 /*DbgPrint("framesync no monitor, write 0xc38 = 0x%x\n", pHalData->framesync);*/
8fc8598e
JC
2970 }
2971 }
2972}
2973
8fc8598e
JC
2974/*-----------------------------------------------------------------------------
2975 * Function: dm_shadow_init()
2976 *
2977 * Overview: Store all NIC MAC/BB register content.
2978 *
2979 * Input: NONE
2980 *
2981 * Output: NONE
2982 *
2983 * Return: NONE
2984 *
2985 * Revised History:
2986 * When Who Remark
2987 * 05/29/2008 amy Create Version 0 porting from windows code.
2988 *
2989 *---------------------------------------------------------------------------*/
c541fa87 2990void dm_shadow_init(struct net_device *dev)
8fc8598e
JC
2991{
2992 u8 page;
2993 u16 offset;
2994
2995 for (page = 0; page < 5; page++)
04d695d7 2996 for (offset = 0; offset < 256; offset++) {
b3d42bf1 2997 read_nic_byte(dev, offset+page*256, &dm_shadow[page][offset]);
e1da1d57 2998 /*DbgPrint("P-%d/O-%02x=%02x\r\n", page, offset, DM_Shadow[page][offset]);*/
8fc8598e
JC
2999 }
3000
3001 for (page = 8; page < 11; page++)
3002 for (offset = 0; offset < 256; offset++)
b3d42bf1 3003 read_nic_byte(dev, offset+page*256, &dm_shadow[page][offset]);
8fc8598e
JC
3004
3005 for (page = 12; page < 15; page++)
3006 for (offset = 0; offset < 256; offset++)
b3d42bf1 3007 read_nic_byte(dev, offset+page*256, &dm_shadow[page][offset]);
8fc8598e
JC
3008
3009} /* dm_shadow_init */
3010
3011/*---------------------------Define function prototype------------------------*/
3012/*-----------------------------------------------------------------------------
3013 * Function: DM_DynamicTxPower()
3014 *
3015 * Overview: Detect Signal strength to control TX Registry
e406322b 3016 Tx Power Control For Near/Far Range
8fc8598e
JC
3017 *
3018 * Input: NONE
3019 *
3020 * Output: NONE
3021 *
3022 * Return: NONE
3023 *
3024 * Revised History:
3025 * When Who Remark
3026 * 03/06/2008 Jacken Create Version 0.
3027 *
3028 *---------------------------------------------------------------------------*/
3029static void dm_init_dynamic_txpower(struct net_device *dev)
3030{
3031 struct r8192_priv *priv = ieee80211_priv(dev);
3032
e1da1d57
LS
3033 /* Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code. */
3034 priv->ieee80211->bdynamic_txpower_enable = true; /* Default to enable Tx Power Control */
8fc8598e
JC
3035 priv->bLastDTPFlag_High = false;
3036 priv->bLastDTPFlag_Low = false;
3037 priv->bDynamicTxHighPower = false;
3038 priv->bDynamicTxLowPower = false;
3039}
3040
3041static void dm_dynamic_txpower(struct net_device *dev)
3042{
3043 struct r8192_priv *priv = ieee80211_priv(dev);
04d695d7
LS
3044 unsigned int txhipower_threshhold = 0;
3045 unsigned int txlowpower_threshold = 0;
3046
3047 if (priv->ieee80211->bdynamic_txpower_enable != true) {
8fc8598e
JC
3048 priv->bDynamicTxHighPower = false;
3049 priv->bDynamicTxLowPower = false;
3050 return;
3051 }
04d695d7
LS
3052 /*printk("priv->ieee80211->current_network.unknown_cap_exist is %d , priv->ieee80211->current_network.broadcom_cap_exist is %d\n", priv->ieee80211->current_network.unknown_cap_exist, priv->ieee80211->current_network.broadcom_cap_exist);*/
3053 if ((priv->ieee80211->current_network.atheros_cap_exist) && (priv->ieee80211->mode == IEEE_G)) {
8fc8598e
JC
3054 txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH;
3055 txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
04d695d7 3056 } else {
8fc8598e
JC
3057 txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
3058 txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
3059 }
3060
04d695d7
LS
3061 /*printk("=======>%s(): txhipower_threshhold is %d, txlowpower_threshold is %d\n", __func__, txhipower_threshhold, txlowpower_threshold);*/
3062 RT_TRACE(COMP_TXAGC, "priv->undecorated_smoothed_pwdb = %ld\n", priv->undecorated_smoothed_pwdb);
8fc8598e 3063
04d695d7
LS
3064 if (priv->ieee80211->state == IEEE80211_LINKED) {
3065 if (priv->undecorated_smoothed_pwdb >= txhipower_threshhold) {
8fc8598e
JC
3066 priv->bDynamicTxHighPower = true;
3067 priv->bDynamicTxLowPower = false;
04d695d7 3068 } else {
e1da1d57 3069 /* high power state check */
c40753b5 3070 if (priv->undecorated_smoothed_pwdb < txlowpower_threshold && priv->bDynamicTxHighPower)
8fc8598e 3071 priv->bDynamicTxHighPower = false;
04d695d7 3072
e1da1d57 3073 /* low power state check */
16da7808 3074 if (priv->undecorated_smoothed_pwdb < 35)
8fc8598e 3075 priv->bDynamicTxLowPower = true;
16da7808 3076 else if (priv->undecorated_smoothed_pwdb >= 40)
8fc8598e 3077 priv->bDynamicTxLowPower = false;
8fc8598e 3078 }
04d695d7 3079 } else {
e1da1d57 3080 /*pHalData->bTXPowerCtrlforNearFarRange = !pHalData->bTXPowerCtrlforNearFarRange;*/
8fc8598e
JC
3081 priv->bDynamicTxHighPower = false;
3082 priv->bDynamicTxLowPower = false;
3083 }
3084
04d695d7
LS
3085 if ((priv->bDynamicTxHighPower != priv->bLastDTPFlag_High) ||
3086 (priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low)) {
3087 RT_TRACE(COMP_TXAGC, "SetTxPowerLevel8190() channel = %d\n", priv->ieee80211->current_network.channel);
8fc8598e
JC
3088
3089#if defined(RTL8190P) || defined(RTL8192E)
04d695d7 3090 SetTxPowerLevel8190(Adapter, pHalData->CurrentChannel);
8fc8598e
JC
3091#endif
3092
04d695d7 3093 rtl8192_phy_setTxPower(dev, priv->ieee80211->current_network.channel);
e1da1d57 3094 /*pHalData->bStartTxCtrlByTPCNFR = FALSE; Clear th flag of Set TX Power from Sitesurvey*/
8fc8598e
JC
3095 }
3096 priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
3097 priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
3098
3099} /* dm_dynamic_txpower */
3100
e1da1d57 3101/* added by vivi, for read tx rate and retrycount */
999d594b 3102static void dm_check_txrateandretrycount(struct net_device *dev)
8fc8598e
JC
3103{
3104 struct r8192_priv *priv = ieee80211_priv(dev);
999d594b 3105 struct ieee80211_device *ieee = priv->ieee80211;
e1da1d57
LS
3106 /* for 11n tx rate */
3107 /*priv->stats.CurrentShowTxate = read_nic_byte(dev, Current_Tx_Rate_Reg);*/
b3d42bf1 3108 read_nic_byte(dev, Current_Tx_Rate_Reg, &ieee->softmac_stats.CurrentShowTxate);
e1da1d57
LS
3109 /*printk("=============>tx_rate_reg:%x\n", ieee->softmac_stats.CurrentShowTxate);*/
3110 /* for initial tx rate */
3111 /*priv->stats.last_packet_rate = read_nic_byte(dev, Initial_Tx_Rate_Reg);*/
b3d42bf1 3112 read_nic_byte(dev, Initial_Tx_Rate_Reg, &ieee->softmac_stats.last_packet_rate);
e1da1d57
LS
3113 /* for tx tx retry count */
3114 /*priv->stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg);*/
b3d42bf1 3115 read_nic_dword(dev, Tx_Retry_Count_Reg, &ieee->softmac_stats.txretrycount);
8fc8598e
JC
3116}
3117
3118static void dm_send_rssi_tofw(struct net_device *dev)
3119{
8fc8598e
JC
3120 struct r8192_priv *priv = ieee80211_priv(dev);
3121
e1da1d57
LS
3122 /*
3123 * If we test chariot, we should stop the TX command ?
3124 * Because 92E will always silent reset when we send tx command. We use register
3125 * 0x1e0(byte) to notify driver.
3126 */
8fc8598e 3127 write_nic_byte(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb);
8fc8598e
JC
3128}
3129
3130/*---------------------------Define function prototype------------------------*/
This page took 1.001335 seconds and 5 git commands to generate.