/* function to adjust PRSSI value for CAC problem */ void ar9300_dfs_cac_war(struct ath_hal *ah, u_int32_t start) { u_int32_t val; struct ath_hal_9300 *ahp = AH9300(ah); bool asleep = ahp->ah_chip_full_sleep; if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_AWAKE, true); } if (AR_SREV_AR9580(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) { val = OS_REG_READ(ah, AR_PHY_RADAR_0); if (start) { val &= ~AR_PHY_RADAR_0_PRSSI; val |= SM(AR9300_DFS_PRSSI_CAC, AR_PHY_RADAR_0_PRSSI); } else { val &= ~AR_PHY_RADAR_0_PRSSI; val |= SM(AR9300_DFS_PRSSI, AR_PHY_RADAR_0_PRSSI); } OS_REG_WRITE(ah, AR_PHY_RADAR_0, val | AR_PHY_RADAR_0_ENA); ah->ah_use_cac_prssi = start; } if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, true); } }
u_int32_t ar9300_dfs_config_fft(struct ath_hal *ah, bool is_enable) { u_int32_t val; struct ath_hal_9300 *ahp = AH9300(ah); bool asleep = ahp->ah_chip_full_sleep; if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_AWAKE, true); } val = OS_REG_READ(ah, AR_PHY_RADAR_0); if (is_enable) { val |= AR_PHY_RADAR_0_FFT_ENA; } else { val &= ~AR_PHY_RADAR_0_FFT_ENA; } OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); val = OS_REG_READ(ah, AR_PHY_RADAR_0); if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, true); } return val; }
void ar9300_start_spectral_scan(struct ath_hal *ah) { u_int32_t val; struct ath_hal_9300 *ahp = AH9300(ah); bool asleep = ahp->ah_chip_full_sleep; if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_AWAKE, true); } ar9300_prep_spectral_scan(ah); /* activate spectral scan */ val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); /* This is a hardware bug fix, the enable and active bits should * not be set/reset in the same write operation to the register */ if (!(val & AR_PHY_SPECTRAL_SCAN_ENABLE)) { val |= AR_PHY_SPECTRAL_SCAN_ENABLE; OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val); val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); } val |= AR_PHY_SPECTRAL_SCAN_ACTIVE; OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val); /* Reset the PHY_ERR_MASK */ val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG); OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val | AR_PHY_ERR_RADAR); if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, true); } }
bool ar9300_handle_radar_bb_panic(struct ath_hal *ah) { u_int32_t status; u_int32_t val; struct ath_hal_9300 *ahp = AH9300(ah); bool asleep = ahp->ah_chip_full_sleep; status = AH_PRIVATE(ah)->ah_bb_panic_last_status; if ( status == 0x04000539 ) { if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_AWAKE, true); } /* recover from this BB panic without reset*/ /* set AR9300_DFS_FIRPWR to -1 */ val = OS_REG_READ(ah, AR_PHY_RADAR_0); val &= (~AR_PHY_RADAR_0_FIRPWR); val |= SM( 0x7f, AR_PHY_RADAR_0_FIRPWR); OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); OS_DELAY(1); /* set AR9300_DFS_FIRPWR to its default value */ val = OS_REG_READ(ah, AR_PHY_RADAR_0); val &= ~AR_PHY_RADAR_0_FIRPWR; val |= SM( AR9300_DFS_FIRPWR, AR_PHY_RADAR_0_FIRPWR); OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, true); } return true; } else if (status == 0x0400000a) { /* EV 92527 : reset required if we see this signature */ HDPRINTF(ah, HAL_DBG_DFS, "%s: BB Panic -- 0x0400000a\n", __func__); return false; } else if (status == 0x1300000a) { /* EV92527: we do not need a reset if we see this signature */ HDPRINTF(ah, HAL_DBG_DFS, "%s: BB Panic -- 0x1300000a\n", __func__); return true; } else if ((AR_SREV_WASP(ah) || AR_SREV_HONEYBEE(ah)) && (status == 0x04000409)) { return true; } else { if (ar9300_get_capability(ah, HAL_CAP_LDPCWAR, 0, AH_NULL) == HAL_OK && (status & 0xff00000f) == 0x04000009 && status != 0x04000409 && status != 0x04000b09 && status != 0x04000e09 && (status & 0x0000ff00)) { /* disable RIFS Rx */ #ifdef AH_DEBUG HDPRINTF(ah, HAL_DBG_UNMASKABLE, "%s: BB status=0x%08x rifs=%d - disable\n", __func__, status, ahp->ah_rifs_enabled); #endif ar9300_set_rifs_delay(ah, false); } return false; } }
void ar9300ConfigureSpectralScan(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss) { u_int32_t val; struct ath_hal_9300 *ahp = AH9300(ah); HAL_POWER_MODE pwrmode = ahp->ah_powerMode; if (AR_SREV_WASP(ah) && (pwrmode == HAL_PM_FULL_SLEEP)) { ar9300SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE); } ar9300PrepSpectralScan(ah); val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); if (ss->ss_fft_period != HAL_SPECTRAL_PARAM_NOVAL) { val &= ~AR_PHY_SPECTRAL_SCAN_FFT_PERIOD; val |= SM(ss->ss_fft_period, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD); } if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) { val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD; val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD); } if (ss->ss_count != HAL_SPECTRAL_PARAM_NOVAL) { val &= ~AR_PHY_SPECTRAL_SCAN_COUNT; /* Remnants of a Merlin bug, 128 translates to 0 for * continuous scanning. Instead we do piecemeal captures * of 64 samples for Osprey. */ if (ss->ss_count == 128) val |= SM(0, AR_PHY_SPECTRAL_SCAN_COUNT); else val |= SM(ss->ss_count, AR_PHY_SPECTRAL_SCAN_COUNT); } if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) { val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD; val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD); } if (ss->ss_short_report == AH_TRUE) { val |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT; } else { val &= ~AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT; } // Enable spectral scan OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val | AR_PHY_SPECTRAL_SCAN_ENABLE); ar9300GetSpectralParams(ah, ss); if (AR_SREV_WASP(ah) && (pwrmode == HAL_PM_FULL_SLEEP)) { ar9300SetPowerMode(ah, HAL_PM_FULL_SLEEP, AH_TRUE); } }
void ar9300_get_spectral_params(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss) { u_int32_t val; HAL_CHANNEL_INTERNAL *chan = NULL; const struct ieee80211_channel *c; int i, ichain, rx_chain_status; struct ath_hal_9300 *ahp = AH9300(ah); HAL_BOOL asleep = ahp->ah_chip_full_sleep; c = AH_PRIVATE(ah)->ah_curchan; if (c != NULL) chan = ath_hal_checkchannel(ah, c); // XXX TODO: just always wake up all chips? if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE); } val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); ss->ss_fft_period = MS(val, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD); ss->ss_period = MS(val, AR_PHY_SPECTRAL_SCAN_PERIOD); ss->ss_count = MS(val, AR_PHY_SPECTRAL_SCAN_COUNT); ss->ss_short_report = (val & AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT) ? 1:0; ss->ss_spectral_pri = ( val & AR_PHY_SPECTRAL_SCAN_PRIORITY_HI) ? 1:0; OS_MEMZERO(ss->ss_nf_cal, sizeof(ss->ss_nf_cal)); OS_MEMZERO(ss->ss_nf_pwr, sizeof(ss->ss_nf_cal)); ss->ss_nf_temp_data = 0; if (chan != NULL) { rx_chain_status = OS_REG_READ(ah, AR_PHY_RX_CHAINMASK) & 0x7; for (i = 0; i < HAL_NUM_NF_READINGS; i++) { ichain = i % 3; if (rx_chain_status & (1 << ichain)) { ss->ss_nf_cal[i] = ar9300_noise_floor_get(ah, chan->channel, ichain); ss->ss_nf_pwr[i] = ar9300_noise_floor_power_get(ah, chan->channel, ichain); } } ss->ss_nf_temp_data = OS_REG_READ_FIELD(ah, AR_PHY_BB_THERM_ADC_4, AR_PHY_BB_THERM_ADC_4_LATEST_THERM); } else { HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, "%s: chan is NULL - no ss nf values\n", __func__); } if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, AH_TRUE); } }
/* * Checks to see if an interrupt is pending on our NIC * * Returns: TRUE if an interrupt is pending * FALSE if not */ HAL_BOOL ar9300_is_interrupt_pending(struct ath_hal *ah) { u_int32_t sync_en_def = AR9300_INTR_SYNC_DEFAULT; u_int32_t host_isr; /* * Some platforms trigger our ISR before applying power to * the card, so make sure. */ host_isr = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_CAUSE)); if ((host_isr & AR_INTR_ASYNC_USED) && (host_isr != AR_INTR_SPURIOUS)) { return AH_TRUE; } host_isr = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE)); if (AR_SREV_POSEIDON(ah)) { sync_en_def = AR9300_INTR_SYNC_DEF_NO_HOST1_PERR; } else if (AR_SREV_WASP(ah)) { sync_en_def = AR9340_INTR_SYNC_DEFAULT; } if ((host_isr & (sync_en_def | AR_INTR_SYNC_MASK_GPIO)) && (host_isr != AR_INTR_SPURIOUS)) { return AH_TRUE; } return AH_FALSE; }
u_int32_t ar9300_get_spectral_config(struct ath_hal *ah) { u_int32_t val; struct ath_hal_9300 *ahp = AH9300(ah); bool asleep = ahp->ah_chip_full_sleep; if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_AWAKE, true); } val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, true); } return val; }
u_int32_t ar9300GetSpectralConfig(struct ath_hal *ah) { u_int32_t val; struct ath_hal_9300 *ahp = AH9300(ah); HAL_POWER_MODE pwrmode = ahp->ah_powerMode; if (AR_SREV_WASP(ah) && (pwrmode == HAL_PM_FULL_SLEEP)) { ar9300SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE); } val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); if (AR_SREV_WASP(ah) && (pwrmode == HAL_PM_FULL_SLEEP)) { ar9300SetPowerMode(ah, HAL_PM_FULL_SLEEP, AH_TRUE); } return val; }
void ar9300_stop_spectral_scan(struct ath_hal *ah) { u_int32_t val; struct ath_hal_9300 *ahp = AH9300(ah); bool asleep = ahp->ah_chip_full_sleep; if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_AWAKE, true); } val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); /* deactivate spectral scan */ /* HW Bug fix -- Do not disable the spectral scan * only turn off the active bit */ //val &= ~AR_PHY_SPECTRAL_SCAN_ENABLE; val &= ~AR_PHY_SPECTRAL_SCAN_ACTIVE; OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val); val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); OS_REG_RMW_FIELD(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_CF_BIN_THRESH, ahp->ah_radar1); OS_REG_RMW_FIELD(ah, AR_PHY_TIMING2, AR_PHY_TIMING2_DC_OFFSET, ahp->ah_dc_offset); OS_REG_WRITE(ah, AR_PHY_ERR, 0); if (AH_PRIVATE(ah)->ah_curchan && IS_5GHZ_FAST_CLOCK_EN(ah, AH_PRIVATE(ah)->ah_curchan)) { /* fast clock */ OS_REG_RMW_FIELD(ah, AR_PHY_MODE, AR_PHY_MODE_DISABLE_CCK, ahp->ah_disable_cck); } val = OS_REG_READ(ah, AR_PHY_ERR); val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG) & (~AR_PHY_ERR_RADAR); OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val); if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, true); } }
HAL_BOOL ar9300_handle_radar_bb_panic(struct ath_hal *ah) { u_int32_t status; u_int32_t val; /*AUTELAN-Added-Begin:Deleted by duanmingzhe for RIFS+LDPC issue*/ #ifdef AH_DEBUG //edit by duanmingzhe struct ath_hal_9300 *ahp = AH9300(ah); #endif /*AUTELAN-Added-End:Deleted by duanmingzhe for RIFS+LDPC issue*/ status = AH_PRIVATE(ah)->ah_bbPanicLastStatus; if ( status == 0x04000539 ) { /* recover from this BB panic without reset*/ /* set AR9300_DFS_FIRPWR to -1 */ val = OS_REG_READ(ah, AR_PHY_RADAR_0); val &= (~AR_PHY_RADAR_0_FIRPWR); val |= SM( 0x7f, AR_PHY_RADAR_0_FIRPWR); OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); OS_DELAY(1); /* set AR9300_DFS_FIRPWR to its default value */ val = OS_REG_READ(ah, AR_PHY_RADAR_0); val &= ~AR_PHY_RADAR_0_FIRPWR; val |= SM( AR9300_DFS_FIRPWR, AR_PHY_RADAR_0_FIRPWR); OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); return AH_TRUE; } else if (status == 0x0400000a) { /* EV 92527 : reset required if we see this signature */ HDPRINTF(ah, HAL_DBG_DFS, "%s: BB Panic -- 0x0400000a\n", __func__); return AH_FALSE; } else if (status == 0x1300000a) { /* EV92527: we do not need a reset if we see this signature */ HDPRINTF(ah, HAL_DBG_DFS, "%s: BB Panic -- 0x1300000a\n", __func__); return AH_TRUE; } else if (AR_SREV_WASP(ah) && (status == 0x04000409)) { return AH_TRUE; } else { /*AUTELAN-Added-Begin:Deleted by duanmingzhe for RIFS+LDPC issue*/ if (ar9300GetCapability(ah, HAL_CAP_LDPCWAR, 0, AH_NULL) == HAL_OK && (status & 0xff00000f) == 0x04000009 && status != 0x04000409 && status != 0x04000b09 && status != 0x04000e09 && (status & 0x0000ff00)) { /* disable RIFS Rx */ HDPRINTF(ah, HAL_DBG_UNMASKABLE, "%s: BB status=0x%08x rifs=%d - disable\n", __func__, status, ahp->ah_rifs_enabled); ar9300SetRifsDelay(ah, false); } /*AUTELAN-Added-End:Deleted by duanmingzhe for RIFS+LDPC issue*/ return AH_FALSE; } }
HAL_BOOL ar9300_handle_radar_bb_panic(struct ath_hal *ah) { u_int32_t status; u_int32_t val; #ifdef AH_DEBUG struct ath_hal_9300 *ahp = AH9300(ah); #endif status = AH_PRIVATE(ah)->ah_bb_panic_last_status; if ( status == 0x04000539 ) { /* recover from this BB panic without reset*/ /* set AR9300_DFS_FIRPWR to -1 */ val = OS_REG_READ(ah, AR_PHY_RADAR_0); val &= (~AR_PHY_RADAR_0_FIRPWR); val |= SM( 0x7f, AR_PHY_RADAR_0_FIRPWR); OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); OS_DELAY(1); /* set AR9300_DFS_FIRPWR to its default value */ val = OS_REG_READ(ah, AR_PHY_RADAR_0); val &= ~AR_PHY_RADAR_0_FIRPWR; val |= SM( AR9300_DFS_FIRPWR, AR_PHY_RADAR_0_FIRPWR); OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); return AH_TRUE; } else if (status == 0x0400000a) { /* EV 92527 : reset required if we see this signature */ HALDEBUG(ah, HAL_DEBUG_DFS, "%s: BB Panic -- 0x0400000a\n", __func__); return AH_FALSE; } else if (status == 0x1300000a) { /* EV92527: we do not need a reset if we see this signature */ HALDEBUG(ah, HAL_DEBUG_DFS, "%s: BB Panic -- 0x1300000a\n", __func__); return AH_TRUE; } else if (AR_SREV_WASP(ah) && (status == 0x04000409)) { return AH_TRUE; } else { if (ar9300_get_capability(ah, HAL_CAP_LDPCWAR, 0, AH_NULL) == HAL_OK && (status & 0xff00000f) == 0x04000009 && status != 0x04000409 && status != 0x04000b09 && status != 0x04000e09 && (status & 0x0000ff00)) { /* disable RIFS Rx */ #ifdef AH_DEBUG HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "%s: BB status=0x%08x rifs=%d - disable\n", __func__, status, ahp->ah_rifs_enabled); #endif ar9300_set_rifs_delay(ah, AH_FALSE); } return AH_FALSE; } }
void ar9300GetSpectralParams(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss) { u_int32_t val; struct ath_hal_9300 *ahp = AH9300(ah); HAL_POWER_MODE pwrmode = ahp->ah_powerMode; if (AR_SREV_WASP(ah) && (pwrmode == HAL_PM_FULL_SLEEP)) { ar9300SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE); } val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); ss->ss_fft_period = MS(val, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD); ss->ss_period = MS(val, AR_PHY_SPECTRAL_SCAN_PERIOD); ss->ss_count = MS(val, AR_PHY_SPECTRAL_SCAN_COUNT); ss->ss_short_report = MS(val, AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT); if (AR_SREV_WASP(ah) && (pwrmode == HAL_PM_FULL_SLEEP)) { ar9300SetPowerMode(ah, HAL_PM_FULL_SLEEP, AH_TRUE); } }
void ar9300StartSpectralScan(struct ath_hal *ah) { u_int32_t val; struct ath_hal_9300 *ahp = AH9300(ah); HAL_POWER_MODE pwrmode = ahp->ah_powerMode; if (AR_SREV_WASP(ah) && (pwrmode == HAL_PM_FULL_SLEEP)) { ar9300SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE); } ar9300PrepSpectralScan(ah); // Activate spectral scan val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); /* This is a hardware bug fix, the enable and active bits should * not be set/reset in the same write operation to the register */ if (!(val & AR_PHY_SPECTRAL_SCAN_ENABLE)) { val |= AR_PHY_SPECTRAL_SCAN_ENABLE; OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val); val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); } val |= AR_PHY_SPECTRAL_SCAN_ACTIVE; OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val); val = OS_REG_READ(ah, AR_PHY_ERR_MASK_REG); OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, val | AR_PHY_ERR_RADAR); val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); if (AR_SREV_WASP(ah) && (pwrmode == HAL_PM_FULL_SLEEP)) { ar9300SetPowerMode(ah, HAL_PM_FULL_SLEEP, AH_TRUE); } HDPRINTF(ah, HAL_DBG_UNMASKABLE, "%s: AR_PHY_MODE=0x%x\n", __func__, OS_REG_READ(ah, AR_PHY_MODE)); }
/* * Get the radar parameter values and return them in the pe * structure */ void ar9300_get_dfs_thresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe) { u_int32_t val, temp; struct ath_hal_9300 *ahp = AH9300(ah); bool asleep = ahp->ah_chip_full_sleep; if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_AWAKE, true); } val = OS_REG_READ(ah, AR_PHY_RADAR_0); temp = MS(val, AR_PHY_RADAR_0_FIRPWR); temp |= ~(AR_PHY_RADAR_0_FIRPWR >> AR_PHY_RADAR_0_FIRPWR_S); pe->pe_firpwr = temp; pe->pe_rrssi = MS(val, AR_PHY_RADAR_0_RRSSI); pe->pe_height = MS(val, AR_PHY_RADAR_0_HEIGHT); pe->pe_prssi = MS(val, AR_PHY_RADAR_0_PRSSI); pe->pe_inband = MS(val, AR_PHY_RADAR_0_INBAND); val = OS_REG_READ(ah, AR_PHY_RADAR_1); pe->pe_relpwr = MS(val, AR_PHY_RADAR_1_RELPWR_THRESH); if (val & AR_PHY_RADAR_1_RELPWR_ENA) { pe->pe_relpwr |= HAL_PHYERR_PARAM_ENABLE; } pe->pe_relstep = MS(val, AR_PHY_RADAR_1_RELSTEP_THRESH); if (val & AR_PHY_RADAR_1_RELSTEP_CHECK) { pe->pe_relstep |= HAL_PHYERR_PARAM_ENABLE; } pe->pe_maxlen = MS(val, AR_PHY_RADAR_1_MAXLEN); if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, true); } }
/* function to adjust PRSSI value for CAC problem */ void ar9300_dfs_cac_war(struct ath_hal *ah, u_int32_t start) { u_int32_t val; if (AR_SREV_AR9580(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) { val = OS_REG_READ(ah, AR_PHY_RADAR_0); if (start) { val &= ~AR_PHY_RADAR_0_PRSSI; val |= SM(AR9300_DFS_PRSSI_CAC, AR_PHY_RADAR_0_PRSSI); } else { val &= ~AR_PHY_RADAR_0_PRSSI; val |= SM(AR9300_DFS_PRSSI, AR_PHY_RADAR_0_PRSSI); } OS_REG_WRITE(ah, AR_PHY_RADAR_0, val | AR_PHY_RADAR_0_ENA); ah->ah_use_cac_prssi = start; } }
void ar9300_tx99_tgt_set_single_carrier(struct ath_hal *ah, int tx_chain_mask, int chtype) { OS_REG_WRITE(ah, AR_PHY_TST_DAC_CONST, OS_REG_READ(ah, AR_PHY_TST_DAC_CONST) | (0x7ff<<11) | 0x7ff); OS_REG_WRITE(ah, AR_PHY_TEST_CTL_STATUS, OS_REG_READ(ah, AR_PHY_TEST_CTL_STATUS) | (1<<7) | (1<<1)); OS_REG_WRITE(ah, AR_PHY_ADDAC_PARA_CTL, (OS_REG_READ(ah, AR_PHY_ADDAC_PARA_CTL) | (1<<31) | (1<<15)) & ~(1<<13)); /* 11G mode */ if (!chtype) { OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2) | (0x1 << 3) | (0x1 << 2)); if (AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah)) { OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP, OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP) & ~(0x1 << 4)); OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP2, (OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP2) | (0x1 << 26) | (0x7 << 24)) & ~(0x1 << 22)); } else { OS_REG_WRITE(ah, AR_HORNET_CH0_TOP, OS_REG_READ(ah, AR_HORNET_CH0_TOP) & ~(0x1 << 4)); OS_REG_WRITE(ah, AR_HORNET_CH0_TOP2, (OS_REG_READ(ah, AR_HORNET_CH0_TOP2) | (0x1 << 26) | (0x7 << 24)) & ~(0x1 << 22)); } /* chain zero */ if((tx_chain_mask & 0x01) == 0x01) { OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX1, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX1) | (0x1 << 31) | (0x5 << 15) | (0x3 << 9)) & ~(0x1 << 27) & ~(0x1 << 12)); OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2) | (0x1 << 12) | (0x1 << 10) | (0x1 << 9) | (0x1 << 8) | (0x1 << 7)) & ~(0x1 << 11)); OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX3, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX3) | (0x1 << 29) | (0x1 << 25) | (0x1 << 23) | (0x1 << 19) | (0x1 << 10) | (0x1 << 9) | (0x1 << 8) | (0x1 << 3)) & ~(0x1 << 28)& ~(0x1 << 24) & ~(0x1 << 22)& ~(0x1 << 7)); OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TXRF1, (OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF1) | (0x1 << 23))& ~(0x1 << 21)); OS_REG_WRITE(ah, AR_PHY_65NM_CH0_BB1, OS_REG_READ(ah, AR_PHY_65NM_CH0_BB1) | (0x1 << 12) | (0x1 << 10) | (0x1 << 9) | (0x1 << 8) | (0x1 << 6) | (0x1 << 5) | (0x1 << 4) | (0x1 << 3) | (0x1 << 2)); OS_REG_WRITE(ah, AR_PHY_65NM_CH0_BB2, OS_REG_READ(ah, AR_PHY_65NM_CH0_BB2) | (0x1 << 31)); } if (AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah)) { /* chain one */ if ((tx_chain_mask & 0x02) == 0x02 ) { OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX1, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX1) | (0x1 << 31) | (0x5 << 15) | (0x3 << 9)) & ~(0x1 << 27) & ~(0x1 << 12)); OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX2) | (0x1 << 12) | (0x1 << 10) | (0x1 << 9) | (0x1 << 8) | (0x1 << 7)) & ~(0x1 << 11)); OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX3, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX3) | (0x1 << 29) | (0x1 << 25) | (0x1 << 23) | (0x1 << 19) | (0x1 << 10) | (0x1 << 9) | (0x1 << 8) | (0x1 << 3)) & ~(0x1 << 28)& ~(0x1 << 24) & ~(0x1 << 22)& ~(0x1 << 7)); OS_REG_WRITE(ah, AR_PHY_65NM_CH1_TXRF1, (OS_REG_READ(ah, AR_PHY_65NM_CH1_TXRF1) | (0x1 << 23))& ~(0x1 << 21)); OS_REG_WRITE(ah, AR_PHY_65NM_CH1_BB1, OS_REG_READ(ah, AR_PHY_65NM_CH1_BB1) | (0x1 << 12) | (0x1 << 10) | (0x1 << 9) | (0x1 << 8) | (0x1 << 6) | (0x1 << 5) | (0x1 << 4) | (0x1 << 3) | (0x1 << 2)); OS_REG_WRITE(ah, AR_PHY_65NM_CH1_BB2, OS_REG_READ(ah, AR_PHY_65NM_CH1_BB2) | (0x1 << 31)); } } if (AR_SREV_OSPREY(ah)) { /* chain two */ if ((tx_chain_mask & 0x04) == 0x04 ) { OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX1, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX1) | (0x1 << 31) | (0x5 << 15) | (0x3 << 9)) & ~(0x1 << 27) & ~(0x1 << 12)); OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX2) | (0x1 << 12) | (0x1 << 10) | (0x1 << 9) | (0x1 << 8) | (0x1 << 7)) & ~(0x1 << 11)); OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX3, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX3) | (0x1 << 29) | (0x1 << 25) | (0x1 << 23) | (0x1 << 19) | (0x1 << 10) | (0x1 << 9) | (0x1 << 8) | (0x1 << 3)) & ~(0x1 << 28)& ~(0x1 << 24) & ~(0x1 << 22)& ~(0x1 << 7)); OS_REG_WRITE(ah, AR_PHY_65NM_CH2_TXRF1, (OS_REG_READ(ah, AR_PHY_65NM_CH2_TXRF1) | (0x1 << 23))& ~(0x1 << 21)); OS_REG_WRITE(ah, AR_PHY_65NM_CH2_BB1, OS_REG_READ(ah, AR_PHY_65NM_CH2_BB1) | (0x1 << 12) | (0x1 << 10) | (0x1 << 9) | (0x1 << 8) | (0x1 << 6) | (0x1 << 5) | (0x1 << 4) | (0x1 << 3) | (0x1 << 2)); OS_REG_WRITE(ah, AR_PHY_65NM_CH2_BB2, OS_REG_READ(ah, AR_PHY_65NM_CH2_BB2) | (0x1 << 31)); } } OS_REG_WRITE(ah, AR_PHY_SWITCH_COM_2, 0x11111); OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, 0x111); } else { /* chain zero */ if((tx_chain_mask & 0x01) == 0x01) { OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX1, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX1) | (0x1 << 31) | (0x1 << 27) | (0x3 << 23) | (0x1 << 19) | (0x1 << 15) | (0x3 << 9)) & ~(0x1 << 12)); OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2) | (0x1 << 12) | (0x1 << 10) | (0x1 << 9) | (0x1 << 8) | (0x1 << 7) | (0x1 << 3) | (0x1 << 2) | (0x1 << 1)) & ~(0x1 << 11)& ~(0x1 << 0)); OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX3, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX3) | (0x1 << 29) | (0x1 << 25) | (0x1 << 23) | (0x1 << 19) | (0x1 << 10) | (0x1 << 9) | (0x1 << 8) | (0x1 << 3)) & ~(0x1 << 28)& ~(0x1 << 24) & ~(0x1 << 22)& ~(0x1 << 7)); OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TXRF1, (OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF1) | (0x1 << 23))& ~(0x1 << 21)); OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TXRF2, OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF2) | (0x3 << 3) | (0x3 << 0)); OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TXRF3, (OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF3) | (0x3 << 29) | (0x3 << 26) | (0x2 << 23) | (0x2 << 20) | (0x2 << 17))& ~(0x1 << 14)); OS_REG_WRITE(ah, AR_PHY_65NM_CH0_BB1, OS_REG_READ(ah, AR_PHY_65NM_CH0_BB1) | (0x1 << 12) | (0x1 << 10) | (0x1 << 9) | (0x1 << 8) | (0x1 << 6) | (0x1 << 5) | (0x1 << 4) | (0x1 << 3) | (0x1 << 2)); OS_REG_WRITE(ah, AR_PHY_65NM_CH0_BB2, OS_REG_READ(ah, AR_PHY_65NM_CH0_BB2) | (0x1 << 31)); if (AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah)) { OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP, OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP) & ~(0x1 << 4)); OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP2, OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP2) | (0x1 << 26) | (0x7 << 24) | (0x3 << 22)); } else { OS_REG_WRITE(ah, AR_HORNET_CH0_TOP, OS_REG_READ(ah, AR_HORNET_CH0_TOP) & ~(0x1 << 4)); OS_REG_WRITE(ah, AR_HORNET_CH0_TOP2, OS_REG_READ(ah, AR_HORNET_CH0_TOP2) | (0x1 << 26) | (0x7 << 24) | (0x3 << 22)); } if (AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah)) { OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX2) | (0x1 << 3) | (0x1 << 2) | (0x1 << 1)) & ~(0x1 << 0)); OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX3, OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX3) | (0x1 << 19) | (0x1 << 3)); OS_REG_WRITE(ah, AR_PHY_65NM_CH1_TXRF1, OS_REG_READ(ah, AR_PHY_65NM_CH1_TXRF1) | (0x1 << 23)); } if (AR_SREV_OSPREY(ah)) { OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX2) | (0x1 << 3) | (0x1 << 2) | (0x1 << 1)) & ~(0x1 << 0)); OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX3, OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX3) | (0x1 << 19) | (0x1 << 3)); OS_REG_WRITE(ah, AR_PHY_65NM_CH2_TXRF1, OS_REG_READ(ah, AR_PHY_65NM_CH2_TXRF1) | (0x1 << 23)); } } if (AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah)) { /* chain one */ if ((tx_chain_mask & 0x02) == 0x02 ) { OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2) | (0x1 << 3) | (0x1 << 2) | (0x1 << 1)) & ~(0x1 << 0)); OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX3, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX3) | (0x1 << 19) | (0x1 << 3)); OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TXRF1, OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF1) | (0x1 << 23)); if (AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah)) { OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP, OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP) & ~(0x1 << 4)); OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP2, OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP2) | (0x1 << 26) | (0x7 << 24) | (0x3 << 22)); } else { OS_REG_WRITE(ah, AR_HORNET_CH0_TOP, OS_REG_READ(ah, AR_HORNET_CH0_TOP) & ~(0x1 << 4)); OS_REG_WRITE(ah, AR_HORNET_CH0_TOP2, OS_REG_READ(ah, AR_HORNET_CH0_TOP2) | (0x1 << 26) | (0x7 << 24) | (0x3 << 22)); } OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX1, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX1) | (0x1 << 31) | (0x1 << 27) | (0x3 << 23) | (0x1 << 19) | (0x1 << 15) | (0x3 << 9)) & ~(0x1 << 12)); OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX2) | (0x1 << 12) | (0x1 << 10) | (0x1 << 9) | (0x1 << 8) | (0x1 << 7) | (0x1 << 3) | (0x1 << 2) | (0x1 << 1)) & ~(0x1 << 11)& ~(0x1 << 0)); OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX3, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX3) | (0x1 << 29) | (0x1 << 25) | (0x1 << 23) | (0x1 << 19) | (0x1 << 10) | (0x1 << 9) | (0x1 << 8) | (0x1 << 3)) & ~(0x1 << 28)& ~(0x1 << 24) & ~(0x1 << 22)& ~(0x1 << 7)); OS_REG_WRITE(ah, AR_PHY_65NM_CH1_TXRF1, (OS_REG_READ(ah, AR_PHY_65NM_CH1_TXRF1) | (0x1 << 23))& ~(0x1 << 21)); OS_REG_WRITE(ah, AR_PHY_65NM_CH1_TXRF2, OS_REG_READ(ah, AR_PHY_65NM_CH1_TXRF2) | (0x3 << 3) | (0x3 << 0)); OS_REG_WRITE(ah, AR_PHY_65NM_CH1_TXRF3, (OS_REG_READ(ah, AR_PHY_65NM_CH1_TXRF3) | (0x3 << 29) | (0x3 << 26) | (0x2 << 23) | (0x2 << 20) | (0x2 << 17))& ~(0x1 << 14)); OS_REG_WRITE(ah, AR_PHY_65NM_CH1_BB1, OS_REG_READ(ah, AR_PHY_65NM_CH1_BB1) | (0x1 << 12) | (0x1 << 10) | (0x1 << 9) | (0x1 << 8) | (0x1 << 6) | (0x1 << 5) | (0x1 << 4) | (0x1 << 3) | (0x1 << 2)); OS_REG_WRITE(ah, AR_PHY_65NM_CH1_BB2, OS_REG_READ(ah, AR_PHY_65NM_CH1_BB2) | (0x1 << 31)); if (AR_SREV_OSPREY(ah)) { OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX2) | (0x1 << 3) | (0x1 << 2) | (0x1 << 1)) & ~(0x1 << 0)); OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX3, OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX3) | (0x1 << 19) | (0x1 << 3)); OS_REG_WRITE(ah, AR_PHY_65NM_CH2_TXRF1, OS_REG_READ(ah, AR_PHY_65NM_CH2_TXRF1) | (0x1 << 23)); } } } if (AR_SREV_OSPREY(ah)) { /* chain two */ if ((tx_chain_mask & 0x04) == 0x04 ) { OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2) | (0x1 << 3) | (0x1 << 2) | (0x1 << 1)) & ~(0x1 << 0)); OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX3, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX3) | (0x1 << 19) | (0x1 << 3)); OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TXRF1, OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF1) | (0x1 << 23)); if (AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah)) { OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP, OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP) & ~(0x1 << 4)); OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP2, OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP2) | (0x1 << 26) | (0x7 << 24) | (0x3 << 22)); } else { OS_REG_WRITE(ah, AR_HORNET_CH0_TOP, OS_REG_READ(ah, AR_HORNET_CH0_TOP) & ~(0x1 << 4)); OS_REG_WRITE(ah, AR_HORNET_CH0_TOP2, OS_REG_READ(ah, AR_HORNET_CH0_TOP2) | (0x1 << 26) | (0x7 << 24) | (0x3 << 22)); } OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX2) | (0x1 << 3) | (0x1 << 2) | (0x1 << 1)) & ~(0x1 << 0)); OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX3, OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX3) | (0x1 << 19) | (0x1 << 3)); OS_REG_WRITE(ah, AR_PHY_65NM_CH1_TXRF1, OS_REG_READ(ah, AR_PHY_65NM_CH1_TXRF1) | (0x1 << 23)); OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX1, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX1) | (0x1 << 31) | (0x1 << 27) | (0x3 << 23) | (0x1 << 19) | (0x1 << 15) | (0x3 << 9)) & ~(0x1 << 12)); OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX2) | (0x1 << 12) | (0x1 << 10) | (0x1 << 9) | (0x1 << 8) | (0x1 << 7) | (0x1 << 3) | (0x1 << 2) | (0x1 << 1)) & ~(0x1 << 11)& ~(0x1 << 0)); OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX3, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX3) | (0x1 << 29) | (0x1 << 25) | (0x1 << 23) | (0x1 << 19) | (0x1 << 10) | (0x1 << 9) | (0x1 << 8) | (0x1 << 3)) & ~(0x1 << 28)& ~(0x1 << 24) & ~(0x1 << 22)& ~(0x1 << 7)); OS_REG_WRITE(ah, AR_PHY_65NM_CH2_TXRF1, (OS_REG_READ(ah, AR_PHY_65NM_CH2_TXRF1) | (0x1 << 23))& ~(0x1 << 21)); OS_REG_WRITE(ah, AR_PHY_65NM_CH2_TXRF2, OS_REG_READ(ah, AR_PHY_65NM_CH2_TXRF2) | (0x3 << 3) | (0x3 << 0)); OS_REG_WRITE(ah, AR_PHY_65NM_CH2_TXRF3, (OS_REG_READ(ah, AR_PHY_65NM_CH2_TXRF3) | (0x3 << 29) | (0x3 << 26) | (0x2 << 23) | (0x2 << 20) | (0x2 << 17))& ~(0x1 << 14)); OS_REG_WRITE(ah, AR_PHY_65NM_CH2_BB1, OS_REG_READ(ah, AR_PHY_65NM_CH2_BB1) | (0x1 << 12) | (0x1 << 10) | (0x1 << 9) | (0x1 << 8) | (0x1 << 6) | (0x1 << 5) | (0x1 << 4) | (0x1 << 3) | (0x1 << 2)); OS_REG_WRITE(ah, AR_PHY_65NM_CH2_BB2, OS_REG_READ(ah, AR_PHY_65NM_CH2_BB2) | (0x1 << 31)); } } OS_REG_WRITE(ah, AR_PHY_SWITCH_COM_2, 0x22222); OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, 0x222); } }
/* * Reads the Interrupt Status Register value from the NIC, thus deasserting * the interrupt line, and returns both the masked and unmasked mapped ISR * values. The value returned is mapped to abstract the hw-specific bit * locations in the Interrupt Status Register. * * Returns: A hardware-abstracted bitmap of all non-masked-out * interrupts pending, as well as an unmasked value */ #define MAP_ISR_S2_HAL_CST 6 /* Carrier sense timeout */ #define MAP_ISR_S2_HAL_GTT 6 /* Global transmit timeout */ #define MAP_ISR_S2_HAL_TIM 3 /* TIM */ #define MAP_ISR_S2_HAL_CABEND 0 /* CABEND */ #define MAP_ISR_S2_HAL_DTIMSYNC 7 /* DTIMSYNC */ #define MAP_ISR_S2_HAL_DTIM 7 /* DTIM */ #define MAP_ISR_S2_HAL_TSFOOR 4 /* Rx TSF out of range */ #define MAP_ISR_S2_HAL_BBPANIC 6 /* Panic watchdog IRQ from BB */ HAL_BOOL ar9300_get_pending_interrupts( struct ath_hal *ah, HAL_INT *masked, HAL_INT_TYPE type, u_int8_t msi, HAL_BOOL nortc) { struct ath_hal_9300 *ahp = AH9300(ah); HAL_BOOL ret_val = AH_TRUE; u_int32_t isr = 0; u_int32_t mask2 = 0; u_int32_t sync_cause = 0; u_int32_t async_cause; u_int32_t msi_pend_addr_mask = 0; u_int32_t sync_en_def = AR9300_INTR_SYNC_DEFAULT; HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps; *masked = 0; if (!nortc) { if (HAL_INT_MSI == type) { if (msi == HAL_MSIVEC_RXHP) { OS_REG_WRITE(ah, AR_ISR, AR_ISR_HP_RXOK); *masked = HAL_INT_RXHP; goto end; } else if (msi == HAL_MSIVEC_RXLP) { OS_REG_WRITE(ah, AR_ISR, (AR_ISR_LP_RXOK | AR_ISR_RXMINTR | AR_ISR_RXINTM)); *masked = HAL_INT_RXLP; goto end; } else if (msi == HAL_MSIVEC_TX) { OS_REG_WRITE(ah, AR_ISR, AR_ISR_TXOK); *masked = HAL_INT_TX; goto end; } else if (msi == HAL_MSIVEC_MISC) { /* * For the misc MSI event fall through and determine the cause. */ } } } /* Make sure mac interrupt is pending in async interrupt cause register */ async_cause = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_CAUSE)); if (async_cause & AR_INTR_ASYNC_USED) { /* * RTC may not be on since it runs on a slow 32khz clock * so check its status to be sure */ if (!nortc && (OS_REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) == AR_RTC_STATUS_ON) { isr = OS_REG_READ(ah, AR_ISR); } } if (AR_SREV_POSEIDON(ah)) { sync_en_def = AR9300_INTR_SYNC_DEF_NO_HOST1_PERR; } else if (AR_SREV_WASP(ah)) { sync_en_def = AR9340_INTR_SYNC_DEFAULT; } /* Store away the async and sync cause registers */ /* XXX Do this before the filtering done below */ #ifdef AH_INTERRUPT_DEBUGGING ah->ah_intrstate[0] = OS_REG_READ(ah, AR_ISR); ah->ah_intrstate[1] = OS_REG_READ(ah, AR_ISR_S0); ah->ah_intrstate[2] = OS_REG_READ(ah, AR_ISR_S1); ah->ah_intrstate[3] = OS_REG_READ(ah, AR_ISR_S2); ah->ah_intrstate[4] = OS_REG_READ(ah, AR_ISR_S3); ah->ah_intrstate[5] = OS_REG_READ(ah, AR_ISR_S4); ah->ah_intrstate[6] = OS_REG_READ(ah, AR_ISR_S5); /* XXX double reading? */ ah->ah_syncstate = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE)); #endif sync_cause = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE)) & (sync_en_def | AR_INTR_SYNC_MASK_GPIO); if (!isr && !sync_cause && !async_cause) { ret_val = AH_FALSE; goto end; } HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: isr=0x%x, sync_cause=0x%x, async_cause=0x%x\n", __func__, isr, sync_cause, async_cause); if (isr) { if (isr & AR_ISR_BCNMISC) { u_int32_t isr2; isr2 = OS_REG_READ(ah, AR_ISR_S2); /* Translate ISR bits to HAL values */ mask2 |= ((isr2 & AR_ISR_S2_TIM) >> MAP_ISR_S2_HAL_TIM); mask2 |= ((isr2 & AR_ISR_S2_DTIM) >> MAP_ISR_S2_HAL_DTIM); mask2 |= ((isr2 & AR_ISR_S2_DTIMSYNC) >> MAP_ISR_S2_HAL_DTIMSYNC); mask2 |= ((isr2 & AR_ISR_S2_CABEND) >> MAP_ISR_S2_HAL_CABEND); mask2 |= ((isr2 & AR_ISR_S2_GTT) << MAP_ISR_S2_HAL_GTT); mask2 |= ((isr2 & AR_ISR_S2_CST) << MAP_ISR_S2_HAL_CST); mask2 |= ((isr2 & AR_ISR_S2_TSFOOR) >> MAP_ISR_S2_HAL_TSFOOR); mask2 |= ((isr2 & AR_ISR_S2_BBPANIC) >> MAP_ISR_S2_HAL_BBPANIC); if (!p_cap->halIsrRacSupport) { /* * EV61133 (missing interrupts due to ISR_RAC): * If not using ISR_RAC, clear interrupts by writing to ISR_S2. * This avoids a race condition where a new BCNMISC interrupt * could come in between reading the ISR and clearing the * interrupt via the primary ISR. We therefore clear the * interrupt via the secondary, which avoids this race. */ OS_REG_WRITE(ah, AR_ISR_S2, isr2); isr &= ~AR_ISR_BCNMISC; } } /* Use AR_ISR_RAC only if chip supports it. * See EV61133 (missing interrupts due to ISR_RAC) */ if (p_cap->halIsrRacSupport) { isr = OS_REG_READ(ah, AR_ISR_RAC); } if (isr == 0xffffffff) { *masked = 0; ret_val = AH_FALSE; goto end; } *masked = isr & HAL_INT_COMMON; /* * When interrupt mitigation is switched on, we fake a normal RX or TX * interrupt when we received a mitigated interrupt. This way, the upper * layer do not need to know about feature. */ if (ahp->ah_intr_mitigation_rx) { /* Only Rx interrupt mitigation. No Tx intr. mitigation. */ if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) { *masked |= HAL_INT_RXLP; } } if (ahp->ah_intr_mitigation_tx) { if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM)) { *masked |= HAL_INT_TX; } } if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR)) { *masked |= HAL_INT_RXLP; } if (isr & AR_ISR_HP_RXOK) { *masked |= HAL_INT_RXHP; } if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) { *masked |= HAL_INT_TX; if (!p_cap->halIsrRacSupport) { u_int32_t s0, s1; /* * EV61133 (missing interrupts due to ISR_RAC): * If not using ISR_RAC, clear interrupts by writing to * ISR_S0/S1. * This avoids a race condition where a new interrupt * could come in between reading the ISR and clearing the * interrupt via the primary ISR. We therefore clear the * interrupt via the secondary, which avoids this race. */ s0 = OS_REG_READ(ah, AR_ISR_S0); OS_REG_WRITE(ah, AR_ISR_S0, s0); s1 = OS_REG_READ(ah, AR_ISR_S1); OS_REG_WRITE(ah, AR_ISR_S1, s1); isr &= ~(AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL); } } /* * Do not treat receive overflows as fatal for owl. */ if (isr & AR_ISR_RXORN) { #if __PKT_SERIOUS_ERRORS__ HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: receive FIFO overrun interrupt\n", __func__); #endif } #if 0 /* XXX Verify if this is fixed for Osprey */ if (!p_cap->halAutoSleepSupport) { u_int32_t isr5 = OS_REG_READ(ah, AR_ISR_S5_S); if (isr5 & AR_ISR_S5_TIM_TIMER) { *masked |= HAL_INT_TIM_TIMER; } } #endif if (isr & AR_ISR_GENTMR) { u_int32_t s5; if (p_cap->halIsrRacSupport) { /* Use secondary shadow registers if using ISR_RAC */ s5 = OS_REG_READ(ah, AR_ISR_S5_S); } else { s5 = OS_REG_READ(ah, AR_ISR_S5); } if (isr & AR_ISR_GENTMR) { HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: GENTIMER, ISR_RAC=0x%x ISR_S2_S=0x%x\n", __func__, isr, s5); ahp->ah_intr_gen_timer_trigger = MS(s5, AR_ISR_S5_GENTIMER_TRIG); ahp->ah_intr_gen_timer_thresh = MS(s5, AR_ISR_S5_GENTIMER_THRESH); if (ahp->ah_intr_gen_timer_trigger) { *masked |= HAL_INT_GENTIMER; } } if (!p_cap->halIsrRacSupport) { /* * EV61133 (missing interrupts due to ISR_RAC): * If not using ISR_RAC, clear interrupts by writing to ISR_S5. * This avoids a race condition where a new interrupt * could come in between reading the ISR and clearing the * interrupt via the primary ISR. We therefore clear the * interrupt via the secondary, which avoids this race. */ OS_REG_WRITE(ah, AR_ISR_S5, s5); isr &= ~AR_ISR_GENTMR; } } *masked |= mask2; if (!p_cap->halIsrRacSupport) { /* * EV61133 (missing interrupts due to ISR_RAC): * If not using ISR_RAC, clear the interrupts we've read by * writing back ones in these locations to the primary ISR * (except for interrupts that have a secondary isr register - * see above). */ OS_REG_WRITE(ah, AR_ISR, isr); /* Flush prior write */ (void) OS_REG_READ(ah, AR_ISR); } #ifdef AH_SUPPORT_AR9300 if (*masked & HAL_INT_BBPANIC) { ar9300_handle_bb_panic(ah); } #endif }
/* * Enable radar detection and set the radar parameters per the * values in pe */ void ar9300_enable_dfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe) { u_int32_t val; struct ath_hal_private *ahp = AH_PRIVATE(ah); HAL_CHANNEL_INTERNAL *ichan = ahp->ah_curchan; struct ath_hal_9300 *ah9300 = AH9300(ah); bool asleep = ah9300->ah_chip_full_sleep; int reg_writes = 0; if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_AWAKE, true); } val = OS_REG_READ(ah, AR_PHY_RADAR_0); val |= AR_PHY_RADAR_0_FFT_ENA | AR_PHY_RADAR_0_ENA; if (pe->pe_firpwr != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_0_FIRPWR; val |= SM(pe->pe_firpwr, AR_PHY_RADAR_0_FIRPWR); } if (pe->pe_rrssi != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_0_RRSSI; val |= SM(pe->pe_rrssi, AR_PHY_RADAR_0_RRSSI); } if (pe->pe_height != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_0_HEIGHT; val |= SM(pe->pe_height, AR_PHY_RADAR_0_HEIGHT); } if (pe->pe_prssi != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_0_PRSSI; if (AR_SREV_AR9580(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) { if (ah->ah_use_cac_prssi) { val |= SM(AR9300_DFS_PRSSI_CAC, AR_PHY_RADAR_0_PRSSI); } else { val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI); } } else { val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI); } } if (pe->pe_inband != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_0_INBAND; val |= SM(pe->pe_inband, AR_PHY_RADAR_0_INBAND); } OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); val = OS_REG_READ(ah, AR_PHY_RADAR_1); val |= AR_PHY_RADAR_1_MAX_RRSSI | AR_PHY_RADAR_1_BLOCK_CHECK; if (pe->pe_maxlen != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_1_MAXLEN; val |= SM(pe->pe_maxlen, AR_PHY_RADAR_1_MAXLEN); } if (pe->pe_relstep != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_1_RELSTEP_THRESH; val |= SM(pe->pe_relstep, AR_PHY_RADAR_1_RELSTEP_THRESH); } if (pe->pe_relpwr != HAL_PHYERR_PARAM_NOVAL) { val &= ~AR_PHY_RADAR_1_RELPWR_THRESH; val |= SM(pe->pe_relpwr, AR_PHY_RADAR_1_RELPWR_THRESH); } OS_REG_WRITE(ah, AR_PHY_RADAR_1, val); if (ath_hal_getcapability(ah, HAL_CAP_EXT_CHAN_DFS, 0, 0) == HAL_OK) { val = OS_REG_READ(ah, AR_PHY_RADAR_EXT); if (IS_CHAN_HT40(ichan)) { /* Enable extension channel radar detection */ OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val | AR_PHY_RADAR_EXT_ENA); } else { /* HT20 mode, disable extension channel radar detect */ OS_REG_WRITE(ah, AR_PHY_RADAR_EXT, val & ~AR_PHY_RADAR_EXT_ENA); } } /* apply DFS postamble array from INI column 0 is register ID, column 1 is HT20 value, colum2 is HT40 value */ if (AR_SREV_AR9580(ah) || AR_SREV_WASP(ah) || AR_SREV_OSPREY_22(ah) || AR_SREV_SCORPION(ah)) { REG_WRITE_ARRAY(&ah9300->ah_ini_dfs,IS_CHAN_HT40(ichan)? 2:1, reg_writes); } #ifdef ATH_HAL_DFS_CHIRPING_FIX_APH128 HDPRINTF(ah, HAL_DBG_DFS,"DFS change the timing value\n"); if (AR_SREV_AR9580(ah) && IS_CHAN_HT40(ichan)) { OS_REG_WRITE(ah, AR_PHY_TIMING6, 0x3140c00a); } #endif if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, true); } }
/* * Take the MHz channel value and set the Channel value * * ASSUMES: Writes enabled to analog bus * * Actual Expression, * * For 2GHz channel, * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17) * (freq_ref = 40MHz) * * For 5GHz channel, * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10) * (freq_ref = 40MHz/(24>>amode_ref_sel)) * * For 5GHz channels which are 5MHz spaced, * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17) * (freq_ref = 40MHz) */ static HAL_BOOL ar9300_set_channel(struct ath_hal *ah, struct ieee80211_channel *chan) { u_int16_t b_mode, frac_mode = 0, a_mode_ref_sel = 0; u_int32_t freq, channel_sel, reg32; u_int8_t clk_25mhz = AH9300(ah)->clk_25mhz; CHAN_CENTERS centers; int load_synth_channel; #ifdef AH_DEBUG_ALQ HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan); #endif /* * Put this behind AH_DEBUG_ALQ for now until the Hornet * channel_sel code below is made to work. */ #ifdef AH_DEBUG_ALQ OS_MARK(ah, AH_MARK_SETCHANNEL, ichan->channel); #endif ar9300_get_channel_centers(ah, chan, ¢ers); freq = centers.synth_center; if (freq < 4800) { /* 2 GHz, fractional mode */ b_mode = 1; /* 2 GHz */ if (AR_SREV_HORNET(ah)) { #if 0 u_int32_t ichan = ieee80211_mhz2ieee(ah, chan->ic_freq, chan->ic_flags); HALASSERT(ichan > 0 && ichan <= 14); if (clk_25mhz) { channel_sel = ar9300_chansel_xtal_25M[ichan - 1]; } else { channel_sel = ar9300_chansel_xtal_40M[ichan - 1]; } #endif uint32_t i; /* * Pay close attention to this bit! * * We need to map the actual desired synth frequency to * one of the channel select array entries. * * For HT20, it'll align with the channel we select. * * For HT40 though it won't - the centre frequency * will not be the frequency of chan->ic_freq or ichan->freq; * it needs to be whatever frequency maps to 'freq'. */ i = ath_hal_mhz2ieee_2ghz(ah, freq); HALASSERT(i > 0 && i <= 14); if (clk_25mhz) { channel_sel = ar9300_chansel_xtal_25M[i - 1]; } else { channel_sel = ar9300_chansel_xtal_40M[i - 1]; } } else if (AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) { u_int32_t channel_frac; /* * freq_ref = (40 / (refdiva >> a_mode_ref_sel)); * (where refdiva = 1 and amoderefsel = 0) * ndiv = ((chan_mhz * 4) / 3) / freq_ref; * chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000 */ channel_sel = (freq * 4) / 120; channel_frac = (((freq * 4) % 120) * 0x20000) / 120; channel_sel = (channel_sel << 17) | (channel_frac); } else if (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah) || AR_SREV_HONEYBEE(ah)) { u_int32_t channel_frac; if (clk_25mhz) { /* * freq_ref = (50 / (refdiva >> a_mode_ref_sel)); * (where refdiva = 1 and amoderefsel = 0) * ndiv = ((chan_mhz * 4) / 3) / freq_ref; * chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000 */ if (AR_SREV_SCORPION(ah) || AR_SREV_HONEYBEE(ah)) { /* Doubler is off for Scorpion */ channel_sel = (freq * 4) / 75; channel_frac = (((freq * 4) % 75) * 0x20000) / 75; } else { channel_sel = (freq * 2) / 75; channel_frac = (((freq * 2) % 75) * 0x20000) / 75; } } else { /* * freq_ref = (50 / (refdiva >> a_mode_ref_sel)); * (where refdiva = 1 and amoderefsel = 0) * ndiv = ((chan_mhz * 4) / 3) / freq_ref; * chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000 */ if (AR_SREV_SCORPION(ah)) { /* Doubler is off for Scorpion */ channel_sel = (freq * 4) / 120; channel_frac = (((freq * 4) % 120) * 0x20000) / 120; } else { channel_sel = (freq * 2) / 120; channel_frac = (((freq * 2) % 120) * 0x20000) / 120; } } channel_sel = (channel_sel << 17) | (channel_frac); } else { channel_sel = CHANSEL_2G(freq); } } else { b_mode = 0; /* 5 GHz */ if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && clk_25mhz){ u_int32_t channel_frac; /* * freq_ref = (50 / (refdiva >> amoderefsel)); * (refdiva = 1, amoderefsel = 0) * ndiv = ((chan_mhz * 2) / 3) / freq_ref; * chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000 */ channel_sel = freq / 75 ; channel_frac = ((freq % 75) * 0x20000) / 75; channel_sel = (channel_sel << 17) | (channel_frac); } else { channel_sel = CHANSEL_5G(freq); /* Doubler is ON, so, divide channel_sel by 2. */ channel_sel >>= 1; } } /* Enable fractional mode for all channels */ frac_mode = 1; a_mode_ref_sel = 0; load_synth_channel = 0; reg32 = (b_mode << 29); OS_REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32); /* Enable Long shift Select for Synthesizer */ OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_SYNTH4, AR_PHY_SYNTH4_LONG_SHIFT_SELECT, 1); /* program synth. setting */ reg32 = (channel_sel << 2) | (a_mode_ref_sel << 28) | (frac_mode << 30) | (load_synth_channel << 31); if (IEEE80211_IS_CHAN_QUARTER(chan)) { reg32 += CHANSEL_5G_DOT5MHZ; } OS_REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32); /* Toggle Load Synth channel bit */ load_synth_channel = 1; reg32 |= load_synth_channel << 31; OS_REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32); AH_PRIVATE(ah)->ah_curchan = chan; return AH_TRUE; }
void ar9300_configure_spectral_scan(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss) { u_int32_t val, i; struct ath_hal_9300 *ahp = AH9300(ah); bool asleep = ahp->ah_chip_full_sleep; int16_t nf_buf[NUM_NF_READINGS]; if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_AWAKE, true); } ar9300_prep_spectral_scan(ah); if (ss->ss_spectral_pri) { for (i = 0; i < NUM_NF_READINGS; i++) { nf_buf[i] = NOISE_PWR_DBM_2_INT(ss->ss_nf_cal[i]); } ar9300_load_nf(ah, nf_buf); #ifdef DEMO_MODE ar9300_disable_strong_signal(ah); ar9300_disable_weak_signal(ah); ar9300_set_radar_dc_thresh(ah); ar9300_set_cca_threshold(ah, MAX_CCA_THRESH); /*ar9300_disable_restart(ah);*/ #endif } val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN); if (ss->ss_fft_period != HAL_SPECTRAL_PARAM_NOVAL) { val &= ~AR_PHY_SPECTRAL_SCAN_FFT_PERIOD; val |= SM(ss->ss_fft_period, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD); } if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) { val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD; val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD); } if (ss->ss_count != HAL_SPECTRAL_PARAM_NOVAL) { val &= ~AR_PHY_SPECTRAL_SCAN_COUNT; /* Remnants of a Merlin bug, 128 translates to 0 for * continuous scanning. Instead we do piecemeal captures * of 64 samples for Osprey. */ if (ss->ss_count == 128) { val |= SM(0, AR_PHY_SPECTRAL_SCAN_COUNT); } else { val |= SM(ss->ss_count, AR_PHY_SPECTRAL_SCAN_COUNT); } } if (ss->ss_period != HAL_SPECTRAL_PARAM_NOVAL) { val &= ~AR_PHY_SPECTRAL_SCAN_PERIOD; val |= SM(ss->ss_period, AR_PHY_SPECTRAL_SCAN_PERIOD); } if (ss->ss_short_report == true) { val |= AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT; } else { val &= ~AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT; } /* if noise power cal, force high priority */ if (ss->ss_spectral_pri) { val |= AR_PHY_SPECTRAL_SCAN_PRIORITY_HI; } else { val &= ~AR_PHY_SPECTRAL_SCAN_PRIORITY_HI; } /* enable spectral scan */ OS_REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val | AR_PHY_SPECTRAL_SCAN_ENABLE); if ((AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) && asleep) { ar9300_set_power_mode(ah, HAL_PM_FULL_SLEEP, true); } }