コード例 #1
0
ファイル: ar9300_freebsd.c プロジェクト: 2trill2spill/freebsd
void
ar9300_attach_freebsd_ops(struct ath_hal *ah)
{

	/* Global functions */
	ah->ah_detach		= ar9300_detach;
	ah->ah_getRateTable		= ar9300_get_rate_table;

	/* Reset functions */
	ah->ah_reset		= ar9300_reset_freebsd;
	ah->ah_phyDisable		= ar9300_phy_disable;
	ah->ah_disable		= ar9300_disable;
	ah->ah_configPCIE		= ar9300_config_pcie_freebsd;
//	ah->ah_disablePCIE		= ar9300_disable_pcie_phy;
	ah->ah_setPCUConfig		= ar9300_set_pcu_config;
	// perCalibration
	ah->ah_perCalibrationN	= ar9300_per_calibration_freebsd;
	ah->ah_resetCalValid	= ar9300_reset_cal_valid_freebsd;
	ah->ah_setTxPowerLimit	= ar9300_freebsd_set_tx_power_limit;
	ah->ah_getChanNoise		= ath_hal_getChanNoise;

	/* Transmit functions */
	ah->ah_setupTxQueue		= ar9300_setup_tx_queue;
	ah->ah_setTxQueueProps	= ar9300_set_tx_queue_props;
	ah->ah_getTxQueueProps	= ar9300_get_tx_queue_props;
	ah->ah_releaseTxQueue	= ar9300_release_tx_queue;
	ah->ah_resetTxQueue		= ar9300_reset_tx_queue;
	ah->ah_getTxDP		= ar9300_get_tx_dp;
	ah->ah_setTxDP		= ar9300_set_tx_dp;
	ah->ah_numTxPending		= ar9300_num_tx_pending;
	ah->ah_startTxDma		= ar9300_start_tx_dma;
	ah->ah_stopTxDma		= ar9300_stop_tx_dma_freebsd;
	ah->ah_setupTxDesc		= ar9300_freebsd_setup_tx_desc;
	ah->ah_setupXTxDesc		= ar9300_freebsd_setup_x_tx_desc;
	ah->ah_fillTxDesc		= ar9300_freebsd_fill_tx_desc;
	ah->ah_procTxDesc		= ar9300_freebsd_proc_tx_desc;
	ah->ah_getTxIntrQueue	= ar9300_get_tx_intr_queue;
	// reqTxIntrDesc
	ah->ah_getTxCompletionRates	= ar9300_freebsd_get_tx_completion_rates;
	ah->ah_setTxDescLink	= ar9300_set_desc_link;
	ah->ah_getTxDescLink	= ar9300_freebsd_get_desc_link;
	ah->ah_getTxDescLinkPtr	= ar9300_get_desc_link_ptr;
	ah->ah_setupTxStatusRing	= ar9300_setup_tx_status_ring;
	ah->ah_getTxRawTxDesc	 = ar9300_get_raw_tx_desc;
	ah->ah_updateTxTrigLevel	= ar9300_update_tx_trig_level;

	/* RX functions */
	ah->ah_getRxDP		= ar9300_get_rx_dp;
	ah->ah_setRxDP		= ar9300_set_rx_dp;
	ah->ah_enableReceive	= ar9300_enable_receive;
	ah->ah_stopDmaReceive	= ar9300_stop_dma_receive_freebsd;
	ah->ah_startPcuReceive	= ar9300_start_pcu_receive_freebsd;
	ah->ah_stopPcuReceive	= ar9300_stop_pcu_receive;
	ah->ah_setMulticastFilter	= ar9300_set_multicast_filter;
	ah->ah_setMulticastFilterIndex = ar9300SetMulticastFilterIndex;
	ah->ah_clrMulticastFilterIndex = ar9300ClrMulticastFilterIndex;
	ah->ah_getRxFilter		= ar9300_get_rx_filter;
	ah->ah_setRxFilter		= ar9300_set_rx_filter;
	/* setupRxDesc */
	ah->ah_procRxDesc		= ar9300_proc_rx_desc_freebsd;
	ah->ah_rxMonitor		= ar9300_ani_rxmonitor_freebsd;
	ah->ah_aniPoll		= ar9300_ani_poll_freebsd;
	ah->ah_procMibEvent		= ar9300_process_mib_intr;

	/* Misc functions */
	ah->ah_getCapability	= ar9300_get_capability;
	ah->ah_setCapability	= ar9300_set_capability;
	ah->ah_getDiagState		= ar9300_get_diag_state;
	ah->ah_getMacAddress	= ar9300_get_mac_address;
	ah->ah_setMacAddress	= ar9300_set_mac_address;
	ah->ah_getBssIdMask		= ar9300_get_bss_id_mask;
	ah->ah_setBssIdMask		= ar9300_set_bss_id_mask;
	ah->ah_setRegulatoryDomain	= ar9300_set_regulatory_domain;
	ah->ah_setLedState		= ar9300_set_led_state;
	ah->ah_writeAssocid		= ar9300_write_associd;
	ah->ah_gpioCfgInput		= ar9300_gpio_cfg_input;
	ah->ah_gpioCfgOutput	= ar9300_gpio_cfg_output;
	ah->ah_gpioGet		= ar9300_gpio_get;
	ah->ah_gpioSet		= ar9300_gpio_set;
	ah->ah_gpioSetIntr		= ar9300_gpio_set_intr;
	/* polarity */
	/* mask */
	ah->ah_getTsf32		= ar9300_get_tsf32;
	ah->ah_getTsf64		= ar9300_get_tsf64;
	ah->ah_resetTsf		= ar9300_reset_tsf;
	ah->ah_setTsf64		= ar9300_freebsd_set_tsf64;
	ah->ah_detectCardPresent	= ar9300_detect_card_present;
	// ah->ah_updateMibCounters	= ar9300_update_mib_counters;
	ah->ah_getRfGain		= ar9300_get_rfgain;
	ah->ah_getDefAntenna	= ar9300_get_def_antenna;
	ah->ah_setDefAntenna	= ar9300_set_def_antenna;
	ah->ah_getAntennaSwitch	= ar9300_freebsd_get_antenna_switch;
	ah->ah_setAntennaSwitch	= ar9300_freebsd_set_antenna_switch;
	// ah->ah_setSifsTime		= ar9300_set_sifs_time;
	// ah->ah_getSifsTime		= ar9300_get_sifs_time;
	ah->ah_setSlotTime		= ar9300_set_slot_time;
	ah->ah_getSlotTime		= ar9300GetSlotTime;
	ah->ah_getAckTimeout	= ar9300_get_ack_timeout;
	ah->ah_setAckTimeout	= ar9300_set_ack_timeout;
	// XXX ack/ctsrate
	// XXX CTS timeout
	ah->ah_getCTSTimeout = ar9300_freebsd_get_cts_timeout;
	// XXX decompmask
	// coverageclass
	ah->ah_setQuiet		= ar9300_set_quiet;
	ah->ah_getMibCycleCounts	= ar9300_freebsd_get_mib_cycle_counts;

	/* DFS functions */
	ah->ah_enableDfs		= ar9300_enable_dfs;
	ah->ah_getDfsThresh		= ar9300_get_dfs_thresh;
	ah->ah_getDfsDefaultThresh	= ar9300_get_default_dfs_thresh;
	ah->ah_procRadarEvent		= ar9300_freebsd_proc_radar_event;
	ah->ah_isFastClockEnabled	= ar9300_is_fast_clock_enabled;
	ah->ah_get11nExtBusy		= ar9300_get_11n_ext_busy;
	ah->ah_setDfsCacTxQuiet		= ar9300_cac_tx_quiet;

	/* Spectral Scan Functions */
	ah->ah_spectralConfigure	= ar9300_configure_spectral_scan;
	ah->ah_spectralGetConfig	= ar9300_get_spectral_params;
	ah->ah_spectralStart		= ar9300_start_spectral_scan;
	ah->ah_spectralStop		= ar9300_stop_spectral_scan;
	ah->ah_spectralIsEnabled	= ar9300_is_spectral_enabled;
	ah->ah_spectralIsActive		= ar9300_is_spectral_active;

	/* Key cache functions */
	ah->ah_getKeyCacheSize	= ar9300_get_key_cache_size;
	ah->ah_resetKeyCacheEntry	= ar9300_reset_key_cache_entry;
	ah->ah_isKeyCacheEntryValid	= ar9300_is_key_cache_entry_valid;
	ah->ah_setKeyCacheEntry	= ar9300_set_key_cache_entry;
	ah->ah_setKeyCacheEntryMac	= ar9300_set_key_cache_entry_mac;

	/* Power management functions */
	ah->ah_setPowerMode		= ar9300_set_power_mode;
	ah->ah_getPowerMode		= ar9300_get_power_mode;

	/* Beacon functions */
	/* ah_setBeaconTimers */
	ah->ah_beaconInit		= ar9300_freebsd_beacon_init;
	ah->ah_setBeaconTimers		= ar9300_beacon_set_beacon_timers;
	ah->ah_setStationBeaconTimers = ar9300_set_sta_beacon_timers;
	/* ah_resetStationBeaconTimers */
	ah->ah_getNextTBTT = ar9300_get_next_tbtt;

	/* Interrupt functions */
	ah->ah_isInterruptPending	= ar9300_is_interrupt_pending;
	ah->ah_getPendingInterrupts	= ar9300_get_pending_interrupts_freebsd;
	ah->ah_getInterrupts =	ar9300_get_interrupts;
	ah->ah_setInterrupts =	ar9300_set_interrupts_freebsd;

	/* Regulatory/internal functions */
	//    AH_PRIVATE(ah)->ah_getNfAdjust = ar9300_get_nf_adjust;
	AH_PRIVATE(ah)->ah_eepromRead = ar9300_eeprom_read_word;
	//    AH_PRIVATE(ah)->ah_getChipPowerLimits = ar9300_get_chip_power_limits;
	AH_PRIVATE(ah)->ah_getWirelessModes = ar9300_get_wireless_modes;
	AH_PRIVATE(ah)->ah_getChannelEdges = ar9300_get_channel_edges;

	AH_PRIVATE(ah)->ah_eepromRead = ar9300_eeprom_read_word;
	/* XXX ah_eeprom */
	/* XXX ah_eeversion */
	/* XXX ah_eepromDetach */
	/* XXX ah_eepromGet */
	AH_PRIVATE(ah)->ah_eepromGet = ar9300_eeprom_get_freebsd;
	/* XXX ah_eepromSet */
	/* XXX ah_getSpurChan */
	/* XXX ah_eepromDiag */

	/* 802.11n functions */
	ah->ah_chainTxDesc = ar9300_freebsd_chain_tx_desc;
	ah->ah_setupFirstTxDesc= ar9300_freebsd_setup_first_tx_desc;
	ah->ah_setupLastTxDesc = ar9300_freebsd_setup_last_tx_desc;
	ah->ah_set11nRateScenario = ar9300_freebsd_set_11n_rate_scenario;
	ah->ah_set11nTxDesc = ar9300_freebsd_setup_11n_desc;
	ah->ah_set11nAggrFirst = ar9300_set_11n_aggr_first;
	ah->ah_set11nAggrMiddle = ar9300_set_11n_aggr_middle;
	ah->ah_set11nAggrLast = ar9300_set_11n_aggr_last;
	ah->ah_clr11nAggr = ar9300_clr_11n_aggr;
	ah->ah_set11nBurstDuration = ar9300_set_11n_burst_duration;
	/* ah_get11nExtBusy */
	ah->ah_set11nMac2040 = ar9300_set_11n_mac2040;
	ah->ah_setChainMasks = ar9300SetChainMasks;
	/* ah_get11nRxClear */
	/* ah_set11nRxClear */

	/* bluetooth coexistence functions */
	ah->ah_btCoexSetInfo		= ar9300_set_bt_coex_info;
	ah->ah_btCoexSetConfig		= ar9300_bt_coex_config;
	ah->ah_btCoexSetQcuThresh	= ar9300_bt_coex_set_qcu_thresh;
	ah->ah_btCoexSetWeights		= ar9300_bt_coex_set_weights;
	ah->ah_btCoexSetBmissThresh	= ar9300_bt_coex_setup_bmiss_thresh;
	ah->ah_btCoexSetParameter	= ar9300_bt_coex_set_parameter;
	ah->ah_btCoexDisable		= ar9300_bt_coex_disable;
	ah->ah_btCoexEnable		= ar9300_bt_coex_enable;

	/* MCI bluetooth functions */
	if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
		/*
		 * Note: these are done in attach too for now, because
		 * at this point we haven't yet setup the mac/bb revision
		 * values, so this code is effectively NULL.
		 * However, I'm leaving this here so people digging
		 * into the code (a) see the MCI bits here, and (b)
		 * are now told they should look elsewhere for
		 * these methods.
		 */
		ah->ah_btCoexSetWeights = ar9300_mci_bt_coex_set_weights;
		ah->ah_btCoexDisable = ar9300_mci_bt_coex_disable;
		ah->ah_btCoexEnable = ar9300_mci_bt_coex_enable;
	}
	ah->ah_btMciSetup		= ar9300_mci_setup;
	ah->ah_btMciSendMessage		= ar9300_mci_send_message;
	ah->ah_btMciGetInterrupt	= ar9300_mci_get_interrupt;
	ah->ah_btMciState		= ar9300_mci_state;
	ah->ah_btMciDetach		= ar9300_mci_detach;

	/* LNA diversity functions */
	ah->ah_divLnaConfGet = ar9300_ant_div_comb_get_config;
	ah->ah_divLnaConfSet = ar9300_ant_div_comb_set_config;
}
コード例 #2
0
/*
 * Control Adaptive Noise Immunity Parameters
 */
