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