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