static void ar5416AniCckErrTrigger(struct ath_hal *ah, HAL_BOOL inISR) { struct ath_hal_5416 *ahp = AH5416(ah); HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan; struct ar5416AniState *aniState; WIRELESS_MODE mode; int32_t rssi; HALASSERT(chan != AH_NULL); if (!DO_ANI(ah)) { return; } /* first, raise noise immunity level, up to max */ aniState = ahp->ah_curani; //PG: For WIRELESS_MODE debug of HT chips mode = ath_hal_chan2htwmode(ah, (HAL_CHANNEL *) chan); HDPRINTF(ah, HAL_DBG_ANI, "%s: Wireless Mode #=%d, Channel=%hu, cflags=0x%x, CLOCK_RATE=%u\n", __func__, mode, chan->channel, chan->channelFlags, CLOCK_RATE(ah)); if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { if (ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL, aniState->noiseImmunityLevel + 1, inISR) == AH_TRUE) {return;} } /* In the case of AP mode operation, we cannot bucketize beacons * according to RSSI. Instead, raise Firstep level, up to max, and * simply return */ if (AH_PRIVATE(ah)->ah_opmode == HAL_M_HOSTAP) { if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { ar5416AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, aniState->firstepLevel + 1, inISR); } return; } rssi = BEACON_RSSI(ahp); if (rssi > aniState->rssiThrLow) { /* * Beacon signal in mid and high range, raise firsteplevel. */ if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) ar5416AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, aniState->firstepLevel + 1, inISR); } else { /* * Beacon rssi is low, zero firstepLevel to maximize * CCK sensitivity. */ mode = ath_hal_chan2wmode(ah, (HAL_CHANNEL *) chan); if (mode == WIRELESS_MODE_11g || mode == WIRELESS_MODE_11b) { if (aniState->firstepLevel > 0) ar5416AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0, inISR); } } }
/* * Cleanup any ANI state setup. */ void ar9300_ani_detach(struct ath_hal *ah) { HDPRINTF(ah, HAL_DBG_ANI, "%s: Detaching Ani\n", __func__); ar9300_disable_mib_counters(ah); OS_REG_WRITE(ah, AR_PHY_ERR_1, 0); OS_REG_WRITE(ah, AR_PHY_ERR_2, 0); }
/* * Initialize the ANI register values with default (ini) values. * This routine is called during a (full) hardware reset after * all the registers are initialised from the INI. */ void ar9300_ani_init_defaults(struct ath_hal *ah, HAL_HT_MACMODE macmode) { struct ath_hal_9300 *ahp = AH9300(ah); struct ar9300_ani_state *ani_state; HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan; int index; u_int32_t val; HALASSERT(chan != AH_NULL); index = ar9300_get_ani_channel_index(ah, chan); ani_state = &ahp->ah_ani[index]; ahp->ah_curani = ani_state; HDPRINTF(ah, HAL_DBG_ANI, "%s: ver %d.%d opmode %u chan %d Mhz/0x%x macmode %d\n", __func__, AH_PRIVATE(ah)->ah_mac_version, AH_PRIVATE(ah)->ah_mac_rev, AH_PRIVATE(ah)->ah_opmode, chan->channel, chan->channel_flags, macmode); val = OS_REG_READ(ah, AR_PHY_SFCORR); ani_state->ini_def.m1_thresh = MS(val, AR_PHY_SFCORR_M1_THRESH); ani_state->ini_def.m2_thresh = MS(val, AR_PHY_SFCORR_M2_THRESH); ani_state->ini_def.m2_count_thr = MS(val, AR_PHY_SFCORR_M2COUNT_THR); val = OS_REG_READ(ah, AR_PHY_SFCORR_LOW); ani_state->ini_def.m1_thresh_low = MS(val, AR_PHY_SFCORR_LOW_M1_THRESH_LOW); ani_state->ini_def.m2_thresh_low = MS(val, AR_PHY_SFCORR_LOW_M2_THRESH_LOW); ani_state->ini_def.m2_count_thr_low = MS(val, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW); val = OS_REG_READ(ah, AR_PHY_SFCORR_EXT); ani_state->ini_def.m1_thresh_ext = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH); ani_state->ini_def.m2_thresh_ext = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH); ani_state->ini_def.m1_thresh_low_ext = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH_LOW); ani_state->ini_def.m2_thresh_low_ext = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH_LOW); ani_state->ini_def.firstep = OS_REG_READ_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRSTEP); ani_state->ini_def.firstep_low = OS_REG_READ_FIELD( ah, AR_PHY_FIND_SIG_LOW, AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW); ani_state->ini_def.cycpwr_thr1 = OS_REG_READ_FIELD(ah, AR_PHY_TIMING5, AR_PHY_TIMING5_CYCPWR_THR1); ani_state->ini_def.cycpwr_thr1_ext = OS_REG_READ_FIELD(ah, AR_PHY_EXT_CCA, AR_PHY_EXT_CYCPWR_THR1); /* these levels just got reset to defaults by the INI */ ani_state->spur_immunity_level = HAL_ANI_DEF_SPUR_IMMUNE_LVL; ani_state->firstep_level = HAL_ANI_DEF_FIRSTEP_LVL; ani_state->ofdm_weak_sig_detect_off = !HAL_ANI_USE_OFDM_WEAK_SIG; ani_state->mrc_cck_off = !HAL_ANI_ENABLE_MRC_CCK; ani_state->cycle_count = 0; }
static void ar9300_setup_test_addac_mode(struct ath_hal *ah) { #if AH_BYTE_ORDER == AH_BIG_ENDIAN /* byteswap Rx/Tx buffer to ensure correct layout */ HDPRINTF(ah, HAL_DBG_RF_PARAM, "%s: big endian - set AR_CFG_SWTB/AR_CFG_SWRB\n", __func__); OS_REG_RMW(ah, AR_CFG, AR_CFG_SWTB | AR_CFG_SWRB, 0); #else /* Rx/Tx buffer should not be byteswaped */ if (OS_REG_READ(ah, AR_CFG) & (AR_CFG_SWTB | AR_CFG_SWRB)) { HDPRINTF(ah, HAL_DBG_UNMASKABLE, "%s: **WARNING: little endian but AR_CFG_SWTB/AR_CFG_SWRB set!\n", __func__); } #endif OS_REG_WRITE(ah, AR_PHY_TEST, 0); OS_REG_WRITE(ah, AR_PHY_TEST_CTL_STATUS, 0); /* cf_bbb_obs_sel=4'b0001 */ OS_REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 0x1); /* cf_rx_obs_sel=5'b00000, this is the 5th bit */ OS_REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5); /* cf_tx_obs_sel=3'b111 */ OS_REG_RMW_FIELD( ah, AR_PHY_TEST_CTL_STATUS, AR_PHY_TEST_CTL_TX_OBS_SEL, 0x7); /* cf_tx_obs_mux_sel=2'b11 */ OS_REG_RMW_FIELD( ah, AR_PHY_TEST_CTL_STATUS, AR_PHY_TEST_CTL_TX_OBS_MUX_SEL, 0x3); /* enable TSTADC */ OS_REG_SET_BIT(ah, AR_PHY_TEST_CTL_STATUS, AR_PHY_TEST_CTL_TSTDAC_EN); /* cf_rx_obs_sel=5'b00000, these are the first 4 bits */ OS_REG_RMW_FIELD( ah, AR_PHY_TEST_CTL_STATUS, AR_PHY_TEST_CTL_RX_OBS_SEL, 0x0); /* tstdac_out_sel=2'b01 */ OS_REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_CHAIN_SEL, 0x1); }
/* * Process a MIB interrupt. We may potentially be invoked because * any of the MIB counters overflow/trigger so don't assume we're * here because a PHY error counter triggered. */ void ar9300_process_mib_intr(struct ath_hal *ah, const HAL_NODE_STATS *stats) { struct ath_hal_9300 *ahp = AH9300(ah); u_int32_t phy_cnt1, phy_cnt2; #if 0 HDPRINTF(ah, HAL_DBG_ANI, "%s: Processing Mib Intr\n", __func__); #endif /* Reset these counters regardless */ OS_REG_WRITE(ah, AR_FILT_OFDM, 0); OS_REG_WRITE(ah, AR_FILT_CCK, 0); if (!(OS_REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING)) { OS_REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR); } /* Clear the mib counters and save them in the stats */ ar9300_update_mib_mac_stats(ah); ahp->ah_stats.ast_nodestats = *stats; if (!DO_ANI(ah)) { /* * We must always clear the interrupt cause by resetting * the phy error regs. */ OS_REG_WRITE(ah, AR_PHY_ERR_1, 0); OS_REG_WRITE(ah, AR_PHY_ERR_2, 0); return; } /* NB: these are not reset-on-read */ phy_cnt1 = OS_REG_READ(ah, AR_PHY_ERR_1); phy_cnt2 = OS_REG_READ(ah, AR_PHY_ERR_2); #if HAL_ANI_DEBUG HDPRINTF(ah, HAL_DBG_ANI, "%s: Errors: OFDM=0x%08x-0x0=%d CCK=0x%08x-0x0=%d\n", __func__, phy_cnt1, phy_cnt1, phy_cnt2, phy_cnt2); #endif if (((phy_cnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || ((phy_cnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) { /* NB: always restart to insure the h/w counters are reset */ ar9300_ani_restart(ah); } }
static HAL_CHANNEL_INTERNAL * getchannel(struct ath_hal *ah, const HAL_CHANNEL *c) { #define CHAN_FLAGS (CHANNEL_ALL | CHANNEL_HALF | CHANNEL_QUARTER) HAL_CHANNEL_INTERNAL *base, *cc; int flags = c->channel_flags & CHAN_FLAGS; int n, lim; /* * Check current channel to avoid the lookup. */ cc = AH_PRIVATE(ah)->ah_curchan; if (cc != AH_NULL && cc->channel == c->channel && (cc->channel_flags & CHAN_FLAGS) == flags) { return cc; } /* binary search based on known sorting order */ base = AH_TABLES(ah)->ah_channels; n = AH_PRIVATE(ah)->ah_nchan; /* binary search based on known sorting order */ for (lim = n; lim != 0; lim >>= 1) { int d; cc = &base[lim >> 1]; d = c->channel - cc->channel; if (d == 0) { if ((cc->channel_flags & CHAN_FLAGS) == flags) { return cc; } d = flags - (cc->channel_flags & CHAN_FLAGS); } HDPRINTF(ah, HAL_DBG_DFS, "%s: channel %u/0x%x d %d\n", __func__, cc->channel, cc->channel_flags, d); if (d > 0) { base = cc + 1; lim--; } } HDPRINTF(ah, HAL_DBG_DFS, "%s: no match for %u/0x%x\n", __func__, c->channel, c->channel_flags); return AH_NULL; #undef CHAN_FLAGS }
struct dfs_pulse * ar5212GetDfsRadars(struct ath_hal *ah, u_int32_t dfsdomain, int *numradars, struct dfs_bin5pulse **bin5pulses, int *numb5radars, HAL_PHYERR_PARAM *pe) { #define N(a) (sizeof(a)/sizeof(a[0])) struct dfs_pulse *dfs_radars = AH_NULL; switch (dfsdomain) { case DFS_FCC_DOMAIN: dfs_radars = &ar5212_fcc_radars[2]; *numradars= N(ar5212_fcc_radars)-2; *bin5pulses = &ar5212_bin5pulses[0]; *numb5radars = N(ar5212_bin5pulses); HDPRINTF(ah, HAL_DBG_DFS, "%s: DFS_FCC_DOMAIN_5212\n", __func__); break; case DFS_ETSI_DOMAIN: dfs_radars = &ar5212_etsi_radars[0]; *numradars = N(ar5212_etsi_radars); *bin5pulses = &ar5212_bin5pulses[0]; *numb5radars = N(ar5212_bin5pulses); HDPRINTF(ah, HAL_DBG_DFS, "%s: DFS_ETSI_DOMAIN_5212\n", __func__); break; case DFS_MKK4_DOMAIN: dfs_radars = &ar5212_fcc_radars[0]; *numradars = N(ar5212_fcc_radars); *bin5pulses = &ar5212_bin5pulses[0]; *numb5radars = N(ar5212_bin5pulses); HDPRINTF(ah, HAL_DBG_DFS, "%s: DFS_MKK4_DOMAIN_5212\n", __func__); break; default: HDPRINTF(ah, HAL_DBG_DFS, "%s: no domain\n", __func__); return AH_NULL; } /* Set the default phy parameters per chip */ pe->pe_firpwr = AR5212_DFS_FIRPWR; pe->pe_rrssi = AR5212_DFS_RRSSI; pe->pe_height = AR5212_DFS_HEIGHT; pe->pe_prssi = AR5212_DFS_PRSSI; pe->pe_inband = AR5212_DFS_INBAND; return dfs_radars; #undef N }
static void ar5416AniRestart(struct ath_hal *ah) { struct ath_hal_5416 *ahp = AH5416(ah); struct ar5416AniState *aniState; if (!DO_ANI(ah)) { return; } aniState = ahp->ah_curani; aniState->listenTime = 0; if (ahp->ah_hasHwPhyCounters) { if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) { aniState->ofdmPhyErrBase = 0; HDPRINTF(ah, HAL_DBG_ANI, "OFDM Trigger is too high for hw counters\n"); } else aniState->ofdmPhyErrBase = AR_PHY_COUNTMAX - aniState->ofdmTrigHigh; if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) { aniState->cckPhyErrBase = 0; HDPRINTF(ah, HAL_DBG_ANI, "CCK Trigger is too high for hw counters\n"); } else aniState->cckPhyErrBase = AR_PHY_COUNTMAX - aniState->cckTrigHigh; HDPRINTF(ah, HAL_DBG_ANI, "%s: Writing ofdmbase=%u cckbase=%u\n", __func__, aniState->ofdmPhyErrBase, aniState->cckPhyErrBase); ENABLE_REG_WRITE_BUFFER OS_REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); OS_REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); OS_REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); OS_REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); OS_REG_WRITE_FLUSH(ah); DISABLE_REG_WRITE_BUFFER /* Clear the mib counters and save them in the stats */ ar5416UpdateMibMacStats(ah); } aniState->ofdmPhyErrCount = 0; aniState->cckPhyErrCount = 0; }
void ar5416DisableMIBCounters(struct ath_hal *ah) { HDPRINTF(ah, HAL_DBG_ANI, "Disabling MIB counters\n"); /* Freeze the mib counters, get the stats and clear them */ OS_REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC); ar5416UpdateMibMacStats(ah); OS_REG_WRITE(ah, AR_MIBC, AR_MIBC_CMC); OS_REG_WRITE(ah, AR_FILT_OFDM, 0); OS_REG_WRITE(ah, AR_FILT_CCK, 0); }
/* * Cleanup any ANI state setup. */ void ar5416AniDetach(struct ath_hal *ah) { struct ath_hal_5416 *ahp = AH5416(ah); HDPRINTF(ah, HAL_DBG_ANI, "Detaching Ani\n"); if (ahp->ah_hasHwPhyCounters) { ar5416DisableMIBCounters(ah); OS_REG_WRITE(ah, AR_PHY_ERR_1, 0); OS_REG_WRITE(ah, AR_PHY_ERR_2, 0); } }
/* * Cleanup any ANI state setup. */ void ar5212AniDetach(struct ath_hal *ah) { struct ath_hal_5212 *ahp = AH5212(ah); HDPRINTF(ah, HAL_DBG_ANI, "Detaching Ani\n"); if (ahp->ah_hasHwPhyCounters) { ar5212DisableMIBCounters(ah); OS_REG_WRITE(ah, AR_PHYCNT1, 0); OS_REG_WRITE(ah, AR_PHYCNT2, 0); } }
HAL_STATUS ar5416EepromAttach(struct ath_hal *ah) { struct ath_hal_5416 *ahp = AH5416(ah); #ifndef WIN32 if (ar5416EepDataInFlash(ah)) ar5416FlashMap(ah); #endif if (AR_SREV_KIWI(ah) ) ahp->ah_eep_map = EEP_MAP_AR9287; else if (AR_SREV_KITE(ah) || AR_SREV_K2(ah)) ahp->ah_eep_map = EEP_MAP_4KBITS; else ahp->ah_eep_map = EEP_MAP_DEFAULT; AH_PRIVATE(ah)->ah_eepromGetSpurChan = ar5416EepromGetSpurChan; if (!ar5416FillEeprom(ah)) { /* eeprom read failure => assume emulation board */ if (ahp->ah_priv.priv.ah_config.ath_hal_soft_eeprom) { ar5416FillEmuEeprom(ahp); ahp->ah_emu_eeprom = 1; return HAL_OK; } else { return HAL_EIO; } } #ifndef ART_BUILD return ar5416CheckEeprom(ah); #else if (ar5416CheckEeprom(ah) == HAL_OK) { return HAL_OK; } else { /* The data of EEPROM is unavailible */ if (AR_SREV_KIWI(ah)) { /* Use default eeprom's data */ HDPRINTF(ah, HAL_DBG_EEPROM, "%s: EEPROM is unavaible. Load EEPROM default value\n", __func__); ar9287EepromLoadDefaults(ah); return HAL_OK; } else { return HAL_EEBADSUM; } } #endif }
u_int32_t __ahdecl ath_hal_reg_read(struct ath_hal *ah, u_int reg) { u_int32_t val; #ifdef AH_ANALOG_SHADOW_READ if (reg<=RF_END && reg>=RF_BEGIN) val = rfshadow[(reg-RF_BEGIN)/4]; else #endif val = _OS_REG_READ(ah, reg); HDPRINTF(ah, HAL_DBG_REG_IO, "READ 0x%x => 0x%x\n", reg, val); return val; }
void ar9300_disable_mib_counters(struct ath_hal *ah) { HDPRINTF(ah, HAL_DBG_RESET, "%s: Disabling MIB counters\n", __func__); OS_REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC | AR_MIBC_CMC); /* Clear the mib counters and save them in the stats */ ar9300_update_mib_mac_stats(ah); OS_REG_WRITE(ah, AR_FILT_OFDM, 0); OS_REG_WRITE(ah, AR_FILT_CCK, 0); }
/* * Allocate memory for analog bank scratch buffers * Scratch Buffer will be reinitialized every reset so no need to zero now */ HAL_BOOL ar2425RfAttach(struct ath_hal *ah, HAL_STATUS *status) { struct ath_hal_5212 *ahp = AH5212(ah); HALASSERT(ahp->ah_analogBanks == AH_NULL); ahp->ah_analogBanks = ath_hal_malloc(ah, sizeof(AR5212_RF_BANKS_2425)); if (ahp->ah_analogBanks == AH_NULL) { HDPRINTF(ah, HAL_DBG_CHANNEL, "%s: cannot allocate RF banks\n", __func__); *status = HAL_ENOMEM; /* XXX */ return AH_FALSE; } HALASSERT(ahp->ah_pcdacTable == AH_NULL); ahp->ah_pcdacTableSize = PWR_TABLE_SIZE_2413 * sizeof(u_int16_t); ahp->ah_pcdacTable = ath_hal_malloc(ah, ahp->ah_pcdacTableSize); if (ahp->ah_pcdacTable == AH_NULL) { HDPRINTF(ah, HAL_DBG_RF_PARAM, "%s: cannot allocate PCDAC table\n", __func__); *status = HAL_ENOMEM; /* XXX */ return AH_FALSE; } HALASSERT(ahp->ah_vpdTable == AH_NULL); ahp->ah_vpdTable = ath_hal_malloc(ah, sizeof(AR2425_VPD_TABLE)); if (ahp->ah_vpdTable == AH_NULL) { HDPRINTF(ah, HAL_DBG_CHANNEL, "%s: cannot allocate VPD table\n", __func__); *status = HAL_ENOMEM; /* XXX */ return AH_FALSE; } ahp->ah_rfHal.rfDetach = ar2425RfDetach; ahp->ah_rfHal.writeRegs = ar2425WriteRegs; ahp->ah_rfHal.getRfBank = ar2425GetRfBank; ahp->ah_rfHal.setChannel = ar2425SetChannel; ahp->ah_rfHal.setRfRegs = ar2425SetRfRegs; ahp->ah_rfHal.setPowerTable = ar2425SetPowerTable; ahp->ah_rfHal.getChipPowerLim = ar2425GetChipPowerLimits; ahp->ah_rfHal.getNfAdjust = ar5212GetNfAdjust; return AH_TRUE; }
void ar9300_adjust_difs(struct ath_hal *ah, u_int32_t val) { if (val == 0) { /* * EV 116936: * Restore the register values with that of the HAL structure. * Do not assume and overwrite these values to whatever * is in ar9300_osprey22.ini. */ struct ath_hal_9300 *ahp = AH9300(ah); HAL_TX_QUEUE_INFO *qi; int q; ah->ah_fccaifs = 0; HDPRINTF(ah, HAL_DBG_DFS, "%s: restore DIFS \n", __func__); for (q = 0; q < 4; q++) { qi = &ahp->ah_txq[q]; OS_REG_WRITE(ah, AR_DLCL_IFS(q), SM(qi->tqi_cwmin, AR_D_LCL_IFS_CWMIN) | SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS)); } } else { /* * These are values from George Lai and are specific to * FCC domain. They are yet to be determined for other domains. */ ah->ah_fccaifs = 1; HDPRINTF(ah, HAL_DBG_DFS, "%s: set DIFS to default\n", __func__); /*printk("%s: modify DIFS\n", __func__);*/ OS_REG_WRITE(ah, AR_DLCL_IFS(0), 0x05fffc0f); OS_REG_WRITE(ah, AR_DLCL_IFS(1), 0x05f0fc0f); OS_REG_WRITE(ah, AR_DLCL_IFS(2), 0x05f03c07); OS_REG_WRITE(ah, AR_DLCL_IFS(3), 0x05f01c03); } }
/* * Set the ANI settings to match an OFDM level. */ static void ar9300_ani_set_odfm_noise_immunity_level(struct ath_hal *ah, u_int8_t ofdm_noise_immunity_level) { struct ath_hal_9300 *ahp = AH9300(ah); struct ar9300_ani_state *ani_state = ahp->ah_curani; ani_state->rssi = BEACON_RSSI(ahp); HDPRINTF(ah, HAL_DBG_ANI, "**** %s: ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", __func__, ani_state->ofdm_noise_immunity_level, ofdm_noise_immunity_level, ani_state->rssi, ani_state->rssi_thr_low, ani_state->rssi_thr_high); ani_state->ofdm_noise_immunity_level = ofdm_noise_immunity_level; if (ani_state->spur_immunity_level != ofdm_level_table[ofdm_noise_immunity_level].spur_immunity_level) { ar9300_ani_control( ah, HAL_ANI_SPUR_IMMUNITY_LEVEL, ofdm_level_table[ofdm_noise_immunity_level].spur_immunity_level); } if (ani_state->firstep_level != ofdm_level_table[ofdm_noise_immunity_level].fir_step_level && ofdm_level_table[ofdm_noise_immunity_level].fir_step_level >= cck_level_table[ani_state->cck_noise_immunity_level].fir_step_level) { ar9300_ani_control( ah, HAL_ANI_FIRSTEP_LEVEL, ofdm_level_table[ofdm_noise_immunity_level].fir_step_level); } if ((AH_PRIVATE(ah)->ah_opmode != HAL_M_STA || ani_state->rssi <= ani_state->rssi_thr_high)) { if (ani_state->ofdm_weak_sig_detect_off) { /* * force on ofdm weak sig detect. */ ar9300_ani_control(ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION, true); } } else if (ani_state->ofdm_weak_sig_detect_off == ofdm_level_table[ofdm_noise_immunity_level].ofdm_weak_signal_on) { ar9300_ani_control( ah, HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION, ofdm_level_table[ofdm_noise_immunity_level].ofdm_weak_signal_on); } }
void __ahdecl ath_hal_reg_write(struct ath_hal *ah, u_int reg, u_int32_t val) { HDPRINTF(ah, HAL_DBG_REG_IO, "WRITE 0x%x <= 0x%x\n", reg, val); #if defined(AH_ANALOG_SHADOW_READ) if (reg<=RF_END && reg>=RF_BEGIN) rfshadow[(reg-RF_BEGIN)/4] = val; #endif #if defined(AH_ANALOG_SHADOW_WRITE) if (reg<=RF_END && reg>=RF_BEGIN) return; #endif _OS_REG_WRITE(ah, reg, val); }
/* * Set power mgt to the requested mode, and conditionally set * the chip as well */ HAL_BOOL ar5416SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode, int set_chip) { struct ath_hal_5416 *ahp = AH5416(ah); #ifdef AH_DEBUG static const char* modes[] = { "AWAKE", "FULL-SLEEP", "NETWORK SLEEP", "UNDEFINED" }; #endif int status = AH_TRUE; HDPRINTF(ah, HAL_DBG_POWER_MGMT, "%s: %s -> %s (%s)\n", __func__, modes[ahp->ah_powerMode], modes[mode], set_chip ? "set chip " : ""); switch (mode) { case HAL_PM_AWAKE: status = ar5416SetPowerModeAwake(ah, set_chip); break; case HAL_PM_FULL_SLEEP: ar5416SetPowerModeSleep(ah, set_chip); ahp->ah_chipFullSleep = AH_TRUE; break; case HAL_PM_NETWORK_SLEEP: ar5416SetPowerModeNetworkSleep(ah, set_chip); break; default: HDPRINTF(ah, HAL_DBG_POWER_MGMT, "%s: unknown power mode %u\n", __func__, mode); return AH_FALSE; } ahp->ah_powerMode = mode; HTC_SET_PS_STATE(ah, mode); return status; }
/* * Notify Power Mgt is enabled in self-generated frames. * If requested, force chip awake. * * Returns A_OK if chip is awake or successfully forced awake. * * WARNING WARNING WARNING * There is a problem with the chip where sometimes it will not wake up. */ HAL_BOOL ar5416SetPowerModeAwake(struct ath_hal *ah, int set_chip) { #define POWER_UP_TIME 10000 u_int32_t val; int i; if (set_chip) { /* Do a Power-On-Reset if OWL is shutdown */ if ((OS_REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) { if (ar5416SetResetReg(ah, HAL_RESET_POWER_ON) != AH_TRUE) { HALASSERT(0); return AH_FALSE; } ar5416InitPLL(ah, AH_NULL); } if(AR_SREV_HOWL(ah)) /* HOWL needs this bit to set to wake up -was cleared in ar5416SetPowerModeSleep() */ OS_REG_SET_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN); OS_REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); if (AR_SREV_HOWL(ah)) { OS_DELAY(10000); /* Give chip the chance to awake */ } else { OS_DELAY(50); } for (i = POWER_UP_TIME / 50; i > 0; i--) { val = OS_REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M; if (val == AR_RTC_STATUS_ON) break; OS_DELAY(50); OS_REG_SET_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN); } if (i == 0) { HDPRINTF(ah, HAL_DBG_POWER_MGMT, "%s: Failed to wakeup in %uus\n", __func__, POWER_UP_TIME/20); return AH_FALSE; } } OS_REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); return AH_TRUE; #undef POWER_UP_TIME }
static HAL_BOOL ar2316GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL *chans, u_int32_t nchans) { HAL_BOOL retVal = AH_TRUE; int i; int16_t maxPow, minPow; for (i=0; i<nchans; i++) { if (ar2316GetChannelMaxMinPower(ah, &chans[i], &maxPow, &minPow)) { chans[i].maxTxPower = maxPow; chans[i].minTxPower = minPow; } else { HDPRINTF(ah, HAL_DBG_RF_PARAM, "Failed setting power table for nchans=%d\n", i); retVal = AH_FALSE; } } #ifdef AH_DEBUG for (i=0; i<nchans; i++) { HDPRINTF(ah, HAL_DBG_CHANNEL, "Chan %d: MaxPow = %d MinPow = %d\n", chans[i].channel,chans[i].maxTxPower, chans[i].minTxPower); } #endif return (retVal); }
void ar9300_enable_mib_counters(struct ath_hal *ah) { HDPRINTF(ah, HAL_DBG_RESET, "%s: Enable MIB counters\n", __func__); /* Clear the mib counters and save them in the stats */ ar9300_update_mib_mac_stats(ah); OS_REG_WRITE(ah, AR_FILT_OFDM, 0); OS_REG_WRITE(ah, AR_FILT_CCK, 0); OS_REG_WRITE(ah, AR_MIBC, ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS) & 0x0f); OS_REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); OS_REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); }
/* * Read 16 bits of data from offset into *data */ HAL_BOOL ar5212EepromRead(struct ath_hal *ah, u_int off, u_int16_t *data) { OS_REG_WRITE(ah, AR_EEPROM_ADDR, off); OS_REG_WRITE(ah, AR_EEPROM_CMD, AR_EEPROM_CMD_READ); if (!ath_hal_wait(ah, AR_EEPROM_STS, AR_EEPROM_STS_READ_COMPLETE | AR_EEPROM_STS_READ_ERROR, AR_EEPROM_STS_READ_COMPLETE, AH_WAIT_TIMEOUT)) { HDPRINTF(ah, HAL_DBG_EEPROM, "%s: read failed for entry 0x%x\n", __func__, off); return AH_FALSE; } *data = OS_REG_READ(ah, AR_EEPROM_DATA) & 0xffff; return AH_TRUE; }
/* * Process a MIB interrupt. We may potentially be invoked because * any of the MIB counters overflow/trigger so don't assume we're * here because a PHY error counter triggered. */ void ar5212ProcessMibIntr(struct ath_hal *ah, const HAL_NODE_STATS *stats) { struct ath_hal_5212 *ahp = AH5212(ah); u_int32_t phyCnt1, phyCnt2; HDPRINTF(ah, HAL_DBG_ANI, "Processing Mib Intr\n"); /* Reset these counters regardless */ OS_REG_WRITE(ah, AR_FILTOFDM, 0); OS_REG_WRITE(ah, AR_FILTCCK, 0); /* Clear the mib counters and save them in the stats */ ar5212UpdateMibMacStats(ah); ahp->ah_stats.ast_nodestats = *stats; /* NB: these are not reset-on-read */ phyCnt1 = OS_REG_READ(ah, AR_PHYCNT1); phyCnt2 = OS_REG_READ(ah, AR_PHYCNT2); if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) { struct ar5212AniState *aniState = ahp->ah_curani; u_int32_t ofdmPhyErrCnt, cckPhyErrCnt; /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */ ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; ahp->ah_stats.ast_ani_ofdmerrs += ofdmPhyErrCnt - aniState->ofdmPhyErrCount; aniState->ofdmPhyErrCount = ofdmPhyErrCnt; cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase; ahp->ah_stats.ast_ani_cckerrs += cckPhyErrCnt - aniState->cckPhyErrCount; aniState->cckPhyErrCount = cckPhyErrCnt; /* * NB: figure out which counter triggered. If both * trigger we'll only deal with one as the processing * clobbers the error counter so the trigger threshold * check will never be true. */ if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh) ar5212AniOfdmErrTrigger(ah); if (aniState->cckPhyErrCount > aniState->cckTrigHigh) ar5212AniCckErrTrigger(ah); /* NB: always restart to insure the h/w counters are reset */ ar5212AniRestart(ah); } }
void ar5212EnableMIBCounters(struct ath_hal *ah) { HDPRINTF(ah, HAL_DBG_ANI, "Enable mib counters\n"); /* Clear the mib counters and save them in the stats */ ar5212UpdateMibMacStats(ah); OS_REG_WRITE(ah, AR_FILTOFDM, 0); OS_REG_WRITE(ah, AR_FILTCCK, 0); OS_REG_WRITE(ah, AR_MIBC, ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS) & 0x0f); OS_REG_WRITE(ah, AR_PHYCNTMASK1, AR_PHY_ERR_OFDM_TIMING); OS_REG_WRITE(ah, AR_PHYCNTMASK2, AR_PHY_ERR_CCK_TIMING); }
const HAL_RATE_TABLE * ar5212GetRateTable(struct ath_hal *ah, u_int mode) { HAL_RATE_TABLE *rt; switch (mode) { case HAL_MODE_11A: rt = &ar5212_11a_table; if (AH_PRIVATE(ah)->ah_curchan) { if (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) { rt = &ar5212_11a_half_table; } else if (IS_CHAN_QUARTER_RATE( AH_PRIVATE(ah)->ah_curchan)) { rt = &ar5212_11a_quarter_table; } } break; case HAL_MODE_11B: rt = &ar5212_11b_table; break; case HAL_MODE_11G: #ifdef notdef case HAL_MODE_PUREG: #endif rt = &ar5212_11g_table; break; case HAL_MODE_TURBO: rt = &ar5212_turboa_table; break; case HAL_MODE_108G: rt = &ar5212_turbog_table; break; case HAL_MODE_XR: rt = &ar5212_xr_table; break; case HAL_MODE_11A_HALF_RATE: rt = &ar5212_11a_half_table; break; case HAL_MODE_11A_QUARTER_RATE: rt = &ar5212_11a_quarter_table; break; default: HDPRINTF(ah, HAL_DBG_CHANNEL, "%s: invalid mode 0x%x\n", __func__, mode); return AH_NULL; } ath_hal_setupratetable(ah, rt); return rt; }
static HAL_STATUS ar5416FlashMap(struct ath_hal *ah) { struct ath_hal_5416 *ahp = AH5416(ah); #ifdef AR9100 ahp->ah_cal_mem = OS_REMAP(ah, AR5416_EEPROM_START_ADDR, AR5416_EEPROM_MAX); #else ahp->ah_cal_mem = OS_REMAP((uintptr_t)ah->ah_st, AR5416_EEPROM_MAX); #endif if (!ahp->ah_cal_mem) { HDPRINTF(ah, HAL_DBG_EEPROM, "%s: cannot remap eeprom region \n", __func__); return HAL_EIO; } return HAL_OK; }
/* * Return a reference to the requested RF Bank. */ static u_int32_t * ar2316GetRfBank(struct ath_hal *ah, int bank) { struct ath_hal_5212 *ahp = AH5212(ah); AR5212_RF_BANKS_2316 *pRfBank2316 = ahp->ah_analogBanks; HALASSERT(ahp->ah_analogBanks != AH_NULL); switch (bank) { case 1: return pRfBank2316->Bank1Data; case 2: return pRfBank2316->Bank2Data; case 3: return pRfBank2316->Bank3Data; case 6: return pRfBank2316->Bank6Data; case 7: return pRfBank2316->Bank7Data; } HDPRINTF(ah, HAL_DBG_RF_PARAM, "%s: unknown RF Bank %d requested\n", __func__, bank); return AH_NULL; }
void ar9300_get_spectral_params(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss) { u_int32_t val; HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan; int i, ichain, rx_chain_status; 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); 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 < 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 { HDPRINTF(AH_NULL, HAL_DBG_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, true); } }
void ar9300ReadPktlogReg( struct ath_hal *ah, u_int32_t *rxfilterVal, u_int32_t *rxcfgVal, u_int32_t *phyErrMaskVal, u_int32_t *macPcuPhyErrRegval) { *rxfilterVal = OS_REG_READ(ah, AR_RX_FILTER); *rxcfgVal = OS_REG_READ(ah, AR_RXCFG); *phyErrMaskVal = OS_REG_READ(ah, AR_PHY_ERR); *macPcuPhyErrRegval = OS_REG_READ(ah, 0x8338); HDPRINTF(ah, HAL_DBG_UNMASKABLE, "%s[%d] rxfilterVal 0x%08x , rxcfgVal 0x%08x, phyErrMaskVal 0x%08x " "macPcuPhyErrRegval 0x%08x\n", __func__, __LINE__, *rxfilterVal, *rxcfgVal, *phyErrMaskVal, *macPcuPhyErrRegval); }