HAL_BOOL
ar9300_ani_control(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
{
    struct ath_hal_9300 *ahp = AH9300(ah);
    struct ar9300_ani_state *ani_state = ahp->ah_curani;
    const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
    int32_t value, value2;
    u_int level = param;
    u_int is_on;

    if (chan == NULL && cmd != HAL_ANI_MODE) {
        HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
            "%s: ignoring cmd 0x%02x - no channel\n", __func__, cmd);
        return AH_FALSE;
    }

    switch (cmd & ahp->ah_ani_function) {
    case HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION: 
        {
            int m1_thresh_low, m2_thresh_low;
            int m1_thresh, m2_thresh;
            int m2_count_thr, m2_count_thr_low;
            int m1_thresh_low_ext, m2_thresh_low_ext;
            int m1_thresh_ext, m2_thresh_ext;
            /*
             * is_on == 1 means ofdm weak signal detection is ON
             * (default, less noise imm)
             * is_on == 0 means ofdm weak signal detection is OFF
             * (more noise imm)
             */
            is_on = param ? 1 : 0;

            if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah))
                goto skip_ws_det;

            /*
             * make register setting for default (weak sig detect ON)
             * come from INI file
             */
            m1_thresh_low    = is_on ?
                ani_state->ini_def.m1_thresh_low    : m1_thresh_low_off;
            m2_thresh_low    = is_on ?
                ani_state->ini_def.m2_thresh_low    : m2_thresh_low_off;
            m1_thresh       = is_on ?
                ani_state->ini_def.m1_thresh       : m1_thresh_off;
            m2_thresh       = is_on ?
                ani_state->ini_def.m2_thresh       : m2_thresh_off;
            m2_count_thr     = is_on ?
                ani_state->ini_def.m2_count_thr     : m2_count_thr_off;
            m2_count_thr_low  = is_on ?
                ani_state->ini_def.m2_count_thr_low  : m2_count_thr_low_off;
            m1_thresh_low_ext = is_on ?
                ani_state->ini_def.m1_thresh_low_ext : m1_thresh_low_ext_off;
            m2_thresh_low_ext = is_on ?
                ani_state->ini_def.m2_thresh_low_ext : m2_thresh_low_ext_off;
            m1_thresh_ext    = is_on ?
                ani_state->ini_def.m1_thresh_ext    : m1_thresh_ext_off;
            m2_thresh_ext    = is_on ?
                ani_state->ini_def.m2_thresh_ext    : m2_thresh_ext_off;
            OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
                AR_PHY_SFCORR_LOW_M1_THRESH_LOW, m1_thresh_low);
            OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
                AR_PHY_SFCORR_LOW_M2_THRESH_LOW, m2_thresh_low);
            OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR, AR_PHY_SFCORR_M1_THRESH,
                m1_thresh);
            OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR, AR_PHY_SFCORR_M2_THRESH,
                m2_thresh);
            OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR, AR_PHY_SFCORR_M2COUNT_THR,
                m2_count_thr);
            OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
                AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, m2_count_thr_low);
            OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
                AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1_thresh_low_ext);
            OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
                AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2_thresh_low_ext);
            OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, AR_PHY_SFCORR_EXT_M1_THRESH,
                m1_thresh_ext);
            OS_REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, AR_PHY_SFCORR_EXT_M2_THRESH,
                m2_thresh_ext);
