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