1 /* 2 * Copyright (c) 2013 Qualcomm Atheros, Inc. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 * PERFORMANCE OF THIS SOFTWARE. 15 */ 16 #include "opt_ah.h" 17 18 #ifdef AH_SUPPORT_AR9300 19 20 #include "ah.h" 21 #include "ah_desc.h" 22 #include "ah_internal.h" 23 24 #include "ar9300/ar9300phy.h" 25 #include "ar9300/ar9300.h" 26 #include "ar9300/ar9300reg.h" 27 #include "ar9300/ar9300desc.h" 28 29 #if ATH_SUPPORT_SPECTRAL 30 31 /* 32 * Default 9300 spectral scan parameters 33 */ 34 #define AR9300_SPECTRAL_SCAN_ENA 0 35 #define AR9300_SPECTRAL_SCAN_ACTIVE 0 36 #define AR9300_SPECTRAL_SCAN_FFT_PERIOD 8 37 #define AR9300_SPECTRAL_SCAN_PERIOD 1 38 #define AR9300_SPECTRAL_SCAN_COUNT 16 /* used to be 128 */ 39 #define AR9300_SPECTRAL_SCAN_SHORT_REPEAT 1 40 41 /* constants */ 42 #define MAX_RADAR_DC_PWR_THRESH 127 43 #define MAX_RADAR_RSSI_THRESH 0x3f 44 #define MAX_RADAR_HEIGHT 0x3f 45 #define MAX_CCA_THRESH 127 46 #define ENABLE_ALL_PHYERR 0xffffffff 47 48 void ar9300_disable_cck(struct ath_hal *ah); 49 void ar9300_disable_radar(struct ath_hal *ah); 50 void ar9300_disable_restart(struct ath_hal *ah); 51 void ar9300_set_radar_dc_thresh(struct ath_hal *ah); 52 void ar9300_disable_weak_signal(struct ath_hal *ah); 53 void ar9300_disable_strong_signal(struct ath_hal *ah); 54 void ar9300_prep_spectral_scan(struct ath_hal *ah); 55 void ar9300_disable_dc_offset(struct ath_hal *ah); 56 void ar9300_enable_cck_detect(struct ath_hal *ah); 57 58 void 59 ar9300_disable_cck(struct ath_hal *ah) 60 { 61 u_int32_t val; 62 63 val = OS_REG_READ(ah, AR_PHY_MODE); 64 val &= ~(AR_PHY_MODE_DYN_CCK_DISABLE); 65 66 OS_REG_WRITE(ah, AR_PHY_MODE, val); 67 } 68 69 void 70 ar9300_disable_radar(struct ath_hal *ah) 71 { 72 u_int32_t val; 73 74 /* Enable radar FFT */ 75 val = OS_REG_READ(ah, AR_PHY_RADAR_0); 76 val |= AR_PHY_RADAR_0_FFT_ENA; 77 78 /* set radar detect thresholds to max to effectively disable radar */ 79 val &= ~AR_PHY_RADAR_0_RRSSI; 80 val |= SM(MAX_RADAR_RSSI_THRESH, AR_PHY_RADAR_0_RRSSI); 81 82 val &= ~AR_PHY_RADAR_0_HEIGHT; 83 val |= SM(MAX_RADAR_HEIGHT, AR_PHY_RADAR_0_HEIGHT); 84 85 val &= ~(AR_PHY_RADAR_0_ENA); 86 OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); 87 88 /* disable extension radar detect */ 89 val = OS_REG_READ(ah, AR_PHY_RADAR_EXT); 90 OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val & ~AR_PHY_RADAR_EXT_ENA); 91 92 val = OS_REG_READ(ah, AR_RX_FILTER); 93 val |= (1 << 13); 94 OS_REG_WRITE(ah, AR_RX_FILTER, val); 95 } 96 97 void ar9300_disable_restart(struct ath_hal *ah) 98 { 99 u_int32_t val; 100 val = OS_REG_READ(ah, AR_PHY_RESTART); 101 val &= ~AR_PHY_RESTART_ENA; 102 OS_REG_WRITE(ah, AR_PHY_RESTART, val); 103 104 val = OS_REG_READ(ah, AR_PHY_RESTART); 105 } 106 107 void ar9300_set_radar_dc_thresh(struct ath_hal *ah) 108 { 109 u_int32_t val; 110 val = OS_REG_READ(ah, AR_PHY_RADAR_EXT); 111 val &= ~AR_PHY_RADAR_DC_PWR_THRESH; 112 val |= SM(MAX_RADAR_DC_PWR_THRESH, AR_PHY_RADAR_DC_PWR_THRESH); 113 OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val); 114 115 val = OS_REG_READ(ah, AR_PHY_RADAR_EXT); 116 } 117 118 void 119 ar9300_disable_weak_signal(struct ath_hal *ah) 120 { 121 /* set firpwr to max (signed) */ 122 OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRPWR, 0x7f); 123 OS_REG_CLR_BIT(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRPWR_SIGN_BIT); 124 125 /* set firstep to max */ 126 OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRSTEP, 0x3f); 127 128 /* set relpwr to max (signed) */ 129 OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_RELPWR, 0x1f); 130 OS_REG_CLR_BIT(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_RELPWR_SIGN_BIT); 131 132 /* set relstep to max (signed) */ 133 OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_RELSTEP, 0x1f); 134 OS_REG_CLR_BIT(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_RELSTEP_SIGN_BIT); 135 136 /* set firpwr_low to max (signed) */ 137 OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_FIRPWR, 0x7f); 138 OS_REG_CLR_BIT( 139 ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_FIRPWR_SIGN_BIT); 140 141 /* set firstep_low to max */ 142 OS_REG_RMW_FIELD( 143 ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW, 0x3f); 144 145 /* set relstep_low to max (signed) */ 146 OS_REG_RMW_FIELD( 147 ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_RELSTEP, 0x1f); 148 OS_REG_CLR_BIT( 149 ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_RELSTEP_SIGN_BIT); 150 } 151 152 void 153 ar9300_disable_strong_signal(struct ath_hal *ah) 154 { 155 u_int32_t val; 156 157 val = OS_REG_READ(ah, AR_PHY_TIMING5); 158 val |= AR_PHY_TIMING5_RSSI_THR1A_ENA; 159 OS_REG_WRITE(ah, AR_PHY_TIMING5, val); 160 161 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING5, AR_PHY_TIMING5_RSSI_THR1A, 0x7f); 162 163 } 164 void 165 ar9300_set_cca_threshold(struct ath_hal *ah, u_int8_t thresh62) 166 { 167 OS_REG_RMW_FIELD(ah, AR_PHY_CCA_0, AR_PHY_CCA_THRESH62, thresh62); 168 OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62, thresh62); 169 /* 170 OS_REG_RMW_FIELD(ah, 171 AR_PHY_EXTCHN_PWRTHR1, AR_PHY_EXT_CCA0_THRESH62, thresh62); 172 */ 173 OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, AR_PHY_EXT_CCA_THRESH62, thresh62); 174 } 175 176 static void ar9300_classify_strong_bins(struct ath_hal *ah) 177 { 178 OS_REG_RMW_FIELD(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_CF_BIN_THRESH, 0x1); 179 } 180 181 void ar9300_disable_dc_offset(struct ath_hal *ah) 182 { 183 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING2, AR_PHY_TIMING2_DC_OFFSET, 0); 184 } 185 186 void ar9300_enable_cck_detect(struct ath_hal *ah) 187 { 188 OS_REG_RMW_FIELD(ah, AR_PHY_MODE, AR_PHY_MODE_DISABLE_CCK, 0); 189 OS_REG_RMW_FIELD(ah, AR_PHY_MODE, AR_PHY_MODE_DYNAMIC, 1); 190 } 191 192 void ar9300_prep_spectral_scan(struct ath_hal *ah) 193 { 194 ar9300_disable_radar(ah); 195 ar9300_classify_strong_bins(ah); 196 ar9300_disable_dc_offset(ah); 197 if (AH_PRIVATE(ah)->ah_curchan && 198 IS_5GHZ_FAST_CLOCK_EN(ah, AH_PRIVATE(ah)->ah_curchan)) 199 { /* fast clock */ 200 ar9300_enable_cck_detect(ah); 201 } 202 #ifdef DEMO_MODE 203 ar9300_disable_strong_signal(ah); 204 ar9300_disable_weak_signal(ah); 205 ar9300_set_radar_dc_thresh(ah); 206 ar9300_set_cca_threshold(ah, MAX_CCA_THRESH); 207 /*ar9300_disable_restart(ah);*/ 208 #endif 209 OS_REG_WRITE(ah, AR_PHY_ERR, HAL_PHYERR_SPECTRAL); 210 } 211 212 213 //#define TEST_NOISE_PWR_WITHOUT_EEPROM 1 214 #ifdef TEST_NOISE_PWR_WITHOUT_EEPROM 215 struct nf_cal { 216 int cal; 217 int pwr; 218 }; 219 struct nf_cal_table_t { 220 int freq; 221 struct nf_cal chain[AH_MAX_CHAINS]; 222 }; 223 224 static const struct nf_cal_table_t nf_cal_table[] = 225 { 226 /* ch 1 */ {2412, { {N2DBM(-101, 00), N2DBM( -94, 25)}, 227 {N2DBM(-107, 75), N2DBM( -99, 75)}, 228 } }, 229 /* ch 6 */ {2437, { {N2DBM(-102, 25), N2DBM( -94, 25)}, 230 {N2DBM(-106, 00), N2DBM( -97, 25)}, 231 } }, 232 /* ch 11 */ {2462, { {N2DBM(-101, 50), N2DBM( -95, 00)}, 233 {N2DBM(-105, 50), N2DBM( -98, 00)}, 234 } }, 235 /* ch 36 */ {5180, { {N2DBM(-114, 25), N2DBM( -95, 00)}, 236 {N2DBM(-114, 75), N2DBM( -94, 00)}, 237 } }, 238 /* ch 44 */ {5220, { {N2DBM(-113, 00), N2DBM( -95, 00)}, 239 {N2DBM(-115, 00), N2DBM( -94, 50)}, 240 } }, 241 /* ch 64 */ {5320, { {N2DBM(-113, 00), N2DBM( -95, 00)}, // not cal'ed 242 {N2DBM(-115, 00), N2DBM( -94, 50)}, 243 } }, 244 /* ch 100*/ {5500, { {N2DBM(-111, 50), N2DBM( -93, 75)}, 245 {N2DBM(-112, 00), N2DBM( -95, 25)}, 246 } }, 247 /* ch 120*/ {5600, { {N2DBM(-111, 50), N2DBM( -93, 75)}, 248 {N2DBM(-112, 00), N2DBM( -95, 25)}, 249 } }, 250 /* ch 140*/ {5700, { {N2DBM(-111, 75), N2DBM( -95, 00)}, 251 {N2DBM(-111, 75), N2DBM( -96, 00)}, 252 } }, 253 /* ch 157*/ {5785, { {N2DBM(-112, 50), N2DBM( -94, 75)}, 254 {N2DBM(-111, 75), N2DBM( -95, 50)}, 255 } }, 256 /* ch 165*/ {5825, { {N2DBM(-111, 50), N2DBM( -95, 00)}, 257 {N2DBM(-112, 00), N2DBM( -95, 00)}, 258 } }, 259 {0} 260 }; 261 262 static int 263 ar9300_noise_floor_get(struct ath_hal *ah, int freq_mhz, int ch) 264 { 265 int i; 266 for (i = 0; nf_cal_table[i].freq != 0; i++) { 267 if (nf_cal_table[i + 0].freq == freq_mhz || 268 nf_cal_table[i + 1].freq > freq_mhz || 269 nf_cal_table[i + 1].freq == 0) { 270 return nf_cal_table[i].chain[ch].cal; 271 } 272 } 273 274 ath_hal_printf(ah, 275 "%s: **Warning: device %d.%d: " 276 "no nf cal offset found for freq %d chain %d\n", 277 __func__, (AH_PRIVATE(ah))->ah_macVersion, 278 (AH_PRIVATE(ah))->ah_macRev, freq_mhz, ch); 279 return 0; 280 } 281 282 static int 283 ar9300_noise_floor_power_get(struct ath_hal *ah, int freq_mhz, int ch) 284 { 285 int i; 286 for (i = 0; nf_cal_table[i].freq != 0; i++) { 287 if (nf_cal_table[i + 0].freq == freq_mhz || 288 nf_cal_table[i + 1].freq > freq_mhz || 289 nf_cal_table[i + 1].freq == 0) { 290 return nf_cal_table[i].chain[ch].pwr; 291 } 292 } 293 294 ath_hal_printf(ah, 295 "%s: **Warning: device %d.%d: " 296 "no nf pwr offset found for freq %d chain %d\n", 297 __func__, (AH_PRIVATE(ah))->ah_macVersion, 298 (AH_PRIVATE(ah))->ah_macRev, freq_mhz, ch); 299 return 0; 300 } 301 #else 302 #define ar9300_noise_floor_get(_ah,_f,_ich) ar9300_noise_floor_cal_or_power_get((_ah), (_f), (_ich), 1/*use_cal*/) 303 #define ar9300_noise_floor_power_get(_ah,_f,_ich) ar9300_noise_floor_cal_or_power_get((_ah), (_f), (_ich), 0/*use_cal*/) 304 #endif 305 306 307 void 308 ar9300_configure_spectral_scan(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss) 309 { 310 u_int32_t val, i; 311 struct ath_hal_9300 *ahp = AH9300(ah); 312 HAL_BOOL asleep = ahp->ah_chip_full_sleep; 313 int16_t nf_buf[NUM_NF_READINGS]; 314 315 if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { 316 ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE); 317 } 318 319 ar9300_prep_spectral_scan(ah); 320 321 if (ss->ss_spectral_pri) { 322 for (i = 0; i < NUM_NF_READINGS; i++) { 323 nf_buf[i] = NOISE_PWR_DBM_2_INT(ss->ss_nf_cal[i]); 324 } 325 ar9300_load_nf(ah, nf_buf); 326 #ifdef DEMO_MODE 327 ar9300_disable_strong_signal(ah); 328 ar9300_disable_weak_signal(ah); 329 ar9300_set_radar_dc_thresh(ah); 330 ar9300_set_cca_threshold(ah, MAX_CCA_THRESH); 331 /*ar9300_disable_restart(ah);*/ 332 #endif 333 } 334 335 val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 336 337 if (ss->ss_fft_period != HAL_SPECTRAL_PARAM_NOVAL) { 338 val &= ~AR_PHY_SPECTRAL_SCAN_FFT_PERIOD; 339 val |= SM(ss->ss_fft_period, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD); 340 } 341 342 if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) { 343 val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD; 344 val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD); 345 } 346 347 if (ss->ss_count != HAL_SPECTRAL_PARAM_NOVAL) { 348 val &= ~AR_PHY_SPECTRAL_SCAN_COUNT; 349 /* Remnants of a Merlin bug, 128 translates to 0 for 350 * continuous scanning. Instead we do piecemeal captures 351 * of 64 samples for Osprey. 352 */ 353 if (ss->ss_count == 128) { 354 val |= SM(0, AR_PHY_SPECTRAL_SCAN_COUNT); 355 } else { 356 val |= SM(ss->ss_count, AR_PHY_SPECTRAL_SCAN_COUNT); 357 } 358 } 359 360 if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) { 361 val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD; 362 val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD); 363 } 364 365 if (ss->ss_short_report == AH_TRUE) { 366 val |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT; 367 } else { 368 val &= ~AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT; 369 } 370 371 /* if noise power cal, force high priority */ 372 if (ss->ss_spectral_pri) { 373 val |= AR_PHY_SPECTRAL_SCAN_PRIORITY_HI; 374 } else { 375 val &= ~AR_PHY_SPECTRAL_SCAN_PRIORITY_HI; 376 } 377 378 /* enable spectral scan */ 379 OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val | AR_PHY_SPECTRAL_SCAN_ENABLE); 380 381 if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { 382 ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, AH_TRUE); 383 } 384 } 385 386 /* 387 * Get the spectral parameter values and return them in the pe 388 * structure 389 */ 390 391 void 392 ar9300_get_spectral_params(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss) 393 { 394 u_int32_t val; 395 HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan; 396 int i, ichain, rx_chain_status; 397 struct ath_hal_9300 *ahp = AH9300(ah); 398 HAL_BOOL asleep = ahp->ah_chip_full_sleep; 399 400 if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { 401 ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE); 402 } 403 404 val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 405 406 ss->ss_fft_period = MS(val, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD); 407 ss->ss_period = MS(val, AR_PHY_SPECTRAL_SCAN_PERIOD); 408 ss->ss_count = MS(val, AR_PHY_SPECTRAL_SCAN_COUNT); 409 ss->ss_short_report = (val & AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT) ? 1:0; 410 ss->ss_spectral_pri = ( val & AR_PHY_SPECTRAL_SCAN_PRIORITY_HI) ? 1:0; 411 OS_MEMZERO(ss->ss_nf_cal, sizeof(ss->ss_nf_cal)); 412 OS_MEMZERO(ss->ss_nf_pwr, sizeof(ss->ss_nf_cal)); 413 ss->ss_nf_temp_data = 0; 414 415 if (chan != NULL) { 416 rx_chain_status = OS_REG_READ(ah, AR_PHY_RX_CHAINMASK) & 0x7; 417 for (i = 0; i < NUM_NF_READINGS; i++) { 418 ichain = i % 3; 419 if (rx_chain_status & (1 << ichain)) { 420 ss->ss_nf_cal[i] = 421 ar9300_noise_floor_get(ah, chan->channel, ichain); 422 ss->ss_nf_pwr[i] = 423 ar9300_noise_floor_power_get(ah, chan->channel, ichain); 424 } 425 } 426 ss->ss_nf_temp_data = OS_REG_READ_FIELD(ah, AR_PHY_BB_THERM_ADC_4, AR_PHY_BB_THERM_ADC_4_LATEST_THERM); 427 } else { 428 HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, 429 "%s: chan is NULL - no ss nf values\n", __func__); 430 } 431 432 if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { 433 ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, AH_TRUE); 434 } 435 } 436 437 HAL_BOOL 438 ar9300_is_spectral_active(struct ath_hal *ah) 439 { 440 u_int32_t val; 441 442 val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 443 return MS(val, AR_PHY_SPECTRAL_SCAN_ACTIVE); 444 } 445 446 HAL_BOOL 447 ar9300_is_spectral_enabled(struct ath_hal *ah) 448 { 449 u_int32_t val; 450 451 val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 452 return MS(val, AR_PHY_SPECTRAL_SCAN_ENABLE); 453 } 454 455 void ar9300_start_spectral_scan(struct ath_hal *ah) 456 { 457 u_int32_t val; 458 struct ath_hal_9300 *ahp = AH9300(ah); 459 HAL_BOOL asleep = ahp->ah_chip_full_sleep; 460 461 if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { 462 ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE); 463 } 464 465 ar9300_prep_spectral_scan(ah); 466 467 /* activate spectral scan */ 468 val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 469 /* This is a hardware bug fix, the enable and active bits should 470 * not be set/reset in the same write operation to the register 471 */ 472 if (!(val & AR_PHY_SPECTRAL_SCAN_ENABLE)) { 473 val |= AR_PHY_SPECTRAL_SCAN_ENABLE; 474 OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val); 475 val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 476 } 477 val |= AR_PHY_SPECTRAL_SCAN_ACTIVE; 478 OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val); 479 480 /* Reset the PHY_ERR_MASK */ 481 val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG); 482 OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val | AR_PHY_ERR_RADAR); 483 484 if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { 485 ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, AH_TRUE); 486 } 487 } 488 489 void ar9300_stop_spectral_scan(struct ath_hal *ah) 490 { 491 u_int32_t val; 492 struct ath_hal_9300 *ahp = AH9300(ah); 493 HAL_BOOL asleep = ahp->ah_chip_full_sleep; 494 495 if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { 496 ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE); 497 } 498 val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 499 500 /* deactivate spectral scan */ 501 /* HW Bug fix -- Do not disable the spectral scan 502 * only turn off the active bit 503 */ 504 //val &= ~AR_PHY_SPECTRAL_SCAN_ENABLE; 505 val &= ~AR_PHY_SPECTRAL_SCAN_ACTIVE; 506 OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val); 507 val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 508 509 OS_REG_RMW_FIELD(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_CF_BIN_THRESH, 510 ahp->ah_radar1); 511 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING2, AR_PHY_TIMING2_DC_OFFSET, 512 ahp->ah_dc_offset); 513 OS_REG_WRITE(ah, AR_PHY_ERR, 0); 514 515 if (AH_PRIVATE(ah)->ah_curchan && 516 IS_5GHZ_FAST_CLOCK_EN(ah, AH_PRIVATE(ah)->ah_curchan)) 517 { /* fast clock */ 518 OS_REG_RMW_FIELD(ah, AR_PHY_MODE, AR_PHY_MODE_DISABLE_CCK, 519 ahp->ah_disable_cck); 520 } 521 522 val = OS_REG_READ(ah, AR_PHY_ERR); 523 524 val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG) & (~AR_PHY_ERR_RADAR); 525 OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val); 526 527 if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { 528 ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, AH_TRUE); 529 } 530 } 531 532 u_int32_t ar9300_get_spectral_config(struct ath_hal *ah) 533 { 534 u_int32_t val; 535 struct ath_hal_9300 *ahp = AH9300(ah); 536 HAL_BOOL asleep = ahp->ah_chip_full_sleep; 537 538 if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { 539 ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE); 540 } 541 542 val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); 543 544 if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { 545 ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, AH_TRUE); 546 } 547 return val; 548 } 549 550 int16_t ar9300_get_ctl_chan_nf(struct ath_hal *ah) 551 { 552 int16_t nf; 553 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 554 555 if ( (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0) { 556 /* Noise floor calibration value is ready */ 557 nf = MS(OS_REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR); 558 } else { 559 /* NF calibration is not done, return nominal value */ 560 nf = ahpriv->nfp->nominal; 561 } 562 if (nf & 0x100) { 563 nf = (0 - ((nf ^ 0x1ff) + 1)); 564 } 565 return nf; 566 } 567 568 int16_t ar9300_get_ext_chan_nf(struct ath_hal *ah) 569 { 570 int16_t nf; 571 struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 572 573 if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0) { 574 /* Noise floor calibration value is ready */ 575 nf = MS(OS_REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); 576 } else { 577 /* NF calibration is not done, return nominal value */ 578 nf = ahpriv->nfp->nominal; 579 } 580 if (nf & 0x100) { 581 nf = (0 - ((nf ^ 0x1ff) + 1)); 582 } 583 return nf; 584 } 585 586 #endif 587 #endif /* ATH_SUPPORT_SPECTRAL */ 588 589