skip_ws_det:
            if (is_on) {
                OS_REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
                    AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
            } else {
                OS_REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
                    AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
            }
            if (!(is_on != ani_state->ofdm_weak_sig_detect_off)) {
                HALDEBUG(ah, HAL_DEBUG_ANI,
                    "%s: ** ch %d: ofdm weak signal: %s=>%s\n",
                    __func__, chan->ic_freq,
                    !ani_state->ofdm_weak_sig_detect_off ? "on" : "off",
                    is_on ? "on" : "off");
                if (is_on) {
                    ahp->ah_stats.ast_ani_ofdmon++;
                } else {
                    ahp->ah_stats.ast_ani_ofdmoff++;
                }
                ani_state->ofdm_weak_sig_detect_off = !is_on;
            }
            break;
        }
    case HAL_ANI_FIRSTEP_LEVEL:
        if (level >= ARRAY_LENGTH(firstep_table)) {
            HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
                "%s: HAL_ANI_FIRSTEP_LEVEL level out of range (%u > %u)\n",
                __func__, level, (unsigned) ARRAY_LENGTH(firstep_table));
            return AH_FALSE;
        }
        /*
         * make register setting relative to default
         * from INI file & cap value
         */
        value =
            firstep_table[level] -
            firstep_table[HAL_ANI_DEF_FIRSTEP_LVL] +
            ani_state->ini_def.firstep;
        if (value < HAL_SIG_FIRSTEP_SETTING_MIN) {
            value = HAL_SIG_FIRSTEP_SETTING_MIN;
        }
        if (value > HAL_SIG_FIRSTEP_SETTING_MAX) {
            value = HAL_SIG_FIRSTEP_SETTING_MAX;
        }
        OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, AR_PHY_FIND_SIG_FIRSTEP, value);
        /*
         * we need to set first step low register too
         * make register setting relative to default from INI file & cap value
         */
        value2 =
            firstep_table[level] -
            firstep_table[HAL_ANI_DEF_FIRSTEP_LVL] +
            ani_state->ini_def.firstep_low;
        if (value2 < HAL_SIG_FIRSTEP_SETTING_MIN) {
            value2 = HAL_SIG_FIRSTEP_SETTING_MIN;
        }
        if (value2 > HAL_SIG_FIRSTEP_SETTING_MAX) {
            value2 = HAL_SIG_FIRSTEP_SETTING_MAX;
        }
        OS_REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW,
            AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW, value2);

        if (level != ani_state->firstep_level) {
            HALDEBUG(ah, HAL_DEBUG_ANI,
                "%s: ** ch %d: level %d=>%d[def:%d] firstep[level]=%d ini=%d\n",
                __func__, chan->ic_freq, ani_state->firstep_level, level,
                HAL_ANI_DEF_FIRSTEP_LVL, value, ani_state->ini_def.firstep);
            HALDEBUG(ah, HAL_DEBUG_ANI,
                "%s: ** ch %d: level %d=>%d[def:%d] "
                "firstep_low[level]=%d ini=%d\n",
                __func__, chan->ic_freq, ani_state->firstep_level, level,
                HAL_ANI_DEF_FIRSTEP_LVL, value2,
                ani_state->ini_def.firstep_low);
            if (level > ani_state->firstep_level) {
                ahp->ah_stats.ast_ani_stepup++;
            } else if (level < ani_state->firstep_level) {
                ahp->ah_stats.ast_ani_stepdown++;
            }
            ani_state->firstep_level = level;
        }
        break;
    case HAL_ANI_SPUR_IMMUNITY_LEVEL:
        if (level >= ARRAY_LENGTH(cycpwr_thr1_table)) {
            HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
                "%s: HAL_ANI_SPUR_IMMUNITY_LEVEL level "
                "out of range (%u > %u)\n",
                __func__, level, (unsigned) ARRAY_LENGTH(cycpwr_thr1_table));
            return AH_FALSE;
        }
        /*
         * make register setting relative to default from INI file & cap value
         */
        value =
            cycpwr_thr1_table[level] -
            cycpwr_thr1_table[HAL_ANI_DEF_SPUR_IMMUNE_LVL] +
            ani_state->ini_def.cycpwr_thr1;
        if (value < HAL_SIG_SPUR_IMM_SETTING_MIN) {
            value = HAL_SIG_SPUR_IMM_SETTING_MIN;
        }
        if (value > HAL_SIG_SPUR_IMM_SETTING_MAX) {
            value = HAL_SIG_SPUR_IMM_SETTING_MAX;
        }
        OS_REG_RMW_FIELD(ah, AR_PHY_TIMING5, AR_PHY_TIMING5_CYCPWR_THR1, value);

        /*
         * set AR_PHY_EXT_CCA for extension channel
         * make register setting relative to default from INI file & cap value
         */
        value2 =
            cycpwr_thr1_table[level] -
            cycpwr_thr1_table[HAL_ANI_DEF_SPUR_IMMUNE_LVL] +
            ani_state->ini_def.cycpwr_thr1_ext;
        if (value2 < HAL_SIG_SPUR_IMM_SETTING_MIN) {
            value2 = HAL_SIG_SPUR_IMM_SETTING_MIN;
        }
        if (value2 > HAL_SIG_SPUR_IMM_SETTING_MAX) {
            value2 = HAL_SIG_SPUR_IMM_SETTING_MAX;
        }
        OS_REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, AR_PHY_EXT_CYCPWR_THR1, value2);

        if (level != ani_state->spur_immunity_level) {
            HALDEBUG(ah, HAL_DEBUG_ANI,
                "%s: ** ch %d: level %d=>%d[def:%d] "
                "cycpwr_thr1[level]=%d ini=%d\n",
                __func__, chan->ic_freq, ani_state->spur_immunity_level, level,
                HAL_ANI_DEF_SPUR_IMMUNE_LVL, value,
                ani_state->ini_def.cycpwr_thr1);
            HALDEBUG(ah, HAL_DEBUG_ANI,
                "%s: ** ch %d: level %d=>%d[def:%d] "
                "cycpwr_thr1_ext[level]=%d ini=%d\n",
                __func__, chan->ic_freq, ani_state->spur_immunity_level, level,
                HAL_ANI_DEF_SPUR_IMMUNE_LVL, value2,
                ani_state->ini_def.cycpwr_thr1_ext);
            if (level > ani_state->spur_immunity_level) {
                ahp->ah_stats.ast_ani_spurup++;
            } else if (level < ani_state->spur_immunity_level) {
                ahp->ah_stats.ast_ani_spurdown++;
            }
            ani_state->spur_immunity_level = level;
        }
        break;
    case HAL_ANI_MRC_CCK:
        /*
         * is_on == 1 means MRC CCK ON (default, less noise imm)
         * is_on == 0 means MRC CCK is OFF (more noise imm)
         */
        is_on = param ? 1 : 0;
        if (!AR_SREV_POSEIDON(ah)) {
            OS_REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
                AR_PHY_MRC_CCK_ENABLE, is_on);
            OS_REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
                AR_PHY_MRC_CCK_MUX_REG, is_on);
        }
        if (!(is_on != ani_state->mrc_cck_off)) {
            HALDEBUG(ah, HAL_DEBUG_ANI,
                "%s: ** ch %d: MRC CCK: %s=>%s\n", __func__, chan->ic_freq,
                !ani_state->mrc_cck_off ? "on" : "off", is_on ? "on" : "off");
            if (is_on) {
                ahp->ah_stats.ast_ani_ccklow++;
            } else {
                ahp->ah_stats.ast_ani_cckhigh++;
            }
            ani_state->mrc_cck_off = !is_on;
        }
        break;
    case HAL_ANI_PRESENT:
        break;
