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