#ifdef AH_PRIVATE_DIAG
    case HAL_ANI_MODE:
        if (param == 0) {
            ahp->ah_proc_phy_err &= ~HAL_PROCESS_ANI;
            /* Turn off HW counters if we have them */
            ar9300_ani_detach(ah);
            if (AH_PRIVATE(ah)->ah_curchan == NULL) {
                return AH_TRUE;
            }
            /* if we're turning off ANI, reset regs back to INI settings */
            if (ah->ah_config.ath_hal_enable_ani) {
                HAL_ANI_CMD savefunc = ahp->ah_ani_function;
                /* temporarly allow all functions so we can reset */
                ahp->ah_ani_function = HAL_ANI_ALL;
                HALDEBUG(ah, HAL_DEBUG_ANI,
                    "%s: disable all ANI functions\n", __func__);
                ar9300_ani_set_odfm_noise_immunity_level(
                    ah, HAL_ANI_OFDM_DEF_LEVEL);
                ar9300_ani_set_cck_noise_immunity_level(
                    ah, HAL_ANI_CCK_DEF_LEVEL);
                ahp->ah_ani_function = savefunc;
            }
        } else {            /* normal/auto mode */
            HALDEBUG(ah, HAL_DEBUG_ANI, "%s: enabled\n", __func__);
            ahp->ah_proc_phy_err |= HAL_PROCESS_ANI;
            if (AH_PRIVATE(ah)->ah_curchan == NULL) {
                return AH_TRUE;
            }
            ar9300_enable_mib_counters(ah);
            ar9300_ani_reset(ah, AH_FALSE);
            ani_state = ahp->ah_curani;
        }
        HALDEBUG(ah, HAL_DEBUG_ANI, "5 ANC: ahp->ah_proc_phy_err %x \n",
                 ahp->ah_proc_phy_err);
        break;
    case HAL_ANI_PHYERR_RESET:
        ahp->ah_stats.ast_ani_ofdmerrs = 0;
        ahp->ah_stats.ast_ani_cckerrs = 0;
        break;
#endif /* AH_PRIVATE_DIAG */
    default:
#if HAL_ANI_DEBUG
        HALDEBUG(ah, HAL_DEBUG_ANI,
            "%s: invalid cmd 0x%02x (allowed=0x%02x)\n",
            __func__, cmd, ahp->ah_ani_function);
#endif
        return AH_FALSE;
    }

#if HAL_ANI_DEBUG
    HALDEBUG(ah, HAL_DEBUG_ANI,
        "%s: ANI parameters: SI=%d, ofdm_ws=%s FS=%d MRCcck=%s listen_time=%d "
        "CC=%d listen=%d ofdm_errs=%d cck_errs=%d\n",
        __func__, ani_state->spur_immunity_level,
        !ani_state->ofdm_weak_sig_detect_off ? "on" : "off",
        ani_state->firstep_level, !ani_state->mrc_cck_off ? "on" : "off",
        ani_state->listen_time, ani_state->cycle_count,
        ani_state->listen_time, ani_state->ofdm_phy_err_count,
        ani_state->cck_phy_err_count);
#endif

#ifndef REMOVE_PKT_LOG
    /* do pktlog */
    {
        struct log_ani log_data;

        /* Populate the ani log record */
        log_data.phy_stats_disable = DO_ANI(ah);
        log_data.noise_immun_lvl = ani_state->ofdm_noise_immunity_level;
        log_data.spur_immun_lvl = ani_state->spur_immunity_level;
        log_data.ofdm_weak_det = ani_state->ofdm_weak_sig_detect_off;
        log_data.cck_weak_thr = ani_state->cck_noise_immunity_level;
        log_data.fir_lvl = ani_state->firstep_level;
        log_data.listen_time = ani_state->listen_time;
        log_data.cycle_count = ani_state->cycle_count;
        /* express ofdm_phy_err_count as errors/second */
        log_data.ofdm_phy_err_count = ani_state->listen_time ?
            ani_state->ofdm_phy_err_count * 1000 / ani_state->listen_time : 0;
        /* express cck_phy_err_count as errors/second */
        log_data.cck_phy_err_count =  ani_state->listen_time ?
            ani_state->cck_phy_err_count * 1000 / ani_state->listen_time  : 0;
        log_data.rssi = ani_state->rssi;

        /* clear interrupt context flag */
        ath_hal_log_ani(AH_PRIVATE(ah)->ah_sc, &log_data, 0);
    }
#endif

    return AH_TRUE;
}