Index: head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c =================================================================== --- head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c (revision 346469) +++ head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c (revision 346470) @@ -1,1007 +1,999 @@ /* * Copyright (c) 2012, 2013 Adrian Chadd . * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "opt_ah.h" #include "ah.h" #include "ah_internal.h" #include "ah_devid.h" #include "ah_desc.h" #include "ar9300.h" #include "ar9300reg.h" #include "ar9300phy.h" #include "ar9300desc.h" #include "ar9300_freebsd.h" #include "ar9300_stub.h" #include "ar9300_stub_funcs.h" #define FIX_NOISE_FLOOR 1 #define NEXT_TBTT_NOW 5 static HAL_BOOL ar9300ClrMulticastFilterIndex(struct ath_hal *ah, uint32_t ix); static HAL_BOOL ar9300SetMulticastFilterIndex(struct ath_hal *ah, uint32_t ix); static void ar9300_beacon_set_beacon_timers(struct ath_hal *ah, const HAL_BEACON_TIMERS *bt); static void ar9300SetChainMasks(struct ath_hal *ah, uint32_t tx_chainmask, uint32_t rx_chainmask) { AH9300(ah)->ah_tx_chainmask = tx_chainmask & AH_PRIVATE(ah)->ah_caps.halTxChainMask; AH9300(ah)->ah_rx_chainmask = rx_chainmask & AH_PRIVATE(ah)->ah_caps.halRxChainMask; } static u_int ar9300GetSlotTime(struct ath_hal *ah) { u_int clks = OS_REG_READ(ah, AR_D_GBL_IFS_SLOT) & 0xffff; return (ath_hal_mac_usec(ah, clks)); /* convert from system clocks */ } static HAL_BOOL ar9300_freebsd_set_tx_power_limit(struct ath_hal *ah, uint32_t limit) { return (ar9300_set_tx_power_limit(ah, limit, 0, 0)); } static uint64_t ar9300_get_next_tbtt(struct ath_hal *ah) { return (OS_REG_READ(ah, AR_NEXT_TBTT_TIMER)); } /* * TODO: implement the antenna diversity control for AR9485 and * other LNA mixing based NICs. * * For now we'll just go with the HAL default and make these no-ops. */ static HAL_ANT_SETTING ar9300_freebsd_get_antenna_switch(struct ath_hal *ah) { return (HAL_ANT_VARIABLE); } static HAL_BOOL ar9300_freebsd_set_antenna_switch(struct ath_hal *ah, HAL_ANT_SETTING setting) { return (AH_TRUE); } static u_int ar9300_freebsd_get_cts_timeout(struct ath_hal *ah) { u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_CTS); return ath_hal_mac_usec(ah, clks); /* convert from system clocks */ } static void ar9300_freebsd_set_tsf64(struct ath_hal *ah, uint64_t tsf64) { /* * XXX TODO: read ar5416SetTsf64() - we should wait before we do * this. */ OS_REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff); OS_REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff); } /* Flags for pulse_bw_info */ #define PRI_CH_RADAR_FOUND 0x01 #define EXT_CH_RADAR_FOUND 0x02 #define EXT_CH_RADAR_EARLY_FOUND 0x04 static HAL_BOOL ar9300_freebsd_proc_radar_event(struct ath_hal *ah, struct ath_rx_status *rxs, uint64_t fulltsf, const char *buf, HAL_DFS_EVENT *event) { HAL_BOOL doDfsExtCh; HAL_BOOL doDfsEnhanced; HAL_BOOL doDfsCombinedRssi; uint8_t rssi = 0, ext_rssi = 0; uint8_t pulse_bw_info = 0, pulse_length_ext = 0, pulse_length_pri = 0; uint32_t dur = 0; int pri_found = 1, ext_found = 0; int early_ext = 0; int is_dc = 0; uint16_t datalen; /* length from the RX status field */ /* Check whether the given phy error is a radar event */ if ((rxs->rs_phyerr != HAL_PHYERR_RADAR) && (rxs->rs_phyerr != HAL_PHYERR_FALSE_RADAR_EXT)) { return AH_FALSE; } /* Grab copies of the capabilities; just to make the code clearer */ doDfsExtCh = AH_PRIVATE(ah)->ah_caps.halExtChanDfsSupport; doDfsEnhanced = AH_PRIVATE(ah)->ah_caps.halEnhancedDfsSupport; doDfsCombinedRssi = AH_PRIVATE(ah)->ah_caps.halUseCombinedRadarRssi; datalen = rxs->rs_datalen; /* If hardware supports it, use combined RSSI, else use chain 0 RSSI */ if (doDfsCombinedRssi) rssi = (uint8_t) rxs->rs_rssi; else rssi = (uint8_t) rxs->rs_rssi_ctl[0]; /* Set this; but only use it if doDfsExtCh is set */ ext_rssi = (uint8_t) rxs->rs_rssi_ext[0]; /* Cap it at 0 if the RSSI is a negative number */ if (rssi & 0x80) rssi = 0; if (ext_rssi & 0x80) ext_rssi = 0; /* * Fetch the relevant data from the frame */ if (doDfsExtCh) { if (datalen < 3) return AH_FALSE; /* Last three bytes of the frame are of interest */ pulse_length_pri = *(buf + datalen - 3); pulse_length_ext = *(buf + datalen - 2); pulse_bw_info = *(buf + datalen - 1); HALDEBUG(ah, HAL_DEBUG_DFS, "%s: rssi=%d, ext_rssi=%d, pulse_length_pri=%d," " pulse_length_ext=%d, pulse_bw_info=%x\n", __func__, rssi, ext_rssi, pulse_length_pri, pulse_length_ext, pulse_bw_info); } else { /* The pulse width is byte 0 of the data */ if (datalen >= 1) dur = ((uint8_t) buf[0]) & 0xff; else dur = 0; if (dur == 0 && rssi == 0) { HALDEBUG(ah, HAL_DEBUG_DFS, "%s: dur and rssi are 0\n", __func__); return AH_FALSE; } HALDEBUG(ah, HAL_DEBUG_DFS, "%s: rssi=%d, dur=%d\n", __func__, rssi, dur); /* Single-channel only */ pri_found = 1; ext_found = 0; } /* * If doing extended channel data, pulse_bw_info must * have one of the flags set. */ if (doDfsExtCh && pulse_bw_info == 0x0) return AH_FALSE; /* * If the extended channel data is available, calculate * which to pay attention to. */ if (doDfsExtCh) { /* If pulse is on DC, take the larger duration of the two */ if ((pulse_bw_info & EXT_CH_RADAR_FOUND) && (pulse_bw_info & PRI_CH_RADAR_FOUND)) { is_dc = 1; if (pulse_length_ext > pulse_length_pri) { dur = pulse_length_ext; pri_found = 0; ext_found = 1; } else { dur = pulse_length_pri; pri_found = 1; ext_found = 0; } } else if (pulse_bw_info & EXT_CH_RADAR_EARLY_FOUND) { dur = pulse_length_ext; pri_found = 0; ext_found = 1; early_ext = 1; } else if (pulse_bw_info & PRI_CH_RADAR_FOUND) { dur = pulse_length_pri; pri_found = 1; ext_found = 0; } else if (pulse_bw_info & EXT_CH_RADAR_FOUND) { dur = pulse_length_ext; pri_found = 0; ext_found = 1; } } /* * For enhanced DFS (Merlin and later), pulse_bw_info has * implications for selecting the correct RSSI value. */ if (doDfsEnhanced) { switch (pulse_bw_info & 0x03) { case 0: /* No radar? */ rssi = 0; break; case PRI_CH_RADAR_FOUND: /* Radar in primary channel */ /* Cannot use ctrl channel RSSI if ext channel is stronger */ if (ext_rssi >= (rssi + 3)) { rssi = 0; } break; case EXT_CH_RADAR_FOUND: /* Radar in extended channel */ /* Cannot use ext channel RSSI if ctrl channel is stronger */ if (rssi >= (ext_rssi + 12)) { rssi = 0; } else { rssi = ext_rssi; } break; case (PRI_CH_RADAR_FOUND | EXT_CH_RADAR_FOUND): /* When both are present, use stronger one */ if (rssi < ext_rssi) rssi = ext_rssi; break; } } /* * If not doing enhanced DFS, choose the ext channel if * it is stronger than the main channel */ if (doDfsExtCh && !doDfsEnhanced) { if ((ext_rssi > rssi) && (ext_rssi < 128)) rssi = ext_rssi; } /* * XXX what happens if the above code decides the RSSI * XXX wasn't valid, an sets it to 0? */ /* * Fill out dfs_event structure. */ event->re_full_ts = fulltsf; event->re_ts = rxs->rs_tstamp; event->re_rssi = rssi; event->re_dur = dur; event->re_flags = 0; if (pri_found) event->re_flags |= HAL_DFS_EVENT_PRICH; if (ext_found) event->re_flags |= HAL_DFS_EVENT_EXTCH; if (early_ext) event->re_flags |= HAL_DFS_EVENT_EXTEARLY; if (is_dc) event->re_flags |= HAL_DFS_EVENT_ISDC; return AH_TRUE; } 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_startPcuReceive = ar9300_start_pcu_receive; 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; } HAL_BOOL ar9300_reset_freebsd(struct ath_hal *ah, HAL_OPMODE opmode, struct ieee80211_channel *chan, HAL_BOOL bChannelChange, HAL_RESET_TYPE resetType, HAL_STATUS *status) { HAL_BOOL r; HAL_HT_MACMODE macmode; struct ath_hal_private *ap = AH_PRIVATE(ah); macmode = IEEE80211_IS_CHAN_HT40(chan) ? HAL_HT_MACMODE_2040 : HAL_HT_MACMODE_20; r = ar9300_reset(ah, opmode, chan, macmode, ap->ah_caps.halTxChainMask, ap->ah_caps.halRxChainMask, HAL_HT_EXTPROTSPACING_20, /* always 20Mhz channel spacing */ bChannelChange, status, AH_FALSE); /* XXX should really extend ath_hal_reset() */ return (r); } void ar9300_config_pcie_freebsd(struct ath_hal *ah, HAL_BOOL restore, HAL_BOOL powerOff) { ar9300_config_pci_power_save(ah, restore ? 1 : 0, powerOff ? 1 : 0); } /* * This is a copy from ar9300_eeprom_get(), purely because the FreeBSD * API is very silly and inconsistent. * * The AR93xx HAL doesn't call the eepromGetFlag() function, so this * only occurs for FreeBSD code. * * When I fix this particular API, I'll undo this. */ HAL_STATUS ar9300_eeprom_get_freebsd(struct ath_hal *ah, int param, void *val) { switch (param) { case AR_EEP_FSTCLK_5G: return HAL_OK; default: ath_hal_printf(ah, "%s: called, param=%d\n", __func__, param); return HAL_EIO; } } HAL_BOOL ar9300_stop_tx_dma_freebsd(struct ath_hal *ah, u_int q) { return ar9300_stop_tx_dma(ah, q, 1000); } void ar9300_ani_poll_freebsd(struct ath_hal *ah, const struct ieee80211_channel *chan) { HAL_NODE_STATS stats; HAL_ANISTATS anistats; HAL_SURVEY_SAMPLE survey; OS_MEMZERO(&stats, sizeof(stats)); OS_MEMZERO(&anistats, sizeof(anistats)); OS_MEMZERO(&survey, sizeof(survey)); ar9300_ani_ar_poll(ah, &stats, chan, &anistats); /* * If ANI stats are valid, use them to update the * channel survey. */ if (anistats.valid) { survey.cycle_count = anistats.cyclecnt_diff; survey.chan_busy = anistats.rxclr_cnt; survey.ext_chan_busy = anistats.extrxclr_cnt; survey.tx_busy = anistats.txframecnt_diff; survey.rx_busy = anistats.rxframecnt_diff; ath_hal_survey_add_sample(ah, &survey); } } /* * Setup the configuration parameters in the style the AR9300 HAL * wants. */ void ar9300_config_defaults_freebsd(struct ath_hal *ah, HAL_OPS_CONFIG *ah_config) { /* Until FreeBSD's HAL does this by default - just copy */ OS_MEMCPY(&ah->ah_config, ah_config, sizeof(HAL_OPS_CONFIG)); ah->ah_config.ath_hal_enable_ani = AH_TRUE; } HAL_BOOL ar9300_stop_dma_receive_freebsd(struct ath_hal *ah) { return ar9300_stop_dma_receive(ah, 1000); } HAL_BOOL ar9300_get_pending_interrupts_freebsd(struct ath_hal *ah, HAL_INT *masked) { /* Non-MSI, so no MSI vector; and 'nortc' = 0 */ return ar9300_get_pending_interrupts(ah, masked, HAL_INT_LINE, 0, 0); } HAL_INT ar9300_set_interrupts_freebsd(struct ath_hal *ah, HAL_INT ints) { /* nortc = 0 */ return ar9300_set_interrupts(ah, ints, 0); } HAL_BOOL ar9300_per_calibration_freebsd(struct ath_hal *ah, struct ieee80211_channel *chan, u_int rxchainmask, HAL_BOOL long_cal, HAL_BOOL *isCalDone) { /* XXX fake scheduled calibrations for now */ u_int32_t sched_cals = 0xfffffff; return ar9300_calibration(ah, chan, AH_PRIVATE(ah)->ah_caps.halRxChainMask, long_cal, isCalDone, 0, /* is_scan */ &sched_cals); } HAL_BOOL ar9300_reset_cal_valid_freebsd(struct ath_hal *ah, const struct ieee80211_channel *chan) { HAL_BOOL is_cal_done = AH_TRUE; ar9300_reset_cal_valid(ah, chan, &is_cal_done, 0xffffffff); return (is_cal_done); } - -void -ar9300_start_pcu_receive_freebsd(struct ath_hal *ah) -{ - - /* is_scanning flag == NULL */ - ar9300_start_pcu_receive(ah, AH_FALSE); -} /* * FreeBSD will just pass in the descriptor value as 'pa'. * The Atheros HAL treats 'pa' as the physical address of the RX * descriptor and 'bufaddr' as the physical address of the RX buffer. * I'm not sure why they didn't collapse them - the AR9300 RX descriptor * routine doesn't check 'pa'. */ HAL_STATUS ar9300_proc_rx_desc_freebsd(struct ath_hal *ah, struct ath_desc *ds, uint32_t pa, struct ath_desc *ds_next, uint64_t tsf, struct ath_rx_status *rxs) { return (ar9300_proc_rx_desc_fast(ah, ds, 0, ds_next, rxs, (void *) ds)); } /* * This is the primary way the ANI code gets the node statistics per packet. */ void ar9300_ani_rxmonitor_freebsd(struct ath_hal *ah, const HAL_NODE_STATS *stats, const struct ieee80211_channel *chan) { struct ath_hal_9300 *ahp = AH9300(ah); ahp->ah_stats.ast_nodestats.ns_avgbrssi = stats->ns_avgbrssi; } void ar9300_freebsd_get_desc_link(struct ath_hal *ah, void *ds, uint32_t *link) { struct ar9300_txc *ads = AR9300TXC(ds); (*link) = ads->ds_link; } /* * TX descriptor field setting wrappers - eek. */ HAL_BOOL ar9300_freebsd_setup_tx_desc(struct ath_hal *ah, struct ath_desc *ds, u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type, u_int txPower, u_int txRate0, u_int txTries0, u_int keyIx, u_int antMode, u_int flags, u_int rtsctsRate, u_int rtsCtsDuration, u_int compicvLen, u_int compivLen, u_int comp) { struct ath_hal_9300 *ahp = AH9300(ah); HAL_KEY_TYPE keyType = 0; /* XXX No padding */ if (keyIx != HAL_TXKEYIX_INVALID) keyType = ahp->ah_keytype[keyIx]; /* XXX bounds check keyix */ ar9300_set_11n_tx_desc(ah, ds, pktLen, type, txPower, keyIx, keyType, flags); return AH_TRUE; } HAL_BOOL ar9300_freebsd_setup_x_tx_desc(struct ath_hal *ah, struct ath_desc *ds, u_int txRate1, u_int txTries1, u_int txRate2, u_int txTries2, u_int txRate3, u_int txTries3) { #if 0 ath_hal_printf(ah, "%s: called, 0x%x/%d, 0x%x/%d, 0x%x/%d\n", __func__, txRate1, txTries1, txRate2, txTries2, txRate3, txTries3); #endif /* XXX should only be called during probe */ return (AH_TRUE); } HAL_BOOL ar9300_freebsd_fill_tx_desc(struct ath_hal *ah, struct ath_desc *ds, HAL_DMA_ADDR *bufListPtr, uint32_t *segLenPtr, u_int descId, u_int qid, HAL_BOOL firstSeg, HAL_BOOL lastSeg, const struct ath_desc *ds0) { HAL_KEY_TYPE keyType = 0; const struct ar9300_txc *ads = AR9300TXC_CONST(ds0); /* * FreeBSD's HAL doesn't pass the keytype to fill_tx_desc(); * it's copied as part of the descriptor chaining. * * So, extract it from ds0. */ keyType = MS(ads->ds_ctl17, AR_encr_type); return ar9300_fill_tx_desc(ah, ds, bufListPtr, segLenPtr, descId, qid, keyType, firstSeg, lastSeg, ds0); } HAL_BOOL ar9300_freebsd_get_tx_completion_rates(struct ath_hal *ah, const struct ath_desc *ds0, int *rates, int *tries) { ath_hal_printf(ah, "%s: called\n", __func__); return AH_FALSE; /* XXX for now */ } /* * 802.11n TX descriptor wrappers */ void ar9300_freebsd_set_11n_rate_scenario(struct ath_hal *ah, struct ath_desc *ds, u_int durUpdateEn, u_int rtsctsRate, HAL_11N_RATE_SERIES series[], u_int nseries, u_int flags) { /* lastds=NULL, rtscts_duration is 0, smart antenna is 0 */ ar9300_set_11n_rate_scenario(ah, (void *) ds, (void *)ds, durUpdateEn, rtsctsRate, 0, series, nseries, flags, 0); } /* chaintxdesc */ HAL_BOOL ar9300_freebsd_chain_tx_desc(struct ath_hal *ah, struct ath_desc *ds, HAL_DMA_ADDR *bufLenList, uint32_t *segLenList, u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type, u_int keyIx, HAL_CIPHER cipher, uint8_t numDelims, HAL_BOOL firstSeg, HAL_BOOL lastSeg, HAL_BOOL lastAggr) { ath_hal_printf(ah, "%s: called\n", __func__); return AH_FALSE; } /* setupfirsttxdesc */ HAL_BOOL ar9300_freebsd_setup_first_tx_desc(struct ath_hal *ah, struct ath_desc *ds, u_int aggrLen, u_int flags, u_int txPower, u_int txRate0, u_int txTries0, u_int antMode, u_int rtsctsRate, u_int rtsctsDuration) { ath_hal_printf(ah, "%s: called\n", __func__); return AH_FALSE; } /* setuplasttxdesc */ /* * This gets called but for now let's not log anything; * it's only used to update the rate control information. */ HAL_BOOL ar9300_freebsd_setup_last_tx_desc(struct ath_hal *ah, struct ath_desc *ds, const struct ath_desc *ds0) { // ath_hal_printf(ah, "%s: called\n", __func__); return AH_FALSE; } void ar9300_freebsd_setup_11n_desc(struct ath_hal *ah, void *ds, u_int pktLen, HAL_PKT_TYPE type, u_int txPower, u_int keyIx, u_int flags) { ath_hal_printf(ah, "%s: called\n", __func__); #if 0 struct ath_hal_9300 *ahp = AH9300(ah); HAL_KEY_TYPE keyType = 0; /* XXX No padding */ if (keyIx != HAL_TXKEYIX_INVALID) keyType = ahp->ah_keytype[keyIx]; /* XXX bounds check keyix */ ar9300_set_11n_tx_desc(ah, ds, pktLen, type, txPower, keyIx, keyType, flags); #endif } HAL_STATUS ar9300_freebsd_proc_tx_desc(struct ath_hal *ah, struct ath_desc *ds, struct ath_tx_status *ts) { return ar9300_proc_tx_desc(ah, ts); } void ar9300_freebsd_beacon_init(struct ath_hal *ah, uint32_t next_beacon, uint32_t beacon_period) { ar9300_beacon_init(ah, next_beacon, beacon_period, 0, AH_PRIVATE(ah)->ah_opmode); } HAL_BOOL ar9300_freebsd_get_mib_cycle_counts(struct ath_hal *ah, HAL_SURVEY_SAMPLE *hs) { return (AH_FALSE); } /* * Clear multicast filter by index - from FreeBSD ar5212_recv.c */ static HAL_BOOL ar9300ClrMulticastFilterIndex(struct ath_hal *ah, uint32_t ix) { uint32_t val; if (ix >= 64) return (AH_FALSE); if (ix >= 32) { val = OS_REG_READ(ah, AR_MCAST_FIL1); OS_REG_WRITE(ah, AR_MCAST_FIL1, (val &~ (1<<(ix-32)))); } else { val = OS_REG_READ(ah, AR_MCAST_FIL0); OS_REG_WRITE(ah, AR_MCAST_FIL0, (val &~ (1<= 64) return (AH_FALSE); if (ix >= 32) { val = OS_REG_READ(ah, AR_MCAST_FIL1); OS_REG_WRITE(ah, AR_MCAST_FIL1, (val | (1<<(ix-32)))); } else { val = OS_REG_READ(ah, AR_MCAST_FIL0); OS_REG_WRITE(ah, AR_MCAST_FIL0, (val | (1<bt_nexttbtt)); OS_REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, ONE_EIGHTH_TU_TO_USEC(bt->bt_nextdba)); OS_REG_WRITE(ah, AR_NEXT_SWBA, ONE_EIGHTH_TU_TO_USEC(bt->bt_nextswba)); OS_REG_WRITE(ah, AR_NEXT_NDP_TIMER, TU_TO_USEC(bt->bt_nextatim)); bperiod = TU_TO_USEC(bt->bt_intval & HAL_BEACON_PERIOD); AH9300(ah)->ah_beaconInterval = bt->bt_intval & HAL_BEACON_PERIOD; OS_REG_WRITE(ah, AR_BEACON_PERIOD, bperiod); OS_REG_WRITE(ah, AR_DMA_BEACON_PERIOD, bperiod); OS_REG_WRITE(ah, AR_SWBA_PERIOD, bperiod); OS_REG_WRITE(ah, AR_NDP_PERIOD, bperiod); /* * Reset TSF if required. */ if (bt->bt_intval & HAL_BEACON_RESET_TSF) ar9300_reset_tsf(ah); /* enable timers */ /* NB: flags == 0 handled specially for backwards compatibility */ OS_REG_SET_BIT(ah, AR_TIMER_MODE, bt->bt_flags != 0 ? bt->bt_flags : AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN); } /* * RF attach stubs */ static HAL_BOOL rf9330_attach(struct ath_hal *ah, HAL_STATUS *status) { (*status) = HAL_EINVAL; return (AH_FALSE); } static HAL_BOOL rf9330_probe(struct ath_hal *ah) { return (AH_FALSE); } AH_RF(RF9330, rf9330_probe, rf9330_attach); Index: head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_stub_funcs.c =================================================================== --- head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_stub_funcs.c (revision 346469) +++ head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_stub_funcs.c (revision 346470) @@ -1,1257 +1,1257 @@ /* * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting * Copyright (c) 2002-2008 Atheros Communications, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $FreeBSD: head/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c 235972 2012-05-25 05:01:27Z adrian $ */ #include "opt_ah.h" #include "ah.h" #include "ah_internal.h" #include "ah_devid.h" #include "ar9300/ar9300.h" #include "ar9300/ar9300reg.h" #include "ar9300/ar9300phy.h" #include "ar9300/ar9300_stub.h" #include "ar9300/ar9300_stub_funcs.h" uint32_t ar9300_Stub_GetRadioRev(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } #if 0 void ar9300_Stub_InitState(struct ath_hal_5212 *, uint16_t devid, HAL_SOFTC, HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status) { ath_hal_printf(ah, "%s: called\n", __func__); return; } #endif void ar9300_Stub_Detach(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return; } HAL_BOOL ar9300_Stub_ChipTest(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_GetChannelEdges(struct ath_hal *ah, uint16_t flags, uint16_t *low, uint16_t *high) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_FillCapabilityInfo(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } void ar9300_Stub_SetBeaconTimers(struct ath_hal *ah, const HAL_BEACON_TIMERS * bs) { ath_hal_printf(ah, "%s: called\n", __func__); } void ar9300_Stub_BeaconInit(struct ath_hal *ah, uint32_t next_beacon, uint32_t beacon_period) { ath_hal_printf(ah, "%s: called\n", __func__); } void ar9300_Stub_ResetStaBeaconTimers(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); } void ar9300_Stub_SetStaBeaconTimers(struct ath_hal *ah, const HAL_BEACON_STATE *bs) { ath_hal_printf(ah, "%s: called\n", __func__); } uint64_t ar9300_Stub_GetNextTBTT(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } HAL_BOOL ar9300_Stub_IsInterruptPending(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_GetPendingInterrupts(struct ath_hal *ah, HAL_INT *mask) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_INT ar9300_Stub_GetInterrupts(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } HAL_INT ar9300_Stub_SetInterrupts(struct ath_hal *ah, HAL_INT ints) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } uint32_t ar9300_Stub_GetKeyCacheSize(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } HAL_BOOL ar9300_Stub_IsKeyCacheEntryValid(struct ath_hal *ah, uint16_t entry) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_ResetKeyCacheEntry(struct ath_hal *ah, uint16_t entry) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_SetKeyCacheEntryMac(struct ath_hal *ah, uint16_t entry, const uint8_t *mac) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_SetKeyCacheEntry(struct ath_hal *ah, uint16_t entry, const HAL_KEYVAL *k, const uint8_t *mac, int xorKey) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } void ar9300_Stub_GetMacAddress(struct ath_hal *ah, uint8_t *mac) { ath_hal_printf(ah, "%s: called\n", __func__); } HAL_BOOL ar9300_Stub_SetMacAddress(struct ath_hal *ah, const uint8_t *mac) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } void ar9300_Stub_GetBssIdMask(struct ath_hal *ah, uint8_t *mac) { ath_hal_printf(ah, "%s: called\n", __func__); } HAL_BOOL ar9300_Stub_SetBssIdMask(struct ath_hal *ah, const uint8_t *bssid) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_EepromRead(struct ath_hal *ah, u_int off, uint16_t *data) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_EepromWrite(struct ath_hal *ah, u_int off, uint16_t data) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_SetRegulatoryDomain(struct ath_hal *ah, uint16_t regDomain, HAL_STATUS *stats) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } u_int ar9300_Stub_GetWirelessModes(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); /* XXX map these */ return (0); } void ar9300_Stub_EnableRfKill(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); } HAL_BOOL ar9300_Stub_GpioCfgOutput(struct ath_hal *ah, uint32_t gpio, HAL_GPIO_MUX_TYPE mux) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_GpioCfgInput(struct ath_hal *ah, uint32_t gpio) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_GpioSet(struct ath_hal *ah, uint32_t gpio, uint32_t val) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } uint32_t ar9300_Stub_GpioGet(struct ath_hal *ah, uint32_t gpio) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } void ar9300_Stub_GpioSetIntr(struct ath_hal *ah, u_int gpioPin, uint32_t ilevel) { ath_hal_printf(ah, "%s: called\n", __func__); } void ar9300_Stub_SetLedState(struct ath_hal *ah, HAL_LED_STATE state) { ath_hal_printf(ah, "%s: called\n", __func__); } void ar9300_Stub_WriteAssocid(struct ath_hal *ah, const uint8_t *bssid, uint16_t assocId) { ath_hal_printf(ah, "%s: called\n", __func__); } uint32_t ar9300_Stub_GetTsf32(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } uint64_t ar9300_Stub_GetTsf64(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } void ar9300_Stub_SetTsf64(struct ath_hal *ah, uint64_t tsf64) { ath_hal_printf(ah, "%s: called\n", __func__); } void ar9300_Stub_ResetTsf(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); } void ar9300_Stub_SetBasicRate(struct ath_hal *ah, HAL_RATE_SET *pSet) { ath_hal_printf(ah, "%s: called\n", __func__); } uint32_t ar9300_Stub_GetRandomSeed(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } HAL_BOOL ar9300_Stub_DetectCardPresent(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_TRUE); } void ar9300_Stub_EnableMibCounters(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); } void ar9300_Stub_DisableMibCounters(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); } void ar9300_Stub_UpdateMibCounters(struct ath_hal *ah, HAL_MIB_STATS* stats) { ath_hal_printf(ah, "%s: called\n", __func__); } HAL_BOOL ar9300_Stub_IsJapanChannelSpreadSupported(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } uint32_t ar9300_Stub_GetCurRssi(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } u_int ar9300_Stub_GetDefAntenna(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } void ar9300_Stub_SetDefAntenna(struct ath_hal *ah, u_int antenna) { ath_hal_printf(ah, "%s: called\n", __func__); } HAL_ANT_SETTING ar9300_Stub_GetAntennaSwitch(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (HAL_ANT_VARIABLE); } HAL_BOOL ar9300_Stub_SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING setting) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_IsSleepAfterBeaconBroken(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_SetSifsTime(struct ath_hal *ah, u_int sifs) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } u_int ar9300_Stub_GetSifsTime(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } HAL_BOOL ar9300_Stub_SetSlotTime(struct ath_hal *ah, u_int slottime) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } u_int ar9300_Stub_GetSlotTime(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } HAL_BOOL ar9300_Stub_SetAckTimeout(struct ath_hal *ah, u_int acktimeout) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } u_int ar9300_Stub_GetAckTimeout(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } HAL_BOOL ar9300_Stub_SetAckCTSRate(struct ath_hal *ah, u_int ctsrate) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } u_int ar9300_Stub_GetAckCTSRate(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } HAL_BOOL ar9300_Stub_SetCTSTimeout(struct ath_hal *ah, u_int ctstimeout) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } u_int ar9300_Stub_GetCTSTimeout(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } HAL_BOOL ar9300_Stub_SetDecompMask(struct ath_hal *ah, uint16_t a, int b) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } void ar9300_Stub_SetCoverageClass(struct ath_hal *ah, uint8_t a, int b) { ath_hal_printf(ah, "%s: called\n", __func__); } void ar9300_Stub_SetPCUConfig(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); } HAL_BOOL ar9300_Stub_Use32KHzclock(struct ath_hal *ah, HAL_OPMODE opmode) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } void ar9300_Stub_SetupClock(struct ath_hal *ah, HAL_OPMODE opmode) { ath_hal_printf(ah, "%s: called\n", __func__); } void ar9300_Stub_RestoreClock(struct ath_hal *ah, HAL_OPMODE opmode) { ath_hal_printf(ah, "%s: called\n", __func__); } int16_t ar9300_Stub_GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *ichan) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } void ar9300_Stub_SetCompRegs(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); } HAL_STATUS ar9300_Stub_GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE ctype, uint32_t which, uint32_t *val) { ath_hal_printf(ah, "%s: called\n", __func__); return (HAL_EIO); } HAL_BOOL ar9300_Stub_SetCapability(struct ath_hal *ah , HAL_CAPABILITY_TYPE ctype, uint32_t which, uint32_t val, HAL_STATUS *status) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_GetDiagState(struct ath_hal *ah, int request, const void *args, uint32_t argsize, void **result, uint32_t *resultsize) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_STATUS ar9300_Stub_SetQuiet(struct ath_hal *ah, uint32_t period, uint32_t duration, uint32_t nextStart, HAL_QUIET_FLAG flag) { ath_hal_printf(ah, "%s: called\n", __func__); return (HAL_EIO); } HAL_BOOL ar9300_Stub_GetMibCycleCounts(struct ath_hal *ah, HAL_SURVEY_SAMPLE *hs) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode, int setChip) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_POWER_MODE ar9300_Stub_GetPowerMode(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (HAL_PM_AWAKE); } HAL_BOOL ar9300_Stub_GetPowerStatus(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } uint32_t ar9300_Stub_GetRxDP(struct ath_hal *ah, HAL_RX_QUEUE qtype) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } void ar9300_Stub_SetRxDP(struct ath_hal *ah, uint32_t rxdp, HAL_RX_QUEUE qtype) { ath_hal_printf(ah, "%s: called\n", __func__); } void ar9300_Stub_EnableReceive(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); } HAL_BOOL ar9300_Stub_StopDmaReceive(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } void -ar9300_Stub_StartPcuReceive(struct ath_hal *ah) +ar9300_Stub_StartPcuReceive(struct ath_hal *ah, HAL_BOOL is_scanning) { ath_hal_printf(ah, "%s: called\n", __func__); } void ar9300_Stub_StopPcuReceive(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); } void ar9300_Stub_SetMulticastFilter(struct ath_hal *ah, uint32_t filter0, uint32_t filter1) { ath_hal_printf(ah, "%s: called\n", __func__); } HAL_BOOL ar9300_Stub_ClrMulticastFilterIndex(struct ath_hal *ah, uint32_t ix) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_SetMulticastFilterIndex(struct ath_hal *ah, uint32_t ix) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } uint32_t ar9300_Stub_GetRxFilter(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } void ar9300_Stub_SetRxFilter(struct ath_hal *ah, uint32_t bits) { ath_hal_printf(ah, "%s: called\n", __func__); } HAL_BOOL ar9300_Stub_SetupRxDesc(struct ath_hal *ah, struct ath_desc *rxdesc, uint32_t size, u_int flags) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_STATUS ar9300_Stub_ProcRxDesc(struct ath_hal *ah, struct ath_desc *desc0, uint32_t a, struct ath_desc *desc, uint64_t tsf, struct ath_rx_status *rxstat) { ath_hal_printf(ah, "%s: called\n", __func__); return (HAL_EIO); } HAL_BOOL ar9300_Stub_Reset(struct ath_hal *ah, HAL_OPMODE opmode, struct ieee80211_channel *chan, HAL_BOOL bChannelChange, HAL_RESET_TYPE resetType, HAL_STATUS *status) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } void ar9300_Stub_SetOperatingMode(struct ath_hal *ah, int opmode) { ath_hal_printf(ah, "%s: called\n", __func__); } HAL_BOOL ar9300_Stub_PhyDisable(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_Disable(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_ChipReset(struct ath_hal *ah, const struct ieee80211_channel *chan) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_PerCalibration(struct ath_hal *ah, struct ieee80211_channel *chan, HAL_BOOL *isIQdone) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_PerCalibrationN(struct ath_hal *ah, struct ieee80211_channel *chan, u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_ResetCalValid(struct ath_hal *ah, const struct ieee80211_channel *chan) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } int16_t ar9300_Stub_GetNoiseFloor(struct ath_hal *ah) { /* XXX */ ath_hal_printf(ah, "%s: called\n", __func__); return (-91); } void ar9300_Stub_InitNfCalHistBuffer(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); } int16_t ar9300_Stub_GetNfHistMid(const int16_t calData[]) { printf("%s: called\n", __func__); return (0); } void ar9300_Stub_SetSpurMitigation(struct ath_hal *ah, const struct ieee80211_channel *chan) { ath_hal_printf(ah, "%s: called\n", __func__); } HAL_BOOL ar9300_Stub_SetAntennaSwitchInternal(struct ath_hal *ah, HAL_ANT_SETTING settings, const struct ieee80211_channel *chan) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_SetTxPowerLimit(struct ath_hal *ah, uint32_t limit) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_GetChipPowerLimits(struct ath_hal *ah, struct ieee80211_channel *chan) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } void ar9300_Stub_InitializeGainValues(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); } HAL_RFGAIN ar9300_Stub_GetRfgain(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } void ar9300_Stub_RequestRfgain(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); } HAL_BOOL ar9300_Stub_UpdateTxTrigLevel(struct ath_hal *ah, HAL_BOOL IncTrigLevel) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_SetTxQueueProps(struct ath_hal *ah, int q, const HAL_TXQ_INFO *qInfo) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_GetTxQueueProps(struct ath_hal *ah, int q, HAL_TXQ_INFO *qInfo) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } int ar9300_Stub_SetupTxQueue(struct ath_hal *ah, HAL_TX_QUEUE type, const HAL_TXQ_INFO *qInfo) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } HAL_BOOL ar9300_Stub_ReleaseTxQueue(struct ath_hal *ah, u_int q) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_ResetTxQueue(struct ath_hal *ah, u_int q) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } uint32_t ar9300_Stub_GetTxDP(struct ath_hal *ah, u_int q) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } HAL_BOOL ar9300_Stub_SetTxDP(struct ath_hal *ah, u_int q, uint32_t txdp) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_StartTxDma(struct ath_hal *ah, u_int q) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } uint32_t ar9300_Stub_NumTxPending(struct ath_hal *ah, u_int q) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } HAL_BOOL ar9300_Stub_StopTxDma(struct ath_hal *ah, u_int q) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds, u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type, u_int txPower, u_int txRate0, u_int txTries0, u_int keyIx, u_int antMode, u_int flags, u_int rtsctsRate, u_int rtsctsDuration, u_int compicvLen, u_int compivLen, u_int comp) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_SetupXTxDesc(struct ath_hal *ah, struct ath_desc *desc, u_int txRate1, u_int txRetries1, u_int txRate2, u_int txRetries2, u_int txRate3, u_int txRetries3) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_FillTxDesc(struct ath_hal *ah, struct ath_desc *ds, HAL_DMA_ADDR *bufAddrList, uint32_t *segLenList, u_int descId, u_int qcuId, HAL_BOOL firstSeg, HAL_BOOL lastSeg, const struct ath_desc *ds0) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_STATUS ar9300_Stub_ProcTxDesc(struct ath_hal *ah, struct ath_desc *ds, struct ath_tx_status *txstat) { ath_hal_printf(ah, "%s: called\n", __func__); return (HAL_EINPROGRESS); } void ar9300_Stub_GetTxIntrQueue(struct ath_hal *ah, uint32_t *val) { ath_hal_printf(ah, "%s: called\n", __func__); } void ar9300_Stub_IntrReqTxDesc(struct ath_hal *ah, struct ath_desc *desc) { ath_hal_printf(ah, "%s: called\n", __func__); } HAL_BOOL ar9300_Stub_GetTxCompletionRates(struct ath_hal *ah, const struct ath_desc *ds0, int *rates, int *tries) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } const HAL_RATE_TABLE * ar9300_Stub_GetRateTable(struct ath_hal *ah, u_int mode) { ath_hal_printf(ah, "%s: called\n", __func__); /* XXX null may panic the kernel? */ return (AH_NULL); } #if 0 void ar9300_Stub_AniAttach(struct ath_hal *ah, const struct ar5212AniParams *, const struct ar5212AniParams *, HAL_BOOL ena) { ath_hal_printf(ah, "%s: called\n", __func__); } void ar9300_Stub_AniDetach(struct ath_hal *) { ath_hal_printf(ah, "%s: called\n", __func__); } #endif #if 0 struct ar5212AniState * ar9300_Stub_AniGetCurrentState(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_NULL); } struct ar5212Stats *ar5212AniGetCurrentStats(struct ath_hal *) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_NULL); } #endif HAL_BOOL ar9300_Stub_AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } #if 0 HAL_BOOL ar9300_Stub_AniSetParams(struct ath_hal *, const struct ar5212AniParams *, const struct ar5212AniParams *) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } #endif struct ath_rx_status; void ar9300_Stub_AniPhyErrReport(struct ath_hal *ah, const struct ath_rx_status *rs) { ath_hal_printf(ah, "%s: called\n", __func__); return; } void ar9300_Stub_ProcessMibIntr(struct ath_hal *ah, const HAL_NODE_STATS *stats) { ath_hal_printf(ah, "%s: called\n", __func__); } void ar9300_Stub_RxMonitor(struct ath_hal *ah, const HAL_NODE_STATS *stats, const struct ieee80211_channel *chan) { ath_hal_printf(ah, "%s: called\n", __func__); } void ar9300_Stub_AniPoll(struct ath_hal *ah, const struct ieee80211_channel * chan) { ath_hal_printf(ah, "%s: called\n", __func__); } void ar9300_Stub_AniReset(struct ath_hal *ah, const struct ieee80211_channel * chan, HAL_OPMODE ani_opmode, int val) { ath_hal_printf(ah, "%s: called\n", __func__); } HAL_BOOL ar9300_Stub_IsNFCalInProgress(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_WaitNFCalComplete(struct ath_hal *ah, int i) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } void ar9300_Stub_EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe) { ath_hal_printf(ah, "%s: called\n", __func__); } void ar9300_Stub_GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe) { ath_hal_printf(ah, "%s: called\n", __func__); } HAL_BOOL ar9300_Stub_ProcessRadarEvent(struct ath_hal *ah, struct ath_rx_status *rxs, uint64_t fulltsf, const char *buf, HAL_DFS_EVENT *event) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } HAL_BOOL ar9300_Stub_IsFastClockEnabled(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (AH_FALSE); } uint32_t ar9300_Stub_Get11nExtBusy(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); return (0); } void ar9300_Stub_ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore, HAL_BOOL powerOff) { ath_hal_printf(ah, "%s: called\n", __func__); } void ar9300_Stub_DisablePCIE(struct ath_hal *ah) { ath_hal_printf(ah, "%s: called\n", __func__); } Index: head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_stub_funcs.h =================================================================== --- head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_stub_funcs.h (revision 346469) +++ head/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_stub_funcs.h (revision 346470) @@ -1,238 +1,238 @@ #ifndef __AR9300_STUB_FUNCS_H__ #define __AR9300_STUB_FUNCS_H__ extern uint32_t ar9300_Stub_GetRadioRev(struct ath_hal *ah); #if 0 extern void ar9300_Stub_InitState(struct ath_hal_5212 *, uint16_t devid, HAL_SOFTC, HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status); #endif extern void ar9300_Stub_Detach(struct ath_hal *ah); extern HAL_BOOL ar9300_Stub_ChipTest(struct ath_hal *ah); extern HAL_BOOL ar9300_Stub_GetChannelEdges(struct ath_hal *ah, uint16_t flags, uint16_t *low, uint16_t *high); extern HAL_BOOL ar9300_Stub_FillCapabilityInfo(struct ath_hal *ah); extern void ar9300_Stub_SetBeaconTimers(struct ath_hal *ah, const HAL_BEACON_TIMERS *); extern void ar9300_Stub_BeaconInit(struct ath_hal *ah, uint32_t next_beacon, uint32_t beacon_period); extern void ar9300_Stub_ResetStaBeaconTimers(struct ath_hal *ah); extern void ar9300_Stub_SetStaBeaconTimers(struct ath_hal *ah, const HAL_BEACON_STATE *); extern uint64_t ar9300_Stub_GetNextTBTT(struct ath_hal *); extern HAL_BOOL ar9300_Stub_IsInterruptPending(struct ath_hal *ah); extern HAL_BOOL ar9300_Stub_GetPendingInterrupts(struct ath_hal *ah, HAL_INT *); extern HAL_INT ar9300_Stub_GetInterrupts(struct ath_hal *ah); extern HAL_INT ar9300_Stub_SetInterrupts(struct ath_hal *ah, HAL_INT ints); extern uint32_t ar9300_Stub_GetKeyCacheSize(struct ath_hal *); extern HAL_BOOL ar9300_Stub_IsKeyCacheEntryValid(struct ath_hal *, uint16_t entry); extern HAL_BOOL ar9300_Stub_ResetKeyCacheEntry(struct ath_hal *ah, uint16_t entry); extern HAL_BOOL ar9300_Stub_SetKeyCacheEntryMac(struct ath_hal *, uint16_t entry, const uint8_t *mac); extern HAL_BOOL ar9300_Stub_SetKeyCacheEntry(struct ath_hal *ah, uint16_t entry, const HAL_KEYVAL *k, const uint8_t *mac, int xorKey); extern void ar9300_Stub_GetMacAddress(struct ath_hal *ah, uint8_t *mac); extern HAL_BOOL ar9300_Stub_SetMacAddress(struct ath_hal *ah, const uint8_t *); extern void ar9300_Stub_GetBssIdMask(struct ath_hal *ah, uint8_t *mac); extern HAL_BOOL ar9300_Stub_SetBssIdMask(struct ath_hal *, const uint8_t *); extern HAL_BOOL ar9300_Stub_EepromRead(struct ath_hal *, u_int off, uint16_t *data); extern HAL_BOOL ar9300_Stub_EepromWrite(struct ath_hal *, u_int off, uint16_t data); extern HAL_BOOL ar9300_Stub_SetRegulatoryDomain(struct ath_hal *ah, uint16_t regDomain, HAL_STATUS *stats); extern u_int ar9300_Stub_GetWirelessModes(struct ath_hal *ah); extern void ar9300_Stub_EnableRfKill(struct ath_hal *); extern HAL_BOOL ar9300_Stub_GpioCfgOutput(struct ath_hal *, uint32_t gpio, HAL_GPIO_MUX_TYPE); extern HAL_BOOL ar9300_Stub_GpioCfgInput(struct ath_hal *, uint32_t gpio); extern HAL_BOOL ar9300_Stub_GpioSet(struct ath_hal *, uint32_t gpio, uint32_t val); extern uint32_t ar9300_Stub_GpioGet(struct ath_hal *ah, uint32_t gpio); extern void ar9300_Stub_GpioSetIntr(struct ath_hal *ah, u_int, uint32_t ilevel); extern void ar9300_Stub_SetLedState(struct ath_hal *ah, HAL_LED_STATE state); extern void ar9300_Stub_WriteAssocid(struct ath_hal *ah, const uint8_t *bssid, uint16_t assocId); extern uint32_t ar9300_Stub_GetTsf32(struct ath_hal *ah); extern uint64_t ar9300_Stub_GetTsf64(struct ath_hal *ah); extern void ar9300_Stub_SetTsf64(struct ath_hal *ah, uint64_t tsf64); extern void ar9300_Stub_ResetTsf(struct ath_hal *ah); extern void ar9300_Stub_SetBasicRate(struct ath_hal *ah, HAL_RATE_SET *pSet); extern uint32_t ar9300_Stub_GetRandomSeed(struct ath_hal *ah); extern HAL_BOOL ar9300_Stub_DetectCardPresent(struct ath_hal *ah); extern void ar9300_Stub_EnableMibCounters(struct ath_hal *); extern void ar9300_Stub_DisableMibCounters(struct ath_hal *); extern void ar9300_Stub_UpdateMibCounters(struct ath_hal *ah, HAL_MIB_STATS* stats); extern HAL_BOOL ar9300_Stub_IsJapanChannelSpreadSupported(struct ath_hal *ah); extern uint32_t ar9300_Stub_GetCurRssi(struct ath_hal *ah); extern u_int ar9300_Stub_GetDefAntenna(struct ath_hal *ah); extern void ar9300_Stub_SetDefAntenna(struct ath_hal *ah, u_int antenna); extern HAL_ANT_SETTING ar9300_Stub_GetAntennaSwitch(struct ath_hal *); extern HAL_BOOL ar9300_Stub_SetAntennaSwitch(struct ath_hal *, HAL_ANT_SETTING); extern HAL_BOOL ar9300_Stub_IsSleepAfterBeaconBroken(struct ath_hal *ah); extern HAL_BOOL ar9300_Stub_SetSifsTime(struct ath_hal *, u_int); extern u_int ar9300_Stub_GetSifsTime(struct ath_hal *); extern HAL_BOOL ar9300_Stub_SetSlotTime(struct ath_hal *, u_int); extern u_int ar9300_Stub_GetSlotTime(struct ath_hal *); extern HAL_BOOL ar9300_Stub_SetAckTimeout(struct ath_hal *, u_int); extern u_int ar9300_Stub_GetAckTimeout(struct ath_hal *); extern HAL_BOOL ar9300_Stub_SetAckCTSRate(struct ath_hal *, u_int); extern u_int ar9300_Stub_GetAckCTSRate(struct ath_hal *); extern HAL_BOOL ar9300_Stub_SetCTSTimeout(struct ath_hal *, u_int); extern u_int ar9300_Stub_GetCTSTimeout(struct ath_hal *); extern HAL_BOOL ar9300_Stub_SetDecompMask(struct ath_hal *, uint16_t, int); void ar9300_Stub_SetCoverageClass(struct ath_hal *, uint8_t, int); extern void ar9300_Stub_SetPCUConfig(struct ath_hal *); extern HAL_BOOL ar9300_Stub_Use32KHzclock(struct ath_hal *ah, HAL_OPMODE opmode); extern void ar9300_Stub_SetupClock(struct ath_hal *ah, HAL_OPMODE opmode); extern void ar9300_Stub_RestoreClock(struct ath_hal *ah, HAL_OPMODE opmode); extern int16_t ar9300_Stub_GetNfAdjust(struct ath_hal *, const HAL_CHANNEL_INTERNAL *); extern void ar9300_Stub_SetCompRegs(struct ath_hal *ah); extern HAL_STATUS ar9300_Stub_GetCapability(struct ath_hal *, HAL_CAPABILITY_TYPE, uint32_t, uint32_t *); extern HAL_BOOL ar9300_Stub_SetCapability(struct ath_hal *, HAL_CAPABILITY_TYPE, uint32_t, uint32_t, HAL_STATUS *); extern HAL_BOOL ar9300_Stub_GetDiagState(struct ath_hal *ah, int request, const void *args, uint32_t argsize, void **result, uint32_t *resultsize); extern HAL_STATUS ar9300_Stub_SetQuiet(struct ath_hal *ah, uint32_t period, uint32_t duration, uint32_t nextStart, HAL_QUIET_FLAG flag); extern HAL_BOOL ar9300_Stub_GetMibCycleCounts(struct ath_hal *, HAL_SURVEY_SAMPLE *); extern HAL_BOOL ar9300_Stub_SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode, int setChip); extern HAL_POWER_MODE ar9300_Stub_GetPowerMode(struct ath_hal *ah); extern HAL_BOOL ar9300_Stub_GetPowerStatus(struct ath_hal *ah); extern uint32_t ar9300_Stub_GetRxDP(struct ath_hal *ath, HAL_RX_QUEUE); extern void ar9300_Stub_SetRxDP(struct ath_hal *ah, uint32_t rxdp, HAL_RX_QUEUE); extern void ar9300_Stub_EnableReceive(struct ath_hal *ah); extern HAL_BOOL ar9300_Stub_StopDmaReceive(struct ath_hal *ah); -extern void ar9300_Stub_StartPcuReceive(struct ath_hal *ah); +extern void ar9300_Stub_StartPcuReceive(struct ath_hal *ah, HAL_BOOL); extern void ar9300_Stub_StopPcuReceive(struct ath_hal *ah); extern void ar9300_Stub_SetMulticastFilter(struct ath_hal *ah, uint32_t filter0, uint32_t filter1); extern HAL_BOOL ar9300_Stub_ClrMulticastFilterIndex(struct ath_hal *, uint32_t ix); extern HAL_BOOL ar9300_Stub_SetMulticastFilterIndex(struct ath_hal *, uint32_t ix); extern uint32_t ar9300_Stub_GetRxFilter(struct ath_hal *ah); extern void ar9300_Stub_SetRxFilter(struct ath_hal *ah, uint32_t bits); extern HAL_BOOL ar9300_Stub_SetupRxDesc(struct ath_hal *, struct ath_desc *, uint32_t size, u_int flags); extern HAL_STATUS ar9300_Stub_ProcRxDesc(struct ath_hal *ah, struct ath_desc *, uint32_t, struct ath_desc *, uint64_t, struct ath_rx_status *); extern HAL_BOOL ar9300_Stub_Reset(struct ath_hal *ah, HAL_OPMODE opmode, struct ieee80211_channel *chan, HAL_BOOL bChannelChange, HAL_RESET_TYPE resetType, HAL_STATUS *status); extern HAL_BOOL ar9300_Stub_SetChannel(struct ath_hal *, const struct ieee80211_channel *); extern void ar9300_Stub_SetOperatingMode(struct ath_hal *ah, int opmode); extern HAL_BOOL ar9300_Stub_PhyDisable(struct ath_hal *ah); extern HAL_BOOL ar9300_Stub_Disable(struct ath_hal *ah); extern HAL_BOOL ar9300_Stub_ChipReset(struct ath_hal *ah, const struct ieee80211_channel *); extern HAL_BOOL ar9300_Stub_PerCalibration(struct ath_hal *ah, struct ieee80211_channel *chan, HAL_BOOL *isIQdone); extern HAL_BOOL ar9300_Stub_PerCalibrationN(struct ath_hal *ah, struct ieee80211_channel *chan, u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone); extern HAL_BOOL ar9300_Stub_ResetCalValid(struct ath_hal *ah, const struct ieee80211_channel *); extern int16_t ar9300_Stub_GetNoiseFloor(struct ath_hal *ah); extern void ar9300_Stub_InitNfCalHistBuffer(struct ath_hal *); extern int16_t ar9300_Stub_GetNfHistMid(const int16_t calData[]); extern void ar9300_Stub_SetSpurMitigation(struct ath_hal *, const struct ieee80211_channel *); extern HAL_BOOL ar9300_Stub_SetAntennaSwitchInternal(struct ath_hal *ah, HAL_ANT_SETTING settings, const struct ieee80211_channel *); extern HAL_BOOL ar9300_Stub_SetTxPowerLimit(struct ath_hal *ah, uint32_t limit); extern HAL_BOOL ar9300_Stub_GetChipPowerLimits(struct ath_hal *ah, struct ieee80211_channel *chan); extern void ar9300_Stub_InitializeGainValues(struct ath_hal *); extern HAL_RFGAIN ar9300_Stub_GetRfgain(struct ath_hal *ah); extern void ar9300_Stub_RequestRfgain(struct ath_hal *); extern HAL_BOOL ar9300_Stub_UpdateTxTrigLevel(struct ath_hal *, HAL_BOOL IncTrigLevel); extern HAL_BOOL ar9300_Stub_SetTxQueueProps(struct ath_hal *ah, int q, const HAL_TXQ_INFO *qInfo); extern HAL_BOOL ar9300_Stub_GetTxQueueProps(struct ath_hal *ah, int q, HAL_TXQ_INFO *qInfo); extern int ar9300_Stub_SetupTxQueue(struct ath_hal *ah, HAL_TX_QUEUE type, const HAL_TXQ_INFO *qInfo); extern HAL_BOOL ar9300_Stub_ReleaseTxQueue(struct ath_hal *ah, u_int q); extern HAL_BOOL ar9300_Stub_ResetTxQueue(struct ath_hal *ah, u_int q); extern uint32_t ar9300_Stub_GetTxDP(struct ath_hal *ah, u_int q); extern HAL_BOOL ar9300_Stub_SetTxDP(struct ath_hal *ah, u_int q, uint32_t txdp); extern HAL_BOOL ar9300_Stub_StartTxDma(struct ath_hal *ah, u_int q); extern uint32_t ar9300_Stub_NumTxPending(struct ath_hal *ah, u_int q); extern HAL_BOOL ar9300_Stub_StopTxDma(struct ath_hal *ah, u_int q); extern HAL_BOOL ar9300_Stub_SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds, u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type, u_int txPower, u_int txRate0, u_int txTries0, u_int keyIx, u_int antMode, u_int flags, u_int rtsctsRate, u_int rtsctsDuration, u_int compicvLen, u_int compivLen, u_int comp); extern HAL_BOOL ar9300_Stub_SetupXTxDesc(struct ath_hal *, struct ath_desc *, u_int txRate1, u_int txRetries1, u_int txRate2, u_int txRetries2, u_int txRate3, u_int txRetries3); extern HAL_BOOL ar9300_Stub_FillTxDesc(struct ath_hal *ah, struct ath_desc *ds, HAL_DMA_ADDR *bufAddrList, uint32_t *segLenList, u_int descId, u_int qcuId, HAL_BOOL firstSeg, HAL_BOOL lastSeg, const struct ath_desc *ds0); extern HAL_STATUS ar9300_Stub_ProcTxDesc(struct ath_hal *ah, struct ath_desc *, struct ath_tx_status *); extern void ar9300_Stub_GetTxIntrQueue(struct ath_hal *ah, uint32_t *); extern void ar9300_Stub_IntrReqTxDesc(struct ath_hal *ah, struct ath_desc *); extern HAL_BOOL ar9300_Stub_GetTxCompletionRates(struct ath_hal *ah, const struct ath_desc *ds0, int *rates, int *tries); extern const HAL_RATE_TABLE * ar9300_Stub_GetRateTable(struct ath_hal *, u_int mode); #if 0 extern void ar9300_Stub_AniAttach(struct ath_hal *, const struct ar9300_Stub_AniParams *, const struct ar9300_Stub_AniParams *, HAL_BOOL ena); #endif extern void ar9300_Stub_AniDetach(struct ath_hal *); extern struct ar9300_Stub_AniState *ar5212AniGetCurrentState(struct ath_hal *); extern struct ar9300_Stub_Stats *ar5212AniGetCurrentStats(struct ath_hal *); extern HAL_BOOL ar9300_Stub_AniControl(struct ath_hal *, HAL_ANI_CMD cmd, int param); #if 0 extern HAL_BOOL ar9300_Stub_AniSetParams(struct ath_hal *, const struct ar9300_Stub_AniParams *, const struct ar9300_Stub_AniParams *); #endif struct ath_rx_status; extern void ar9300_Stub_AniPhyErrReport(struct ath_hal *ah, const struct ath_rx_status *rs); extern void ar9300_Stub_ProcessMibIntr(struct ath_hal *, const HAL_NODE_STATS *); extern void ar9300_Stub_RxMonitor(struct ath_hal *, const HAL_NODE_STATS *, const struct ieee80211_channel *); extern void ar9300_Stub_AniPoll(struct ath_hal *, const struct ieee80211_channel *); extern void ar9300_Stub_AniReset(struct ath_hal *, const struct ieee80211_channel *, HAL_OPMODE, int); extern HAL_BOOL ar9300_Stub_IsNFCalInProgress(struct ath_hal *ah); extern HAL_BOOL ar9300_Stub_WaitNFCalComplete(struct ath_hal *ah, int i); extern void ar9300_Stub_EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe); extern void ar9300_Stub_GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe); extern HAL_BOOL ar9300_Stub_ProcessRadarEvent(struct ath_hal *ah, struct ath_rx_status *rxs, uint64_t fulltsf, const char *buf, HAL_DFS_EVENT *event); extern HAL_BOOL ar9300_Stub_IsFastClockEnabled(struct ath_hal *ah); extern uint32_t ar9300_Stub_Get11nExtBusy(struct ath_hal *ah); extern void ar9300_Stub_ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore, HAL_BOOL powerOff); extern void ar9300_Stub_DisablePCIE(struct ath_hal *ah); #endif /* __AR9300_STUB_FUNCS_H__ */ Index: head/sys/dev/ath/ath_hal/ah.h =================================================================== --- head/sys/dev/ath/ath_hal/ah.h (revision 346469) +++ head/sys/dev/ath/ath_hal/ah.h (revision 346470) @@ -1,1702 +1,1702 @@ /*- * SPDX-License-Identifier: ISC * * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting * Copyright (c) 2002-2008 Atheros Communications, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $FreeBSD$ */ #ifndef _ATH_AH_H_ #define _ATH_AH_H_ /* * Atheros Hardware Access Layer * * Clients of the HAL call ath_hal_attach to obtain a reference to an ath_hal * structure for use with the device. Hardware-related operations that * follow must call back into the HAL through interface, supplying the * reference as the first parameter. */ #include "ah_osdep.h" /* * The maximum number of TX/RX chains supported. * This is intended to be used by various statistics gathering operations * (NF, RSSI, EVM). */ #define AH_MAX_CHAINS 3 #define AH_MIMO_MAX_EVM_PILOTS 6 /* * __ahdecl is analogous to _cdecl; it defines the calling * convention used within the HAL. For most systems this * can just default to be empty and the compiler will (should) * use _cdecl. For systems where _cdecl is not compatible this * must be defined. See linux/ah_osdep.h for an example. */ #ifndef __ahdecl #define __ahdecl #endif /* * Status codes that may be returned by the HAL. Note that * interfaces that return a status code set it only when an * error occurs--i.e. you cannot check it for success. */ typedef enum { HAL_OK = 0, /* No error */ HAL_ENXIO = 1, /* No hardware present */ HAL_ENOMEM = 2, /* Memory allocation failed */ HAL_EIO = 3, /* Hardware didn't respond as expected */ HAL_EEMAGIC = 4, /* EEPROM magic number invalid */ HAL_EEVERSION = 5, /* EEPROM version invalid */ HAL_EELOCKED = 6, /* EEPROM unreadable */ HAL_EEBADSUM = 7, /* EEPROM checksum invalid */ HAL_EEREAD = 8, /* EEPROM read problem */ HAL_EEBADMAC = 9, /* EEPROM mac address invalid */ HAL_EESIZE = 10, /* EEPROM size not supported */ HAL_EEWRITE = 11, /* Attempt to change write-locked EEPROM */ HAL_EINVAL = 12, /* Invalid parameter to function */ HAL_ENOTSUPP = 13, /* Hardware revision not supported */ HAL_ESELFTEST = 14, /* Hardware self-test failed */ HAL_EINPROGRESS = 15, /* Operation incomplete */ HAL_EEBADREG = 16, /* EEPROM invalid regulatory contents */ HAL_EEBADCC = 17, /* EEPROM invalid country code */ HAL_INV_PMODE = 18, /* Couldn't bring out of sleep state */ } HAL_STATUS; typedef enum { AH_FALSE = 0, /* NB: lots of code assumes false is zero */ AH_TRUE = 1, } HAL_BOOL; typedef enum { HAL_CAP_REG_DMN = 0, /* current regulatory domain */ HAL_CAP_CIPHER = 1, /* hardware supports cipher */ HAL_CAP_TKIP_MIC = 2, /* handle TKIP MIC in hardware */ HAL_CAP_TKIP_SPLIT = 3, /* hardware TKIP uses split keys */ HAL_CAP_PHYCOUNTERS = 4, /* hardware PHY error counters */ HAL_CAP_DIVERSITY = 5, /* hardware supports fast diversity */ HAL_CAP_KEYCACHE_SIZE = 6, /* number of entries in key cache */ HAL_CAP_NUM_TXQUEUES = 7, /* number of hardware xmit queues */ HAL_CAP_VEOL = 9, /* hardware supports virtual EOL */ HAL_CAP_PSPOLL = 10, /* hardware has working PS-Poll support */ HAL_CAP_DIAG = 11, /* hardware diagnostic support */ HAL_CAP_COMPRESSION = 12, /* hardware supports compression */ HAL_CAP_BURST = 13, /* hardware supports packet bursting */ HAL_CAP_FASTFRAME = 14, /* hardware supoprts fast frames */ HAL_CAP_TXPOW = 15, /* global tx power limit */ HAL_CAP_TPC = 16, /* per-packet tx power control */ HAL_CAP_PHYDIAG = 17, /* hardware phy error diagnostic */ HAL_CAP_BSSIDMASK = 18, /* hardware supports bssid mask */ HAL_CAP_MCAST_KEYSRCH = 19, /* hardware has multicast key search */ HAL_CAP_TSF_ADJUST = 20, /* hardware has beacon tsf adjust */ /* 21 was HAL_CAP_XR */ HAL_CAP_WME_TKIPMIC = 22, /* hardware can support TKIP MIC when WMM is turned on */ /* 23 was HAL_CAP_CHAN_HALFRATE */ /* 24 was HAL_CAP_CHAN_QUARTERRATE */ HAL_CAP_RFSILENT = 25, /* hardware has rfsilent support */ HAL_CAP_TPC_ACK = 26, /* ack txpower with per-packet tpc */ HAL_CAP_TPC_CTS = 27, /* cts txpower with per-packet tpc */ HAL_CAP_11D = 28, /* 11d beacon support for changing cc */ HAL_CAP_PCIE_PS = 29, HAL_CAP_HT = 30, /* hardware can support HT */ HAL_CAP_GTXTO = 31, /* hardware supports global tx timeout */ HAL_CAP_FAST_CC = 32, /* hardware supports fast channel change */ HAL_CAP_TX_CHAINMASK = 33, /* mask of TX chains supported */ HAL_CAP_RX_CHAINMASK = 34, /* mask of RX chains supported */ HAL_CAP_NUM_GPIO_PINS = 36, /* number of GPIO pins */ HAL_CAP_CST = 38, /* hardware supports carrier sense timeout */ HAL_CAP_RIFS_RX = 39, HAL_CAP_RIFS_TX = 40, HAL_CAP_FORCE_PPM = 41, HAL_CAP_RTS_AGGR_LIMIT = 42, /* aggregation limit with RTS */ HAL_CAP_4ADDR_AGGR = 43, /* hardware is capable of 4addr aggregation */ HAL_CAP_DFS_DMN = 44, /* current DFS domain */ HAL_CAP_EXT_CHAN_DFS = 45, /* DFS support for extension channel */ HAL_CAP_COMBINED_RADAR_RSSI = 46, /* Is combined RSSI for radar accurate */ HAL_CAP_AUTO_SLEEP = 48, /* hardware can go to network sleep automatically after waking up to receive TIM */ HAL_CAP_MBSSID_AGGR_SUPPORT = 49, /* Support for mBSSID Aggregation */ HAL_CAP_SPLIT_4KB_TRANS = 50, /* hardware supports descriptors straddling a 4k page boundary */ HAL_CAP_REG_FLAG = 51, /* Regulatory domain flags */ HAL_CAP_BB_RIFS_HANG = 52, HAL_CAP_RIFS_RX_ENABLED = 53, HAL_CAP_BB_DFS_HANG = 54, HAL_CAP_RX_STBC = 58, HAL_CAP_TX_STBC = 59, HAL_CAP_BT_COEX = 60, /* hardware is capable of bluetooth coexistence */ HAL_CAP_DYNAMIC_SMPS = 61, /* Dynamic MIMO Power Save hardware support */ HAL_CAP_DS = 67, /* 2 stream */ HAL_CAP_BB_RX_CLEAR_STUCK_HANG = 68, HAL_CAP_MAC_HANG = 69, /* can MAC hang */ HAL_CAP_MFP = 70, /* Management Frame Protection in hardware */ HAL_CAP_TS = 72, /* 3 stream */ HAL_CAP_ENHANCED_DMA_SUPPORT = 75, /* DMA FIFO support */ HAL_CAP_NUM_TXMAPS = 76, /* Number of buffers in a transmit descriptor */ HAL_CAP_TXDESCLEN = 77, /* Length of transmit descriptor */ HAL_CAP_TXSTATUSLEN = 78, /* Length of transmit status descriptor */ HAL_CAP_RXSTATUSLEN = 79, /* Length of transmit status descriptor */ HAL_CAP_RXFIFODEPTH = 80, /* Receive hardware FIFO depth */ HAL_CAP_RXBUFSIZE = 81, /* Receive Buffer Length */ HAL_CAP_NUM_MR_RETRIES = 82, /* limit on multirate retries */ HAL_CAP_OL_PWRCTRL = 84, /* Open loop TX power control */ HAL_CAP_SPECTRAL_SCAN = 90, /* Hardware supports spectral scan */ HAL_CAP_BB_PANIC_WATCHDOG = 92, HAL_CAP_HT20_SGI = 96, /* hardware supports HT20 short GI */ HAL_CAP_LDPC = 99, HAL_CAP_RXTSTAMP_PREC = 100, /* rx desc tstamp precision (bits) */ HAL_CAP_ANT_DIV_COMB = 105, /* Enable antenna diversity/combining */ HAL_CAP_PHYRESTART_CLR_WAR = 106, /* in some cases, clear phy restart to fix bb hang */ HAL_CAP_ENTERPRISE_MODE = 107, /* Enterprise mode features */ HAL_CAP_LDPCWAR = 108, HAL_CAP_CHANNEL_SWITCH_TIME_USEC = 109, /* Channel change time, usec */ HAL_CAP_ENABLE_APM = 110, /* APM enabled */ HAL_CAP_PCIE_LCR_EXTSYNC_EN = 111, HAL_CAP_PCIE_LCR_OFFSET = 112, HAL_CAP_ENHANCED_DFS_SUPPORT = 117, /* hardware supports enhanced DFS */ HAL_CAP_MCI = 118, HAL_CAP_SMARTANTENNA = 119, HAL_CAP_TRAFFIC_FAST_RECOVER = 120, HAL_CAP_TX_DIVERSITY = 121, HAL_CAP_CRDC = 122, /* The following are private to the FreeBSD HAL (224 onward) */ HAL_CAP_INTMIT = 229, /* interference mitigation */ HAL_CAP_RXORN_FATAL = 230, /* HAL_INT_RXORN treated as fatal */ HAL_CAP_BB_HANG = 235, /* can baseband hang */ HAL_CAP_INTRMASK = 237, /* bitmask of supported interrupts */ HAL_CAP_BSSIDMATCH = 238, /* hardware has disable bssid match */ HAL_CAP_STREAMS = 239, /* how many 802.11n spatial streams are available */ HAL_CAP_RXDESC_SELFLINK = 242, /* support a self-linked tail RX descriptor */ HAL_CAP_BB_READ_WAR = 244, /* baseband read WAR */ HAL_CAP_SERIALISE_WAR = 245, /* serialise register access on PCI */ HAL_CAP_ENFORCE_TXOP = 246, /* Enforce TXOP if supported */ HAL_CAP_RX_LNA_MIXING = 247, /* RX hardware uses LNA mixing */ HAL_CAP_DO_MYBEACON = 248, /* Supports HAL_RX_FILTER_MYBEACON */ HAL_CAP_TOA_LOCATIONING = 249, /* time of flight / arrival locationing */ HAL_CAP_TXTSTAMP_PREC = 250, /* tx desc tstamp precision (bits) */ } HAL_CAPABILITY_TYPE; /* * "States" for setting the LED. These correspond to * the possible 802.11 operational states and there may * be a many-to-one mapping between these states and the * actual hardware state for the LED's (i.e. the hardware * may have fewer states). */ typedef enum { HAL_LED_INIT = 0, HAL_LED_SCAN = 1, HAL_LED_AUTH = 2, HAL_LED_ASSOC = 3, HAL_LED_RUN = 4 } HAL_LED_STATE; /* * Transmit queue types/numbers. These are used to tag * each transmit queue in the hardware and to identify a set * of transmit queues for operations such as start/stop dma. */ typedef enum { HAL_TX_QUEUE_INACTIVE = 0, /* queue is inactive/unused */ HAL_TX_QUEUE_DATA = 1, /* data xmit q's */ HAL_TX_QUEUE_BEACON = 2, /* beacon xmit q */ HAL_TX_QUEUE_CAB = 3, /* "crap after beacon" xmit q */ HAL_TX_QUEUE_UAPSD = 4, /* u-apsd power save xmit q */ HAL_TX_QUEUE_PSPOLL = 5, /* power save poll xmit q */ HAL_TX_QUEUE_CFEND = 6, HAL_TX_QUEUE_PAPRD = 7, } HAL_TX_QUEUE; #define HAL_NUM_TX_QUEUES 10 /* max possible # of queues */ /* * Receive queue types. These are used to tag * each transmit queue in the hardware and to identify a set * of transmit queues for operations such as start/stop dma. */ typedef enum { HAL_RX_QUEUE_HP = 0, /* high priority recv queue */ HAL_RX_QUEUE_LP = 1, /* low priority recv queue */ } HAL_RX_QUEUE; #define HAL_NUM_RX_QUEUES 2 /* max possible # of queues */ #define HAL_TXFIFO_DEPTH 8 /* transmit fifo depth */ /* * Transmit queue subtype. These map directly to * WME Access Categories (except for UPSD). Refer * to Table 5 of the WME spec. */ typedef enum { HAL_WME_AC_BK = 0, /* background access category */ HAL_WME_AC_BE = 1, /* best effort access category*/ HAL_WME_AC_VI = 2, /* video access category */ HAL_WME_AC_VO = 3, /* voice access category */ HAL_WME_UPSD = 4, /* uplink power save */ } HAL_TX_QUEUE_SUBTYPE; /* * Transmit queue flags that control various * operational parameters. */ typedef enum { /* * Per queue interrupt enables. When set the associated * interrupt may be delivered for packets sent through * the queue. Without these enabled no interrupts will * be delivered for transmits through the queue. */ HAL_TXQ_TXOKINT_ENABLE = 0x0001, /* enable TXOK interrupt */ HAL_TXQ_TXERRINT_ENABLE = 0x0001, /* enable TXERR interrupt */ HAL_TXQ_TXDESCINT_ENABLE = 0x0002, /* enable TXDESC interrupt */ HAL_TXQ_TXEOLINT_ENABLE = 0x0004, /* enable TXEOL interrupt */ HAL_TXQ_TXURNINT_ENABLE = 0x0008, /* enable TXURN interrupt */ /* * Enable hardware compression for packets sent through * the queue. The compression buffer must be setup and * packets must have a key entry marked in the tx descriptor. */ HAL_TXQ_COMPRESSION_ENABLE = 0x0010, /* enable h/w compression */ /* * Disable queue when veol is hit or ready time expires. * By default the queue is disabled only on reaching the * physical end of queue (i.e. a null link ptr in the * descriptor chain). */ HAL_TXQ_RDYTIME_EXP_POLICY_ENABLE = 0x0020, /* * Schedule frames on delivery of a DBA (DMA Beacon Alert) * event. Frames will be transmitted only when this timer * fires, e.g to transmit a beacon in ap or adhoc modes. */ HAL_TXQ_DBA_GATED = 0x0040, /* schedule based on DBA */ /* * Each transmit queue has a counter that is incremented * each time the queue is enabled and decremented when * the list of frames to transmit is traversed (or when * the ready time for the queue expires). This counter * must be non-zero for frames to be scheduled for * transmission. The following controls disable bumping * this counter under certain conditions. Typically this * is used to gate frames based on the contents of another * queue (e.g. CAB traffic may only follow a beacon frame). * These are meaningful only when frames are scheduled * with a non-ASAP policy (e.g. DBA-gated). */ HAL_TXQ_CBR_DIS_QEMPTY = 0x0080, /* disable on this q empty */ HAL_TXQ_CBR_DIS_BEMPTY = 0x0100, /* disable on beacon q empty */ /* * Fragment burst backoff policy. Normally the no backoff * is done after a successful transmission, the next fragment * is sent at SIFS. If this flag is set backoff is done * after each fragment, regardless whether it was ack'd or * not, after the backoff count reaches zero a normal channel * access procedure is done before the next transmit (i.e. * wait AIFS instead of SIFS). */ HAL_TXQ_FRAG_BURST_BACKOFF_ENABLE = 0x00800000, /* * Disable post-tx backoff following each frame. */ HAL_TXQ_BACKOFF_DISABLE = 0x00010000, /* disable post backoff */ /* * DCU arbiter lockout control. This controls how * lower priority tx queues are handled with respect to * to a specific queue when multiple queues have frames * to send. No lockout means lower priority queues arbitrate * concurrently with this queue. Intra-frame lockout * means lower priority queues are locked out until the * current frame transmits (e.g. including backoffs and bursting). * Global lockout means nothing lower can arbitrary so * long as there is traffic activity on this queue (frames, * backoff, etc). */ HAL_TXQ_ARB_LOCKOUT_INTRA = 0x00020000, /* intra-frame lockout */ HAL_TXQ_ARB_LOCKOUT_GLOBAL = 0x00040000, /* full lockout s */ HAL_TXQ_IGNORE_VIRTCOL = 0x00080000, /* ignore virt collisions */ HAL_TXQ_SEQNUM_INC_DIS = 0x00100000, /* disable seqnum increment */ } HAL_TX_QUEUE_FLAGS; typedef struct { uint32_t tqi_ver; /* hal TXQ version */ HAL_TX_QUEUE_SUBTYPE tqi_subtype; /* subtype if applicable */ HAL_TX_QUEUE_FLAGS tqi_qflags; /* flags (see above) */ uint32_t tqi_priority; /* (not used) */ uint32_t tqi_aifs; /* aifs */ uint32_t tqi_cwmin; /* cwMin */ uint32_t tqi_cwmax; /* cwMax */ uint16_t tqi_shretry; /* rts retry limit */ uint16_t tqi_lgretry; /* long retry limit (not used)*/ uint32_t tqi_cbrPeriod; /* CBR period (us) */ uint32_t tqi_cbrOverflowLimit; /* threshold for CBROVF int */ uint32_t tqi_burstTime; /* max burst duration (us) */ uint32_t tqi_readyTime; /* frame schedule time (us) */ uint32_t tqi_compBuf; /* comp buffer phys addr */ } HAL_TXQ_INFO; #define HAL_TQI_NONVAL 0xffff /* token to use for aifs, cwmin, cwmax */ #define HAL_TXQ_USEDEFAULT ((uint32_t) -1) /* compression definitions */ #define HAL_COMP_BUF_MAX_SIZE 9216 /* 9K */ #define HAL_COMP_BUF_ALIGN_SIZE 512 /* * Transmit packet types. This belongs in ah_desc.h, but * is here so we can give a proper type to various parameters * (and not require everyone include the file). * * NB: These values are intentionally assigned for * direct use when setting up h/w descriptors. */ typedef enum { HAL_PKT_TYPE_NORMAL = 0, HAL_PKT_TYPE_ATIM = 1, HAL_PKT_TYPE_PSPOLL = 2, HAL_PKT_TYPE_BEACON = 3, HAL_PKT_TYPE_PROBE_RESP = 4, HAL_PKT_TYPE_CHIRP = 5, HAL_PKT_TYPE_GRP_POLL = 6, HAL_PKT_TYPE_AMPDU = 7, } HAL_PKT_TYPE; /* Rx Filter Frame Types */ typedef enum { /* * These bits correspond to AR_RX_FILTER for all chips. * Not all bits are supported by all chips. */ HAL_RX_FILTER_UCAST = 0x00000001, /* Allow unicast frames */ HAL_RX_FILTER_MCAST = 0x00000002, /* Allow multicast frames */ HAL_RX_FILTER_BCAST = 0x00000004, /* Allow broadcast frames */ HAL_RX_FILTER_CONTROL = 0x00000008, /* Allow control frames */ HAL_RX_FILTER_BEACON = 0x00000010, /* Allow beacon frames */ HAL_RX_FILTER_PROM = 0x00000020, /* Promiscuous mode */ HAL_RX_FILTER_PROBEREQ = 0x00000080, /* Allow probe request frames */ HAL_RX_FILTER_PHYERR = 0x00000100, /* Allow phy errors */ HAL_RX_FILTER_MYBEACON = 0x00000200, /* Filter beacons other than mine */ HAL_RX_FILTER_COMPBAR = 0x00000400, /* Allow compressed BAR */ HAL_RX_FILTER_COMP_BA = 0x00000800, /* Allow compressed blockack */ HAL_RX_FILTER_PHYRADAR = 0x00002000, /* Allow phy radar errors */ HAL_RX_FILTER_PSPOLL = 0x00004000, /* Allow PS-POLL frames */ HAL_RX_FILTER_MCAST_BCAST_ALL = 0x00008000, /* Allow all mcast/bcast frames */ /* * Magic RX filter flags that aren't targeting hardware bits * but instead the HAL sets individual bits - eg PHYERR will result * in OFDM/CCK timing error frames being received. */ HAL_RX_FILTER_BSSID = 0x40000000, /* Disable BSSID match */ } HAL_RX_FILTER; typedef enum { HAL_PM_AWAKE = 0, HAL_PM_FULL_SLEEP = 1, HAL_PM_NETWORK_SLEEP = 2, HAL_PM_UNDEFINED = 3 } HAL_POWER_MODE; /* * Enterprise mode flags */ #define AH_ENT_DUAL_BAND_DISABLE 0x00000001 #define AH_ENT_CHAIN2_DISABLE 0x00000002 #define AH_ENT_5MHZ_DISABLE 0x00000004 #define AH_ENT_10MHZ_DISABLE 0x00000008 #define AH_ENT_49GHZ_DISABLE 0x00000010 #define AH_ENT_LOOPBACK_DISABLE 0x00000020 #define AH_ENT_TPC_PERF_DISABLE 0x00000040 #define AH_ENT_MIN_PKT_SIZE_DISABLE 0x00000080 #define AH_ENT_SPECTRAL_PRECISION 0x00000300 #define AH_ENT_SPECTRAL_PRECISION_S 8 #define AH_ENT_RTSCTS_DELIM_WAR 0x00010000 #define AH_FIRST_DESC_NDELIMS 60 /* * NOTE WELL: * These are mapped to take advantage of the common locations for many of * the bits on all of the currently supported MAC chips. This is to make * the ISR as efficient as possible, while still abstracting HW differences. * When new hardware breaks this commonality this enumerated type, as well * as the HAL functions using it, must be modified. All values are directly * mapped unless commented otherwise. */ typedef enum { HAL_INT_RX = 0x00000001, /* Non-common mapping */ HAL_INT_RXDESC = 0x00000002, /* Legacy mapping */ HAL_INT_RXERR = 0x00000004, HAL_INT_RXHP = 0x00000001, /* EDMA */ HAL_INT_RXLP = 0x00000002, /* EDMA */ HAL_INT_RXNOFRM = 0x00000008, HAL_INT_RXEOL = 0x00000010, HAL_INT_RXORN = 0x00000020, HAL_INT_TX = 0x00000040, /* Non-common mapping */ HAL_INT_TXDESC = 0x00000080, HAL_INT_TIM_TIMER= 0x00000100, HAL_INT_MCI = 0x00000200, HAL_INT_BBPANIC = 0x00000400, HAL_INT_TXURN = 0x00000800, HAL_INT_MIB = 0x00001000, HAL_INT_RXPHY = 0x00004000, HAL_INT_RXKCM = 0x00008000, HAL_INT_SWBA = 0x00010000, HAL_INT_BRSSI = 0x00020000, HAL_INT_BMISS = 0x00040000, HAL_INT_BNR = 0x00100000, HAL_INT_TIM = 0x00200000, /* Non-common mapping */ HAL_INT_DTIM = 0x00400000, /* Non-common mapping */ HAL_INT_DTIMSYNC= 0x00800000, /* Non-common mapping */ HAL_INT_GPIO = 0x01000000, HAL_INT_CABEND = 0x02000000, /* Non-common mapping */ HAL_INT_TSFOOR = 0x04000000, /* Non-common mapping */ HAL_INT_TBTT = 0x08000000, /* Non-common mapping */ /* Atheros ref driver has a generic timer interrupt now..*/ HAL_INT_GENTIMER = 0x08000000, /* Non-common mapping */ HAL_INT_CST = 0x10000000, /* Non-common mapping */ HAL_INT_GTT = 0x20000000, /* Non-common mapping */ HAL_INT_FATAL = 0x40000000, /* Non-common mapping */ #define HAL_INT_GLOBAL 0x80000000 /* Set/clear IER */ HAL_INT_BMISC = HAL_INT_TIM | HAL_INT_DTIM | HAL_INT_DTIMSYNC | HAL_INT_CABEND | HAL_INT_TBTT, /* Interrupt bits that map directly to ISR/IMR bits */ HAL_INT_COMMON = HAL_INT_RXNOFRM | HAL_INT_RXDESC | HAL_INT_RXEOL | HAL_INT_RXORN | HAL_INT_TXDESC | HAL_INT_TXURN | HAL_INT_MIB | HAL_INT_RXPHY | HAL_INT_RXKCM | HAL_INT_SWBA | HAL_INT_BMISS | HAL_INT_BRSSI | HAL_INT_BNR | HAL_INT_GPIO, } HAL_INT; /* * MSI vector assignments */ typedef enum { HAL_MSIVEC_MISC = 0, HAL_MSIVEC_TX = 1, HAL_MSIVEC_RXLP = 2, HAL_MSIVEC_RXHP = 3, } HAL_MSIVEC; typedef enum { HAL_INT_LINE = 0, HAL_INT_MSI = 1, } HAL_INT_TYPE; /* For interrupt mitigation registers */ typedef enum { HAL_INT_RX_FIRSTPKT=0, HAL_INT_RX_LASTPKT, HAL_INT_TX_FIRSTPKT, HAL_INT_TX_LASTPKT, HAL_INT_THRESHOLD } HAL_INT_MITIGATION; /* XXX this is duplicate information! */ typedef struct { u_int32_t cyclecnt_diff; /* delta cycle count */ u_int32_t rxclr_cnt; /* rx clear count */ u_int32_t extrxclr_cnt; /* ext chan rx clear count */ u_int32_t txframecnt_diff; /* delta tx frame count */ u_int32_t rxframecnt_diff; /* delta rx frame count */ u_int32_t listen_time; /* listen time in msec - time for which ch is free */ u_int32_t ofdmphyerr_cnt; /* OFDM err count since last reset */ u_int32_t cckphyerr_cnt; /* CCK err count since last reset */ u_int32_t ofdmphyerrcnt_diff; /* delta OFDM Phy Error Count */ HAL_BOOL valid; /* if the stats are valid*/ } HAL_ANISTATS; typedef struct { u_int8_t txctl_offset; u_int8_t txctl_numwords; u_int8_t txstatus_offset; u_int8_t txstatus_numwords; u_int8_t rxctl_offset; u_int8_t rxctl_numwords; u_int8_t rxstatus_offset; u_int8_t rxstatus_numwords; u_int8_t macRevision; } HAL_DESC_INFO; typedef enum { HAL_GPIO_OUTPUT_MUX_AS_OUTPUT = 0, HAL_GPIO_OUTPUT_MUX_PCIE_ATTENTION_LED = 1, HAL_GPIO_OUTPUT_MUX_PCIE_POWER_LED = 2, HAL_GPIO_OUTPUT_MUX_MAC_NETWORK_LED = 3, HAL_GPIO_OUTPUT_MUX_MAC_POWER_LED = 4, HAL_GPIO_OUTPUT_MUX_AS_WLAN_ACTIVE = 5, HAL_GPIO_OUTPUT_MUX_AS_TX_FRAME = 6, HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA, HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK, HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA, HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK, HAL_GPIO_OUTPUT_MUX_AS_WL_IN_TX, HAL_GPIO_OUTPUT_MUX_AS_WL_IN_RX, HAL_GPIO_OUTPUT_MUX_AS_BT_IN_TX, HAL_GPIO_OUTPUT_MUX_AS_BT_IN_RX, HAL_GPIO_OUTPUT_MUX_AS_RUCKUS_STROBE, HAL_GPIO_OUTPUT_MUX_AS_RUCKUS_DATA, HAL_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL0, HAL_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL1, HAL_GPIO_OUTPUT_MUX_AS_SMARTANT_CTRL2, HAL_GPIO_OUTPUT_MUX_NUM_ENTRIES } HAL_GPIO_MUX_TYPE; typedef enum { HAL_GPIO_INTR_LOW = 0, HAL_GPIO_INTR_HIGH = 1, HAL_GPIO_INTR_DISABLE = 2 } HAL_GPIO_INTR_TYPE; typedef struct halCounters { u_int32_t tx_frame_count; u_int32_t rx_frame_count; u_int32_t rx_clear_count; u_int32_t cycle_count; u_int8_t is_rx_active; // true (1) or false (0) u_int8_t is_tx_active; // true (1) or false (0) } HAL_COUNTERS; typedef enum { HAL_RFGAIN_INACTIVE = 0, HAL_RFGAIN_READ_REQUESTED = 1, HAL_RFGAIN_NEED_CHANGE = 2 } HAL_RFGAIN; typedef uint16_t HAL_CTRY_CODE; /* country code */ typedef uint16_t HAL_REG_DOMAIN; /* regulatory domain code */ #define HAL_ANTENNA_MIN_MODE 0 #define HAL_ANTENNA_FIXED_A 1 #define HAL_ANTENNA_FIXED_B 2 #define HAL_ANTENNA_MAX_MODE 3 typedef struct { uint32_t ackrcv_bad; uint32_t rts_bad; uint32_t rts_good; uint32_t fcs_bad; uint32_t beacons; } HAL_MIB_STATS; /* * These bits represent what's in ah_currentRDext. */ typedef enum { REG_EXT_FCC_MIDBAND = 0, REG_EXT_JAPAN_MIDBAND = 1, REG_EXT_FCC_DFS_HT40 = 2, REG_EXT_JAPAN_NONDFS_HT40 = 3, REG_EXT_JAPAN_DFS_HT40 = 4, REG_EXT_FCC_CH_144 = 5, } REG_EXT_BITMAP; enum { HAL_MODE_11A = 0x001, /* 11a channels */ HAL_MODE_TURBO = 0x002, /* 11a turbo-only channels */ HAL_MODE_11B = 0x004, /* 11b channels */ HAL_MODE_PUREG = 0x008, /* 11g channels (OFDM only) */ #ifdef notdef HAL_MODE_11G = 0x010, /* 11g channels (OFDM/CCK) */ #else HAL_MODE_11G = 0x008, /* XXX historical */ #endif HAL_MODE_108G = 0x020, /* 11g+Turbo channels */ HAL_MODE_108A = 0x040, /* 11a+Turbo channels */ HAL_MODE_11A_HALF_RATE = 0x200, /* 11a half width channels */ HAL_MODE_11A_QUARTER_RATE = 0x400, /* 11a quarter width channels */ HAL_MODE_11G_HALF_RATE = 0x800, /* 11g half width channels */ HAL_MODE_11G_QUARTER_RATE = 0x1000, /* 11g quarter width channels */ HAL_MODE_11NG_HT20 = 0x008000, HAL_MODE_11NA_HT20 = 0x010000, HAL_MODE_11NG_HT40PLUS = 0x020000, HAL_MODE_11NG_HT40MINUS = 0x040000, HAL_MODE_11NA_HT40PLUS = 0x080000, HAL_MODE_11NA_HT40MINUS = 0x100000, HAL_MODE_ALL = 0xffffff }; typedef struct { int rateCount; /* NB: for proper padding */ uint8_t rateCodeToIndex[256]; /* back mapping */ struct { uint8_t valid; /* valid for rate control use */ uint8_t phy; /* CCK/OFDM/XR */ uint32_t rateKbps; /* transfer rate in kbs */ uint8_t rateCode; /* rate for h/w descriptors */ uint8_t shortPreamble; /* mask for enabling short * preamble in CCK rate code */ uint8_t dot11Rate; /* value for supported rates * info element of MLME */ uint8_t controlRate; /* index of next lower basic * rate; used for dur. calcs */ uint16_t lpAckDuration; /* long preamble ACK duration */ uint16_t spAckDuration; /* short preamble ACK duration*/ } info[64]; } HAL_RATE_TABLE; typedef struct { u_int rs_count; /* number of valid entries */ uint8_t rs_rates[64]; /* rates */ } HAL_RATE_SET; /* * 802.11n specific structures and enums */ typedef enum { HAL_CHAINTYPE_TX = 1, /* Tx chain type */ HAL_CHAINTYPE_RX = 2, /* RX chain type */ } HAL_CHAIN_TYPE; typedef struct { u_int Tries; u_int Rate; /* hardware rate code */ u_int RateIndex; /* rate series table index */ u_int PktDuration; u_int ChSel; u_int RateFlags; #define HAL_RATESERIES_RTS_CTS 0x0001 /* use rts/cts w/this series */ #define HAL_RATESERIES_2040 0x0002 /* use ext channel for series */ #define HAL_RATESERIES_HALFGI 0x0004 /* use half-gi for series */ #define HAL_RATESERIES_STBC 0x0008 /* use STBC for series */ u_int tx_power_cap; /* in 1/2 dBm units XXX TODO */ } HAL_11N_RATE_SERIES; typedef enum { HAL_HT_MACMODE_20 = 0, /* 20 MHz operation */ HAL_HT_MACMODE_2040 = 1, /* 20/40 MHz operation */ } HAL_HT_MACMODE; typedef enum { HAL_HT_PHYMODE_20 = 0, /* 20 MHz operation */ HAL_HT_PHYMODE_2040 = 1, /* 20/40 MHz operation */ } HAL_HT_PHYMODE; typedef enum { HAL_HT_EXTPROTSPACING_20 = 0, /* 20 MHz spacing */ HAL_HT_EXTPROTSPACING_25 = 1, /* 25 MHz spacing */ } HAL_HT_EXTPROTSPACING; typedef enum { HAL_RX_CLEAR_CTL_LOW = 0x1, /* force control channel to appear busy */ HAL_RX_CLEAR_EXT_LOW = 0x2, /* force extension channel to appear busy */ } HAL_HT_RXCLEAR; typedef enum { HAL_FREQ_BAND_5GHZ = 0, HAL_FREQ_BAND_2GHZ = 1, } HAL_FREQ_BAND; /* * Antenna switch control. By default antenna selection * enables multiple (2) antenna use. To force use of the * A or B antenna only specify a fixed setting. Fixing * the antenna will also disable any diversity support. */ typedef enum { HAL_ANT_VARIABLE = 0, /* variable by programming */ HAL_ANT_FIXED_A = 1, /* fixed antenna A */ HAL_ANT_FIXED_B = 2, /* fixed antenna B */ } HAL_ANT_SETTING; typedef enum { HAL_M_STA = 1, /* infrastructure station */ HAL_M_IBSS = 0, /* IBSS (adhoc) station */ HAL_M_HOSTAP = 6, /* Software Access Point */ HAL_M_MONITOR = 8 /* Monitor mode */ } HAL_OPMODE; typedef enum { HAL_RESET_NORMAL = 0, /* Do normal reset */ HAL_RESET_BBPANIC = 1, /* Reset because of BB panic */ HAL_RESET_FORCE_COLD = 2, /* Force full reset */ } HAL_RESET_TYPE; enum { HAL_RESET_POWER_ON, HAL_RESET_WARM, HAL_RESET_COLD }; typedef struct { uint8_t kv_type; /* one of HAL_CIPHER */ uint8_t kv_apsd; /* Mask for APSD enabled ACs */ uint16_t kv_len; /* length in bits */ uint8_t kv_val[16]; /* enough for 128-bit keys */ uint8_t kv_mic[8]; /* TKIP MIC key */ uint8_t kv_txmic[8]; /* TKIP TX MIC key (optional) */ } HAL_KEYVAL; /* * This is the TX descriptor field which marks the key padding requirement. * The naming is unfortunately unclear. */ #define AH_KEYTYPE_MASK 0x0F typedef enum { HAL_KEY_TYPE_CLEAR, HAL_KEY_TYPE_WEP, HAL_KEY_TYPE_AES, HAL_KEY_TYPE_TKIP, } HAL_KEY_TYPE; typedef enum { HAL_CIPHER_WEP = 0, HAL_CIPHER_AES_OCB = 1, HAL_CIPHER_AES_CCM = 2, HAL_CIPHER_CKIP = 3, HAL_CIPHER_TKIP = 4, HAL_CIPHER_CLR = 5, /* no encryption */ HAL_CIPHER_MIC = 127 /* TKIP-MIC, not a cipher */ } HAL_CIPHER; enum { HAL_SLOT_TIME_6 = 6, /* NB: for turbo mode */ HAL_SLOT_TIME_9 = 9, HAL_SLOT_TIME_20 = 20, }; /* * Per-station beacon timer state. Note that the specified * beacon interval (given in TU's) can also include flags * to force a TSF reset and to enable the beacon xmit logic. * If bs_cfpmaxduration is non-zero the hardware is setup to * coexist with a PCF-capable AP. */ typedef struct { uint32_t bs_nexttbtt; /* next beacon in TU */ uint32_t bs_nextdtim; /* next DTIM in TU */ uint32_t bs_intval; /* beacon interval+flags */ /* * HAL_BEACON_PERIOD, HAL_BEACON_ENA and HAL_BEACON_RESET_TSF * are all 1:1 correspondances with the pre-11n chip AR_BEACON * register. */ #define HAL_BEACON_PERIOD 0x0000ffff /* beacon interval period */ #define HAL_BEACON_PERIOD_TU8 0x0007ffff /* beacon interval, tu/8 */ #define HAL_BEACON_ENA 0x00800000 /* beacon xmit enable */ #define HAL_BEACON_RESET_TSF 0x01000000 /* clear TSF */ #define HAL_TSFOOR_THRESHOLD 0x00004240 /* TSF OOR thresh (16k uS) */ uint32_t bs_dtimperiod; uint16_t bs_cfpperiod; /* CFP period in TU */ uint16_t bs_cfpmaxduration; /* max CFP duration in TU */ uint32_t bs_cfpnext; /* next CFP in TU */ uint16_t bs_timoffset; /* byte offset to TIM bitmap */ uint16_t bs_bmissthreshold; /* beacon miss threshold */ uint32_t bs_sleepduration; /* max sleep duration */ uint32_t bs_tsfoor_threshold; /* TSF out of range threshold */ } HAL_BEACON_STATE; /* * Like HAL_BEACON_STATE but for non-station mode setup. * NB: see above flag definitions for bt_intval. */ typedef struct { uint32_t bt_intval; /* beacon interval+flags */ uint32_t bt_nexttbtt; /* next beacon in TU */ uint32_t bt_nextatim; /* next ATIM in TU */ uint32_t bt_nextdba; /* next DBA in 1/8th TU */ uint32_t bt_nextswba; /* next SWBA in 1/8th TU */ uint32_t bt_flags; /* timer enables */ #define HAL_BEACON_TBTT_EN 0x00000001 #define HAL_BEACON_DBA_EN 0x00000002 #define HAL_BEACON_SWBA_EN 0x00000004 } HAL_BEACON_TIMERS; /* * Per-node statistics maintained by the driver for use in * optimizing signal quality and other operational aspects. */ typedef struct { uint32_t ns_avgbrssi; /* average beacon rssi */ uint32_t ns_avgrssi; /* average data rssi */ uint32_t ns_avgtxrssi; /* average tx rssi */ } HAL_NODE_STATS; #define HAL_RSSI_EP_MULTIPLIER (1<<7) /* pow2 to optimize out * and / */ /* * This is the ANI state and MIB stats. * * It's used by the HAL modules to keep state /and/ by the debug ioctl * to fetch ANI information. */ typedef struct { uint32_t ast_ani_niup; /* ANI increased noise immunity */ uint32_t ast_ani_nidown; /* ANI decreased noise immunity */ uint32_t ast_ani_spurup; /* ANI increased spur immunity */ uint32_t ast_ani_spurdown;/* ANI descreased spur immunity */ uint32_t ast_ani_ofdmon; /* ANI OFDM weak signal detect on */ uint32_t ast_ani_ofdmoff;/* ANI OFDM weak signal detect off */ uint32_t ast_ani_cckhigh;/* ANI CCK weak signal threshold high */ uint32_t ast_ani_ccklow; /* ANI CCK weak signal threshold low */ uint32_t ast_ani_stepup; /* ANI increased first step level */ uint32_t ast_ani_stepdown;/* ANI decreased first step level */ uint32_t ast_ani_ofdmerrs;/* ANI cumulative ofdm phy err count */ uint32_t ast_ani_cckerrs;/* ANI cumulative cck phy err count */ uint32_t ast_ani_reset; /* ANI parameters zero'd for non-STA */ uint32_t ast_ani_lzero; /* ANI listen time forced to zero */ uint32_t ast_ani_lneg; /* ANI listen time calculated < 0 */ HAL_MIB_STATS ast_mibstats; /* MIB counter stats */ HAL_NODE_STATS ast_nodestats; /* Latest rssi stats from driver */ } HAL_ANI_STATS; typedef struct { uint8_t noiseImmunityLevel; /* Global for pre-AR9380; OFDM later*/ uint8_t cckNoiseImmunityLevel; /* AR9380: CCK specific NI */ uint8_t spurImmunityLevel; uint8_t firstepLevel; uint8_t ofdmWeakSigDetectOff; uint8_t cckWeakSigThreshold; uint8_t mrcCck; /* MRC CCK is enabled */ uint32_t listenTime; /* NB: intentionally ordered so data exported to user space is first */ uint32_t txFrameCount; /* Last txFrameCount */ uint32_t rxFrameCount; /* Last rx Frame count */ uint32_t cycleCount; /* Last cycleCount (to detect wrap-around) */ uint32_t ofdmPhyErrCount;/* OFDM err count since last reset */ uint32_t cckPhyErrCount; /* CCK err count since last reset */ } HAL_ANI_STATE; struct ath_desc; struct ath_tx_status; struct ath_rx_status; struct ieee80211_channel; /* * This is a channel survey sample entry. * * The AR5212 ANI routines fill these samples. The ANI code then uses it * when calculating listen time; it is also exported via a diagnostic * API. */ typedef struct { uint32_t seq_num; uint32_t tx_busy; uint32_t rx_busy; uint32_t chan_busy; uint32_t ext_chan_busy; uint32_t cycle_count; /* XXX TODO */ uint32_t ofdm_phyerr_count; uint32_t cck_phyerr_count; } HAL_SURVEY_SAMPLE; /* * This provides 3.2 seconds of sample space given an * ANI time of 1/10th of a second. This may not be enough! */ #define CHANNEL_SURVEY_SAMPLE_COUNT 32 typedef struct { HAL_SURVEY_SAMPLE samples[CHANNEL_SURVEY_SAMPLE_COUNT]; uint32_t cur_sample; /* current sample in sequence */ uint32_t cur_seq; /* current sequence number */ } HAL_CHANNEL_SURVEY; /* * ANI commands. * * These are used both internally and externally via the diagnostic * API. * * Note that this is NOT the ANI commands being used via the INTMIT * capability - that has a different mapping for some reason. */ typedef enum { HAL_ANI_PRESENT = 0, /* is ANI support present */ HAL_ANI_NOISE_IMMUNITY_LEVEL = 1, /* set level (global or ofdm) */ HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION = 2, /* enable/disable */ HAL_ANI_CCK_WEAK_SIGNAL_THR = 3, /* enable/disable */ HAL_ANI_FIRSTEP_LEVEL = 4, /* set level */ HAL_ANI_SPUR_IMMUNITY_LEVEL = 5, /* set level */ HAL_ANI_MODE = 6, /* 0 => manual, 1 => auto (XXX do not change) */ HAL_ANI_PHYERR_RESET = 7, /* reset phy error stats */ HAL_ANI_MRC_CCK = 8, HAL_ANI_CCK_NOISE_IMMUNITY_LEVEL = 9, /* set level (cck) */ } HAL_ANI_CMD; #define HAL_ANI_ALL 0xffffffff /* * This is the layout of the ANI INTMIT capability. * * Notice that the command values differ to HAL_ANI_CMD. */ typedef enum { HAL_CAP_INTMIT_PRESENT = 0, HAL_CAP_INTMIT_ENABLE = 1, HAL_CAP_INTMIT_NOISE_IMMUNITY_LEVEL = 2, HAL_CAP_INTMIT_OFDM_WEAK_SIGNAL_LEVEL = 3, HAL_CAP_INTMIT_CCK_WEAK_SIGNAL_THR = 4, HAL_CAP_INTMIT_FIRSTEP_LEVEL = 5, HAL_CAP_INTMIT_SPUR_IMMUNITY_LEVEL = 6 } HAL_CAP_INTMIT_CMD; typedef struct { int32_t pe_firpwr; /* FIR pwr out threshold */ int32_t pe_rrssi; /* Radar rssi thresh */ int32_t pe_height; /* Pulse height thresh */ int32_t pe_prssi; /* Pulse rssi thresh */ int32_t pe_inband; /* Inband thresh */ /* The following params are only for AR5413 and later */ u_int32_t pe_relpwr; /* Relative power threshold in 0.5dB steps */ u_int32_t pe_relstep; /* Pulse Relative step threshold in 0.5dB steps */ u_int32_t pe_maxlen; /* Max length of radar sign in 0.8us units */ int32_t pe_usefir128; /* Use the average in-band power measured over 128 cycles */ int32_t pe_blockradar; /* * Enable to block radar check if pkt detect is done via OFDM * weak signal detect or pkt is detected immediately after tx * to rx transition */ int32_t pe_enmaxrssi; /* * Enable to use the max rssi instead of the last rssi during * fine gain changes for radar detection */ int32_t pe_extchannel; /* Enable DFS on ext channel */ int32_t pe_enabled; /* Whether radar detection is enabled */ int32_t pe_enrelpwr; int32_t pe_en_relstep_check; } HAL_PHYERR_PARAM; #define HAL_PHYERR_PARAM_NOVAL 65535 typedef struct { u_int16_t ss_fft_period; /* Skip interval for FFT reports */ u_int16_t ss_period; /* Spectral scan period */ u_int16_t ss_count; /* # of reports to return from ss_active */ u_int16_t ss_short_report;/* Set to report ony 1 set of FFT results */ u_int8_t radar_bin_thresh_sel; /* strong signal radar FFT threshold configuration */ u_int16_t ss_spectral_pri; /* are we doing a noise power cal ? */ int8_t ss_nf_cal[AH_MAX_CHAINS*2]; /* nf calibrated values for ctl+ext from eeprom */ int8_t ss_nf_pwr[AH_MAX_CHAINS*2]; /* nf pwr values for ctl+ext from eeprom */ int32_t ss_nf_temp_data; /* temperature data taken during nf scan */ int ss_enabled; int ss_active; } HAL_SPECTRAL_PARAM; #define HAL_SPECTRAL_PARAM_NOVAL 0xFFFF #define HAL_SPECTRAL_PARAM_ENABLE 0x8000 /* Enable/Disable if applicable */ /* * DFS operating mode flags. */ typedef enum { HAL_DFS_UNINIT_DOMAIN = 0, /* Uninitialized dfs domain */ HAL_DFS_FCC_DOMAIN = 1, /* FCC3 dfs domain */ HAL_DFS_ETSI_DOMAIN = 2, /* ETSI dfs domain */ HAL_DFS_MKK4_DOMAIN = 3, /* Japan dfs domain */ } HAL_DFS_DOMAIN; /* * MFP decryption options for initializing the MAC. */ typedef enum { HAL_MFP_QOSDATA = 0, /* Decrypt MFP frames like QoS data frames. All chips before Merlin. */ HAL_MFP_PASSTHRU, /* Don't decrypt MFP frames at all. Passthrough */ HAL_MFP_HW_CRYPTO /* hardware decryption enabled. Merlin can do it. */ } HAL_MFP_OPT_T; /* LNA config supported */ typedef enum { HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2 = 0, HAL_ANT_DIV_COMB_LNA2 = 1, HAL_ANT_DIV_COMB_LNA1 = 2, HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2 = 3, } HAL_ANT_DIV_COMB_LNA_CONF; typedef struct { u_int8_t main_lna_conf; u_int8_t alt_lna_conf; u_int8_t fast_div_bias; u_int8_t main_gaintb; u_int8_t alt_gaintb; u_int8_t antdiv_configgroup; int8_t lna1_lna2_delta; } HAL_ANT_COMB_CONFIG; #define DEFAULT_ANTDIV_CONFIG_GROUP 0x00 #define HAL_ANTDIV_CONFIG_GROUP_1 0x01 #define HAL_ANTDIV_CONFIG_GROUP_2 0x02 #define HAL_ANTDIV_CONFIG_GROUP_3 0x03 /* * Flag for setting QUIET period */ typedef enum { HAL_QUIET_DISABLE = 0x0, HAL_QUIET_ENABLE = 0x1, HAL_QUIET_ADD_CURRENT_TSF = 0x2, /* add current TSF to next_start offset */ HAL_QUIET_ADD_SWBA_RESP_TIME = 0x4, /* add beacon response time to next_start offset */ } HAL_QUIET_FLAG; #define HAL_DFS_EVENT_PRICH 0x0000001 #define HAL_DFS_EVENT_EXTCH 0x0000002 #define HAL_DFS_EVENT_EXTEARLY 0x0000004 #define HAL_DFS_EVENT_ISDC 0x0000008 struct hal_dfs_event { uint64_t re_full_ts; /* 64-bit full timestamp from interrupt time */ uint32_t re_ts; /* Original 15 bit recv timestamp */ uint8_t re_rssi; /* rssi of radar event */ uint8_t re_dur; /* duration of radar pulse */ uint32_t re_flags; /* Flags (see above) */ }; typedef struct hal_dfs_event HAL_DFS_EVENT; /* * Generic Timer domain */ typedef enum { HAL_GEN_TIMER_TSF = 0, HAL_GEN_TIMER_TSF2, HAL_GEN_TIMER_TSF_ANY } HAL_GEN_TIMER_DOMAIN; /* * BT Co-existence definitions */ #include "ath_hal/ah_btcoex.h" struct hal_bb_panic_info { u_int32_t status; u_int32_t tsf; u_int32_t phy_panic_wd_ctl1; u_int32_t phy_panic_wd_ctl2; u_int32_t phy_gen_ctrl; u_int32_t rxc_pcnt; u_int32_t rxf_pcnt; u_int32_t txf_pcnt; u_int32_t cycles; u_int32_t wd; u_int32_t det; u_int32_t rdar; u_int32_t r_odfm; u_int32_t r_cck; u_int32_t t_odfm; u_int32_t t_cck; u_int32_t agc; u_int32_t src; }; /* Serialize Register Access Mode */ typedef enum { SER_REG_MODE_OFF = 0, SER_REG_MODE_ON = 1, SER_REG_MODE_AUTO = 2, } SER_REG_MODE; typedef struct { int ah_debug; /* only used if AH_DEBUG is defined */ int ah_ar5416_biasadj; /* enable AR2133 radio specific bias fiddling */ /* NB: these are deprecated; they exist for now for compatibility */ int ah_dma_beacon_response_time;/* in TU's */ int ah_sw_beacon_response_time; /* in TU's */ int ah_additional_swba_backoff; /* in TU's */ int ah_force_full_reset; /* force full chip reset rather then warm reset */ int ah_serialise_reg_war; /* force serialisation of register IO */ /* XXX these don't belong here, they're just for the ar9300 HAL port effort */ int ath_hal_desc_tpc; /* Per-packet TPC */ int ath_hal_sta_update_tx_pwr_enable; /* GreenTX */ int ath_hal_sta_update_tx_pwr_enable_S1; /* GreenTX */ int ath_hal_sta_update_tx_pwr_enable_S2; /* GreenTX */ int ath_hal_sta_update_tx_pwr_enable_S3; /* GreenTX */ /* I'm not sure what the default values for these should be */ int ath_hal_pll_pwr_save; int ath_hal_pcie_power_save_enable; int ath_hal_intr_mitigation_rx; int ath_hal_intr_mitigation_tx; int ath_hal_pcie_clock_req; #define AR_PCIE_PLL_PWRSAVE_CONTROL (1<<0) #define AR_PCIE_PLL_PWRSAVE_ON_D3 (1<<1) #define AR_PCIE_PLL_PWRSAVE_ON_D0 (1<<2) int ath_hal_pcie_waen; int ath_hal_pcie_ser_des_write; /* these are important for correct AR9300 behaviour */ int ath_hal_ht_enable; /* needs to be enabled for AR9300 HT */ int ath_hal_diversity_control; int ath_hal_antenna_switch_swap; int ath_hal_ext_lna_ctl_gpio; int ath_hal_spur_mode; int ath_hal_6mb_ack; /* should set this to 1 for 11a/11na? */ int ath_hal_enable_msi; /* enable MSI interrupts (needed?) */ int ath_hal_beacon_filter_interval; /* ok to be 0 for now? */ /* For now, set this to 0 - net80211 needs to know about hardware MFP support */ int ath_hal_mfp_support; int ath_hal_enable_ani; /* should set this.. */ int ath_hal_cwm_ignore_ext_cca; int ath_hal_show_bb_panic; int ath_hal_ant_ctrl_comm2g_switch_enable; int ath_hal_ext_atten_margin_cfg; int ath_hal_min_gainidx; int ath_hal_war70c; uint32_t ath_hal_mci_config; } HAL_OPS_CONFIG; /* * Hardware Access Layer (HAL) API. * * Clients of the HAL call ath_hal_attach to obtain a reference to an * ath_hal structure for use with the device. Hardware-related operations * that follow must call back into the HAL through interface, supplying * the reference as the first parameter. Note that before using the * reference returned by ath_hal_attach the caller should verify the * ABI version number. */ struct ath_hal { uint32_t ah_magic; /* consistency check magic number */ uint16_t ah_devid; /* PCI device ID */ uint16_t ah_subvendorid; /* PCI subvendor ID */ HAL_SOFTC ah_sc; /* back pointer to driver/os state */ HAL_BUS_TAG ah_st; /* params for register r+w */ HAL_BUS_HANDLE ah_sh; HAL_CTRY_CODE ah_countryCode; uint32_t ah_macVersion; /* MAC version id */ uint16_t ah_macRev; /* MAC revision */ uint16_t ah_phyRev; /* PHY revision */ /* NB: when only one radio is present the rev is in 5Ghz */ uint16_t ah_analog5GhzRev;/* 5GHz radio revision */ uint16_t ah_analog2GhzRev;/* 2GHz radio revision */ uint16_t *ah_eepromdata; /* eeprom buffer, if needed */ uint32_t ah_intrstate[8]; /* last int state */ uint32_t ah_syncstate; /* last sync intr state */ /* Current powerstate from HAL calls */ HAL_POWER_MODE ah_powerMode; HAL_OPS_CONFIG ah_config; const HAL_RATE_TABLE *__ahdecl(*ah_getRateTable)(struct ath_hal *, u_int mode); void __ahdecl(*ah_detach)(struct ath_hal*); /* Reset functions */ HAL_BOOL __ahdecl(*ah_reset)(struct ath_hal *, HAL_OPMODE, struct ieee80211_channel *, HAL_BOOL bChannelChange, HAL_RESET_TYPE resetType, HAL_STATUS *status); HAL_BOOL __ahdecl(*ah_phyDisable)(struct ath_hal *); HAL_BOOL __ahdecl(*ah_disable)(struct ath_hal *); void __ahdecl(*ah_configPCIE)(struct ath_hal *, HAL_BOOL restore, HAL_BOOL power_off); void __ahdecl(*ah_disablePCIE)(struct ath_hal *); void __ahdecl(*ah_setPCUConfig)(struct ath_hal *); HAL_BOOL __ahdecl(*ah_perCalibration)(struct ath_hal*, struct ieee80211_channel *, HAL_BOOL *); HAL_BOOL __ahdecl(*ah_perCalibrationN)(struct ath_hal *, struct ieee80211_channel *, u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone); HAL_BOOL __ahdecl(*ah_resetCalValid)(struct ath_hal *, const struct ieee80211_channel *); HAL_BOOL __ahdecl(*ah_setTxPower)(struct ath_hal *, const struct ieee80211_channel *, uint16_t *); HAL_BOOL __ahdecl(*ah_setTxPowerLimit)(struct ath_hal *, uint32_t); HAL_BOOL __ahdecl(*ah_setBoardValues)(struct ath_hal *, const struct ieee80211_channel *); /* Transmit functions */ HAL_BOOL __ahdecl(*ah_updateTxTrigLevel)(struct ath_hal*, HAL_BOOL incTrigLevel); int __ahdecl(*ah_setupTxQueue)(struct ath_hal *, HAL_TX_QUEUE, const HAL_TXQ_INFO *qInfo); HAL_BOOL __ahdecl(*ah_setTxQueueProps)(struct ath_hal *, int q, const HAL_TXQ_INFO *qInfo); HAL_BOOL __ahdecl(*ah_getTxQueueProps)(struct ath_hal *, int q, HAL_TXQ_INFO *qInfo); HAL_BOOL __ahdecl(*ah_releaseTxQueue)(struct ath_hal *ah, u_int q); HAL_BOOL __ahdecl(*ah_resetTxQueue)(struct ath_hal *ah, u_int q); uint32_t __ahdecl(*ah_getTxDP)(struct ath_hal*, u_int); HAL_BOOL __ahdecl(*ah_setTxDP)(struct ath_hal*, u_int, uint32_t txdp); uint32_t __ahdecl(*ah_numTxPending)(struct ath_hal *, u_int q); HAL_BOOL __ahdecl(*ah_startTxDma)(struct ath_hal*, u_int); HAL_BOOL __ahdecl(*ah_stopTxDma)(struct ath_hal*, u_int); HAL_BOOL __ahdecl(*ah_setupTxDesc)(struct ath_hal *, struct ath_desc *, u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type, u_int txPower, u_int txRate0, u_int txTries0, u_int keyIx, u_int antMode, u_int flags, u_int rtsctsRate, u_int rtsctsDuration, u_int compicvLen, u_int compivLen, u_int comp); HAL_BOOL __ahdecl(*ah_setupXTxDesc)(struct ath_hal *, struct ath_desc*, u_int txRate1, u_int txTries1, u_int txRate2, u_int txTries2, u_int txRate3, u_int txTries3); HAL_BOOL __ahdecl(*ah_fillTxDesc)(struct ath_hal *, struct ath_desc *, HAL_DMA_ADDR *bufAddrList, uint32_t *segLenList, u_int descId, u_int qcuId, HAL_BOOL firstSeg, HAL_BOOL lastSeg, const struct ath_desc *); HAL_STATUS __ahdecl(*ah_procTxDesc)(struct ath_hal *, struct ath_desc *, struct ath_tx_status *); void __ahdecl(*ah_getTxIntrQueue)(struct ath_hal *, uint32_t *); void __ahdecl(*ah_reqTxIntrDesc)(struct ath_hal *, struct ath_desc*); HAL_BOOL __ahdecl(*ah_getTxCompletionRates)(struct ath_hal *, const struct ath_desc *ds, int *rates, int *tries); void __ahdecl(*ah_setTxDescLink)(struct ath_hal *ah, void *ds, uint32_t link); void __ahdecl(*ah_getTxDescLink)(struct ath_hal *ah, void *ds, uint32_t *link); void __ahdecl(*ah_getTxDescLinkPtr)(struct ath_hal *ah, void *ds, uint32_t **linkptr); void __ahdecl(*ah_setupTxStatusRing)(struct ath_hal *, void *ts_start, uint32_t ts_paddr_start, uint16_t size); void __ahdecl(*ah_getTxRawTxDesc)(struct ath_hal *, u_int32_t *); /* Receive Functions */ uint32_t __ahdecl(*ah_getRxDP)(struct ath_hal*, HAL_RX_QUEUE); void __ahdecl(*ah_setRxDP)(struct ath_hal*, uint32_t rxdp, HAL_RX_QUEUE); void __ahdecl(*ah_enableReceive)(struct ath_hal*); HAL_BOOL __ahdecl(*ah_stopDmaReceive)(struct ath_hal*); - void __ahdecl(*ah_startPcuReceive)(struct ath_hal*); + void __ahdecl(*ah_startPcuReceive)(struct ath_hal*, HAL_BOOL); void __ahdecl(*ah_stopPcuReceive)(struct ath_hal*); void __ahdecl(*ah_setMulticastFilter)(struct ath_hal*, uint32_t filter0, uint32_t filter1); HAL_BOOL __ahdecl(*ah_setMulticastFilterIndex)(struct ath_hal*, uint32_t index); HAL_BOOL __ahdecl(*ah_clrMulticastFilterIndex)(struct ath_hal*, uint32_t index); uint32_t __ahdecl(*ah_getRxFilter)(struct ath_hal*); void __ahdecl(*ah_setRxFilter)(struct ath_hal*, uint32_t); HAL_BOOL __ahdecl(*ah_setupRxDesc)(struct ath_hal *, struct ath_desc *, uint32_t size, u_int flags); HAL_STATUS __ahdecl(*ah_procRxDesc)(struct ath_hal *, struct ath_desc *, uint32_t phyAddr, struct ath_desc *next, uint64_t tsf, struct ath_rx_status *); void __ahdecl(*ah_rxMonitor)(struct ath_hal *, const HAL_NODE_STATS *, const struct ieee80211_channel *); void __ahdecl(*ah_aniPoll)(struct ath_hal *, const struct ieee80211_channel *); void __ahdecl(*ah_procMibEvent)(struct ath_hal *, const HAL_NODE_STATS *); /* Misc Functions */ HAL_STATUS __ahdecl(*ah_getCapability)(struct ath_hal *, HAL_CAPABILITY_TYPE, uint32_t capability, uint32_t *result); HAL_BOOL __ahdecl(*ah_setCapability)(struct ath_hal *, HAL_CAPABILITY_TYPE, uint32_t capability, uint32_t setting, HAL_STATUS *); HAL_BOOL __ahdecl(*ah_getDiagState)(struct ath_hal *, int request, const void *args, uint32_t argsize, void **result, uint32_t *resultsize); void __ahdecl(*ah_getMacAddress)(struct ath_hal *, uint8_t *); HAL_BOOL __ahdecl(*ah_setMacAddress)(struct ath_hal *, const uint8_t*); void __ahdecl(*ah_getBssIdMask)(struct ath_hal *, uint8_t *); HAL_BOOL __ahdecl(*ah_setBssIdMask)(struct ath_hal *, const uint8_t*); HAL_BOOL __ahdecl(*ah_setRegulatoryDomain)(struct ath_hal*, uint16_t, HAL_STATUS *); void __ahdecl(*ah_setLedState)(struct ath_hal*, HAL_LED_STATE); void __ahdecl(*ah_writeAssocid)(struct ath_hal*, const uint8_t *bssid, uint16_t assocId); HAL_BOOL __ahdecl(*ah_gpioCfgOutput)(struct ath_hal *, uint32_t gpio, HAL_GPIO_MUX_TYPE); HAL_BOOL __ahdecl(*ah_gpioCfgInput)(struct ath_hal *, uint32_t gpio); uint32_t __ahdecl(*ah_gpioGet)(struct ath_hal *, uint32_t gpio); HAL_BOOL __ahdecl(*ah_gpioSet)(struct ath_hal *, uint32_t gpio, uint32_t val); void __ahdecl(*ah_gpioSetIntr)(struct ath_hal*, u_int, uint32_t); uint32_t __ahdecl(*ah_getTsf32)(struct ath_hal*); uint64_t __ahdecl(*ah_getTsf64)(struct ath_hal*); void __ahdecl(*ah_setTsf64)(struct ath_hal *, uint64_t); void __ahdecl(*ah_resetTsf)(struct ath_hal*); HAL_BOOL __ahdecl(*ah_detectCardPresent)(struct ath_hal*); void __ahdecl(*ah_updateMibCounters)(struct ath_hal*, HAL_MIB_STATS*); HAL_RFGAIN __ahdecl(*ah_getRfGain)(struct ath_hal*); u_int __ahdecl(*ah_getDefAntenna)(struct ath_hal*); void __ahdecl(*ah_setDefAntenna)(struct ath_hal*, u_int); HAL_ANT_SETTING __ahdecl(*ah_getAntennaSwitch)(struct ath_hal*); HAL_BOOL __ahdecl(*ah_setAntennaSwitch)(struct ath_hal*, HAL_ANT_SETTING); HAL_BOOL __ahdecl(*ah_setSifsTime)(struct ath_hal*, u_int); u_int __ahdecl(*ah_getSifsTime)(struct ath_hal*); HAL_BOOL __ahdecl(*ah_setSlotTime)(struct ath_hal*, u_int); u_int __ahdecl(*ah_getSlotTime)(struct ath_hal*); HAL_BOOL __ahdecl(*ah_setAckTimeout)(struct ath_hal*, u_int); u_int __ahdecl(*ah_getAckTimeout)(struct ath_hal*); HAL_BOOL __ahdecl(*ah_setAckCTSRate)(struct ath_hal*, u_int); u_int __ahdecl(*ah_getAckCTSRate)(struct ath_hal*); HAL_BOOL __ahdecl(*ah_setCTSTimeout)(struct ath_hal*, u_int); u_int __ahdecl(*ah_getCTSTimeout)(struct ath_hal*); HAL_BOOL __ahdecl(*ah_setDecompMask)(struct ath_hal*, uint16_t, int); void __ahdecl(*ah_setCoverageClass)(struct ath_hal*, uint8_t, int); HAL_STATUS __ahdecl(*ah_setQuiet)(struct ath_hal *ah, uint32_t period, uint32_t duration, uint32_t nextStart, HAL_QUIET_FLAG flag); void __ahdecl(*ah_setChainMasks)(struct ath_hal *, uint32_t, uint32_t); /* DFS functions */ void __ahdecl(*ah_enableDfs)(struct ath_hal *ah, HAL_PHYERR_PARAM *pe); void __ahdecl(*ah_getDfsThresh)(struct ath_hal *ah, HAL_PHYERR_PARAM *pe); HAL_BOOL __ahdecl(*ah_getDfsDefaultThresh)(struct ath_hal *ah, HAL_PHYERR_PARAM *pe); HAL_BOOL __ahdecl(*ah_procRadarEvent)(struct ath_hal *ah, struct ath_rx_status *rxs, uint64_t fulltsf, const char *buf, HAL_DFS_EVENT *event); HAL_BOOL __ahdecl(*ah_isFastClockEnabled)(struct ath_hal *ah); void __ahdecl(*ah_setDfsCacTxQuiet)(struct ath_hal *, HAL_BOOL); /* Spectral Scan functions */ void __ahdecl(*ah_spectralConfigure)(struct ath_hal *ah, HAL_SPECTRAL_PARAM *sp); void __ahdecl(*ah_spectralGetConfig)(struct ath_hal *ah, HAL_SPECTRAL_PARAM *sp); void __ahdecl(*ah_spectralStart)(struct ath_hal *); void __ahdecl(*ah_spectralStop)(struct ath_hal *); HAL_BOOL __ahdecl(*ah_spectralIsEnabled)(struct ath_hal *); HAL_BOOL __ahdecl(*ah_spectralIsActive)(struct ath_hal *); /* XXX getNfPri() and getNfExt() */ /* Key Cache Functions */ uint32_t __ahdecl(*ah_getKeyCacheSize)(struct ath_hal*); HAL_BOOL __ahdecl(*ah_resetKeyCacheEntry)(struct ath_hal*, uint16_t); HAL_BOOL __ahdecl(*ah_isKeyCacheEntryValid)(struct ath_hal *, uint16_t); HAL_BOOL __ahdecl(*ah_setKeyCacheEntry)(struct ath_hal*, uint16_t, const HAL_KEYVAL *, const uint8_t *, int); HAL_BOOL __ahdecl(*ah_setKeyCacheEntryMac)(struct ath_hal*, uint16_t, const uint8_t *); /* Power Management Functions */ HAL_BOOL __ahdecl(*ah_setPowerMode)(struct ath_hal*, HAL_POWER_MODE mode, int setChip); HAL_POWER_MODE __ahdecl(*ah_getPowerMode)(struct ath_hal*); int16_t __ahdecl(*ah_getChanNoise)(struct ath_hal *, const struct ieee80211_channel *); /* Beacon Management Functions */ void __ahdecl(*ah_setBeaconTimers)(struct ath_hal*, const HAL_BEACON_TIMERS *); /* NB: deprecated, use ah_setBeaconTimers instead */ void __ahdecl(*ah_beaconInit)(struct ath_hal *, uint32_t nexttbtt, uint32_t intval); void __ahdecl(*ah_setStationBeaconTimers)(struct ath_hal*, const HAL_BEACON_STATE *); void __ahdecl(*ah_resetStationBeaconTimers)(struct ath_hal*); uint64_t __ahdecl(*ah_getNextTBTT)(struct ath_hal *); /* 802.11n Functions */ HAL_BOOL __ahdecl(*ah_chainTxDesc)(struct ath_hal *, struct ath_desc *, HAL_DMA_ADDR *bufAddrList, uint32_t *segLenList, u_int, u_int, HAL_PKT_TYPE, u_int, HAL_CIPHER, uint8_t, HAL_BOOL, HAL_BOOL, HAL_BOOL); HAL_BOOL __ahdecl(*ah_setupFirstTxDesc)(struct ath_hal *, struct ath_desc *, u_int, u_int, u_int, u_int, u_int, u_int, u_int, u_int); HAL_BOOL __ahdecl(*ah_setupLastTxDesc)(struct ath_hal *, struct ath_desc *, const struct ath_desc *); void __ahdecl(*ah_set11nRateScenario)(struct ath_hal *, struct ath_desc *, u_int, u_int, HAL_11N_RATE_SERIES [], u_int, u_int); /* * The next 4 (set11ntxdesc -> set11naggrlast) are specific * to the EDMA HAL. Descriptors are chained together by * using filltxdesc (not ChainTxDesc) and then setting the * aggregate flags appropriately using first/middle/last. */ void __ahdecl(*ah_set11nTxDesc)(struct ath_hal *, void *, u_int, HAL_PKT_TYPE, u_int, u_int, u_int); void __ahdecl(*ah_set11nAggrFirst)(struct ath_hal *, struct ath_desc *, u_int, u_int); void __ahdecl(*ah_set11nAggrMiddle)(struct ath_hal *, struct ath_desc *, u_int); void __ahdecl(*ah_set11nAggrLast)(struct ath_hal *, struct ath_desc *); void __ahdecl(*ah_clr11nAggr)(struct ath_hal *, struct ath_desc *); void __ahdecl(*ah_set11nBurstDuration)(struct ath_hal *, struct ath_desc *, u_int); void __ahdecl(*ah_set11nVirtMoreFrag)(struct ath_hal *, struct ath_desc *, u_int); HAL_BOOL __ahdecl(*ah_getMibCycleCounts) (struct ath_hal *, HAL_SURVEY_SAMPLE *); uint32_t __ahdecl(*ah_get11nExtBusy)(struct ath_hal *); void __ahdecl(*ah_set11nMac2040)(struct ath_hal *, HAL_HT_MACMODE); HAL_HT_RXCLEAR __ahdecl(*ah_get11nRxClear)(struct ath_hal *ah); void __ahdecl(*ah_set11nRxClear)(struct ath_hal *, HAL_HT_RXCLEAR); /* Interrupt functions */ HAL_BOOL __ahdecl(*ah_isInterruptPending)(struct ath_hal*); HAL_BOOL __ahdecl(*ah_getPendingInterrupts)(struct ath_hal*, HAL_INT*); HAL_INT __ahdecl(*ah_getInterrupts)(struct ath_hal*); HAL_INT __ahdecl(*ah_setInterrupts)(struct ath_hal*, HAL_INT); /* Bluetooth Coexistence functions */ void __ahdecl(*ah_btCoexSetInfo)(struct ath_hal *, HAL_BT_COEX_INFO *); void __ahdecl(*ah_btCoexSetConfig)(struct ath_hal *, HAL_BT_COEX_CONFIG *); void __ahdecl(*ah_btCoexSetQcuThresh)(struct ath_hal *, int); void __ahdecl(*ah_btCoexSetWeights)(struct ath_hal *, uint32_t); void __ahdecl(*ah_btCoexSetBmissThresh)(struct ath_hal *, uint32_t); void __ahdecl(*ah_btCoexSetParameter)(struct ath_hal *, uint32_t, uint32_t); void __ahdecl(*ah_btCoexDisable)(struct ath_hal *); int __ahdecl(*ah_btCoexEnable)(struct ath_hal *); /* Bluetooth MCI methods */ void __ahdecl(*ah_btMciSetup)(struct ath_hal *, uint32_t, void *, uint16_t, uint32_t); HAL_BOOL __ahdecl(*ah_btMciSendMessage)(struct ath_hal *, uint8_t, uint32_t, uint32_t *, uint8_t, HAL_BOOL, HAL_BOOL); uint32_t __ahdecl(*ah_btMciGetInterrupt)(struct ath_hal *, uint32_t *, uint32_t *); uint32_t __ahdecl(*ah_btMciState)(struct ath_hal *, uint32_t, uint32_t *); void __ahdecl(*ah_btMciDetach)(struct ath_hal *); /* LNA diversity configuration */ void __ahdecl(*ah_divLnaConfGet)(struct ath_hal *, HAL_ANT_COMB_CONFIG *); void __ahdecl(*ah_divLnaConfSet)(struct ath_hal *, HAL_ANT_COMB_CONFIG *); }; /* * Check the PCI vendor ID and device ID against Atheros' values * and return a printable description for any Atheros hardware. * AH_NULL is returned if the ID's do not describe Atheros hardware. */ extern const char *__ahdecl ath_hal_probe(uint16_t vendorid, uint16_t devid); /* * Attach the HAL for use with the specified device. The device is * defined by the PCI device ID. The caller provides an opaque pointer * to an upper-layer data structure (HAL_SOFTC) that is stored in the * HAL state block for later use. Hardware register accesses are done * using the specified bus tag and handle. On successful return a * reference to a state block is returned that must be supplied in all * subsequent HAL calls. Storage associated with this reference is * dynamically allocated and must be freed by calling the ah_detach * method when the client is done. If the attach operation fails a * null (AH_NULL) reference will be returned and a status code will * be returned if the status parameter is non-zero. */ extern struct ath_hal * __ahdecl ath_hal_attach(uint16_t devid, HAL_SOFTC, HAL_BUS_TAG, HAL_BUS_HANDLE, uint16_t *eepromdata, HAL_OPS_CONFIG *ah_config, HAL_STATUS* status); extern const char *ath_hal_mac_name(struct ath_hal *); extern const char *ath_hal_rf_name(struct ath_hal *); /* * Regulatory interfaces. Drivers should use ath_hal_init_channels to * request a set of channels for a particular country code and/or * regulatory domain. If CTRY_DEFAULT and SKU_NONE are specified then * this list is constructed according to the contents of the EEPROM. * ath_hal_getchannels acts similarly but does not alter the operating * state; this can be used to collect information for a particular * regulatory configuration. Finally ath_hal_set_channels installs a * channel list constructed outside the driver. The HAL will adopt the * channel list and setup internal state according to the specified * regulatory configuration (e.g. conformance test limits). * * For all interfaces the channel list is returned in the supplied array. * maxchans defines the maximum size of this array. nchans contains the * actual number of channels returned. If a problem occurred then a * status code != HAL_OK is returned. */ struct ieee80211_channel; /* * Return a list of channels according to the specified regulatory. */ extern HAL_STATUS __ahdecl ath_hal_getchannels(struct ath_hal *, struct ieee80211_channel *chans, u_int maxchans, int *nchans, u_int modeSelect, HAL_CTRY_CODE cc, HAL_REG_DOMAIN regDmn, HAL_BOOL enableExtendedChannels); /* * Return a list of channels and install it as the current operating * regulatory list. */ extern HAL_STATUS __ahdecl ath_hal_init_channels(struct ath_hal *, struct ieee80211_channel *chans, u_int maxchans, int *nchans, u_int modeSelect, HAL_CTRY_CODE cc, HAL_REG_DOMAIN rd, HAL_BOOL enableExtendedChannels); /* * Install the list of channels as the current operating regulatory * and setup related state according to the country code and sku. */ extern HAL_STATUS __ahdecl ath_hal_set_channels(struct ath_hal *, struct ieee80211_channel *chans, int nchans, HAL_CTRY_CODE cc, HAL_REG_DOMAIN regDmn); /* * Fetch the ctl/ext noise floor values reported by a MIMO * radio. Returns 1 for valid results, 0 for invalid channel. */ extern int __ahdecl ath_hal_get_mimo_chan_noise(struct ath_hal *ah, const struct ieee80211_channel *chan, int16_t *nf_ctl, int16_t *nf_ext); /* * Calibrate noise floor data following a channel scan or similar. * This must be called prior retrieving noise floor data. */ extern void __ahdecl ath_hal_process_noisefloor(struct ath_hal *ah); /* * Return bit mask of wireless modes supported by the hardware. */ extern u_int __ahdecl ath_hal_getwirelessmodes(struct ath_hal*); /* * Get the HAL wireless mode for the given channel. */ extern int ath_hal_get_curmode(struct ath_hal *ah, const struct ieee80211_channel *chan); /* * Calculate the packet TX time for a legacy or 11n frame */ extern uint32_t __ahdecl ath_hal_pkt_txtime(struct ath_hal *ah, const HAL_RATE_TABLE *rates, uint32_t frameLen, uint16_t rateix, HAL_BOOL isht40, HAL_BOOL shortPreamble, HAL_BOOL includeSifs); /* * Calculate the duration of an 11n frame. */ extern uint32_t __ahdecl ath_computedur_ht(uint32_t frameLen, uint16_t rate, int streams, HAL_BOOL isht40, HAL_BOOL isShortGI); /* * Calculate the transmit duration of a legacy frame. */ extern uint16_t __ahdecl ath_hal_computetxtime(struct ath_hal *, const HAL_RATE_TABLE *rates, uint32_t frameLen, uint16_t rateix, HAL_BOOL shortPreamble, HAL_BOOL includeSifs); /* * Adjust the TSF. */ extern void __ahdecl ath_hal_adjusttsf(struct ath_hal *ah, int32_t tsfdelta); /* * Enable or disable CCA. */ void __ahdecl ath_hal_setcca(struct ath_hal *ah, int ena); /* * Get CCA setting. */ int __ahdecl ath_hal_getcca(struct ath_hal *ah); /* * Enable/disable and get self-gen frame (ACK, CTS) for CAC. */ void __ahdecl ath_hal_set_dfs_cac_tx_quiet(struct ath_hal *ah, HAL_BOOL ena); /* * Read EEPROM data from ah_eepromdata */ HAL_BOOL __ahdecl ath_hal_EepromDataRead(struct ath_hal *ah, u_int off, uint16_t *data); /* * For now, simply pass through MFP frames. */ static inline u_int32_t ath_hal_get_mfp_qos(struct ath_hal *ah) { //return AH_PRIVATE(ah)->ah_mfp_qos; return HAL_MFP_QOSDATA; } /* * Convert between microseconds and core system clocks. */ extern u_int ath_hal_mac_clks(struct ath_hal *ah, u_int usecs); extern u_int ath_hal_mac_usec(struct ath_hal *ah, u_int clks); extern uint64_t ath_hal_mac_psec(struct ath_hal *ah, u_int clks); #endif /* _ATH_AH_H_ */ Index: head/sys/dev/ath/ath_hal/ar5210/ar5210.h =================================================================== --- head/sys/dev/ath/ath_hal/ar5210/ar5210.h (revision 346469) +++ head/sys/dev/ath/ath_hal/ar5210/ar5210.h (revision 346470) @@ -1,305 +1,305 @@ /*- * SPDX-License-Identifier: ISC * * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting * Copyright (c) 2002-2004 Atheros Communications, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $FreeBSD$ */ #ifndef _ATH_AR5210_H_ #define _ATH_AR5210_H_ #define AR5210_MAGIC 0x19980124 #if 0 /* * RTS_ENABLE includes LONG_PKT because they essentially * imply the same thing, and are set or not set together * for this chip */ #define AR5210_TXD_CTRL_A_HDR_LEN(_val) (((_val) ) & 0x0003f) #define AR5210_TXD_CTRL_A_TX_RATE(_val) (((_val) << 6) & 0x003c0) #define AR5210_TXD_CTRL_A_RTS_ENABLE ( 0x00c00) #define AR5210_TXD_CTRL_A_CLEAR_DEST_MASK(_val) (((_val) << 12) & 0x01000) #define AR5210_TXD_CTRL_A_ANT_MODE(_val) (((_val) << 13) & 0x02000) #define AR5210_TXD_CTRL_A_PKT_TYPE(_val) (((_val) << 14) & 0x1c000) #define AR5210_TXD_CTRL_A_INT_REQ ( 0x20000) #define AR5210_TXD_CTRL_A_KEY_VALID ( 0x40000) #define AR5210_TXD_CTRL_B_KEY_ID(_val) (((_val) ) & 0x0003f) #define AR5210_TXD_CTRL_B_RTS_DURATION(_val) (((_val) << 6) & 0x7ffc0) #endif #define INIT_CONFIG_STATUS 0x00000000 #define INIT_ACKTOPS 0x00000008 #define INIT_BCON_CNTRL_REG 0x00000000 #define INIT_SLOT_TIME 0x00000168 #define INIT_SLOT_TIME_TURBO 0x000001e0 /* More aggressive turbo slot timing = 6 us */ #define INIT_ACK_CTS_TIMEOUT 0x04000400 #define INIT_ACK_CTS_TIMEOUT_TURBO 0x08000800 #define INIT_USEC 0x27 #define INIT_USEC_TURBO 0x4f #define INIT_USEC_32 0x1f #define INIT_TX_LATENCY 0x36 #define INIT_RX_LATENCY 0x1D #define INIT_TRANSMIT_LATENCY \ ((INIT_RX_LATENCY << AR_USEC_RX_LATENCY_S) | \ (INIT_TX_LATENCY << AR_USEC_TX_LATENCY_S) | \ (INIT_USEC_32 << 7) | INIT_USEC ) #define INIT_TRANSMIT_LATENCY_TURBO \ ((INIT_RX_LATENCY << AR_USEC_RX_LATENCY_S) | \ (INIT_TX_LATENCY << AR_USEC_TX_LATENCY_S) | \ (INIT_USEC_32 << 7) | INIT_USEC_TURBO) #define INIT_SIFS 0x230 /* = 16 us - 2 us */ #define INIT_SIFS_TURBO 0x1E0 /* More aggressive turbo SIFS timing - 8 us - 2 us */ /* * Various fifo fill before Tx start, in 64-byte units * i.e. put the frame in the air while still DMAing */ #define MIN_TX_FIFO_THRESHOLD 0x1 #define MAX_TX_FIFO_THRESHOLD ((IEEE80211_MAX_LEN / 64) + 1) #define INIT_NEXT_CFP_START 0xffffffff #define INIT_BEACON_PERIOD 0xffff #define INIT_BEACON_EN 0 /* this should be set by AP only when it's ready */ #define INIT_BEACON_CONTROL \ ((INIT_RESET_TSF << 24) | (INIT_BEACON_EN << 23) | \ (INIT_TIM_OFFSET<<16) | INIT_BEACON_PERIOD) #define INIT_RSSI_THR 0x00000700 /* Missed beacon counter initialized to max value of 7 */ #define INIT_ProgIFS 0x398 /* PIFS - 2us */ #define INIT_ProgIFS_TURBO 0x3C0 #define INIT_EIFS 0xd70 #define INIT_EIFS_TURBO 0x1ae0 #define INIT_CARR_SENSE_EN 1 #define INIT_PROTO_TIME_CNTRL ( (INIT_CARR_SENSE_EN << 26) | (INIT_EIFS << 12) | \ (INIT_ProgIFS) ) #define INIT_PROTO_TIME_CNTRL_TURBO ( (INIT_CARR_SENSE_EN << 26) | (INIT_EIFS_TURBO << 12) | \ (INIT_ProgIFS_TURBO) ) #define AR5210_MAX_RATE_POWER 60 #undef HAL_NUM_TX_QUEUES /* from ah.h */ #define HAL_NUM_TX_QUEUES 3 struct ath_hal_5210 { struct ath_hal_private ah_priv; /* base definitions */ uint8_t ah_macaddr[IEEE80211_ADDR_LEN]; /* * Runtime state. */ uint32_t ah_maskReg; /* shadow of IMR+IER regs */ uint32_t ah_txOkInterruptMask; uint32_t ah_txErrInterruptMask; uint32_t ah_txDescInterruptMask; uint32_t ah_txEolInterruptMask; uint32_t ah_txUrnInterruptMask; uint8_t ah_bssid[IEEE80211_ADDR_LEN]; HAL_TX_QUEUE_INFO ah_txq[HAL_NUM_TX_QUEUES]; /* beacon+cab+data */ /* * Station mode support. */ uint32_t ah_staId1Defaults; /* STA_ID1 default settings */ uint32_t ah_rssiThr; /* RSSI_THR settings */ u_int ah_sifstime; /* user-specified sifs time */ u_int ah_slottime; /* user-specified slot time */ u_int ah_acktimeout; /* user-specified ack timeout */ u_int ah_ctstimeout; /* user-specified cts timeout */ uint16_t ah_associd; /* association id */ }; #define AH5210(ah) ((struct ath_hal_5210 *)(ah)) struct ath_hal; extern void ar5210Detach(struct ath_hal *ah); extern HAL_BOOL ar5210Reset(struct ath_hal *, HAL_OPMODE, struct ieee80211_channel *, HAL_BOOL bChannelChange, HAL_RESET_TYPE, HAL_STATUS *); extern void ar5210SetPCUConfig(struct ath_hal *); extern HAL_BOOL ar5210PhyDisable(struct ath_hal *); extern HAL_BOOL ar5210Disable(struct ath_hal *); extern HAL_BOOL ar5210ChipReset(struct ath_hal *, struct ieee80211_channel *); extern HAL_BOOL ar5210PerCalibration(struct ath_hal *, struct ieee80211_channel *, HAL_BOOL *); extern HAL_BOOL ar5210PerCalibrationN(struct ath_hal *ah, struct ieee80211_channel *chan, u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone); extern HAL_BOOL ar5210ResetCalValid(struct ath_hal *ah, const struct ieee80211_channel *); extern int16_t ar5210GetNoiseFloor(struct ath_hal *); extern int16_t ar5210GetNfAdjust(struct ath_hal *, const HAL_CHANNEL_INTERNAL *); extern HAL_BOOL ar5210SetTxPowerLimit(struct ath_hal *, uint32_t limit); extern HAL_BOOL ar5210SetTransmitPower(struct ath_hal *, const struct ieee80211_channel *); extern HAL_BOOL ar5210CalNoiseFloor(struct ath_hal *, HAL_CHANNEL_INTERNAL *); extern HAL_BOOL ar5210ResetDma(struct ath_hal *, HAL_OPMODE); extern HAL_BOOL ar5210SetTxQueueProps(struct ath_hal *ah, int q, const HAL_TXQ_INFO *qInfo); extern HAL_BOOL ar5210GetTxQueueProps(struct ath_hal *ah, int q, HAL_TXQ_INFO *qInfo); extern int ar5210SetupTxQueue(struct ath_hal *ah, HAL_TX_QUEUE type, const HAL_TXQ_INFO *qInfo); extern HAL_BOOL ar5210ReleaseTxQueue(struct ath_hal *ah, u_int q); extern HAL_BOOL ar5210ResetTxQueue(struct ath_hal *ah, u_int q); extern uint32_t ar5210GetTxDP(struct ath_hal *, u_int); extern HAL_BOOL ar5210SetTxDP(struct ath_hal *, u_int, uint32_t txdp); extern HAL_BOOL ar5210UpdateTxTrigLevel(struct ath_hal *, HAL_BOOL); extern uint32_t ar5210NumTxPending(struct ath_hal *, u_int); extern HAL_BOOL ar5210StartTxDma(struct ath_hal *, u_int); extern HAL_BOOL ar5210StopTxDma(struct ath_hal *, u_int); extern HAL_BOOL ar5210SetupTxDesc(struct ath_hal *, struct ath_desc *, u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type, u_int txPower, u_int txRate0, u_int txRetries0, u_int keyIx, u_int antMode, u_int flags, u_int rtsctsRate, u_int rtsctsDuration, u_int compicvLen, u_int compivLen, u_int comp); extern HAL_BOOL ar5210SetupXTxDesc(struct ath_hal *, struct ath_desc *, u_int txRate1, u_int txRetries1, u_int txRate2, u_int txRetries2, u_int txRate3, u_int txRetries3); extern HAL_BOOL ar5210FillTxDesc(struct ath_hal *, struct ath_desc *, HAL_DMA_ADDR *bufAddrList, uint32_t *segLenList, u_int descId, u_int qcuId, HAL_BOOL firstSeg, HAL_BOOL lastSeg, const struct ath_desc *ds0); extern HAL_STATUS ar5210ProcTxDesc(struct ath_hal *, struct ath_desc *, struct ath_tx_status *); extern void ar5210GetTxIntrQueue(struct ath_hal *ah, uint32_t *); extern void ar5210IntrReqTxDesc(struct ath_hal *ah, struct ath_desc *); extern HAL_BOOL ar5210GetTxCompletionRates(struct ath_hal *ah, const struct ath_desc *, int *rates, int *tries); extern void ar5210SetTxDescLink(struct ath_hal *ah, void *ds, uint32_t link); extern void ar5210GetTxDescLink(struct ath_hal *ah, void *ds, uint32_t *link); extern void ar5210GetTxDescLinkPtr(struct ath_hal *ah, void *ds, uint32_t **linkptr); extern uint32_t ar5210GetRxDP(struct ath_hal *, HAL_RX_QUEUE); extern void ar5210SetRxDP(struct ath_hal *, uint32_t rxdp, HAL_RX_QUEUE); extern void ar5210EnableReceive(struct ath_hal *); extern HAL_BOOL ar5210StopDmaReceive(struct ath_hal *); -extern void ar5210StartPcuReceive(struct ath_hal *); +extern void ar5210StartPcuReceive(struct ath_hal *, HAL_BOOL); extern void ar5210StopPcuReceive(struct ath_hal *); extern void ar5210SetMulticastFilter(struct ath_hal *, uint32_t filter0, uint32_t filter1); extern HAL_BOOL ar5210ClrMulticastFilterIndex(struct ath_hal *, uint32_t); extern HAL_BOOL ar5210SetMulticastFilterIndex(struct ath_hal *, uint32_t); extern uint32_t ar5210GetRxFilter(struct ath_hal *); extern void ar5210SetRxFilter(struct ath_hal *, uint32_t); extern HAL_BOOL ar5210SetupRxDesc(struct ath_hal *, struct ath_desc *, uint32_t, u_int flags); extern HAL_STATUS ar5210ProcRxDesc(struct ath_hal *, struct ath_desc *, uint32_t, struct ath_desc *, uint64_t, struct ath_rx_status *); extern void ar5210GetMacAddress(struct ath_hal *, uint8_t *); extern HAL_BOOL ar5210SetMacAddress(struct ath_hal *ah, const uint8_t *); extern void ar5210GetBssIdMask(struct ath_hal *, uint8_t *); extern HAL_BOOL ar5210SetBssIdMask(struct ath_hal *, const uint8_t *); extern HAL_BOOL ar5210EepromRead(struct ath_hal *, u_int off, uint16_t *data); extern HAL_BOOL ar5210EepromWrite(struct ath_hal *, u_int off, uint16_t data); extern HAL_BOOL ar5210SetRegulatoryDomain(struct ath_hal *, uint16_t, HAL_STATUS *); extern u_int ar5210GetWirelessModes(struct ath_hal *ah); extern void ar5210EnableRfKill(struct ath_hal *); extern HAL_BOOL ar5210GpioCfgInput(struct ath_hal *, uint32_t gpio); extern HAL_BOOL ar5210GpioCfgOutput(struct ath_hal *, uint32_t gpio, HAL_GPIO_MUX_TYPE); extern uint32_t ar5210GpioGet(struct ath_hal *, uint32_t gpio); extern HAL_BOOL ar5210GpioSet(struct ath_hal *, uint32_t gpio, uint32_t); extern void ar5210Gpio0SetIntr(struct ath_hal *, u_int, uint32_t ilevel); extern void ar5210SetLedState(struct ath_hal *, HAL_LED_STATE); extern u_int ar5210GetDefAntenna(struct ath_hal *); extern void ar5210SetDefAntenna(struct ath_hal *, u_int); extern HAL_ANT_SETTING ar5210GetAntennaSwitch(struct ath_hal *); extern HAL_BOOL ar5210SetAntennaSwitch(struct ath_hal *, HAL_ANT_SETTING); extern void ar5210WriteAssocid(struct ath_hal *, const uint8_t *bssid, uint16_t assocId); extern uint32_t ar5210GetTsf32(struct ath_hal *); extern uint64_t ar5210GetTsf64(struct ath_hal *); extern void ar5210ResetTsf(struct ath_hal *); extern uint32_t ar5210GetRandomSeed(struct ath_hal *); extern HAL_BOOL ar5210DetectCardPresent(struct ath_hal *); extern void ar5210UpdateMibCounters(struct ath_hal *, HAL_MIB_STATS *); extern void ar5210EnableHwEncryption(struct ath_hal *); extern void ar5210DisableHwEncryption(struct ath_hal *); extern HAL_RFGAIN ar5210GetRfgain(struct ath_hal *); extern HAL_BOOL ar5210SetSifsTime(struct ath_hal *, u_int); extern u_int ar5210GetSifsTime(struct ath_hal *); extern HAL_BOOL ar5210SetSlotTime(struct ath_hal *, u_int); extern u_int ar5210GetSlotTime(struct ath_hal *); extern HAL_BOOL ar5210SetAckTimeout(struct ath_hal *, u_int); extern u_int ar5210GetAckTimeout(struct ath_hal *); extern HAL_BOOL ar5210SetAckCTSRate(struct ath_hal *, u_int); extern u_int ar5210GetAckCTSRate(struct ath_hal *); extern HAL_BOOL ar5210SetCTSTimeout(struct ath_hal *, u_int); extern u_int ar5210GetCTSTimeout(struct ath_hal *); extern HAL_BOOL ar5210SetDecompMask(struct ath_hal *, uint16_t, int); void ar5210SetCoverageClass(struct ath_hal *, uint8_t, int); extern HAL_STATUS ar5210SetQuiet(struct ath_hal *, uint32_t, uint32_t, uint32_t, HAL_QUIET_FLAG); extern HAL_STATUS ar5210GetCapability(struct ath_hal *, HAL_CAPABILITY_TYPE, uint32_t, uint32_t *); extern HAL_BOOL ar5210SetCapability(struct ath_hal *, HAL_CAPABILITY_TYPE, uint32_t, uint32_t, HAL_STATUS *); extern HAL_BOOL ar5210GetDiagState(struct ath_hal *ah, int request, const void *args, uint32_t argsize, void **result, uint32_t *resultsize); extern uint32_t ar5210Get11nExtBusy(struct ath_hal *); extern HAL_BOOL ar5210GetMibCycleCounts(struct ath_hal *, HAL_SURVEY_SAMPLE *); extern void ar5210SetChainMasks(struct ath_hal *, uint32_t, uint32_t); extern void ar5210EnableDfs(struct ath_hal *, HAL_PHYERR_PARAM *); extern void ar5210GetDfsThresh(struct ath_hal *, HAL_PHYERR_PARAM *); extern void ar5210UpdateDiagReg(struct ath_hal *ah, uint32_t val); extern u_int ar5210GetKeyCacheSize(struct ath_hal *); extern HAL_BOOL ar5210IsKeyCacheEntryValid(struct ath_hal *, uint16_t); extern HAL_BOOL ar5210ResetKeyCacheEntry(struct ath_hal *, uint16_t entry); extern HAL_BOOL ar5210SetKeyCacheEntry(struct ath_hal *, uint16_t entry, const HAL_KEYVAL *, const uint8_t *mac, int xorKey); extern HAL_BOOL ar5210SetKeyCacheEntryMac(struct ath_hal *, uint16_t, const uint8_t *); extern HAL_BOOL ar5210SetPowerMode(struct ath_hal *, uint32_t powerRequest, int setChip); extern HAL_POWER_MODE ar5210GetPowerMode(struct ath_hal *); extern void ar5210SetBeaconTimers(struct ath_hal *, const HAL_BEACON_TIMERS *); extern void ar5210BeaconInit(struct ath_hal *, uint32_t, uint32_t); extern void ar5210SetStaBeaconTimers(struct ath_hal *, const HAL_BEACON_STATE *); extern void ar5210ResetStaBeaconTimers(struct ath_hal *); extern uint64_t ar5210GetNextTBTT(struct ath_hal *); extern HAL_BOOL ar5210IsInterruptPending(struct ath_hal *); extern HAL_BOOL ar5210GetPendingInterrupts(struct ath_hal *, HAL_INT *); extern HAL_INT ar5210GetInterrupts(struct ath_hal *); extern HAL_INT ar5210SetInterrupts(struct ath_hal *, HAL_INT ints); extern const HAL_RATE_TABLE *ar5210GetRateTable(struct ath_hal *, u_int mode); extern HAL_BOOL ar5210AniControl(struct ath_hal *, HAL_ANI_CMD, int ); extern void ar5210AniPoll(struct ath_hal *, const struct ieee80211_channel *); extern void ar5210RxMonitor(struct ath_hal *, const HAL_NODE_STATS *, const struct ieee80211_channel *); extern void ar5210MibEvent(struct ath_hal *, const HAL_NODE_STATS *); #endif /* _ATH_AR5210_H_ */ Index: head/sys/dev/ath/ath_hal/ar5210/ar5210_recv.c =================================================================== --- head/sys/dev/ath/ath_hal/ar5210/ar5210_recv.c (revision 346469) +++ head/sys/dev/ath/ath_hal/ar5210/ar5210_recv.c (revision 346470) @@ -1,272 +1,272 @@ /*- * SPDX-License-Identifier: ISC * * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting * Copyright (c) 2002-2004 Atheros Communications, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $FreeBSD$ */ #include "opt_ah.h" #include "ah.h" #include "ah_internal.h" #include "ah_desc.h" #include "ar5210/ar5210.h" #include "ar5210/ar5210reg.h" #include "ar5210/ar5210desc.h" /* * Get the RXDP. */ uint32_t ar5210GetRxDP(struct ath_hal *ah, HAL_RX_QUEUE qtype) { HALASSERT(qtype == HAL_RX_QUEUE_HP); return OS_REG_READ(ah, AR_RXDP); } /* * Set the RxDP. */ void ar5210SetRxDP(struct ath_hal *ah, uint32_t rxdp, HAL_RX_QUEUE qtype) { HALASSERT(qtype == HAL_RX_QUEUE_HP); OS_REG_WRITE(ah, AR_RXDP, rxdp); } /* * Set Receive Enable bits. */ void ar5210EnableReceive(struct ath_hal *ah) { OS_REG_WRITE(ah, AR_CR, AR_CR_RXE); } /* * Stop Receive at the DMA engine */ HAL_BOOL ar5210StopDmaReceive(struct ath_hal *ah) { int i; OS_REG_WRITE(ah, AR_CR, AR_CR_RXD); /* Set receive disable bit */ for (i = 0; i < 1000; i++) { if ((OS_REG_READ(ah, AR_CR) & AR_CR_RXE) == 0) return AH_TRUE; OS_DELAY(10); } #ifdef AH_DEBUG ath_hal_printf(ah, "ar5210: dma receive failed to stop in 10ms\n"); ath_hal_printf(ah, "AR_CR=0x%x\n", OS_REG_READ(ah, AR_CR)); ath_hal_printf(ah, "AR_DIAG_SW=0x%x\n", OS_REG_READ(ah, AR_DIAG_SW)); #endif return AH_FALSE; } /* * Start Transmit at the PCU engine (unpause receive) */ void -ar5210StartPcuReceive(struct ath_hal *ah) +ar5210StartPcuReceive(struct ath_hal *ah, HAL_BOOL is_scanning) { ar5210UpdateDiagReg(ah, OS_REG_READ(ah, AR_DIAG_SW) & ~(AR_DIAG_SW_DIS_RX)); } /* * Stop Transmit at the PCU engine (pause receive) */ void ar5210StopPcuReceive(struct ath_hal *ah) { ar5210UpdateDiagReg(ah, OS_REG_READ(ah, AR_DIAG_SW) | AR_DIAG_SW_DIS_RX); } /* * Set multicast filter 0 (lower 32-bits) * filter 1 (upper 32-bits) */ void ar5210SetMulticastFilter(struct ath_hal *ah, uint32_t filter0, uint32_t filter1) { OS_REG_WRITE(ah, AR_MCAST_FIL0, filter0); OS_REG_WRITE(ah, AR_MCAST_FIL1, filter1); } /* * Clear multicast filter by index */ HAL_BOOL ar5210ClrMulticastFilterIndex(struct ath_hal *ah, uint32_t ix) { uint32_t val; if (ix >= 64) return AH_FALSE; if (ix >= 32) { val = OS_REG_READ(ah, AR_MCAST_FIL1); OS_REG_WRITE(ah, AR_MCAST_FIL1, (val &~ (1<<(ix-32)))); } else { val = OS_REG_READ(ah, AR_MCAST_FIL0); OS_REG_WRITE(ah, AR_MCAST_FIL0, (val &~ (1<= 64) return AH_FALSE; if (ix >= 32) { val = OS_REG_READ(ah, AR_MCAST_FIL1); OS_REG_WRITE(ah, AR_MCAST_FIL1, (val | (1<<(ix-32)))); } else { val = OS_REG_READ(ah, AR_MCAST_FIL0); OS_REG_WRITE(ah, AR_MCAST_FIL0, (val | (1<ds_ctl0 = 0; ads->ds_ctl1 = size & AR_BufLen; if (ads->ds_ctl1 != size) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: buffer size %u too large\n", __func__, size); return AH_FALSE; } if (flags & HAL_RXDESC_INTREQ) ads->ds_ctl1 |= AR_RxInterReq; ads->ds_status0 = ads->ds_status1 = 0; return AH_TRUE; } /* * Process an RX descriptor, and return the status to the caller. * Copy some hardware specific items into the software portion * of the descriptor. * * NB: the caller is responsible for validating the memory contents * of the descriptor (e.g. flushing any cached copy). */ HAL_STATUS ar5210ProcRxDesc(struct ath_hal *ah, struct ath_desc *ds, uint32_t pa, struct ath_desc *nds, uint64_t tsf, struct ath_rx_status *rs) { struct ar5210_desc *ads = AR5210DESC(ds); struct ar5210_desc *ands = AR5210DESC(nds); uint32_t now, rstamp; if ((ads->ds_status1 & AR_Done) == 0) return HAL_EINPROGRESS; /* * Given the use of a self-linked tail be very sure that the hw is * done with this descriptor; the hw may have done this descriptor * once and picked it up again...make sure the hw has moved on. */ if ((ands->ds_status1 & AR_Done) == 0 && OS_REG_READ(ah, AR_RXDP) == pa) return HAL_EINPROGRESS; rs->rs_datalen = ads->ds_status0 & AR_DataLen; rstamp = MS(ads->ds_status1, AR_RcvTimestamp); /* * Convert timestamp. The value in the * descriptor is bits [10..22] of the TSF. */ now = (OS_REG_READ(ah, AR_TSF_L32) >> 10) & 0xffff; if ((now & 0x1fff) < rstamp) rstamp |= (now - 0x2000) & 0xffff; else rstamp |= now; /* NB: keep only 15 bits for consistency w/ other chips */ rs->rs_tstamp = rstamp & 0x7fff; rs->rs_status = 0; if ((ads->ds_status1 & AR_FrmRcvOK) == 0) { if (ads->ds_status1 & AR_CRCErr) rs->rs_status |= HAL_RXERR_CRC; else if (ads->ds_status1 & AR_DecryptCRCErr) rs->rs_status |= HAL_RXERR_DECRYPT; else if (ads->ds_status1 & AR_FIFOOverrun) rs->rs_status |= HAL_RXERR_FIFO; else { rs->rs_status |= HAL_RXERR_PHY; rs->rs_phyerr = (ads->ds_status1 & AR_PHYErr) >> AR_PHYErr_S; } } /* XXX what about KeyCacheMiss? */ rs->rs_rssi = MS(ads->ds_status0, AR_RcvSigStrength); if (ads->ds_status1 & AR_KeyIdxValid) rs->rs_keyix = MS(ads->ds_status1, AR_KeyIdx); else rs->rs_keyix = HAL_RXKEYIX_INVALID; /* NB: caller expected to do rate table mapping */ rs->rs_rate = MS(ads->ds_status0, AR_RcvRate); rs->rs_antenna = (ads->ds_status0 & AR_RcvAntenna) ? 1 : 0; rs->rs_more = (ads->ds_status0 & AR_More) ? 1 : 0; return HAL_OK; } Index: head/sys/dev/ath/ath_hal/ar5211/ar5211.h =================================================================== --- head/sys/dev/ath/ath_hal/ar5211/ar5211.h (revision 346469) +++ head/sys/dev/ath/ath_hal/ar5211/ar5211.h (revision 346470) @@ -1,331 +1,331 @@ /*- * SPDX-License-Identifier: ISC * * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting * Copyright (c) 2002-2006 Atheros Communications, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $FreeBSD$ */ #ifndef _ATH_AR5211_H_ #define _ATH_AR5211_H_ #include "ah_eeprom.h" #define AR5211_MAGIC 0x19570405 /* Classes for WME streams */ #define AC_BK 0 #define AC_BE 1 #define AC_VI 2 #define AC_VO 3 /* DCU Transmit Filter macros */ #define CALC_MMR(dcu, idx) \ ( (4 * dcu) + (idx < 32 ? 0 : (idx < 64 ? 1 : (idx < 96 ? 2 : 3))) ) #define TXBLK_FROM_MMR(mmr) \ (AR_D_TXBLK_BASE + ((mmr & 0x1f) << 6) + ((mmr & 0x20) >> 3)) #define CALC_TXBLK_ADDR(dcu, idx) (TXBLK_FROM_MMR(CALC_MMR(dcu, idx))) #define CALC_TXBLK_VALUE(idx) (1 << (idx & 0x1f)) /* MAC register values */ #define INIT_INTERRUPT_MASK \ ( AR_IMR_TXERR | AR_IMR_TXOK | AR_IMR_RXORN | \ AR_IMR_RXERR | AR_IMR_RXOK | AR_IMR_TXURN | \ AR_IMR_HIUERR ) #define INIT_BEACON_CONTROL \ ( (INIT_RESET_TSF << 24) | (INIT_BEACON_EN << 23) | \ (INIT_TIM_OFFSET << 16) | INIT_BEACON_PERIOD ) #define INIT_CONFIG_STATUS 0x00000000 #define INIT_RSSI_THR 0x00000700 /* Missed beacon counter initialized to 0x7 (max is 0xff) */ #define INIT_IQCAL_LOG_COUNT_MAX 0xF #define INIT_BCON_CNTRL_REG 0x00000000 #define INIT_BEACON_PERIOD 0xffff #define INIT_TIM_OFFSET 0 #define INIT_BEACON_EN 0 /* this should be set by AP only when it's ready */ #define INIT_RESET_TSF 0 /* * Various fifo fill before Tx start, in 64-byte units * i.e. put the frame in the air while still DMAing */ #define MIN_TX_FIFO_THRESHOLD 0x1 #define MAX_TX_FIFO_THRESHOLD ((IEEE80211_MAX_LEN / 64) + 1) #define INIT_TX_FIFO_THRESHOLD MIN_TX_FIFO_THRESHOLD /* * Gain support. */ typedef struct _gainOptStep { int16_t paramVal[4]; int32_t stepGain; int8_t stepName[16]; } GAIN_OPTIMIZATION_STEP; typedef struct { uint32_t numStepsInLadder; uint32_t defaultStepNum; GAIN_OPTIMIZATION_STEP optStep[10]; } GAIN_OPTIMIZATION_LADDER; typedef struct { uint32_t currStepNum; uint32_t currGain; uint32_t targetGain; uint32_t loTrig; uint32_t hiTrig; uint32_t active; const GAIN_OPTIMIZATION_STEP *currStep; } GAIN_VALUES; enum { RFGAIN_INACTIVE, RFGAIN_READ_REQUESTED, RFGAIN_NEED_CHANGE }; /* * Header Info - general parameters and * values set for each chipset board solution * that are programmed every reset */ struct ath_hal_5211 { struct ath_hal_private ah_priv; /* base class */ GAIN_VALUES ah_gainValues; uint8_t ah_macaddr[IEEE80211_ADDR_LEN]; uint8_t ah_bssid[IEEE80211_ADDR_LEN]; /* * Runtime state. */ uint32_t ah_maskReg; /* copy of AR_IMR */ uint32_t ah_txOkInterruptMask; uint32_t ah_txErrInterruptMask; uint32_t ah_txDescInterruptMask; uint32_t ah_txEolInterruptMask; uint32_t ah_txUrnInterruptMask; HAL_TX_QUEUE_INFO ah_txq[HAL_NUM_TX_QUEUES]; HAL_ANT_SETTING ah_diversityControl; /* antenna setting */ uint32_t ah_calibrationTime; HAL_BOOL ah_bIQCalibration; int ah_rfgainState; uint32_t ah_tx6PowerInHalfDbm; /* power output for 6Mb tx */ uint32_t ah_staId1Defaults; /* STA_ID1 default settings */ uint32_t ah_beaconInterval; uint32_t ah_rssiThr; /* RSSI_THR settings */ u_int ah_sifstime; /* user-specified sifs time */ u_int ah_slottime; /* user-specified slot time */ u_int ah_acktimeout; /* user-specified ack timeout */ u_int ah_ctstimeout; /* user-specified cts timeout */ /* * RF Silent handling. */ uint32_t ah_gpioSelect; /* GPIO pin to use */ uint32_t ah_polarity; /* polarity to disable RF */ uint32_t ah_gpioBit; /* after init, prev value */ }; #define AH5211(ah) ((struct ath_hal_5211 *)(ah)) struct ath_hal; extern void ar5211Detach(struct ath_hal *); extern HAL_BOOL ar5211Reset(struct ath_hal *, HAL_OPMODE, struct ieee80211_channel *, HAL_BOOL bChannelChange, HAL_RESET_TYPE, HAL_STATUS *); extern HAL_BOOL ar5211PhyDisable(struct ath_hal *); extern HAL_BOOL ar5211Disable(struct ath_hal *); extern HAL_BOOL ar5211ChipReset(struct ath_hal *, const struct ieee80211_channel *); extern HAL_BOOL ar5211PerCalibration(struct ath_hal *, struct ieee80211_channel *, HAL_BOOL *); extern HAL_BOOL ar5211PerCalibrationN(struct ath_hal *ah, struct ieee80211_channel *chan, u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone); extern HAL_BOOL ar5211ResetCalValid(struct ath_hal *ah, const struct ieee80211_channel *); extern HAL_BOOL ar5211SetTxPowerLimit(struct ath_hal *, uint32_t limit); extern HAL_BOOL ar5211CalNoiseFloor(struct ath_hal *, const struct ieee80211_channel *); extern HAL_BOOL ar5211SetAntennaSwitchInternal(struct ath_hal *, HAL_ANT_SETTING, const struct ieee80211_channel *); extern int16_t ar5211GetNfAdjust(struct ath_hal *, const HAL_CHANNEL_INTERNAL *); extern HAL_BOOL ar5211ResetDma(struct ath_hal *, HAL_OPMODE); extern void ar5211InitializeGainValues(struct ath_hal *); extern HAL_RFGAIN ar5211GetRfgain(struct ath_hal *); extern void ar5211SetPCUConfig(struct ath_hal *); extern HAL_BOOL ar5211SetTxQueueProps(struct ath_hal *ah, int q, const HAL_TXQ_INFO *qInfo); extern HAL_BOOL ar5211GetTxQueueProps(struct ath_hal *ah, int q, HAL_TXQ_INFO *qInfo); extern int ar5211SetupTxQueue(struct ath_hal *ah, HAL_TX_QUEUE type, const HAL_TXQ_INFO *qInfo); extern HAL_BOOL ar5211ReleaseTxQueue(struct ath_hal *ah, u_int q); extern HAL_BOOL ar5211ResetTxQueue(struct ath_hal *ah, u_int q); extern uint32_t ar5211GetTxDP(struct ath_hal *, u_int); extern HAL_BOOL ar5211SetTxDP(struct ath_hal *, u_int, uint32_t txdp); extern HAL_BOOL ar5211UpdateTxTrigLevel(struct ath_hal *, HAL_BOOL); extern HAL_BOOL ar5211StartTxDma(struct ath_hal *, u_int); extern HAL_BOOL ar5211StopTxDma(struct ath_hal *, u_int); extern uint32_t ar5211NumTxPending(struct ath_hal *, u_int qnum); extern HAL_BOOL ar5211IsTxQueueStopped(struct ath_hal *, u_int); extern HAL_BOOL ar5211GetTransmitFilterIndex(struct ath_hal *, uint32_t); extern HAL_BOOL ar5211SetupTxDesc(struct ath_hal *, struct ath_desc *, u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type, u_int txPower, u_int txRate0, u_int txTries0, u_int keyIx, u_int antMode, u_int flags, u_int rtsctsRate, u_int rtsctsDuration, u_int compicvLen, u_int compivLen, u_int comp); extern HAL_BOOL ar5211SetupXTxDesc(struct ath_hal *, struct ath_desc *, u_int txRate1, u_int txRetries1, u_int txRate2, u_int txRetries2, u_int txRate3, u_int txRetries3); extern HAL_BOOL ar5211FillTxDesc(struct ath_hal *, struct ath_desc *, HAL_DMA_ADDR *bufAddrList, uint32_t *segLenList, u_int descId, u_int qcuId, HAL_BOOL firstSeg, HAL_BOOL lastSeg, const struct ath_desc *ds0); extern HAL_STATUS ar5211ProcTxDesc(struct ath_hal *, struct ath_desc *, struct ath_tx_status *); extern void ar5211GetTxIntrQueue(struct ath_hal *ah, uint32_t *); extern void ar5211IntrReqTxDesc(struct ath_hal *ah, struct ath_desc *); extern HAL_BOOL ar5211GetTxCompletionRates(struct ath_hal *ah, const struct ath_desc *ds0, int *rates, int *tries); extern void ar5211SetTxDescLink(struct ath_hal *ah, void *ds, uint32_t link); extern void ar5211GetTxDescLink(struct ath_hal *ah, void *ds, uint32_t *link); extern void ar5211GetTxDescLinkPtr(struct ath_hal *ah, void *ds, uint32_t **linkptr); extern uint32_t ar5211GetRxDP(struct ath_hal *, HAL_RX_QUEUE); extern void ar5211SetRxDP(struct ath_hal *, uint32_t rxdp, HAL_RX_QUEUE); extern void ar5211EnableReceive(struct ath_hal *); extern HAL_BOOL ar5211StopDmaReceive(struct ath_hal *); -extern void ar5211StartPcuReceive(struct ath_hal *); +extern void ar5211StartPcuReceive(struct ath_hal *, HAL_BOOL); extern void ar5211StopPcuReceive(struct ath_hal *); extern void ar5211SetMulticastFilter(struct ath_hal *, uint32_t filter0, uint32_t filter1); extern HAL_BOOL ar5211ClrMulticastFilterIndex(struct ath_hal *, uint32_t); extern HAL_BOOL ar5211SetMulticastFilterIndex(struct ath_hal *, uint32_t); extern uint32_t ar5211GetRxFilter(struct ath_hal *); extern void ar5211SetRxFilter(struct ath_hal *, uint32_t); extern HAL_BOOL ar5211SetupRxDesc(struct ath_hal *, struct ath_desc *, uint32_t, u_int flags); extern HAL_STATUS ar5211ProcRxDesc(struct ath_hal *, struct ath_desc *, uint32_t, struct ath_desc *, uint64_t, struct ath_rx_status *); extern void ar5211GetMacAddress(struct ath_hal *, uint8_t *); extern HAL_BOOL ar5211SetMacAddress(struct ath_hal *ah, const uint8_t *); extern void ar5211GetBssIdMask(struct ath_hal *, uint8_t *); extern HAL_BOOL ar5211SetBssIdMask(struct ath_hal *, const uint8_t *); extern HAL_BOOL ar5211EepromRead(struct ath_hal *, u_int off, uint16_t *data); extern HAL_BOOL ar5211EepromWrite(struct ath_hal *, u_int off, uint16_t data); extern HAL_BOOL ar5211SetRegulatoryDomain(struct ath_hal *, uint16_t, HAL_STATUS *); extern u_int ar5211GetWirelessModes(struct ath_hal *); extern void ar5211EnableRfKill(struct ath_hal *); extern uint32_t ar5211GpioGet(struct ath_hal *, uint32_t gpio); extern void ar5211GpioSetIntr(struct ath_hal *, u_int, uint32_t ilevel); extern HAL_BOOL ar5211GpioCfgOutput(struct ath_hal *, uint32_t gpio, HAL_GPIO_MUX_TYPE); extern HAL_BOOL ar5211GpioCfgInput(struct ath_hal *, uint32_t gpio); extern HAL_BOOL ar5211GpioSet(struct ath_hal *, uint32_t gpio, uint32_t val); extern void ar5211SetLedState(struct ath_hal *, HAL_LED_STATE); extern u_int ar5211AntennaGet(struct ath_hal *); extern void ar5211WriteAssocid(struct ath_hal *, const uint8_t *bssid, uint16_t assocId); extern uint64_t ar5211GetTsf64(struct ath_hal *); extern uint32_t ar5211GetTsf32(struct ath_hal *); extern void ar5211ResetTsf(struct ath_hal *); extern uint32_t ar5211GetMaxTurboRate(struct ath_hal *); extern uint32_t ar5211GetRandomSeed(struct ath_hal *); extern HAL_BOOL ar5211DetectCardPresent(struct ath_hal *); extern void ar5211UpdateMibCounters(struct ath_hal *, HAL_MIB_STATS *); extern void ar5211EnableHwEncryption(struct ath_hal *); extern void ar5211DisableHwEncryption(struct ath_hal *); extern HAL_BOOL ar5211SetSlotTime(struct ath_hal *, u_int); extern u_int ar5211GetSlotTime(struct ath_hal *); extern HAL_BOOL ar5211SetAckTimeout(struct ath_hal *, u_int); extern u_int ar5211GetAckTimeout(struct ath_hal *); extern HAL_BOOL ar5211SetAckCTSRate(struct ath_hal *, u_int); extern u_int ar5211GetAckCTSRate(struct ath_hal *); extern HAL_BOOL ar5211SetCTSTimeout(struct ath_hal *, u_int); extern u_int ar5211GetCTSTimeout(struct ath_hal *); extern HAL_BOOL ar5211SetSifsTime(struct ath_hal *, u_int); extern u_int ar5211GetSifsTime(struct ath_hal *); extern HAL_BOOL ar5211SetDecompMask(struct ath_hal *, uint16_t, int); extern void ar5211SetCoverageClass(struct ath_hal *, uint8_t, int); extern HAL_STATUS ar5211SetQuiet(struct ath_hal *, uint32_t, uint32_t, uint32_t, HAL_QUIET_FLAG); extern uint32_t ar5211GetCurRssi(struct ath_hal *); extern u_int ar5211GetDefAntenna(struct ath_hal *); extern void ar5211SetDefAntenna(struct ath_hal *ah, u_int antenna); extern HAL_ANT_SETTING ar5211GetAntennaSwitch(struct ath_hal *); extern HAL_BOOL ar5211SetAntennaSwitch(struct ath_hal *, HAL_ANT_SETTING); extern HAL_STATUS ar5211GetCapability(struct ath_hal *, HAL_CAPABILITY_TYPE, uint32_t, uint32_t *); extern HAL_BOOL ar5211SetCapability(struct ath_hal *, HAL_CAPABILITY_TYPE, uint32_t, uint32_t, HAL_STATUS *); extern HAL_BOOL ar5211GetDiagState(struct ath_hal *ah, int request, const void *args, uint32_t argsize, void **result, uint32_t *resultsize); extern uint32_t ar5211Get11nExtBusy(struct ath_hal *); extern HAL_BOOL ar5211GetMibCycleCounts(struct ath_hal *, HAL_SURVEY_SAMPLE *); extern void ar5211SetChainMasks(struct ath_hal *ah, uint32_t, uint32_t); extern void ar5211EnableDfs(struct ath_hal *, HAL_PHYERR_PARAM *); extern void ar5211GetDfsThresh(struct ath_hal *, HAL_PHYERR_PARAM *); extern u_int ar5211GetKeyCacheSize(struct ath_hal *); extern HAL_BOOL ar5211IsKeyCacheEntryValid(struct ath_hal *, uint16_t); extern HAL_BOOL ar5211ResetKeyCacheEntry(struct ath_hal *, uint16_t entry); extern HAL_BOOL ar5211SetKeyCacheEntry(struct ath_hal *, uint16_t entry, const HAL_KEYVAL *, const uint8_t *mac, int xorKey); extern HAL_BOOL ar5211SetKeyCacheEntryMac(struct ath_hal *, uint16_t, const uint8_t *); extern HAL_BOOL ar5211SetPowerMode(struct ath_hal *, uint32_t powerRequest, int setChip); extern HAL_POWER_MODE ar5211GetPowerMode(struct ath_hal *); extern void ar5211SetBeaconTimers(struct ath_hal *, const HAL_BEACON_TIMERS *); extern void ar5211BeaconInit(struct ath_hal *, uint32_t, uint32_t); extern void ar5211SetStaBeaconTimers(struct ath_hal *, const HAL_BEACON_STATE *); extern void ar5211ResetStaBeaconTimers(struct ath_hal *); extern uint64_t ar5211GetNextTBTT(struct ath_hal *); extern HAL_BOOL ar5211IsInterruptPending(struct ath_hal *); extern HAL_BOOL ar5211GetPendingInterrupts(struct ath_hal *, HAL_INT *); extern HAL_INT ar5211GetInterrupts(struct ath_hal *); extern HAL_INT ar5211SetInterrupts(struct ath_hal *, HAL_INT ints); extern const HAL_RATE_TABLE *ar5211GetRateTable(struct ath_hal *, u_int mode); extern HAL_BOOL ar5211AniControl(struct ath_hal *, HAL_ANI_CMD, int ); extern void ar5211RxMonitor(struct ath_hal *, const HAL_NODE_STATS *, const struct ieee80211_channel *); extern void ar5211AniPoll(struct ath_hal *, const struct ieee80211_channel *); extern void ar5211MibEvent(struct ath_hal *, const HAL_NODE_STATS *); #endif /* _ATH_AR5211_H_ */ Index: head/sys/dev/ath/ath_hal/ar5211/ar5211_recv.c =================================================================== --- head/sys/dev/ath/ath_hal/ar5211/ar5211_recv.c (revision 346469) +++ head/sys/dev/ath/ath_hal/ar5211/ar5211_recv.c (revision 346470) @@ -1,251 +1,251 @@ /*- * SPDX-License-Identifier: ISC * * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting * Copyright (c) 2002-2006 Atheros Communications, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $FreeBSD$ */ #include "opt_ah.h" #include "ah.h" #include "ah_internal.h" #include "ah_desc.h" #include "ar5211/ar5211.h" #include "ar5211/ar5211reg.h" #include "ar5211/ar5211desc.h" /* * Get the RXDP. */ uint32_t ar5211GetRxDP(struct ath_hal *ah, HAL_RX_QUEUE qtype) { HALASSERT(qtype == HAL_RX_QUEUE_HP); return OS_REG_READ(ah, AR_RXDP); } /* * Set the RxDP. */ void ar5211SetRxDP(struct ath_hal *ah, uint32_t rxdp, HAL_RX_QUEUE qtype) { HALASSERT(qtype == HAL_RX_QUEUE_HP); OS_REG_WRITE(ah, AR_RXDP, rxdp); HALASSERT(OS_REG_READ(ah, AR_RXDP) == rxdp); } /* * Set Receive Enable bits. */ void ar5211EnableReceive(struct ath_hal *ah) { OS_REG_WRITE(ah, AR_CR, AR_CR_RXE); } /* * Stop Receive at the DMA engine */ HAL_BOOL ar5211StopDmaReceive(struct ath_hal *ah) { OS_REG_WRITE(ah, AR_CR, AR_CR_RXD); /* Set receive disable bit */ if (!ath_hal_wait(ah, AR_CR, AR_CR_RXE, 0)) { #ifdef AH_DEBUG ath_hal_printf(ah, "%s failed to stop in 10ms\n" "AR_CR=0x%08X\nAR_DIAG_SW=0x%08X\n" , __func__ , OS_REG_READ(ah, AR_CR) , OS_REG_READ(ah, AR_DIAG_SW) ); #endif return AH_FALSE; } else { return AH_TRUE; } } /* * Start Transmit at the PCU engine (unpause receive) */ void -ar5211StartPcuReceive(struct ath_hal *ah) +ar5211StartPcuReceive(struct ath_hal *ah, HAL_BOOL is_scanning) { OS_REG_WRITE(ah, AR_DIAG_SW, OS_REG_READ(ah, AR_DIAG_SW) & ~(AR_DIAG_SW_DIS_RX)); } /* * Stop Transmit at the PCU engine (pause receive) */ void ar5211StopPcuReceive(struct ath_hal *ah) { OS_REG_WRITE(ah, AR_DIAG_SW, OS_REG_READ(ah, AR_DIAG_SW) | AR_DIAG_SW_DIS_RX); } /* * Set multicast filter 0 (lower 32-bits) * filter 1 (upper 32-bits) */ void ar5211SetMulticastFilter(struct ath_hal *ah, uint32_t filter0, uint32_t filter1) { OS_REG_WRITE(ah, AR_MCAST_FIL0, filter0); OS_REG_WRITE(ah, AR_MCAST_FIL1, filter1); } /* * Clear multicast filter by index */ HAL_BOOL ar5211ClrMulticastFilterIndex(struct ath_hal *ah, uint32_t ix) { uint32_t val; if (ix >= 64) return AH_FALSE; if (ix >= 32) { val = OS_REG_READ(ah, AR_MCAST_FIL1); OS_REG_WRITE(ah, AR_MCAST_FIL1, (val &~ (1<<(ix-32)))); } else { val = OS_REG_READ(ah, AR_MCAST_FIL0); OS_REG_WRITE(ah, AR_MCAST_FIL0, (val &~ (1<= 64) return AH_FALSE; if (ix >= 32) { val = OS_REG_READ(ah, AR_MCAST_FIL1); OS_REG_WRITE(ah, AR_MCAST_FIL1, (val | (1<<(ix-32)))); } else { val = OS_REG_READ(ah, AR_MCAST_FIL0); OS_REG_WRITE(ah, AR_MCAST_FIL0, (val | (1<ds_ctl0 = 0; ads->ds_ctl1 = size & AR_BufLen; if (ads->ds_ctl1 != size) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: buffer size %u too large\n", __func__, size); return AH_FALSE; } if (flags & HAL_RXDESC_INTREQ) ads->ds_ctl1 |= AR_RxInterReq; ads->ds_status0 = ads->ds_status1 = 0; return AH_TRUE; } /* * Process an RX descriptor, and return the status to the caller. * Copy some hardware specific items into the software portion * of the descriptor. * * NB: the caller is responsible for validating the memory contents * of the descriptor (e.g. flushing any cached copy). */ HAL_STATUS ar5211ProcRxDesc(struct ath_hal *ah, struct ath_desc *ds, uint32_t pa, struct ath_desc *nds, uint64_t tsf, struct ath_rx_status *rs) { struct ar5211_desc *ads = AR5211DESC(ds); struct ar5211_desc *ands = AR5211DESC(nds); if ((ads->ds_status1 & AR_Done) == 0) return HAL_EINPROGRESS; /* * Given the use of a self-linked tail be very sure that the hw is * done with this descriptor; the hw may have done this descriptor * once and picked it up again...make sure the hw has moved on. */ if ((ands->ds_status1 & AR_Done) == 0 && OS_REG_READ(ah, AR_RXDP) == pa) return HAL_EINPROGRESS; rs->rs_datalen = ads->ds_status0 & AR_DataLen; rs->rs_tstamp = MS(ads->ds_status1, AR_RcvTimestamp); rs->rs_status = 0; if ((ads->ds_status1 & AR_FrmRcvOK) == 0) { if (ads->ds_status1 & AR_CRCErr) rs->rs_status |= HAL_RXERR_CRC; else if (ads->ds_status1 & AR_DecryptCRCErr) rs->rs_status |= HAL_RXERR_DECRYPT; else { rs->rs_status |= HAL_RXERR_PHY; rs->rs_phyerr = MS(ads->ds_status1, AR_PHYErr); } } /* XXX what about KeyCacheMiss? */ rs->rs_rssi = MS(ads->ds_status0, AR_RcvSigStrength); if (ads->ds_status1 & AR_KeyIdxValid) rs->rs_keyix = MS(ads->ds_status1, AR_KeyIdx); else rs->rs_keyix = HAL_RXKEYIX_INVALID; /* NB: caller expected to do rate table mapping */ rs->rs_rate = MS(ads->ds_status0, AR_RcvRate); rs->rs_antenna = MS(ads->ds_status0, AR_RcvAntenna); rs->rs_more = (ads->ds_status0 & AR_More) ? 1 : 0; return HAL_OK; } Index: head/sys/dev/ath/ath_hal/ar5212/ar5212.h =================================================================== --- head/sys/dev/ath/ath_hal/ar5212/ar5212.h (revision 346469) +++ head/sys/dev/ath/ath_hal/ar5212/ar5212.h (revision 346470) @@ -1,661 +1,661 @@ /*- * SPDX-License-Identifier: ISC * * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting * Copyright (c) 2002-2008 Atheros Communications, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $FreeBSD$ */ #ifndef _ATH_AR5212_H_ #define _ATH_AR5212_H_ #include "ah_eeprom.h" #define AR5212_MAGIC 0x19541014 /* DCU Transmit Filter macros */ #define CALC_MMR(dcu, idx) \ ( (4 * dcu) + (idx < 32 ? 0 : (idx < 64 ? 1 : (idx < 96 ? 2 : 3))) ) #define TXBLK_FROM_MMR(mmr) \ (AR_D_TXBLK_BASE + ((mmr & 0x1f) << 6) + ((mmr & 0x20) >> 3)) #define CALC_TXBLK_ADDR(dcu, idx) (TXBLK_FROM_MMR(CALC_MMR(dcu, idx))) #define CALC_TXBLK_VALUE(idx) (1 << (idx & 0x1f)) /* MAC register values */ #define INIT_INTERRUPT_MASK \ ( AR_IMR_TXERR | AR_IMR_TXOK | AR_IMR_RXORN | \ AR_IMR_RXERR | AR_IMR_RXOK | AR_IMR_TXURN | \ AR_IMR_HIUERR ) #define INIT_BEACON_CONTROL \ ((INIT_RESET_TSF << 24) | (INIT_BEACON_EN << 23) | \ (INIT_TIM_OFFSET << 16) | INIT_BEACON_PERIOD) #define INIT_CONFIG_STATUS 0x00000000 #define INIT_RSSI_THR 0x00000781 /* Missed beacon counter initialized to 0x7 (max is 0xff) */ #define INIT_IQCAL_LOG_COUNT_MAX 0xF #define INIT_BCON_CNTRL_REG 0x00000000 #define INIT_USEC 40 #define HALF_RATE_USEC 19 /* ((40 / 2) - 1 ) */ #define QUARTER_RATE_USEC 9 /* ((40 / 4) - 1 ) */ #define RX_NON_FULL_RATE_LATENCY 63 #define TX_HALF_RATE_LATENCY 108 #define TX_QUARTER_RATE_LATENCY 216 #define IFS_SLOT_FULL_RATE 0x168 /* 9 us half, 40 MHz core clock (9*40) */ #define IFS_SLOT_HALF_RATE 0x104 /* 13 us half, 20 MHz core clock (13*20) */ #define IFS_SLOT_QUARTER_RATE 0xD2 /* 21 us quarter, 10 MHz core clock (21*10) */ #define IFS_EIFS_FULL_RATE 0xE60 /* (74 + (2 * 9)) * 40MHz core clock */ #define IFS_EIFS_HALF_RATE 0xDAC /* (149 + (2 * 13)) * 20MHz core clock */ #define IFS_EIFS_QUARTER_RATE 0xD48 /* (298 + (2 * 21)) * 10MHz core clock */ #define ACK_CTS_TIMEOUT_11A 0x3E8 /* ACK timeout in 11a core clocks */ /* Tx frame start to tx data start delay */ #define TX_FRAME_D_START_HALF_RATE 0xc #define TX_FRAME_D_START_QUARTER_RATE 0xd /* * Various fifo fill before Tx start, in 64-byte units * i.e. put the frame in the air while still DMAing */ #define MIN_TX_FIFO_THRESHOLD 0x1 #define MAX_TX_FIFO_THRESHOLD ((IEEE80211_MAX_LEN / 64) + 1) #define INIT_TX_FIFO_THRESHOLD MIN_TX_FIFO_THRESHOLD #define HAL_DECOMP_MASK_SIZE 128 /* 1 byte per key */ /* * Gain support. */ #define NUM_CORNER_FIX_BITS 4 #define NUM_CORNER_FIX_BITS_5112 7 #define DYN_ADJ_UP_MARGIN 15 #define DYN_ADJ_LO_MARGIN 20 #define PHY_PROBE_CCK_CORRECTION 5 #define CCK_OFDM_GAIN_DELTA 15 enum GAIN_PARAMS { GP_TXCLIP, GP_PD90, GP_PD84, GP_GSEL, }; enum GAIN_PARAMS_5112 { GP_MIXGAIN_OVR, GP_PWD_138, GP_PWD_137, GP_PWD_136, GP_PWD_132, GP_PWD_131, GP_PWD_130, }; typedef struct _gainOptStep { int16_t paramVal[NUM_CORNER_FIX_BITS_5112]; int32_t stepGain; int8_t stepName[16]; } GAIN_OPTIMIZATION_STEP; typedef struct { uint32_t numStepsInLadder; uint32_t defaultStepNum; GAIN_OPTIMIZATION_STEP optStep[10]; } GAIN_OPTIMIZATION_LADDER; typedef struct { uint32_t currStepNum; uint32_t currGain; uint32_t targetGain; uint32_t loTrig; uint32_t hiTrig; uint32_t active; const GAIN_OPTIMIZATION_STEP *currStep; } GAIN_VALUES; /* RF HAL structures */ typedef struct RfHalFuncs { void *priv; /* private state */ void (*rfDetach)(struct ath_hal *ah); void (*writeRegs)(struct ath_hal *, u_int modeIndex, u_int freqIndex, int regWrites); uint32_t *(*getRfBank)(struct ath_hal *ah, int bank); HAL_BOOL (*setChannel)(struct ath_hal *, const struct ieee80211_channel *); HAL_BOOL (*setRfRegs)(struct ath_hal *, const struct ieee80211_channel *, uint16_t modesIndex, uint16_t *rfXpdGain); HAL_BOOL (*setPowerTable)(struct ath_hal *ah, int16_t *minPower, int16_t *maxPower, const struct ieee80211_channel *, uint16_t *rfXpdGain); HAL_BOOL (*getChannelMaxMinPower)(struct ath_hal *ah, const struct ieee80211_channel *, int16_t *maxPow, int16_t *minPow); int16_t (*getNfAdjust)(struct ath_hal *, const HAL_CHANNEL_INTERNAL*); } RF_HAL_FUNCS; struct ar5212AniParams { int maxNoiseImmunityLevel; /* [0..4] */ int totalSizeDesired[5]; int coarseHigh[5]; int coarseLow[5]; int firpwr[5]; int maxSpurImmunityLevel; /* [0..7] */ int cycPwrThr1[8]; int maxFirstepLevel; /* [0..2] */ int firstep[3]; uint32_t ofdmTrigHigh; uint32_t ofdmTrigLow; uint32_t cckTrigHigh; uint32_t cckTrigLow; int32_t rssiThrLow; uint32_t rssiThrHigh; int period; /* update listen period */ /* NB: intentionally ordered so data exported to user space is first */ uint32_t ofdmPhyErrBase; /* Base value for ofdm err counter */ uint32_t cckPhyErrBase; /* Base value for cck err counters */ }; /* * Per-channel ANI state private to the driver. */ struct ar5212AniState { uint8_t noiseImmunityLevel; uint8_t spurImmunityLevel; uint8_t firstepLevel; uint8_t ofdmWeakSigDetectOff; uint8_t cckWeakSigThreshold; uint32_t listenTime; /* NB: intentionally ordered so data exported to user space is first */ uint32_t txFrameCount; /* Last txFrameCount */ uint32_t rxFrameCount; /* Last rx Frame count */ uint32_t cycleCount; /* Last cycleCount (to detect wrap-around) */ uint32_t ofdmPhyErrCount;/* OFDM err count since last reset */ uint32_t cckPhyErrCount; /* CCK err count since last reset */ const struct ar5212AniParams *params; }; #define HAL_ANI_ENA 0x00000001 /* ANI operation enabled */ #define HAL_RSSI_ANI_ENA 0x00000002 /* rssi-based processing ena'd*/ #if 0 struct ar5212Stats { uint32_t ast_ani_niup; /* ANI increased noise immunity */ uint32_t ast_ani_nidown; /* ANI decreased noise immunity */ uint32_t ast_ani_spurup; /* ANI increased spur immunity */ uint32_t ast_ani_spurdown;/* ANI descreased spur immunity */ uint32_t ast_ani_ofdmon; /* ANI OFDM weak signal detect on */ uint32_t ast_ani_ofdmoff;/* ANI OFDM weak signal detect off */ uint32_t ast_ani_cckhigh;/* ANI CCK weak signal threshold high */ uint32_t ast_ani_ccklow; /* ANI CCK weak signal threshold low */ uint32_t ast_ani_stepup; /* ANI increased first step level */ uint32_t ast_ani_stepdown;/* ANI decreased first step level */ uint32_t ast_ani_ofdmerrs;/* ANI cumulative ofdm phy err count */ uint32_t ast_ani_cckerrs;/* ANI cumulative cck phy err count */ uint32_t ast_ani_reset; /* ANI parameters zero'd for non-STA */ uint32_t ast_ani_lzero; /* ANI listen time forced to zero */ uint32_t ast_ani_lneg; /* ANI listen time calculated < 0 */ HAL_MIB_STATS ast_mibstats; /* MIB counter stats */ HAL_NODE_STATS ast_nodestats; /* Latest rssi stats from driver */ }; #endif /* * NF Cal history buffer */ #define AR5212_CCA_MAX_GOOD_VALUE -95 #define AR5212_CCA_MAX_HIGH_VALUE -62 #define AR5212_CCA_MIN_BAD_VALUE -125 #define AR512_NF_CAL_HIST_MAX 5 struct ar5212NfCalHist { int16_t nfCalBuffer[AR512_NF_CAL_HIST_MAX]; int16_t privNF; uint8_t currIndex; uint8_t first_run; uint8_t invalidNFcount; }; struct ath_hal_5212 { struct ath_hal_private ah_priv; /* base class */ /* * Per-chip common Initialization data. * NB: RF backends have their own ini data. */ HAL_INI_ARRAY ah_ini_modes; HAL_INI_ARRAY ah_ini_common; GAIN_VALUES ah_gainValues; uint8_t ah_macaddr[IEEE80211_ADDR_LEN]; uint8_t ah_bssid[IEEE80211_ADDR_LEN]; uint8_t ah_bssidmask[IEEE80211_ADDR_LEN]; uint16_t ah_assocId; /* * Runtime state. */ uint32_t ah_maskReg; /* copy of AR_IMR */ HAL_ANI_STATS ah_stats; /* various statistics */ RF_HAL_FUNCS *ah_rfHal; uint32_t ah_txDescMask; /* mask for TXDESC */ uint32_t ah_txOkInterruptMask; uint32_t ah_txErrInterruptMask; uint32_t ah_txDescInterruptMask; uint32_t ah_txEolInterruptMask; uint32_t ah_txUrnInterruptMask; HAL_TX_QUEUE_INFO ah_txq[HAL_NUM_TX_QUEUES]; uint32_t ah_intrTxqs; /* tx q interrupt state */ /* decomp mask array */ uint8_t ah_decompMask[HAL_DECOMP_MASK_SIZE]; HAL_ANT_SETTING ah_antControl; /* antenna setting */ HAL_BOOL ah_diversity; /* fast diversity setting */ enum { IQ_CAL_INACTIVE, IQ_CAL_RUNNING, IQ_CAL_DONE } ah_bIQCalibration; /* IQ calibrate state */ HAL_RFGAIN ah_rfgainState; /* RF gain calibrartion state */ uint32_t ah_tx6PowerInHalfDbm; /* power output for 6Mb tx */ uint32_t ah_staId1Defaults; /* STA_ID1 default settings */ uint32_t ah_miscMode; /* MISC_MODE settings */ uint32_t ah_rssiThr; /* RSSI_THR settings */ HAL_BOOL ah_cwCalRequire; /* for ap51 */ HAL_BOOL ah_tpcEnabled; /* per-packet tpc enabled */ HAL_BOOL ah_phyPowerOn; /* PHY power state */ HAL_BOOL ah_isHb63; /* cached HB63 check */ uint32_t ah_macTPC; /* tpc register */ uint32_t ah_beaconInterval; /* XXX */ enum { AUTO_32KHZ, /* use it if 32kHz crystal present */ USE_32KHZ, /* do it regardless */ DONT_USE_32KHZ, /* don't use it regardless */ } ah_enable32kHzClock; /* whether to sleep at 32kHz */ uint32_t ah_ofdmTxPower; int16_t ah_txPowerIndexOffset; /* * Noise floor cal histogram support. */ struct ar5212NfCalHist ah_nfCalHist; u_int ah_slottime; /* user-specified slot time */ u_int ah_acktimeout; /* user-specified ack timeout */ u_int ah_ctstimeout; /* user-specified cts timeout */ u_int ah_sifstime; /* user-specified sifs time */ /* * RF Silent handling; setup according to the EEPROM. */ uint32_t ah_gpioSelect; /* GPIO pin to use */ uint32_t ah_polarity; /* polarity to disable RF */ uint32_t ah_gpioBit; /* after init, prev value */ /* * ANI support. */ uint32_t ah_procPhyErr; /* Process Phy errs */ HAL_BOOL ah_hasHwPhyCounters; /* Hardware has phy counters */ struct ar5212AniParams ah_aniParams24; /* 2.4GHz parameters */ struct ar5212AniParams ah_aniParams5; /* 5GHz parameters */ struct ar5212AniState *ah_curani; /* cached last reference */ struct ar5212AniState ah_ani[AH_MAXCHAN]; /* per-channel state */ /* AR5416 uses some of the AR5212 ANI code; these are the ANI methods */ HAL_BOOL (*ah_aniControl) (struct ath_hal *, HAL_ANI_CMD cmd, int param); /* * Transmit power state. Note these are maintained * here so they can be retrieved by diagnostic tools. */ uint16_t *ah_pcdacTable; u_int ah_pcdacTableSize; uint16_t ah_ratesArray[37]; uint8_t ah_txTrigLev; /* current Tx trigger level */ uint8_t ah_maxTxTrigLev; /* max tx trigger level */ /* * Channel Tx, Rx, Rx Clear State */ uint32_t ah_cycleCount; uint32_t ah_ctlBusy; uint32_t ah_rxBusy; uint32_t ah_txBusy; uint32_t ah_rx_chainmask; uint32_t ah_tx_chainmask; /* Used to return ANI statistics to the diagnostic API */ HAL_ANI_STATS ext_ani_stats; }; #define AH5212(_ah) ((struct ath_hal_5212 *)(_ah)) /* * IS_XXXX macros test the MAC version * IS_RADXXX macros test the radio/RF version (matching both 2G-only and 2/5G) * * Some single chip radios have equivalent radio/RF (e.g. 5112) * for those use IS_RADXXX_ANY macros. */ #define IS_2317(ah) \ ((AH_PRIVATE(ah)->ah_devid == AR5212_AR2317_REV1) || \ (AH_PRIVATE(ah)->ah_devid == AR5212_AR2317_REV2)) #define IS_2316(ah) \ (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_2415) #define IS_2413(ah) \ (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_2413 || IS_2316(ah)) #define IS_5424(ah) \ (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_5424 || \ (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_5413 && \ AH_PRIVATE(ah)->ah_macRev <= AR_SREV_D2PLUS_MS)) #define IS_5413(ah) \ (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_5413 || IS_5424(ah)) #define IS_2425(ah) \ (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_2425) #define IS_2417(ah) \ ((AH_PRIVATE(ah)->ah_macVersion) == AR_SREV_2417) #define IS_HB63(ah) (AH5212(ah)->ah_isHb63 == AH_TRUE) #define AH_RADIO_MAJOR(ah) \ (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) #define AH_RADIO_MINOR(ah) \ (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MINOR) #define IS_RAD5111(ah) \ (AH_RADIO_MAJOR(ah) == AR_RAD5111_SREV_MAJOR || \ AH_RADIO_MAJOR(ah) == AR_RAD2111_SREV_MAJOR) #define IS_RAD5112(ah) \ (AH_RADIO_MAJOR(ah) == AR_RAD5112_SREV_MAJOR || \ AH_RADIO_MAJOR(ah) == AR_RAD2112_SREV_MAJOR) /* NB: does not include 5413 as Atheros' IS_5112 macro does */ #define IS_RAD5112_ANY(ah) \ (AR_RAD5112_SREV_MAJOR <= AH_RADIO_MAJOR(ah) && \ AH_RADIO_MAJOR(ah) <= AR_RAD2413_SREV_MAJOR) #define IS_RAD5112_REV1(ah) \ (IS_RAD5112(ah) && \ AH_RADIO_MINOR(ah) < (AR_RAD5112_SREV_2_0 & AR_RADIO_SREV_MINOR)) #define IS_RADX112_REV2(ah) \ (AH_PRIVATE(ah)->ah_analog5GhzRev == AR_RAD5112_SREV_2_0 || \ AH_PRIVATE(ah)->ah_analog5GhzRev == AR_RAD2112_SREV_2_0 || \ AH_PRIVATE(ah)->ah_analog5GhzRev == AR_RAD2112_SREV_2_1 || \ AH_PRIVATE(ah)->ah_analog5GhzRev == AR_RAD5112_SREV_2_1) #define ar5212RfDetach(ah) do { \ if (AH5212(ah)->ah_rfHal != AH_NULL) \ AH5212(ah)->ah_rfHal->rfDetach(ah); \ } while (0) #define ar5212GetRfBank(ah, b) \ AH5212(ah)->ah_rfHal->getRfBank(ah, b) /* * Hack macros for Nala/San: 11b is handled * using 11g; flip the channel flags to accomplish this. */ #define SAVE_CCK(_ah, _chan, _flag) do { \ if ((IS_2425(_ah) || IS_2417(_ah)) && \ (((_chan)->ic_flags) & IEEE80211_CHAN_CCK)) { \ (_chan)->ic_flags &= ~IEEE80211_CHAN_CCK; \ (_chan)->ic_flags |= IEEE80211_CHAN_DYN; \ (_flag) = AH_TRUE; \ } else \ (_flag) = AH_FALSE; \ } while (0) #define RESTORE_CCK(_ah, _chan, _flag) do { \ if ((_flag) && (IS_2425(_ah) || IS_2417(_ah))) { \ (_chan)->ic_flags &= ~IEEE80211_CHAN_DYN; \ (_chan)->ic_flags |= IEEE80211_CHAN_CCK; \ } \ } while (0) struct ath_hal; extern uint32_t ar5212GetRadioRev(struct ath_hal *ah); extern void ar5212InitState(struct ath_hal_5212 *, uint16_t devid, HAL_SOFTC, HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status); extern void ar5212Detach(struct ath_hal *ah); extern HAL_BOOL ar5212ChipTest(struct ath_hal *ah); extern HAL_BOOL ar5212GetChannelEdges(struct ath_hal *ah, uint16_t flags, uint16_t *low, uint16_t *high); extern HAL_BOOL ar5212FillCapabilityInfo(struct ath_hal *ah); extern void ar5212SetBeaconTimers(struct ath_hal *ah, const HAL_BEACON_TIMERS *); extern void ar5212BeaconInit(struct ath_hal *ah, uint32_t next_beacon, uint32_t beacon_period); extern void ar5212ResetStaBeaconTimers(struct ath_hal *ah); extern void ar5212SetStaBeaconTimers(struct ath_hal *ah, const HAL_BEACON_STATE *); extern uint64_t ar5212GetNextTBTT(struct ath_hal *); extern HAL_BOOL ar5212IsInterruptPending(struct ath_hal *ah); extern HAL_BOOL ar5212GetPendingInterrupts(struct ath_hal *ah, HAL_INT *); extern HAL_INT ar5212GetInterrupts(struct ath_hal *ah); extern HAL_INT ar5212SetInterrupts(struct ath_hal *ah, HAL_INT ints); extern uint32_t ar5212GetKeyCacheSize(struct ath_hal *); extern HAL_BOOL ar5212IsKeyCacheEntryValid(struct ath_hal *, uint16_t entry); extern HAL_BOOL ar5212ResetKeyCacheEntry(struct ath_hal *ah, uint16_t entry); extern HAL_BOOL ar5212SetKeyCacheEntryMac(struct ath_hal *, uint16_t entry, const uint8_t *mac); extern HAL_BOOL ar5212SetKeyCacheEntry(struct ath_hal *ah, uint16_t entry, const HAL_KEYVAL *k, const uint8_t *mac, int xorKey); extern void ar5212GetMacAddress(struct ath_hal *ah, uint8_t *mac); extern HAL_BOOL ar5212SetMacAddress(struct ath_hal *ah, const uint8_t *); extern void ar5212GetBssIdMask(struct ath_hal *ah, uint8_t *mac); extern HAL_BOOL ar5212SetBssIdMask(struct ath_hal *, const uint8_t *); extern HAL_BOOL ar5212EepromRead(struct ath_hal *, u_int off, uint16_t *data); extern HAL_BOOL ar5212EepromWrite(struct ath_hal *, u_int off, uint16_t data); extern HAL_BOOL ar5212SetRegulatoryDomain(struct ath_hal *ah, uint16_t regDomain, HAL_STATUS *stats); extern u_int ar5212GetWirelessModes(struct ath_hal *ah); extern void ar5212EnableRfKill(struct ath_hal *); extern HAL_BOOL ar5212GpioCfgOutput(struct ath_hal *, uint32_t gpio, HAL_GPIO_MUX_TYPE); extern HAL_BOOL ar5212GpioCfgInput(struct ath_hal *, uint32_t gpio); extern HAL_BOOL ar5212GpioSet(struct ath_hal *, uint32_t gpio, uint32_t val); extern uint32_t ar5212GpioGet(struct ath_hal *ah, uint32_t gpio); extern void ar5212GpioSetIntr(struct ath_hal *ah, u_int, uint32_t ilevel); extern void ar5212SetLedState(struct ath_hal *ah, HAL_LED_STATE state); extern void ar5212WriteAssocid(struct ath_hal *ah, const uint8_t *bssid, uint16_t assocId); extern uint32_t ar5212GetTsf32(struct ath_hal *ah); extern uint64_t ar5212GetTsf64(struct ath_hal *ah); extern void ar5212SetTsf64(struct ath_hal *ah, uint64_t tsf64); extern void ar5212ResetTsf(struct ath_hal *ah); extern void ar5212SetBasicRate(struct ath_hal *ah, HAL_RATE_SET *pSet); extern uint32_t ar5212GetRandomSeed(struct ath_hal *ah); extern HAL_BOOL ar5212DetectCardPresent(struct ath_hal *ah); extern void ar5212EnableMibCounters(struct ath_hal *); extern void ar5212DisableMibCounters(struct ath_hal *); extern void ar5212UpdateMibCounters(struct ath_hal *ah, HAL_MIB_STATS* stats); extern HAL_BOOL ar5212IsJapanChannelSpreadSupported(struct ath_hal *ah); extern uint32_t ar5212GetCurRssi(struct ath_hal *ah); extern u_int ar5212GetDefAntenna(struct ath_hal *ah); extern void ar5212SetDefAntenna(struct ath_hal *ah, u_int antenna); extern HAL_ANT_SETTING ar5212GetAntennaSwitch(struct ath_hal *); extern HAL_BOOL ar5212SetAntennaSwitch(struct ath_hal *, HAL_ANT_SETTING); extern HAL_BOOL ar5212IsSleepAfterBeaconBroken(struct ath_hal *ah); extern HAL_BOOL ar5212SetSifsTime(struct ath_hal *, u_int); extern u_int ar5212GetSifsTime(struct ath_hal *); extern HAL_BOOL ar5212SetSlotTime(struct ath_hal *, u_int); extern u_int ar5212GetSlotTime(struct ath_hal *); extern HAL_BOOL ar5212SetAckTimeout(struct ath_hal *, u_int); extern u_int ar5212GetAckTimeout(struct ath_hal *); extern HAL_BOOL ar5212SetAckCTSRate(struct ath_hal *, u_int); extern u_int ar5212GetAckCTSRate(struct ath_hal *); extern HAL_BOOL ar5212SetCTSTimeout(struct ath_hal *, u_int); extern u_int ar5212GetCTSTimeout(struct ath_hal *); extern HAL_BOOL ar5212SetDecompMask(struct ath_hal *, uint16_t, int); void ar5212SetCoverageClass(struct ath_hal *, uint8_t, int); extern void ar5212SetPCUConfig(struct ath_hal *); extern HAL_BOOL ar5212Use32KHzclock(struct ath_hal *ah, HAL_OPMODE opmode); extern void ar5212SetupClock(struct ath_hal *ah, HAL_OPMODE opmode); extern void ar5212RestoreClock(struct ath_hal *ah, HAL_OPMODE opmode); extern int16_t ar5212GetNfAdjust(struct ath_hal *, const HAL_CHANNEL_INTERNAL *); extern void ar5212SetCompRegs(struct ath_hal *ah); extern HAL_STATUS ar5212GetCapability(struct ath_hal *, HAL_CAPABILITY_TYPE, uint32_t, uint32_t *); extern HAL_BOOL ar5212SetCapability(struct ath_hal *, HAL_CAPABILITY_TYPE, uint32_t, uint32_t, HAL_STATUS *); extern HAL_BOOL ar5212GetDiagState(struct ath_hal *ah, int request, const void *args, uint32_t argsize, void **result, uint32_t *resultsize); extern HAL_STATUS ar5212SetQuiet(struct ath_hal *ah, uint32_t period, uint32_t duration, uint32_t nextStart, HAL_QUIET_FLAG flag); extern HAL_BOOL ar5212GetMibCycleCounts(struct ath_hal *, HAL_SURVEY_SAMPLE *); extern void ar5212SetChainMasks(struct ath_hal *, uint32_t, uint32_t); extern HAL_BOOL ar5212SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode, int setChip); extern HAL_POWER_MODE ar5212GetPowerMode(struct ath_hal *ah); extern HAL_BOOL ar5212GetPowerStatus(struct ath_hal *ah); extern uint32_t ar5212GetRxDP(struct ath_hal *ath, HAL_RX_QUEUE); extern void ar5212SetRxDP(struct ath_hal *ah, uint32_t rxdp, HAL_RX_QUEUE); extern void ar5212EnableReceive(struct ath_hal *ah); extern HAL_BOOL ar5212StopDmaReceive(struct ath_hal *ah); -extern void ar5212StartPcuReceive(struct ath_hal *ah); +extern void ar5212StartPcuReceive(struct ath_hal *ah, HAL_BOOL); extern void ar5212StopPcuReceive(struct ath_hal *ah); extern void ar5212SetMulticastFilter(struct ath_hal *ah, uint32_t filter0, uint32_t filter1); extern HAL_BOOL ar5212ClrMulticastFilterIndex(struct ath_hal *, uint32_t ix); extern HAL_BOOL ar5212SetMulticastFilterIndex(struct ath_hal *, uint32_t ix); extern uint32_t ar5212GetRxFilter(struct ath_hal *ah); extern void ar5212SetRxFilter(struct ath_hal *ah, uint32_t bits); extern HAL_BOOL ar5212SetupRxDesc(struct ath_hal *, struct ath_desc *, uint32_t size, u_int flags); extern HAL_STATUS ar5212ProcRxDesc(struct ath_hal *ah, struct ath_desc *, uint32_t, struct ath_desc *, uint64_t, struct ath_rx_status *); extern HAL_BOOL ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode, struct ieee80211_channel *chan, HAL_BOOL bChannelChange, HAL_RESET_TYPE, HAL_STATUS *status); extern HAL_BOOL ar5212SetChannel(struct ath_hal *, const struct ieee80211_channel *); extern void ar5212SetOperatingMode(struct ath_hal *ah, int opmode); extern HAL_BOOL ar5212PhyDisable(struct ath_hal *ah); extern HAL_BOOL ar5212Disable(struct ath_hal *ah); extern HAL_BOOL ar5212ChipReset(struct ath_hal *ah, const struct ieee80211_channel *); extern HAL_BOOL ar5212PerCalibration(struct ath_hal *ah, struct ieee80211_channel *chan, HAL_BOOL *isIQdone); extern HAL_BOOL ar5212PerCalibrationN(struct ath_hal *ah, struct ieee80211_channel *chan, u_int chainMask, HAL_BOOL longCal, HAL_BOOL *isCalDone); extern HAL_BOOL ar5212ResetCalValid(struct ath_hal *ah, const struct ieee80211_channel *); extern int16_t ar5212GetNoiseFloor(struct ath_hal *ah); extern void ar5212InitNfCalHistBuffer(struct ath_hal *); extern int16_t ar5212GetNfHistMid(const int16_t calData[]); extern void ar5212SetSpurMitigation(struct ath_hal *, const struct ieee80211_channel *); extern HAL_BOOL ar5212SetAntennaSwitchInternal(struct ath_hal *ah, HAL_ANT_SETTING settings, const struct ieee80211_channel *); extern HAL_BOOL ar5212SetTxPowerLimit(struct ath_hal *ah, uint32_t limit); extern HAL_BOOL ar5212GetChipPowerLimits(struct ath_hal *ah, struct ieee80211_channel *chan); extern void ar5212InitializeGainValues(struct ath_hal *); extern HAL_RFGAIN ar5212GetRfgain(struct ath_hal *ah); extern void ar5212RequestRfgain(struct ath_hal *); extern HAL_BOOL ar5212UpdateTxTrigLevel(struct ath_hal *, HAL_BOOL IncTrigLevel); extern HAL_BOOL ar5212SetTxQueueProps(struct ath_hal *ah, int q, const HAL_TXQ_INFO *qInfo); extern HAL_BOOL ar5212GetTxQueueProps(struct ath_hal *ah, int q, HAL_TXQ_INFO *qInfo); extern int ar5212SetupTxQueue(struct ath_hal *ah, HAL_TX_QUEUE type, const HAL_TXQ_INFO *qInfo); extern HAL_BOOL ar5212ReleaseTxQueue(struct ath_hal *ah, u_int q); extern HAL_BOOL ar5212ResetTxQueue(struct ath_hal *ah, u_int q); extern uint32_t ar5212GetTxDP(struct ath_hal *ah, u_int q); extern HAL_BOOL ar5212SetTxDP(struct ath_hal *ah, u_int q, uint32_t txdp); extern HAL_BOOL ar5212StartTxDma(struct ath_hal *ah, u_int q); extern uint32_t ar5212NumTxPending(struct ath_hal *ah, u_int q); extern HAL_BOOL ar5212StopTxDma(struct ath_hal *ah, u_int q); extern HAL_BOOL ar5212SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds, u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type, u_int txPower, u_int txRate0, u_int txTries0, u_int keyIx, u_int antMode, u_int flags, u_int rtsctsRate, u_int rtsctsDuration, u_int compicvLen, u_int compivLen, u_int comp); extern HAL_BOOL ar5212SetupXTxDesc(struct ath_hal *, struct ath_desc *, u_int txRate1, u_int txRetries1, u_int txRate2, u_int txRetries2, u_int txRate3, u_int txRetries3); extern HAL_BOOL ar5212FillTxDesc(struct ath_hal *ah, struct ath_desc *ds, HAL_DMA_ADDR *bufAddrList, uint32_t *segLenList, u_int descId, u_int qcuId, HAL_BOOL firstSeg, HAL_BOOL lastSeg, const struct ath_desc *ds0); extern HAL_STATUS ar5212ProcTxDesc(struct ath_hal *ah, struct ath_desc *, struct ath_tx_status *); extern void ar5212GetTxIntrQueue(struct ath_hal *ah, uint32_t *); extern void ar5212IntrReqTxDesc(struct ath_hal *ah, struct ath_desc *); extern HAL_BOOL ar5212GetTxCompletionRates(struct ath_hal *ah, const struct ath_desc *ds0, int *rates, int *tries); extern void ar5212SetTxDescLink(struct ath_hal *ah, void *ds, uint32_t link); extern void ar5212GetTxDescLink(struct ath_hal *ah, void *ds, uint32_t *link); extern void ar5212GetTxDescLinkPtr(struct ath_hal *ah, void *ds, uint32_t **linkptr); extern const HAL_RATE_TABLE *ar5212GetRateTable(struct ath_hal *, u_int mode); extern void ar5212AniAttach(struct ath_hal *, const struct ar5212AniParams *, const struct ar5212AniParams *, HAL_BOOL ena); extern void ar5212AniDetach(struct ath_hal *); extern struct ar5212AniState *ar5212AniGetCurrentState(struct ath_hal *); extern HAL_ANI_STATS *ar5212AniGetCurrentStats(struct ath_hal *); extern HAL_BOOL ar5212AniControl(struct ath_hal *, HAL_ANI_CMD cmd, int param); extern HAL_BOOL ar5212AniSetParams(struct ath_hal *, const struct ar5212AniParams *, const struct ar5212AniParams *); struct ath_rx_status; extern void ar5212AniPhyErrReport(struct ath_hal *ah, const struct ath_rx_status *rs); extern void ar5212ProcessMibIntr(struct ath_hal *, const HAL_NODE_STATS *); extern void ar5212RxMonitor(struct ath_hal *, const HAL_NODE_STATS *, const struct ieee80211_channel *); extern void ar5212AniPoll(struct ath_hal *, const struct ieee80211_channel *); extern void ar5212AniReset(struct ath_hal *, const struct ieee80211_channel *, HAL_OPMODE, int); extern HAL_BOOL ar5212IsNFCalInProgress(struct ath_hal *ah); extern HAL_BOOL ar5212WaitNFCalComplete(struct ath_hal *ah, int i); extern void ar5212EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe); extern HAL_BOOL ar5212GetDfsDefaultThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe); extern void ar5212GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe); extern HAL_BOOL ar5212ProcessRadarEvent(struct ath_hal *ah, struct ath_rx_status *rxs, uint64_t fulltsf, const char *buf, HAL_DFS_EVENT *event); extern HAL_BOOL ar5212IsFastClockEnabled(struct ath_hal *ah); extern uint32_t ar5212Get11nExtBusy(struct ath_hal *ah); #endif /* _ATH_AR5212_H_ */ Index: head/sys/dev/ath/ath_hal/ar5212/ar5212_recv.c =================================================================== --- head/sys/dev/ath/ath_hal/ar5212/ar5212_recv.c (revision 346469) +++ head/sys/dev/ath/ath_hal/ar5212/ar5212_recv.c (revision 346470) @@ -1,319 +1,319 @@ /*- * SPDX-License-Identifier: ISC * * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting * Copyright (c) 2002-2008 Atheros Communications, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $FreeBSD$ */ #include "opt_ah.h" #include "ah.h" #include "ah_internal.h" #include "ah_desc.h" #include "ar5212/ar5212.h" #include "ar5212/ar5212reg.h" #include "ar5212/ar5212desc.h" /* * Get the RXDP. */ uint32_t ar5212GetRxDP(struct ath_hal *ath, HAL_RX_QUEUE qtype) { HALASSERT(qtype == HAL_RX_QUEUE_HP); return OS_REG_READ(ath, AR_RXDP); } /* * Set the RxDP. */ void ar5212SetRxDP(struct ath_hal *ah, uint32_t rxdp, HAL_RX_QUEUE qtype) { HALASSERT(qtype == HAL_RX_QUEUE_HP); OS_REG_WRITE(ah, AR_RXDP, rxdp); HALASSERT(OS_REG_READ(ah, AR_RXDP) == rxdp); } /* * Set Receive Enable bits. */ void ar5212EnableReceive(struct ath_hal *ah) { OS_REG_WRITE(ah, AR_CR, AR_CR_RXE); } /* * Stop Receive at the DMA engine */ HAL_BOOL ar5212StopDmaReceive(struct ath_hal *ah) { OS_MARK(ah, AH_MARK_RX_CTL, AH_MARK_RX_CTL_DMA_STOP); OS_REG_WRITE(ah, AR_CR, AR_CR_RXD); /* Set receive disable bit */ if (!ath_hal_wait(ah, AR_CR, AR_CR_RXE, 0)) { OS_MARK(ah, AH_MARK_RX_CTL, AH_MARK_RX_CTL_DMA_STOP_ERR); #ifdef AH_DEBUG ath_hal_printf(ah, "%s: dma failed to stop in 10ms\n" "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n", __func__, OS_REG_READ(ah, AR_CR), OS_REG_READ(ah, AR_DIAG_SW)); #endif return AH_FALSE; } else { return AH_TRUE; } } /* * Start Transmit at the PCU engine (unpause receive) */ void -ar5212StartPcuReceive(struct ath_hal *ah) +ar5212StartPcuReceive(struct ath_hal *ah, HAL_BOOL is_scanning) { struct ath_hal_private *ahp = AH_PRIVATE(ah); OS_MARK(ah, AH_MARK_RX_CTL, AH_MARK_RX_CTL_PCU_START); OS_REG_WRITE(ah, AR_DIAG_SW, OS_REG_READ(ah, AR_DIAG_SW) &~ AR_DIAG_RX_DIS); ar5212EnableMibCounters(ah); - /* NB: restore current settings */ - ar5212AniReset(ah, ahp->ah_curchan, ahp->ah_opmode, AH_TRUE); + /* NB: restore current settings if we're not scanning */ + ar5212AniReset(ah, ahp->ah_curchan, ahp->ah_opmode, !is_scanning); } /* * Stop Transmit at the PCU engine (pause receive) */ void ar5212StopPcuReceive(struct ath_hal *ah) { OS_MARK(ah, AH_MARK_RX_CTL, AH_MARK_RX_CTL_PCU_STOP); OS_REG_WRITE(ah, AR_DIAG_SW, OS_REG_READ(ah, AR_DIAG_SW) | AR_DIAG_RX_DIS); ar5212DisableMibCounters(ah); } /* * Set multicast filter 0 (lower 32-bits) * filter 1 (upper 32-bits) */ void ar5212SetMulticastFilter(struct ath_hal *ah, uint32_t filter0, uint32_t filter1) { OS_REG_WRITE(ah, AR_MCAST_FIL0, filter0); OS_REG_WRITE(ah, AR_MCAST_FIL1, filter1); } /* * Clear multicast filter by index */ HAL_BOOL ar5212ClrMulticastFilterIndex(struct ath_hal *ah, uint32_t ix) { uint32_t val; if (ix >= 64) return AH_FALSE; if (ix >= 32) { val = OS_REG_READ(ah, AR_MCAST_FIL1); OS_REG_WRITE(ah, AR_MCAST_FIL1, (val &~ (1<<(ix-32)))); } else { val = OS_REG_READ(ah, AR_MCAST_FIL0); OS_REG_WRITE(ah, AR_MCAST_FIL0, (val &~ (1<= 64) return AH_FALSE; if (ix >= 32) { val = OS_REG_READ(ah, AR_MCAST_FIL1); OS_REG_WRITE(ah, AR_MCAST_FIL1, (val | (1<<(ix-32)))); } else { val = OS_REG_READ(ah, AR_MCAST_FIL0); OS_REG_WRITE(ah, AR_MCAST_FIL0, (val | (1<ah_caps.halBssidMatchSupport && (AH5212(ah)->ah_miscMode & AR_MISC_MODE_BSSID_MATCH_FORCE)) bits |= HAL_RX_FILTER_BSSID; return bits; } /* * Set the receive filter. */ void ar5212SetRxFilter(struct ath_hal *ah, uint32_t bits) { struct ath_hal_5212 *ahp = AH5212(ah); uint32_t phybits; OS_REG_WRITE(ah, AR_RX_FILTER, bits &~ (HAL_RX_FILTER_PHYRADAR|HAL_RX_FILTER_PHYERR| HAL_RX_FILTER_BSSID)); phybits = 0; if (bits & HAL_RX_FILTER_PHYRADAR) phybits |= AR_PHY_ERR_RADAR; if (bits & HAL_RX_FILTER_PHYERR) phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING; OS_REG_WRITE(ah, AR_PHY_ERR, phybits); if (phybits) { OS_REG_WRITE(ah, AR_RXCFG, OS_REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA); } else { OS_REG_WRITE(ah, AR_RXCFG, OS_REG_READ(ah, AR_RXCFG) &~ AR_RXCFG_ZLFDMA); } if (AH_PRIVATE(ah)->ah_caps.halBssidMatchSupport) { if (bits & HAL_RX_FILTER_BSSID) ahp->ah_miscMode |= AR_MISC_MODE_BSSID_MATCH_FORCE; else ahp->ah_miscMode &= ~AR_MISC_MODE_BSSID_MATCH_FORCE; OS_REG_WRITE(ah, AR_MISC_MODE, OS_REG_READ(ah, AR_MISC_MODE) | ahp->ah_miscMode); } } /* * Initialize RX descriptor, by clearing the status and setting * the size (and any other flags). */ HAL_BOOL ar5212SetupRxDesc(struct ath_hal *ah, struct ath_desc *ds, uint32_t size, u_int flags) { struct ar5212_desc *ads = AR5212DESC(ds); HALASSERT((size &~ AR_BufLen) == 0); ads->ds_ctl0 = 0; ads->ds_ctl1 = size & AR_BufLen; if (flags & HAL_RXDESC_INTREQ) ads->ds_ctl1 |= AR_RxInterReq; ads->ds_rxstatus0 = ads->ds_rxstatus1 = 0; return AH_TRUE; } /* * Process an RX descriptor, and return the status to the caller. * Copy some hardware specific items into the software portion * of the descriptor. * * NB: the caller is responsible for validating the memory contents * of the descriptor (e.g. flushing any cached copy). */ HAL_STATUS ar5212ProcRxDesc(struct ath_hal *ah, struct ath_desc *ds, uint32_t pa, struct ath_desc *nds, uint64_t tsf, struct ath_rx_status *rs) { struct ar5212_desc *ads = AR5212DESC(ds); struct ar5212_desc *ands = AR5212DESC(nds); if ((ads->ds_rxstatus1 & AR_Done) == 0) return HAL_EINPROGRESS; /* * Given the use of a self-linked tail be very sure that the hw is * done with this descriptor; the hw may have done this descriptor * once and picked it up again...make sure the hw has moved on. */ if ((ands->ds_rxstatus1&AR_Done) == 0 && OS_REG_READ(ah, AR_RXDP) == pa) return HAL_EINPROGRESS; rs->rs_datalen = ads->ds_rxstatus0 & AR_DataLen; rs->rs_tstamp = MS(ads->ds_rxstatus1, AR_RcvTimestamp); rs->rs_status = 0; /* XXX what about KeyCacheMiss? */ rs->rs_rssi = MS(ads->ds_rxstatus0, AR_RcvSigStrength); /* discard invalid h/w rssi data */ if (rs->rs_rssi == -128) rs->rs_rssi = 0; if (ads->ds_rxstatus1 & AR_KeyIdxValid) rs->rs_keyix = MS(ads->ds_rxstatus1, AR_KeyIdx); else rs->rs_keyix = HAL_RXKEYIX_INVALID; /* NB: caller expected to do rate table mapping */ rs->rs_rate = MS(ads->ds_rxstatus0, AR_RcvRate); rs->rs_antenna = MS(ads->ds_rxstatus0, AR_RcvAntenna); rs->rs_more = (ads->ds_rxstatus0 & AR_More) ? 1 : 0; /* * The AR5413 (at least) sometimes sets both AR_CRCErr and * AR_PHYErr when reporting radar pulses. In this instance * set HAL_RXERR_PHY as well as HAL_RXERR_CRC and * let the driver layer figure out what to do. * * See PR kern/169362. */ if ((ads->ds_rxstatus1 & AR_FrmRcvOK) == 0) { /* * These four bits should not be set together. The * 5212 spec states a Michael error can only occur if * DecryptCRCErr not set (and TKIP is used). Experience * indicates however that you can also get Michael errors * when a CRC error is detected, but these are specious. * Consequently we filter them out here so we don't * confuse and/or complicate drivers. */ if (ads->ds_rxstatus1 & AR_PHYErr) { u_int phyerr; rs->rs_status |= HAL_RXERR_PHY; phyerr = MS(ads->ds_rxstatus1, AR_PHYErrCode); rs->rs_phyerr = phyerr; if (!AH5212(ah)->ah_hasHwPhyCounters && phyerr != HAL_PHYERR_RADAR) ar5212AniPhyErrReport(ah, rs); } if (ads->ds_rxstatus1 & AR_CRCErr) rs->rs_status |= HAL_RXERR_CRC; else if (ads->ds_rxstatus1 & AR_DecryptCRCErr) rs->rs_status |= HAL_RXERR_DECRYPT; else if (ads->ds_rxstatus1 & AR_MichaelErr) rs->rs_status |= HAL_RXERR_MIC; } return HAL_OK; } Index: head/sys/dev/ath/ath_hal/ar5416/ar5416.h =================================================================== --- head/sys/dev/ath/ath_hal/ar5416/ar5416.h (revision 346469) +++ head/sys/dev/ath/ath_hal/ar5416/ar5416.h (revision 346470) @@ -1,422 +1,422 @@ /*- * SPDX-License-Identifier: ISC * * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting * Copyright (c) 2002-2008 Atheros Communications, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $FreeBSD$ */ #ifndef _ATH_AR5416_H_ #define _ATH_AR5416_H_ #include "ar5212/ar5212.h" #include "ar5416_cal.h" #include "ah_eeprom_v14.h" /* for CAL_TARGET_POWER_* */ #define AR5416_MAGIC 0x20065416 typedef struct { uint16_t synth_center; uint16_t ctl_center; uint16_t ext_center; } CHAN_CENTERS; typedef enum Ar5416_Rates { rate6mb, rate9mb, rate12mb, rate18mb, rate24mb, rate36mb, rate48mb, rate54mb, rate1l, rate2l, rate2s, rate5_5l, rate5_5s, rate11l, rate11s, rateXr, rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3, rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7, rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3, rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7, rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm, Ar5416RateSize } AR5416_RATES; #define AR5416_DEFAULT_RXCHAINMASK 7 #define AR5416_DEFAULT_TXCHAINMASK 1 #define AR5416_MAX_RATE_POWER 63 #define AR5416_KEYTABLE_SIZE 128 #define AR5416_CCA_MAX_GOOD_VALUE -85 #define AR5416_CCA_MAX_HIGH_VALUE -62 #define AR5416_CCA_MIN_BAD_VALUE -140 #define AR9285_CCA_MAX_GOOD_VALUE -118 #define AR5416_SPUR_RSSI_THRESH 40 struct ar5416NfLimits { int16_t max; int16_t min; int16_t nominal; }; struct ath_hal_5416 { struct ath_hal_5212 ah_5212; /* NB: RF data setup at attach */ HAL_INI_ARRAY ah_ini_bb_rfgain; HAL_INI_ARRAY ah_ini_bank0; HAL_INI_ARRAY ah_ini_bank1; HAL_INI_ARRAY ah_ini_bank2; HAL_INI_ARRAY ah_ini_bank3; HAL_INI_ARRAY ah_ini_bank6; HAL_INI_ARRAY ah_ini_bank7; HAL_INI_ARRAY ah_ini_addac; HAL_INI_ARRAY ah_ini_pcieserdes; void (*ah_writeIni)(struct ath_hal *, const struct ieee80211_channel *); void (*ah_spurMitigate)(struct ath_hal *, const struct ieee80211_channel *); /* calibration ops */ HAL_BOOL (*ah_cal_initcal)(struct ath_hal *, const struct ieee80211_channel *); void (*ah_cal_pacal)(struct ath_hal *, HAL_BOOL is_reset); /* optional open-loop tx power control related methods */ void (*ah_olcInit)(struct ath_hal *); void (*ah_olcTempCompensation)(struct ath_hal *); /* tx power control */ HAL_BOOL (*ah_setPowerCalTable) (struct ath_hal *ah, struct ar5416eeprom *pEepData, const struct ieee80211_channel *chan, int16_t *pTxPowerIndexOffset); /* baseband operations */ void (*ah_initPLL) (struct ath_hal *ah, const struct ieee80211_channel *chan); /* bluetooth coexistence operations */ void (*ah_btCoexSetDiversity)(struct ath_hal *ah); u_int ah_globaltxtimeout; /* global tx timeout */ u_int ah_gpioMask; int ah_hangs; /* h/w hangs state */ uint8_t ah_keytype[AR5416_KEYTABLE_SIZE]; /* * Primary/Extension Channel Tx, Rx, Rx Clear State */ uint32_t ah_cycleCount; uint32_t ah_ctlBusy; uint32_t ah_extBusy; uint32_t ah_rxBusy; uint32_t ah_txBusy; uint32_t ah_rx_chainmask; uint32_t ah_tx_chainmask; HAL_ANI_CMD ah_ani_function; struct ar5416PerCal ah_cal; /* periodic calibration state */ struct ar5416NfLimits nf_2g; struct ar5416NfLimits nf_5g; /* * TX power configuration related structures */ int initPDADC; int ah_ht40PowerIncForPdadc; int16_t ah_ratesArray[Ar5416RateSize]; int ah_need_an_top2_fixup; /* merlin or later chips that may need this workaround */ /* * Bluetooth coexistence static setup according to the registry */ HAL_BT_MODULE ah_btModule; /* Bluetooth module identifier */ uint8_t ah_btCoexConfigType; /* BT coex configuration */ uint8_t ah_btActiveGpioSelect; /* GPIO pin for BT_ACTIVE */ uint8_t ah_btPriorityGpioSelect; /* GPIO pin for BT_PRIORITY */ uint8_t ah_wlanActiveGpioSelect; /* GPIO pin for WLAN_ACTIVE */ uint8_t ah_btActivePolarity; /* Polarity of BT_ACTIVE */ HAL_BOOL ah_btCoexSingleAnt; /* Single or dual antenna configuration */ uint8_t ah_btWlanIsolation; /* Isolation between BT and WLAN in dB */ /* * Bluetooth coexistence runtime settings */ HAL_BOOL ah_btCoexEnabled; /* If Bluetooth coexistence is enabled */ uint32_t ah_btCoexMode; /* Register setting for AR_BT_COEX_MODE */ uint32_t ah_btCoexBTWeight; /* Register setting for AR_BT_COEX_WEIGHT */ uint32_t ah_btCoexWLANWeight; /* Register setting for AR_BT_COEX_WEIGHT */ uint32_t ah_btCoexMode2; /* Register setting for AR_BT_COEX_MODE2 */ uint32_t ah_btCoexFlag; /* Special tuning flags for BT coex */ }; #define AH5416(_ah) ((struct ath_hal_5416 *)(_ah)) #define IS_5416_PCI(ah) ((AH_PRIVATE(ah)->ah_macVersion) == AR_SREV_VERSION_OWL_PCI) #define IS_5416_PCIE(ah) ((AH_PRIVATE(ah)->ah_macVersion) == AR_SREV_VERSION_OWL_PCIE) #undef IS_PCIE #define IS_PCIE(ah) (IS_5416_PCIE(ah)) extern HAL_BOOL ar2133RfAttach(struct ath_hal *, HAL_STATUS *); struct ath_hal; extern uint32_t ar5416GetRadioRev(struct ath_hal *ah); extern void ar5416InitState(struct ath_hal_5416 *, uint16_t devid, HAL_SOFTC sc, HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status); extern void ar5416Detach(struct ath_hal *ah); extern void ar5416AttachPCIE(struct ath_hal *ah); extern HAL_BOOL ar5416FillCapabilityInfo(struct ath_hal *ah); extern void ar5416AniAttach(struct ath_hal *, const struct ar5212AniParams *, const struct ar5212AniParams *, HAL_BOOL ena); extern void ar5416AniDetach(struct ath_hal *); extern HAL_BOOL ar5416AniControl(struct ath_hal *, HAL_ANI_CMD cmd, int param); extern HAL_BOOL ar5416AniSetParams(struct ath_hal *, const struct ar5212AniParams *, const struct ar5212AniParams *); extern void ar5416ProcessMibIntr(struct ath_hal *, const HAL_NODE_STATS *); extern void ar5416RxMonitor(struct ath_hal *, const HAL_NODE_STATS *, const struct ieee80211_channel *); extern void ar5416AniPoll(struct ath_hal *, const struct ieee80211_channel *); extern void ar5416AniReset(struct ath_hal *, const struct ieee80211_channel *, HAL_OPMODE, int); extern void ar5416SetBeaconTimers(struct ath_hal *, const HAL_BEACON_TIMERS *); extern void ar5416BeaconInit(struct ath_hal *ah, uint32_t next_beacon, uint32_t beacon_period); extern void ar5416ResetStaBeaconTimers(struct ath_hal *ah); extern void ar5416SetStaBeaconTimers(struct ath_hal *ah, const HAL_BEACON_STATE *); extern uint64_t ar5416GetNextTBTT(struct ath_hal *); /* ar5416_btcoex.c */ extern void ar5416SetBTCoexInfo(struct ath_hal *ah, HAL_BT_COEX_INFO *btinfo); extern void ar5416BTCoexConfig(struct ath_hal *ah, HAL_BT_COEX_CONFIG *btconf); extern void ar5416BTCoexAntennaDiversity(struct ath_hal *ah); extern void ar5416BTCoexSetQcuThresh(struct ath_hal *ah, int qnum); extern void ar5416BTCoexSetWeights(struct ath_hal *ah, uint32_t stompType); extern void ar5416BTCoexSetupBmissThresh(struct ath_hal *ah, uint32_t thresh); extern void ar5416BTCoexSetParameter(struct ath_hal *ah, uint32_t type, uint32_t value); extern void ar5416BTCoexDisable(struct ath_hal *ah); extern int ar5416BTCoexEnable(struct ath_hal *ah); extern void ar5416InitBTCoex(struct ath_hal *ah); extern HAL_BOOL ar5416EepromRead(struct ath_hal *, u_int off, uint16_t *data); extern HAL_BOOL ar5416EepromWrite(struct ath_hal *, u_int off, uint16_t data); extern HAL_BOOL ar5416IsInterruptPending(struct ath_hal *ah); extern HAL_BOOL ar5416GetPendingInterrupts(struct ath_hal *, HAL_INT *masked); extern HAL_INT ar5416SetInterrupts(struct ath_hal *ah, HAL_INT ints); extern HAL_BOOL ar5416GpioCfgOutput(struct ath_hal *, uint32_t gpio, HAL_GPIO_MUX_TYPE); extern HAL_BOOL ar5416GpioCfgInput(struct ath_hal *, uint32_t gpio); extern HAL_BOOL ar5416GpioSet(struct ath_hal *, uint32_t gpio, uint32_t val); extern uint32_t ar5416GpioGet(struct ath_hal *ah, uint32_t gpio); extern void ar5416GpioSetIntr(struct ath_hal *ah, u_int, uint32_t ilevel); extern u_int ar5416GetWirelessModes(struct ath_hal *ah); extern void ar5416SetLedState(struct ath_hal *ah, HAL_LED_STATE state); extern uint64_t ar5416GetTsf64(struct ath_hal *ah); extern void ar5416SetTsf64(struct ath_hal *ah, uint64_t tsf64); extern void ar5416ResetTsf(struct ath_hal *ah); extern uint32_t ar5416GetCurRssi(struct ath_hal *ah); extern HAL_BOOL ar5416SetAntennaSwitch(struct ath_hal *, HAL_ANT_SETTING); extern HAL_BOOL ar5416SetDecompMask(struct ath_hal *, uint16_t, int); extern void ar5416SetCoverageClass(struct ath_hal *, uint8_t, int); extern HAL_BOOL ar5416GetMibCycleCounts(struct ath_hal *ah, HAL_SURVEY_SAMPLE *hsample); extern void ar5416SetChainMasks(struct ath_hal *ah, uint32_t, uint32_t); extern uint32_t ar5416Get11nExtBusy(struct ath_hal *ah); extern void ar5416Set11nMac2040(struct ath_hal *ah, HAL_HT_MACMODE mode); extern HAL_HT_RXCLEAR ar5416Get11nRxClear(struct ath_hal *ah); extern void ar5416Set11nRxClear(struct ath_hal *ah, HAL_HT_RXCLEAR rxclear); extern HAL_STATUS ar5416SetQuiet(struct ath_hal *ah, uint32_t period, uint32_t duration, uint32_t nextStart, HAL_QUIET_FLAG flag); extern HAL_STATUS ar5416GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, uint32_t capability, uint32_t *result); extern HAL_BOOL ar5416SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, uint32_t capability, uint32_t val, HAL_STATUS *status); extern HAL_BOOL ar5416GetDiagState(struct ath_hal *ah, int request, const void *args, uint32_t argsize, void **result, uint32_t *resultsize); extern HAL_BOOL ar5416SetRifsDelay(struct ath_hal *ah, const struct ieee80211_channel *chan, HAL_BOOL enable); extern void ar5416EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe); extern HAL_BOOL ar5416GetDfsDefaultThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe); extern void ar5416GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe); extern HAL_BOOL ar5416ProcessRadarEvent(struct ath_hal *ah, struct ath_rx_status *rxs, uint64_t fulltsf, const char *buf, HAL_DFS_EVENT *event); extern HAL_BOOL ar5416IsFastClockEnabled(struct ath_hal *ah); /* ar9280_spectral.c */ extern void ar5416ConfigureSpectralScan(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss); extern void ar5416GetSpectralParams(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss); extern HAL_BOOL ar5416IsSpectralActive(struct ath_hal *ah); extern HAL_BOOL ar5416IsSpectralEnabled(struct ath_hal *ah); extern void ar5416StartSpectralScan(struct ath_hal *ah); extern void ar5416StopSpectralScan(struct ath_hal *ah); extern uint32_t ar5416GetSpectralConfig(struct ath_hal *ah); extern void ar5416RestoreSpectralConfig(struct ath_hal *ah, uint32_t restoreval); extern HAL_BOOL ar5416SetPowerMode(struct ath_hal *ah, HAL_POWER_MODE mode, int setChip); extern HAL_POWER_MODE ar5416GetPowerMode(struct ath_hal *ah); extern HAL_BOOL ar5416GetPowerStatus(struct ath_hal *ah); extern HAL_BOOL ar5416ResetKeyCacheEntry(struct ath_hal *ah, uint16_t entry); extern HAL_BOOL ar5416SetKeyCacheEntry(struct ath_hal *ah, uint16_t entry, const HAL_KEYVAL *k, const uint8_t *mac, int xorKey); extern uint32_t ar5416GetRxFilter(struct ath_hal *ah); extern void ar5416SetRxFilter(struct ath_hal *ah, uint32_t bits); extern HAL_BOOL ar5416StopDmaReceive(struct ath_hal *ah); -extern void ar5416StartPcuReceive(struct ath_hal *ah); +extern void ar5416StartPcuReceive(struct ath_hal *ah, HAL_BOOL); extern void ar5416StopPcuReceive(struct ath_hal *ah); extern HAL_BOOL ar5416SetupRxDesc(struct ath_hal *, struct ath_desc *, uint32_t size, u_int flags); extern HAL_STATUS ar5416ProcRxDesc(struct ath_hal *ah, struct ath_desc *, uint32_t, struct ath_desc *, uint64_t, struct ath_rx_status *); extern HAL_BOOL ar5416Reset(struct ath_hal *ah, HAL_OPMODE opmode, struct ieee80211_channel *chan, HAL_BOOL bChannelChange, HAL_RESET_TYPE, HAL_STATUS *status); extern HAL_BOOL ar5416PhyDisable(struct ath_hal *ah); extern HAL_RFGAIN ar5416GetRfgain(struct ath_hal *ah); extern HAL_BOOL ar5416Disable(struct ath_hal *ah); extern HAL_BOOL ar5416ChipReset(struct ath_hal *ah, const struct ieee80211_channel *); extern int ar5416GetRegChainOffset(struct ath_hal *ah, int i); extern HAL_BOOL ar5416SetBoardValues(struct ath_hal *, const struct ieee80211_channel *); extern HAL_BOOL ar5416SetResetReg(struct ath_hal *, uint32_t type); extern HAL_BOOL ar5416SetTxPowerLimit(struct ath_hal *ah, uint32_t limit); extern HAL_BOOL ar5416SetTransmitPower(struct ath_hal *, const struct ieee80211_channel *, uint16_t *); extern HAL_BOOL ar5416GetChipPowerLimits(struct ath_hal *ah, struct ieee80211_channel *chan); extern void ar5416GetChannelCenters(struct ath_hal *, const struct ieee80211_channel *chan, CHAN_CENTERS *centers); extern void ar5416SetRatesArrayFromTargetPower(struct ath_hal *ah, const struct ieee80211_channel *chan, int16_t *ratesArray, const CAL_TARGET_POWER_LEG *targetPowerCck, const CAL_TARGET_POWER_LEG *targetPowerCckExt, const CAL_TARGET_POWER_LEG *targetPowerOfdm, const CAL_TARGET_POWER_LEG *targetPowerOfdmExt, const CAL_TARGET_POWER_HT *targetPowerHt20, const CAL_TARGET_POWER_HT *targetPowerHt40); extern void ar5416GetTargetPowers(struct ath_hal *ah, const struct ieee80211_channel *chan, CAL_TARGET_POWER_HT *powInfo, uint16_t numChannels, CAL_TARGET_POWER_HT *pNewPower, uint16_t numRates, HAL_BOOL isHt40Target); extern void ar5416GetTargetPowersLeg(struct ath_hal *ah, const struct ieee80211_channel *chan, CAL_TARGET_POWER_LEG *powInfo, uint16_t numChannels, CAL_TARGET_POWER_LEG *pNewPower, uint16_t numRates, HAL_BOOL isExtTarget); extern void ar5416InitChainMasks(struct ath_hal *ah); extern void ar5416RestoreChainMask(struct ath_hal *ah); extern void ar5416EepromSetAddac(struct ath_hal *ah, const struct ieee80211_channel *chan); extern uint16_t ar5416GetMaxEdgePower(uint16_t freq, CAL_CTL_EDGES *pRdEdgesPower, HAL_BOOL is2GHz); extern void ar5416InitPLL(struct ath_hal *ah, const struct ieee80211_channel *chan); /* TX power setup related routines in ar5416_reset.c */ extern void ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah, const struct ieee80211_channel *chan, CAL_DATA_PER_FREQ *pRawDataSet, uint8_t * bChans, uint16_t availPiers, uint16_t tPdGainOverlap, int16_t *pMinCalPower, uint16_t * pPdGainBoundaries, uint8_t * pPDADCValues, uint16_t numXpdGains); extern void ar5416SetGainBoundariesClosedLoop(struct ath_hal *ah, int i, uint16_t pdGainOverlap_t2, uint16_t gainBoundaries[]); extern uint16_t ar5416GetXpdGainValues(struct ath_hal *ah, uint16_t xpdMask, uint16_t xpdGainValues[]); extern void ar5416WriteDetectorGainBiases(struct ath_hal *ah, uint16_t numXpdGain, uint16_t xpdGainValues[]); extern void ar5416WritePdadcValues(struct ath_hal *ah, int i, uint8_t pdadcValues[]); extern HAL_BOOL ar5416SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData, const struct ieee80211_channel *chan, int16_t *pTxPowerIndexOffset); extern void ar5416WriteTxPowerRateRegisters(struct ath_hal *ah, const struct ieee80211_channel *chan, const int16_t ratesArray[]); extern HAL_BOOL ar5416StopTxDma(struct ath_hal *ah, u_int q); extern HAL_BOOL ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds, u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type, u_int txPower, u_int txRate0, u_int txTries0, u_int keyIx, u_int antMode, u_int flags, u_int rtsctsRate, u_int rtsctsDuration, u_int compicvLen, u_int compivLen, u_int comp); extern HAL_BOOL ar5416SetupXTxDesc(struct ath_hal *, struct ath_desc *, u_int txRate1, u_int txRetries1, u_int txRate2, u_int txRetries2, u_int txRate3, u_int txRetries3); extern HAL_BOOL ar5416FillTxDesc(struct ath_hal *ah, struct ath_desc *ds, HAL_DMA_ADDR *bufAddrList, uint32_t *segLenList, u_int descId, u_int qcuId, HAL_BOOL firstSeg, HAL_BOOL lastSeg, const struct ath_desc *ds0); extern HAL_STATUS ar5416ProcTxDesc(struct ath_hal *ah, struct ath_desc *, struct ath_tx_status *); extern HAL_BOOL ar5416GetTxCompletionRates(struct ath_hal *ah, const struct ath_desc *ds0, int *rates, int *tries); extern HAL_BOOL ar5416ResetTxQueue(struct ath_hal *ah, u_int q); extern int ar5416SetupTxQueue(struct ath_hal *ah, HAL_TX_QUEUE type, const HAL_TXQ_INFO *qInfo); extern HAL_BOOL ar5416ChainTxDesc(struct ath_hal *ah, struct ath_desc *ds, HAL_DMA_ADDR *bufAddrList, uint32_t *segLenList, u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type, u_int keyIx, HAL_CIPHER cipher, uint8_t delims, HAL_BOOL firstSeg, HAL_BOOL lastSeg, HAL_BOOL lastAggr); extern HAL_BOOL ar5416SetupFirstTxDesc(struct ath_hal *ah, struct ath_desc *ds, u_int aggrLen, u_int flags, u_int txPower, u_int txRate0, u_int txTries0, u_int antMode, u_int rtsctsRate, u_int rtsctsDuration); extern HAL_BOOL ar5416SetupLastTxDesc(struct ath_hal *ah, struct ath_desc *ds, const struct ath_desc *ds0); extern HAL_BOOL ar5416SetGlobalTxTimeout(struct ath_hal *ah, u_int tu); extern u_int ar5416GetGlobalTxTimeout(struct ath_hal *ah); extern void ar5416Set11nRateScenario(struct ath_hal *ah, struct ath_desc *ds, u_int durUpdateEn, u_int rtsctsRate, HAL_11N_RATE_SERIES series[], u_int nseries, u_int flags); extern void ar5416Set11nAggrFirst(struct ath_hal *ah, struct ath_desc *ds, u_int aggrLen, u_int numDelims); extern void ar5416Set11nAggrMiddle(struct ath_hal *ah, struct ath_desc *ds, u_int numDelims); extern void ar5416Set11nAggrLast(struct ath_hal *ah, struct ath_desc *ds); extern void ar5416Clr11nAggr(struct ath_hal *ah, struct ath_desc *ds); extern void ar5416Set11nVirtualMoreFrag(struct ath_hal *ah, struct ath_desc *ds, u_int vmf); extern void ar5416Set11nBurstDuration(struct ath_hal *ah, struct ath_desc *ds, u_int burstDuration); extern const HAL_RATE_TABLE *ar5416GetRateTable(struct ath_hal *, u_int mode); #endif /* _ATH_AR5416_H_ */ Index: head/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c =================================================================== --- head/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c (revision 346469) +++ head/sys/dev/ath/ath_hal/ar5416/ar5416_recv.c (revision 346470) @@ -1,281 +1,281 @@ /*- * SPDX-License-Identifier: ISC * * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting * Copyright (c) 2002-2008 Atheros Communications, Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $FreeBSD$ */ #include "opt_ah.h" #include "ah.h" #include "ah_desc.h" #include "ah_internal.h" #include "ar5416/ar5416.h" #include "ar5416/ar5416reg.h" #include "ar5416/ar5416desc.h" /* * Get the receive filter. */ uint32_t ar5416GetRxFilter(struct ath_hal *ah) { uint32_t bits = OS_REG_READ(ah, AR_RX_FILTER); uint32_t phybits = OS_REG_READ(ah, AR_PHY_ERR); if (phybits & AR_PHY_ERR_RADAR) bits |= HAL_RX_FILTER_PHYRADAR; if (phybits & (AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING)) bits |= HAL_RX_FILTER_PHYERR; return bits; } /* * Set the receive filter. */ void ar5416SetRxFilter(struct ath_hal *ah, u_int32_t bits) { uint32_t phybits; OS_REG_WRITE(ah, AR_RX_FILTER, (bits & 0xffff)); phybits = 0; if (bits & HAL_RX_FILTER_PHYRADAR) phybits |= AR_PHY_ERR_RADAR; if (bits & HAL_RX_FILTER_PHYERR) phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING; OS_REG_WRITE(ah, AR_PHY_ERR, phybits); if (phybits) { OS_REG_WRITE(ah, AR_RXCFG, OS_REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA); } else { OS_REG_WRITE(ah, AR_RXCFG, OS_REG_READ(ah, AR_RXCFG) &~ AR_RXCFG_ZLFDMA); } } /* * Stop Receive at the DMA engine */ HAL_BOOL ar5416StopDmaReceive(struct ath_hal *ah) { HAL_BOOL status; OS_MARK(ah, AH_MARK_RX_CTL, AH_MARK_RX_CTL_DMA_STOP); OS_REG_WRITE(ah, AR_CR, AR_CR_RXD); /* Set receive disable bit */ if (!ath_hal_wait(ah, AR_CR, AR_CR_RXE, 0)) { OS_MARK(ah, AH_MARK_RX_CTL, AH_MARK_RX_CTL_DMA_STOP_ERR); #ifdef AH_DEBUG ath_hal_printf(ah, "%s: dma failed to stop in 10ms\n" "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n", __func__, OS_REG_READ(ah, AR_CR), OS_REG_READ(ah, AR_DIAG_SW)); #endif status = AH_FALSE; } else { status = AH_TRUE; } /* * XXX Is this to flush whatever is in a FIFO somewhere? * XXX If so, what should the correct behaviour should be? */ if (AR_SREV_9100(ah)) OS_DELAY(3000); return (status); } /* * Start receive at the PCU engine */ void -ar5416StartPcuReceive(struct ath_hal *ah) +ar5416StartPcuReceive(struct ath_hal *ah, HAL_BOOL is_scanning) { struct ath_hal_private *ahp = AH_PRIVATE(ah); HALDEBUG(ah, HAL_DEBUG_RX, "%s: Start PCU Receive \n", __func__); ar5212EnableMibCounters(ah); - /* NB: restore current settings */ - ar5416AniReset(ah, ahp->ah_curchan, ahp->ah_opmode, AH_TRUE); + /* NB: restore current settings if we're not scanning */ + ar5416AniReset(ah, ahp->ah_curchan, ahp->ah_opmode, ! is_scanning); /* * NB: must do after enabling phy errors to avoid rx * frames w/ corrupted descriptor status. */ OS_REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT); } /* * Stop receive at the PCU engine * and abort current frame in PCU */ void ar5416StopPcuReceive(struct ath_hal *ah) { OS_REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT); HALDEBUG(ah, HAL_DEBUG_RX, "%s: Stop PCU Receive \n", __func__); ar5212DisableMibCounters(ah); } /* * Initialize RX descriptor, by clearing the status and setting * the size (and any other flags). */ HAL_BOOL ar5416SetupRxDesc(struct ath_hal *ah, struct ath_desc *ds, uint32_t size, u_int flags) { struct ar5416_desc *ads = AR5416DESC(ds); HALASSERT((size &~ AR_BufLen) == 0); ads->ds_ctl1 = size & AR_BufLen; if (flags & HAL_RXDESC_INTREQ) ads->ds_ctl1 |= AR_RxIntrReq; /* this should be enough */ ads->ds_rxstatus8 &= ~AR_RxDone; /* clear the rest of the status fields */ OS_MEMZERO(&(ads->u), sizeof(ads->u)); return AH_TRUE; } /* * Process an RX descriptor, and return the status to the caller. * Copy some hardware specific items into the software portion * of the descriptor. * * NB: the caller is responsible for validating the memory contents * of the descriptor (e.g. flushing any cached copy). */ HAL_STATUS ar5416ProcRxDesc(struct ath_hal *ah, struct ath_desc *ds, uint32_t pa, struct ath_desc *nds, uint64_t tsf, struct ath_rx_status *rs) { struct ar5416_desc *ads = AR5416DESC(ds); if ((ads->ds_rxstatus8 & AR_RxDone) == 0) return HAL_EINPROGRESS; rs->rs_status = 0; rs->rs_flags = 0; rs->rs_datalen = ads->ds_rxstatus1 & AR_DataLen; rs->rs_tstamp = ads->AR_RcvTimestamp; /* XXX what about KeyCacheMiss? */ rs->rs_rssi = MS(ads->ds_rxstatus4, AR_RxRSSICombined); rs->rs_rssi_ctl[0] = MS(ads->ds_rxstatus0, AR_RxRSSIAnt00); rs->rs_rssi_ctl[1] = MS(ads->ds_rxstatus0, AR_RxRSSIAnt01); rs->rs_rssi_ctl[2] = MS(ads->ds_rxstatus0, AR_RxRSSIAnt02); rs->rs_rssi_ext[0] = MS(ads->ds_rxstatus4, AR_RxRSSIAnt10); rs->rs_rssi_ext[1] = MS(ads->ds_rxstatus4, AR_RxRSSIAnt11); rs->rs_rssi_ext[2] = MS(ads->ds_rxstatus4, AR_RxRSSIAnt12); if (ads->ds_rxstatus8 & AR_RxKeyIdxValid) rs->rs_keyix = MS(ads->ds_rxstatus8, AR_KeyIdx); else rs->rs_keyix = HAL_RXKEYIX_INVALID; /* NB: caller expected to do rate table mapping */ rs->rs_rate = RXSTATUS_RATE(ah, ads); rs->rs_more = (ads->ds_rxstatus1 & AR_RxMore) ? 1 : 0; rs->rs_isaggr = (ads->ds_rxstatus8 & AR_RxAggr) ? 1 : 0; rs->rs_moreaggr = (ads->ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0; rs->rs_antenna = MS(ads->ds_rxstatus3, AR_RxAntenna); if (ads->ds_rxstatus3 & AR_GI) rs->rs_flags |= HAL_RX_GI; if (ads->ds_rxstatus3 & AR_2040) rs->rs_flags |= HAL_RX_2040; /* * Only the AR9280 and later chips support STBC RX, so * ensure we only set this bit for those chips. */ if (AR_SREV_MERLIN_10_OR_LATER(ah) && ads->ds_rxstatus3 & AR_STBCFrame) rs->rs_flags |= HAL_RX_STBC; if (ads->ds_rxstatus8 & AR_PreDelimCRCErr) rs->rs_flags |= HAL_RX_DELIM_CRC_PRE; if (ads->ds_rxstatus8 & AR_PostDelimCRCErr) rs->rs_flags |= HAL_RX_DELIM_CRC_POST; if (ads->ds_rxstatus8 & AR_DecryptBusyErr) rs->rs_flags |= HAL_RX_DECRYPT_BUSY; if (ads->ds_rxstatus8 & AR_HiRxChain) rs->rs_flags |= HAL_RX_HI_RX_CHAIN; if ((ads->ds_rxstatus8 & AR_RxFrameOK) == 0) { /* * These four bits should not be set together. The * 5416 spec states a Michael error can only occur if * DecryptCRCErr not set (and TKIP is used). Experience * indicates however that you can also get Michael errors * when a CRC error is detected, but these are specious. * Consequently we filter them out here so we don't * confuse and/or complicate drivers. */ /* * The AR5416 sometimes sets both AR_CRCErr and AR_PHYErr * when reporting radar pulses. In this instance * set HAL_RXERR_PHY as well as HAL_RXERR_CRC and * let the driver layer figure out what to do. * * See PR kern/169362. */ if (ads->ds_rxstatus8 & AR_PHYErr) { u_int phyerr; /* * Packets with OFDM_RESTART on post delimiter are CRC OK and * usable and MAC ACKs them. * To avoid packet from being lost, we remove the PHY Err flag * so that driver layer does not drop them. */ phyerr = MS(ads->ds_rxstatus8, AR_PHYErrCode); if ((phyerr == HAL_PHYERR_OFDM_RESTART) && (ads->ds_rxstatus8 & AR_PostDelimCRCErr)) { ath_hal_printf(ah, "%s: OFDM_RESTART on post-delim CRC error\n", __func__); rs->rs_phyerr = 0; } else { rs->rs_status |= HAL_RXERR_PHY; rs->rs_phyerr = phyerr; } } if (ads->ds_rxstatus8 & AR_CRCErr) rs->rs_status |= HAL_RXERR_CRC; else if (ads->ds_rxstatus8 & AR_DecryptCRCErr) rs->rs_status |= HAL_RXERR_DECRYPT; else if (ads->ds_rxstatus8 & AR_MichaelErr) rs->rs_status |= HAL_RXERR_MIC; } return HAL_OK; } Index: head/sys/dev/ath/if_ath_rx.c =================================================================== --- head/sys/dev/ath/if_ath_rx.c (revision 346469) +++ head/sys/dev/ath/if_ath_rx.c (revision 346470) @@ -1,1511 +1,1511 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. */ #include __FBSDID("$FreeBSD$"); /* * Driver for the Atheros Wireless LAN controller. * * This software is derived from work of Atsushi Onoe; his contribution * is greatly appreciated. */ #include "opt_inet.h" #include "opt_ath.h" /* * This is needed for register operations which are performed * by the driver - eg, calls to ath_hal_gettsf32(). * * It's also required for any AH_DEBUG checks in here, eg the * module dependencies. */ #include "opt_ah.h" #include "opt_wlan.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* for mp_ncpus */ #include #include #include #include #include #include #include #include #include #include #include #ifdef IEEE80211_SUPPORT_SUPERG #include #endif #ifdef IEEE80211_SUPPORT_TDMA #include #endif #include #ifdef INET #include #include #endif #include #include /* XXX for softled */ #include #include #include #include #include #include #include #include #include #include #include #include #ifdef ATH_TX99_DIAG #include #endif #ifdef ATH_DEBUG_ALQ #include #endif #include /* * Calculate the receive filter according to the * operating mode and state: * * o always accept unicast, broadcast, and multicast traffic * o accept PHY error frames when hardware doesn't have MIB support * to count and we need them for ANI (sta mode only until recently) * and we are not scanning (ANI is disabled) * NB: older hal's add rx filter bits out of sight and we need to * blindly preserve them * o probe request frames are accepted only when operating in * hostap, adhoc, mesh, or monitor modes * o enable promiscuous mode * - when in monitor mode * - if interface marked PROMISC (assumes bridge setting is filtered) * o accept beacons: * - when operating in station mode for collecting rssi data when * the station is otherwise quiet, or * - when operating in adhoc mode so the 802.11 layer creates * node table entries for peers, * - when scanning * - when doing s/w beacon miss (e.g. for ap+sta) * - when operating in ap mode in 11g to detect overlapping bss that * require protection * - when operating in mesh mode to detect neighbors * o accept control frames: * - when in monitor mode * XXX HT protection for 11n */ u_int32_t ath_calcrxfilter(struct ath_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; u_int32_t rfilt; rfilt = HAL_RX_FILTER_UCAST | HAL_RX_FILTER_BCAST | HAL_RX_FILTER_MCAST; if (!sc->sc_needmib && !sc->sc_scanning) rfilt |= HAL_RX_FILTER_PHYERR; if (ic->ic_opmode != IEEE80211_M_STA) rfilt |= HAL_RX_FILTER_PROBEREQ; /* XXX ic->ic_monvaps != 0? */ if (ic->ic_opmode == IEEE80211_M_MONITOR || ic->ic_promisc > 0) rfilt |= HAL_RX_FILTER_PROM; /* * Only listen to all beacons if we're scanning. * * Otherwise we only really need to hear beacons from * our own BSSID. * * IBSS? software beacon miss? Just receive all beacons. * We need to hear beacons/probe requests from everyone so * we can merge ibss. */ if (ic->ic_opmode == IEEE80211_M_IBSS || sc->sc_swbmiss) { rfilt |= HAL_RX_FILTER_BEACON; } else if (ic->ic_opmode == IEEE80211_M_STA) { if (sc->sc_do_mybeacon && ! sc->sc_scanning) { rfilt |= HAL_RX_FILTER_MYBEACON; } else { /* scanning, non-mybeacon chips */ rfilt |= HAL_RX_FILTER_BEACON; } } /* * NB: We don't recalculate the rx filter when * ic_protmode changes; otherwise we could do * this only when ic_protmode != NONE. */ if (ic->ic_opmode == IEEE80211_M_HOSTAP && IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) rfilt |= HAL_RX_FILTER_BEACON; /* * Enable hardware PS-POLL RX only for hostap mode; * STA mode sends PS-POLL frames but never * receives them. */ if (ath_hal_getcapability(sc->sc_ah, HAL_CAP_PSPOLL, 0, NULL) == HAL_OK && ic->ic_opmode == IEEE80211_M_HOSTAP) rfilt |= HAL_RX_FILTER_PSPOLL; if (sc->sc_nmeshvaps) { rfilt |= HAL_RX_FILTER_BEACON; if (sc->sc_hasbmatch) rfilt |= HAL_RX_FILTER_BSSID; else rfilt |= HAL_RX_FILTER_PROM; } if (ic->ic_opmode == IEEE80211_M_MONITOR) rfilt |= HAL_RX_FILTER_CONTROL; /* * Enable RX of compressed BAR frames only when doing * 802.11n. Required for A-MPDU. */ if (IEEE80211_IS_CHAN_HT(ic->ic_curchan)) rfilt |= HAL_RX_FILTER_COMPBAR; /* * Enable radar PHY errors if requested by the * DFS module. */ if (sc->sc_dodfs) rfilt |= HAL_RX_FILTER_PHYRADAR; /* * Enable spectral PHY errors if requested by the * spectral module. */ if (sc->sc_dospectral) rfilt |= HAL_RX_FILTER_PHYRADAR; DPRINTF(sc, ATH_DEBUG_MODE, "%s: RX filter 0x%x, %s\n", __func__, rfilt, ieee80211_opmode_name[ic->ic_opmode]); return rfilt; } static int ath_legacy_rxbuf_init(struct ath_softc *sc, struct ath_buf *bf) { struct ath_hal *ah = sc->sc_ah; int error; struct mbuf *m; struct ath_desc *ds; /* XXX TODO: ATH_RX_LOCK_ASSERT(sc); */ m = bf->bf_m; if (m == NULL) { /* * NB: by assigning a page to the rx dma buffer we * implicitly satisfy the Atheros requirement that * this buffer be cache-line-aligned and sized to be * multiple of the cache line size. Not doing this * causes weird stuff to happen (for the 5210 at least). */ m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (m == NULL) { DPRINTF(sc, ATH_DEBUG_ANY, "%s: no mbuf/cluster\n", __func__); sc->sc_stats.ast_rx_nombuf++; return ENOMEM; } m->m_pkthdr.len = m->m_len = m->m_ext.ext_size; error = bus_dmamap_load_mbuf_sg(sc->sc_dmat, bf->bf_dmamap, m, bf->bf_segs, &bf->bf_nseg, BUS_DMA_NOWAIT); if (error != 0) { DPRINTF(sc, ATH_DEBUG_ANY, "%s: bus_dmamap_load_mbuf_sg failed; error %d\n", __func__, error); sc->sc_stats.ast_rx_busdma++; m_freem(m); return error; } KASSERT(bf->bf_nseg == 1, ("multi-segment packet; nseg %u", bf->bf_nseg)); bf->bf_m = m; } bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_PREREAD); /* * Setup descriptors. For receive we always terminate * the descriptor list with a self-linked entry so we'll * not get overrun under high load (as can happen with a * 5212 when ANI processing enables PHY error frames). * * To insure the last descriptor is self-linked we create * each descriptor as self-linked and add it to the end. As * each additional descriptor is added the previous self-linked * entry is ``fixed'' naturally. This should be safe even * if DMA is happening. When processing RX interrupts we * never remove/process the last, self-linked, entry on the * descriptor list. This insures the hardware always has * someplace to write a new frame. */ /* * 11N: we can no longer afford to self link the last descriptor. * MAC acknowledges BA status as long as it copies frames to host * buffer (or rx fifo). This can incorrectly acknowledge packets * to a sender if last desc is self-linked. */ ds = bf->bf_desc; if (sc->sc_rxslink) ds->ds_link = bf->bf_daddr; /* link to self */ else ds->ds_link = 0; /* terminate the list */ ds->ds_data = bf->bf_segs[0].ds_addr; ath_hal_setuprxdesc(ah, ds , m->m_len /* buffer size */ , 0 ); if (sc->sc_rxlink != NULL) *sc->sc_rxlink = bf->bf_daddr; sc->sc_rxlink = &ds->ds_link; return 0; } /* * Intercept management frames to collect beacon rssi data * and to do ibss merges. */ void ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf) { struct ieee80211vap *vap = ni->ni_vap; struct ath_softc *sc = vap->iv_ic->ic_softc; uint64_t tsf_beacon_old, tsf_beacon; uint64_t nexttbtt; int64_t tsf_delta; int32_t tsf_delta_bmiss; int32_t tsf_remainder; uint64_t tsf_beacon_target; int tsf_intval; tsf_beacon_old = ((uint64_t) le32dec(ni->ni_tstamp.data + 4)) << 32; tsf_beacon_old |= le32dec(ni->ni_tstamp.data); #define TU_TO_TSF(_tu) (((u_int64_t)(_tu)) << 10) tsf_intval = 1; if (ni->ni_intval > 0) { tsf_intval = TU_TO_TSF(ni->ni_intval); } #undef TU_TO_TSF /* * Call up first so subsequent work can use information * potentially stored in the node (e.g. for ibss merge). */ ATH_VAP(vap)->av_recv_mgmt(ni, m, subtype, rxs, rssi, nf); switch (subtype) { case IEEE80211_FC0_SUBTYPE_BEACON: /* * Only do the following processing if it's for * the current BSS. * * In scan and IBSS mode we receive all beacons, * which means we need to filter out stuff * that isn't for us or we'll end up constantly * trying to sync / merge to BSSes that aren't * actually us. */ if (IEEE80211_ADDR_EQ(ni->ni_bssid, vap->iv_bss->ni_bssid)) { /* update rssi statistics for use by the hal */ /* XXX unlocked check against vap->iv_bss? */ ATH_RSSI_LPF(sc->sc_halstats.ns_avgbrssi, rssi); tsf_beacon = ((uint64_t) le32dec(ni->ni_tstamp.data + 4)) << 32; tsf_beacon |= le32dec(ni->ni_tstamp.data); nexttbtt = ath_hal_getnexttbtt(sc->sc_ah); /* * Let's calculate the delta and remainder, so we can see * if the beacon timer from the AP is varying by more than * a few TU. (Which would be a huge, huge problem.) */ tsf_delta = (long long) tsf_beacon - (long long) tsf_beacon_old; tsf_delta_bmiss = tsf_delta / tsf_intval; /* * If our delta is greater than half the beacon interval, * let's round the bmiss value up to the next beacon * interval. Ie, we're running really, really early * on the next beacon. */ if (tsf_delta % tsf_intval > (tsf_intval / 2)) tsf_delta_bmiss ++; tsf_beacon_target = tsf_beacon_old + (((unsigned long long) tsf_delta_bmiss) * (long long) tsf_intval); /* * The remainder using '%' is between 0 .. intval-1. * If we're actually running too fast, then the remainder * will be some large number just under intval-1. * So we need to look at whether we're running * before or after the target beacon interval * and if we are, modify how we do the remainder * calculation. */ if (tsf_beacon < tsf_beacon_target) { tsf_remainder = -(tsf_intval - ((tsf_beacon - tsf_beacon_old) % tsf_intval)); } else { tsf_remainder = (tsf_beacon - tsf_beacon_old) % tsf_intval; } DPRINTF(sc, ATH_DEBUG_BEACON, "%s: old_tsf=%llu (%u), new_tsf=%llu (%u), target_tsf=%llu (%u), delta=%lld, bmiss=%d, remainder=%d\n", __func__, (unsigned long long) tsf_beacon_old, (unsigned int) (tsf_beacon_old >> 10), (unsigned long long) tsf_beacon, (unsigned int ) (tsf_beacon >> 10), (unsigned long long) tsf_beacon_target, (unsigned int) (tsf_beacon_target >> 10), (long long) tsf_delta, tsf_delta_bmiss, tsf_remainder); DPRINTF(sc, ATH_DEBUG_BEACON, "%s: tsf=%llu (%u), nexttbtt=%llu (%u), delta=%d\n", __func__, (unsigned long long) tsf_beacon, (unsigned int) (tsf_beacon >> 10), (unsigned long long) nexttbtt, (unsigned int) (nexttbtt >> 10), (int32_t) tsf_beacon - (int32_t) nexttbtt + tsf_intval); /* We only do syncbeacon on STA VAPs; not on IBSS */ if (vap->iv_opmode == IEEE80211_M_STA && sc->sc_syncbeacon && ni == vap->iv_bss && (vap->iv_state == IEEE80211_S_RUN || vap->iv_state == IEEE80211_S_SLEEP)) { DPRINTF(sc, ATH_DEBUG_BEACON, "%s: syncbeacon=1; syncing\n", __func__); /* * Resync beacon timers using the tsf of the beacon * frame we just received. */ ath_beacon_config(sc, vap); sc->sc_syncbeacon = 0; } } /* fall thru... */ case IEEE80211_FC0_SUBTYPE_PROBE_RESP: if (vap->iv_opmode == IEEE80211_M_IBSS && vap->iv_state == IEEE80211_S_RUN && ieee80211_ibss_merge_check(ni)) { uint32_t rstamp = sc->sc_lastrs->rs_tstamp; uint64_t tsf = ath_extend_tsf(sc, rstamp, ath_hal_gettsf64(sc->sc_ah)); /* * Handle ibss merge as needed; check the tsf on the * frame before attempting the merge. The 802.11 spec * says the station should change it's bssid to match * the oldest station with the same ssid, where oldest * is determined by the tsf. Note that hardware * reconfiguration happens through callback to * ath_newstate as the state machine will go from * RUN -> RUN when this happens. */ if (le64toh(ni->ni_tstamp.tsf) >= tsf) { DPRINTF(sc, ATH_DEBUG_STATE, "ibss merge, rstamp %u tsf %ju " "tstamp %ju\n", rstamp, (uintmax_t)tsf, (uintmax_t)ni->ni_tstamp.tsf); (void) ieee80211_ibss_merge(ni); } } break; } } #ifdef ATH_ENABLE_RADIOTAP_VENDOR_EXT static void ath_rx_tap_vendor(struct ath_softc *sc, struct mbuf *m, const struct ath_rx_status *rs, u_int64_t tsf, int16_t nf) { /* Fill in the extension bitmap */ sc->sc_rx_th.wr_ext_bitmap = htole32(1 << ATH_RADIOTAP_VENDOR_HEADER); /* Fill in the vendor header */ sc->sc_rx_th.wr_vh.vh_oui[0] = 0x7f; sc->sc_rx_th.wr_vh.vh_oui[1] = 0x03; sc->sc_rx_th.wr_vh.vh_oui[2] = 0x00; /* XXX what should this be? */ sc->sc_rx_th.wr_vh.vh_sub_ns = 0; sc->sc_rx_th.wr_vh.vh_skip_len = htole16(sizeof(struct ath_radiotap_vendor_hdr)); /* General version info */ sc->sc_rx_th.wr_v.vh_version = 1; sc->sc_rx_th.wr_v.vh_rx_chainmask = sc->sc_rxchainmask; /* rssi */ sc->sc_rx_th.wr_v.rssi_ctl[0] = rs->rs_rssi_ctl[0]; sc->sc_rx_th.wr_v.rssi_ctl[1] = rs->rs_rssi_ctl[1]; sc->sc_rx_th.wr_v.rssi_ctl[2] = rs->rs_rssi_ctl[2]; sc->sc_rx_th.wr_v.rssi_ext[0] = rs->rs_rssi_ext[0]; sc->sc_rx_th.wr_v.rssi_ext[1] = rs->rs_rssi_ext[1]; sc->sc_rx_th.wr_v.rssi_ext[2] = rs->rs_rssi_ext[2]; /* evm */ sc->sc_rx_th.wr_v.evm[0] = rs->rs_evm0; sc->sc_rx_th.wr_v.evm[1] = rs->rs_evm1; sc->sc_rx_th.wr_v.evm[2] = rs->rs_evm2; /* These are only populated from the AR9300 or later */ sc->sc_rx_th.wr_v.evm[3] = rs->rs_evm3; sc->sc_rx_th.wr_v.evm[4] = rs->rs_evm4; /* direction */ sc->sc_rx_th.wr_v.vh_flags = ATH_VENDOR_PKT_RX; /* RX rate */ sc->sc_rx_th.wr_v.vh_rx_hwrate = rs->rs_rate; /* RX flags */ sc->sc_rx_th.wr_v.vh_rs_flags = rs->rs_flags; if (rs->rs_isaggr) sc->sc_rx_th.wr_v.vh_flags |= ATH_VENDOR_PKT_ISAGGR; if (rs->rs_moreaggr) sc->sc_rx_th.wr_v.vh_flags |= ATH_VENDOR_PKT_MOREAGGR; /* phyerr info */ if (rs->rs_status & HAL_RXERR_PHY) { sc->sc_rx_th.wr_v.vh_phyerr_code = rs->rs_phyerr; sc->sc_rx_th.wr_v.vh_flags |= ATH_VENDOR_PKT_RXPHYERR; } else { sc->sc_rx_th.wr_v.vh_phyerr_code = 0xff; } sc->sc_rx_th.wr_v.vh_rs_status = rs->rs_status; sc->sc_rx_th.wr_v.vh_rssi = rs->rs_rssi; } #endif /* ATH_ENABLE_RADIOTAP_VENDOR_EXT */ static void ath_rx_tap(struct ath_softc *sc, struct mbuf *m, const struct ath_rx_status *rs, u_int64_t tsf, int16_t nf) { #define CHAN_HT20 htole32(IEEE80211_CHAN_HT20) #define CHAN_HT40U htole32(IEEE80211_CHAN_HT40U) #define CHAN_HT40D htole32(IEEE80211_CHAN_HT40D) #define CHAN_HT (CHAN_HT20|CHAN_HT40U|CHAN_HT40D) const HAL_RATE_TABLE *rt; uint8_t rix; rt = sc->sc_currates; KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); rix = rt->rateCodeToIndex[rs->rs_rate]; sc->sc_rx_th.wr_rate = sc->sc_hwmap[rix].ieeerate; sc->sc_rx_th.wr_flags = sc->sc_hwmap[rix].rxflags; /* 802.11 specific flags */ sc->sc_rx_th.wr_chan_flags &= ~CHAN_HT; if (rs->rs_status & HAL_RXERR_PHY) { /* * PHY error - make sure the channel flags * reflect the actual channel configuration, * not the received frame. */ if (IEEE80211_IS_CHAN_HT40U(sc->sc_curchan)) sc->sc_rx_th.wr_chan_flags |= CHAN_HT40U; else if (IEEE80211_IS_CHAN_HT40D(sc->sc_curchan)) sc->sc_rx_th.wr_chan_flags |= CHAN_HT40D; else if (IEEE80211_IS_CHAN_HT20(sc->sc_curchan)) sc->sc_rx_th.wr_chan_flags |= CHAN_HT20; } else if (sc->sc_rx_th.wr_rate & IEEE80211_RATE_MCS) { /* HT rate */ struct ieee80211com *ic = &sc->sc_ic; if ((rs->rs_flags & HAL_RX_2040) == 0) sc->sc_rx_th.wr_chan_flags |= CHAN_HT20; else if (IEEE80211_IS_CHAN_HT40U(ic->ic_curchan)) sc->sc_rx_th.wr_chan_flags |= CHAN_HT40U; else sc->sc_rx_th.wr_chan_flags |= CHAN_HT40D; if (rs->rs_flags & HAL_RX_GI) sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTGI; } sc->sc_rx_th.wr_tsf = htole64(ath_extend_tsf(sc, rs->rs_tstamp, tsf)); if (rs->rs_status & HAL_RXERR_CRC) sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_BADFCS; /* XXX propagate other error flags from descriptor */ sc->sc_rx_th.wr_antnoise = nf; sc->sc_rx_th.wr_antsignal = nf + rs->rs_rssi; sc->sc_rx_th.wr_antenna = rs->rs_antenna; #undef CHAN_HT #undef CHAN_HT20 #undef CHAN_HT40U #undef CHAN_HT40D } static void ath_handle_micerror(struct ieee80211com *ic, struct ieee80211_frame *wh, int keyix) { struct ieee80211_node *ni; /* XXX recheck MIC to deal w/ chips that lie */ /* XXX discard MIC errors on !data frames */ ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) wh); if (ni != NULL) { ieee80211_notify_michael_failure(ni->ni_vap, wh, keyix); ieee80211_free_node(ni); } } /* * Process a single packet. * * The mbuf must already be synced, unmapped and removed from bf->bf_m * by this stage. * * The mbuf must be consumed by this routine - either passed up the * net80211 stack, put on the holding queue, or freed. */ int ath_rx_pkt(struct ath_softc *sc, struct ath_rx_status *rs, HAL_STATUS status, uint64_t tsf, int nf, HAL_RX_QUEUE qtype, struct ath_buf *bf, struct mbuf *m) { uint64_t rstamp; /* XXX TODO: make this an mbuf tag? */ struct ieee80211_rx_stats rxs; int len, type, i; struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_node *ni; int is_good = 0; struct ath_rx_edma *re = &sc->sc_rxedma[qtype]; /* * Calculate the correct 64 bit TSF given * the TSF64 register value and rs_tstamp. */ rstamp = ath_extend_tsf(sc, rs->rs_tstamp, tsf); /* 802.11 return codes - These aren't specifically errors */ if (rs->rs_flags & HAL_RX_GI) sc->sc_stats.ast_rx_halfgi++; if (rs->rs_flags & HAL_RX_2040) sc->sc_stats.ast_rx_2040++; if (rs->rs_flags & HAL_RX_DELIM_CRC_PRE) sc->sc_stats.ast_rx_pre_crc_err++; if (rs->rs_flags & HAL_RX_DELIM_CRC_POST) sc->sc_stats.ast_rx_post_crc_err++; if (rs->rs_flags & HAL_RX_DECRYPT_BUSY) sc->sc_stats.ast_rx_decrypt_busy_err++; if (rs->rs_flags & HAL_RX_HI_RX_CHAIN) sc->sc_stats.ast_rx_hi_rx_chain++; if (rs->rs_flags & HAL_RX_STBC) sc->sc_stats.ast_rx_stbc++; if (rs->rs_status != 0) { if (rs->rs_status & HAL_RXERR_CRC) sc->sc_stats.ast_rx_crcerr++; if (rs->rs_status & HAL_RXERR_FIFO) sc->sc_stats.ast_rx_fifoerr++; if (rs->rs_status & HAL_RXERR_PHY) { sc->sc_stats.ast_rx_phyerr++; /* Process DFS radar events */ if ((rs->rs_phyerr == HAL_PHYERR_RADAR) || (rs->rs_phyerr == HAL_PHYERR_FALSE_RADAR_EXT)) { /* Now pass it to the radar processing code */ ath_dfs_process_phy_err(sc, m, rstamp, rs); } /* Be suitably paranoid about receiving phy errors out of the stats array bounds */ if (rs->rs_phyerr < 64) sc->sc_stats.ast_rx_phy[rs->rs_phyerr]++; goto rx_error; /* NB: don't count in ierrors */ } if (rs->rs_status & HAL_RXERR_DECRYPT) { /* * Decrypt error. If the error occurred * because there was no hardware key, then * let the frame through so the upper layers * can process it. This is necessary for 5210 * parts which have no way to setup a ``clear'' * key cache entry. * * XXX do key cache faulting */ if (rs->rs_keyix == HAL_RXKEYIX_INVALID) goto rx_accept; sc->sc_stats.ast_rx_badcrypt++; } /* * Similar as above - if the failure was a keymiss * just punt it up to the upper layers for now. */ if (rs->rs_status & HAL_RXERR_KEYMISS) { sc->sc_stats.ast_rx_keymiss++; goto rx_accept; } if (rs->rs_status & HAL_RXERR_MIC) { sc->sc_stats.ast_rx_badmic++; /* * Do minimal work required to hand off * the 802.11 header for notification. */ /* XXX frag's and qos frames */ len = rs->rs_datalen; if (len >= sizeof (struct ieee80211_frame)) { ath_handle_micerror(ic, mtod(m, struct ieee80211_frame *), sc->sc_splitmic ? rs->rs_keyix-32 : rs->rs_keyix); } } counter_u64_add(ic->ic_ierrors, 1); rx_error: /* * Cleanup any pending partial frame. */ if (re->m_rxpending != NULL) { m_freem(re->m_rxpending); re->m_rxpending = NULL; } /* * When a tap is present pass error frames * that have been requested. By default we * pass decrypt+mic errors but others may be * interesting (e.g. crc). */ if (ieee80211_radiotap_active(ic) && (rs->rs_status & sc->sc_monpass)) { /* NB: bpf needs the mbuf length setup */ len = rs->rs_datalen; m->m_pkthdr.len = m->m_len = len; ath_rx_tap(sc, m, rs, rstamp, nf); #ifdef ATH_ENABLE_RADIOTAP_VENDOR_EXT ath_rx_tap_vendor(sc, m, rs, rstamp, nf); #endif /* ATH_ENABLE_RADIOTAP_VENDOR_EXT */ ieee80211_radiotap_rx_all(ic, m); } /* XXX pass MIC errors up for s/w reclaculation */ m_freem(m); m = NULL; goto rx_next; } rx_accept: len = rs->rs_datalen; m->m_len = len; if (rs->rs_more) { /* * Frame spans multiple descriptors; save * it for the next completed descriptor, it * will be used to construct a jumbogram. */ if (re->m_rxpending != NULL) { /* NB: max frame size is currently 2 clusters */ sc->sc_stats.ast_rx_toobig++; m_freem(re->m_rxpending); } m->m_pkthdr.len = len; re->m_rxpending = m; m = NULL; goto rx_next; } else if (re->m_rxpending != NULL) { /* * This is the second part of a jumbogram, * chain it to the first mbuf, adjust the * frame length, and clear the rxpending state. */ re->m_rxpending->m_next = m; re->m_rxpending->m_pkthdr.len += len; m = re->m_rxpending; re->m_rxpending = NULL; } else { /* * Normal single-descriptor receive; setup packet length. */ m->m_pkthdr.len = len; } /* * Validate rs->rs_antenna. * * Some users w/ AR9285 NICs have reported crashes * here because rs_antenna field is bogusly large. * Let's enforce the maximum antenna limit of 8 * (and it shouldn't be hard coded, but that's a * separate problem) and if there's an issue, print * out an error and adjust rs_antenna to something * sensible. * * This code should be removed once the actual * root cause of the issue has been identified. * For example, it may be that the rs_antenna * field is only valid for the last frame of * an aggregate and it just happens that it is * "mostly" right. (This is a general statement - * the majority of the statistics are only valid * for the last frame in an aggregate. */ if (rs->rs_antenna > 7) { device_printf(sc->sc_dev, "%s: rs_antenna > 7 (%d)\n", __func__, rs->rs_antenna); #ifdef ATH_DEBUG ath_printrxbuf(sc, bf, 0, status == HAL_OK); #endif /* ATH_DEBUG */ rs->rs_antenna = 0; /* XXX better than nothing */ } /* * If this is an AR9285/AR9485, then the receive and LNA * configuration is stored in RSSI[2] / EXTRSSI[2]. * We can extract this out to build a much better * receive antenna profile. * * Yes, this just blurts over the above RX antenna field * for now. It's fine, the AR9285 doesn't really use * that. * * Later on we should store away the fine grained LNA * information and keep separate counters just for * that. It'll help when debugging the AR9285/AR9485 * combined diversity code. */ if (sc->sc_rx_lnamixer) { rs->rs_antenna = 0; /* Bits 0:1 - the LNA configuration used */ rs->rs_antenna |= ((rs->rs_rssi_ctl[2] & HAL_RX_LNA_CFG_USED) >> HAL_RX_LNA_CFG_USED_S); /* Bit 2 - the external RX antenna switch */ if (rs->rs_rssi_ctl[2] & HAL_RX_LNA_EXTCFG) rs->rs_antenna |= 0x4; } sc->sc_stats.ast_ant_rx[rs->rs_antenna]++; /* * Populate the rx status block. When there are bpf * listeners we do the additional work to provide * complete status. Otherwise we fill in only the * material required by ieee80211_input. Note that * noise setting is filled in above. */ if (ieee80211_radiotap_active(ic)) { ath_rx_tap(sc, m, rs, rstamp, nf); #ifdef ATH_ENABLE_RADIOTAP_VENDOR_EXT ath_rx_tap_vendor(sc, m, rs, rstamp, nf); #endif /* ATH_ENABLE_RADIOTAP_VENDOR_EXT */ } /* * From this point on we assume the frame is at least * as large as ieee80211_frame_min; verify that. */ if (len < IEEE80211_MIN_LEN) { if (!ieee80211_radiotap_active(ic)) { DPRINTF(sc, ATH_DEBUG_RECV, "%s: short packet %d\n", __func__, len); sc->sc_stats.ast_rx_tooshort++; } else { /* NB: in particular this captures ack's */ ieee80211_radiotap_rx_all(ic, m); } m_freem(m); m = NULL; goto rx_next; } if (IFF_DUMPPKTS(sc, ATH_DEBUG_RECV)) { const HAL_RATE_TABLE *rt = sc->sc_currates; uint8_t rix = rt->rateCodeToIndex[rs->rs_rate]; ieee80211_dump_pkt(ic, mtod(m, caddr_t), len, sc->sc_hwmap[rix].ieeerate, rs->rs_rssi); } m_adj(m, -IEEE80211_CRC_LEN); /* * Locate the node for sender, track state, and then * pass the (referenced) node up to the 802.11 layer * for its use. */ ni = ieee80211_find_rxnode_withkey(ic, mtod(m, const struct ieee80211_frame_min *), rs->rs_keyix == HAL_RXKEYIX_INVALID ? IEEE80211_KEYIX_NONE : rs->rs_keyix); sc->sc_lastrs = rs; if (rs->rs_isaggr) sc->sc_stats.ast_rx_agg++; /* * Populate the per-chain RSSI values where appropriate. */ bzero(&rxs, sizeof(rxs)); rxs.r_flags |= IEEE80211_R_NF | IEEE80211_R_RSSI | IEEE80211_R_C_CHAIN | IEEE80211_R_C_NF | IEEE80211_R_C_RSSI | IEEE80211_R_TSF64 | IEEE80211_R_TSF_START; /* XXX TODO: validate */ rxs.c_rssi = rs->rs_rssi; rxs.c_nf = nf; rxs.c_chain = 3; /* XXX TODO: check */ rxs.c_rx_tsf = rstamp; for (i = 0; i < 3; i++) { rxs.c_rssi_ctl[i] = rs->rs_rssi_ctl[i]; rxs.c_rssi_ext[i] = rs->rs_rssi_ext[i]; /* * XXX note: we currently don't track * per-chain noisefloor. */ rxs.c_nf_ctl[i] = nf; rxs.c_nf_ext[i] = nf; } if (ni != NULL) { /* * Only punt packets for ampdu reorder processing for * 11n nodes; net80211 enforces that M_AMPDU is only * set for 11n nodes. */ if (ni->ni_flags & IEEE80211_NODE_HT) m->m_flags |= M_AMPDU; /* * Sending station is known, dispatch directly. */ (void) ieee80211_add_rx_params(m, &rxs); type = ieee80211_input_mimo(ni, m); ieee80211_free_node(ni); m = NULL; /* * Arrange to update the last rx timestamp only for * frames from our ap when operating in station mode. * This assumes the rx key is always setup when * associated. */ if (ic->ic_opmode == IEEE80211_M_STA && rs->rs_keyix != HAL_RXKEYIX_INVALID) is_good = 1; } else { (void) ieee80211_add_rx_params(m, &rxs); type = ieee80211_input_mimo_all(ic, m); m = NULL; } /* * At this point we have passed the frame up the stack; thus * the mbuf is no longer ours. */ /* * Track rx rssi and do any rx antenna management. */ ATH_RSSI_LPF(sc->sc_halstats.ns_avgrssi, rs->rs_rssi); if (sc->sc_diversity) { /* * When using fast diversity, change the default rx * antenna if diversity chooses the other antenna 3 * times in a row. */ if (sc->sc_defant != rs->rs_antenna) { if (++sc->sc_rxotherant >= 3) ath_setdefantenna(sc, rs->rs_antenna); } else sc->sc_rxotherant = 0; } /* Handle slow diversity if enabled */ if (sc->sc_dolnadiv) { ath_lna_rx_comb_scan(sc, rs, ticks, hz); } if (sc->sc_softled) { /* * Blink for any data frame. Otherwise do a * heartbeat-style blink when idle. The latter * is mainly for station mode where we depend on * periodic beacon frames to trigger the poll event. */ if (type == IEEE80211_FC0_TYPE_DATA) { const HAL_RATE_TABLE *rt = sc->sc_currates; ath_led_event(sc, rt->rateCodeToIndex[rs->rs_rate]); } else if (ticks - sc->sc_ledevent >= sc->sc_ledidle) ath_led_event(sc, 0); } rx_next: /* * Debugging - complain if we didn't NULL the mbuf pointer * here. */ if (m != NULL) { device_printf(sc->sc_dev, "%s: mbuf %p should've been freed!\n", __func__, m); } return (is_good); } #define ATH_RX_MAX 128 /* * XXX TODO: break out the "get buffers" from "call ath_rx_pkt()" like * the EDMA code does. * * XXX TODO: then, do all of the RX list management stuff inside * ATH_RX_LOCK() so we don't end up potentially racing. The EDMA * code is doing it right. */ static void ath_rx_proc(struct ath_softc *sc, int resched) { #define PA2DESC(_sc, _pa) \ ((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \ ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr))) struct ath_buf *bf; struct ath_hal *ah = sc->sc_ah; #ifdef IEEE80211_SUPPORT_SUPERG struct ieee80211com *ic = &sc->sc_ic; #endif struct ath_desc *ds; struct ath_rx_status *rs; struct mbuf *m; int ngood; HAL_STATUS status; int16_t nf; u_int64_t tsf; int npkts = 0; int kickpcu = 0; int ret; /* XXX we must not hold the ATH_LOCK here */ ATH_UNLOCK_ASSERT(sc); ATH_PCU_UNLOCK_ASSERT(sc); ATH_PCU_LOCK(sc); sc->sc_rxproc_cnt++; kickpcu = sc->sc_kickpcu; ATH_PCU_UNLOCK(sc); ATH_LOCK(sc); ath_power_set_power_state(sc, HAL_PM_AWAKE); ATH_UNLOCK(sc); DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: called\n", __func__); ngood = 0; nf = ath_hal_getchannoise(ah, sc->sc_curchan); sc->sc_stats.ast_rx_noise = nf; tsf = ath_hal_gettsf64(ah); do { /* * Don't process too many packets at a time; give the * TX thread time to also run - otherwise the TX * latency can jump by quite a bit, causing throughput * degredation. */ if (!kickpcu && npkts >= ATH_RX_MAX) break; bf = TAILQ_FIRST(&sc->sc_rxbuf); if (sc->sc_rxslink && bf == NULL) { /* NB: shouldn't happen */ device_printf(sc->sc_dev, "%s: no buffer!\n", __func__); break; } else if (bf == NULL) { /* * End of List: * this can happen for non-self-linked RX chains */ sc->sc_stats.ast_rx_hitqueueend++; break; } m = bf->bf_m; if (m == NULL) { /* NB: shouldn't happen */ /* * If mbuf allocation failed previously there * will be no mbuf; try again to re-populate it. */ /* XXX make debug msg */ device_printf(sc->sc_dev, "%s: no mbuf!\n", __func__); TAILQ_REMOVE(&sc->sc_rxbuf, bf, bf_list); goto rx_proc_next; } ds = bf->bf_desc; if (ds->ds_link == bf->bf_daddr) { /* NB: never process the self-linked entry at the end */ sc->sc_stats.ast_rx_hitqueueend++; break; } /* XXX sync descriptor memory */ /* * Must provide the virtual address of the current * descriptor, the physical address, and the virtual * address of the next descriptor in the h/w chain. * This allows the HAL to look ahead to see if the * hardware is done with a descriptor by checking the * done bit in the following descriptor and the address * of the current descriptor the DMA engine is working * on. All this is necessary because of our use of * a self-linked list to avoid rx overruns. */ rs = &bf->bf_status.ds_rxstat; status = ath_hal_rxprocdesc(ah, ds, bf->bf_daddr, PA2DESC(sc, ds->ds_link), rs); #ifdef ATH_DEBUG if (sc->sc_debug & ATH_DEBUG_RECV_DESC) ath_printrxbuf(sc, bf, 0, status == HAL_OK); #endif #ifdef ATH_DEBUG_ALQ if (if_ath_alq_checkdebug(&sc->sc_alq, ATH_ALQ_EDMA_RXSTATUS)) if_ath_alq_post(&sc->sc_alq, ATH_ALQ_EDMA_RXSTATUS, sc->sc_rx_statuslen, (char *) ds); #endif /* ATH_DEBUG_ALQ */ if (status == HAL_EINPROGRESS) break; TAILQ_REMOVE(&sc->sc_rxbuf, bf, bf_list); npkts++; /* * Process a single frame. */ bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_POSTREAD); bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap); bf->bf_m = NULL; if (ath_rx_pkt(sc, rs, status, tsf, nf, HAL_RX_QUEUE_HP, bf, m)) ngood++; rx_proc_next: /* * If there's a holding buffer, insert that onto * the RX list; the hardware is now definitely not pointing * to it now. */ ret = 0; if (sc->sc_rxedma[HAL_RX_QUEUE_HP].m_holdbf != NULL) { TAILQ_INSERT_TAIL(&sc->sc_rxbuf, sc->sc_rxedma[HAL_RX_QUEUE_HP].m_holdbf, bf_list); ret = ath_rxbuf_init(sc, sc->sc_rxedma[HAL_RX_QUEUE_HP].m_holdbf); } /* * Next, throw our buffer into the holding entry. The hardware * may use the descriptor to read the link pointer before * DMAing the next descriptor in to write out a packet. */ sc->sc_rxedma[HAL_RX_QUEUE_HP].m_holdbf = bf; } while (ret == 0); /* rx signal state monitoring */ ath_hal_rxmonitor(ah, &sc->sc_halstats, sc->sc_curchan); if (ngood) sc->sc_lastrx = tsf; ATH_KTR(sc, ATH_KTR_RXPROC, 2, "ath_rx_proc: npkts=%d, ngood=%d", npkts, ngood); /* Queue DFS tasklet if needed */ if (resched && ath_dfs_tasklet_needed(sc, sc->sc_curchan)) taskqueue_enqueue(sc->sc_tq, &sc->sc_dfstask); /* * Now that all the RX frames were handled that * need to be handled, kick the PCU if there's * been an RXEOL condition. */ if (resched && kickpcu) { ATH_PCU_LOCK(sc); ATH_KTR(sc, ATH_KTR_ERROR, 0, "ath_rx_proc: kickpcu"); device_printf(sc->sc_dev, "%s: kickpcu; handled %d packets\n", __func__, npkts); /* * Go through the process of fully tearing down * the RX buffers and reinitialising them. * * There's a hardware bug that causes the RX FIFO * to get confused under certain conditions and * constantly write over the same frame, leading * the RX driver code here to get heavily confused. */ /* * XXX Has RX DMA stopped enough here to just call * ath_startrecv()? * XXX Do we need to use the holding buffer to restart * RX DMA by appending entries to the final * descriptor? Quite likely. */ #if 1 ath_startrecv(sc); #else /* * Disabled for now - it'd be nice to be able to do * this in order to limit the amount of CPU time spent * reinitialising the RX side (and thus minimise RX * drops) however there's a hardware issue that * causes things to get too far out of whack. */ /* * XXX can we hold the PCU lock here? * Are there any net80211 buffer calls involved? */ bf = TAILQ_FIRST(&sc->sc_rxbuf); ath_hal_putrxbuf(ah, bf->bf_daddr, HAL_RX_QUEUE_HP); ath_hal_rxena(ah); /* enable recv descriptors */ ath_mode_init(sc); /* set filters, etc. */ - ath_hal_startpcurecv(ah); /* re-enable PCU/DMA engine */ + ath_hal_startpcurecv(ah, (!! sc->sc_scanning)); /* re-enable PCU/DMA engine */ #endif ath_hal_intrset(ah, sc->sc_imask); sc->sc_kickpcu = 0; ATH_PCU_UNLOCK(sc); } #ifdef IEEE80211_SUPPORT_SUPERG if (resched) ieee80211_ff_age_all(ic, 100); #endif /* * Put the hardware to sleep again if we're done with it. */ ATH_LOCK(sc); ath_power_restore_power_state(sc); ATH_UNLOCK(sc); /* * If we hit the maximum number of frames in this round, * reschedule for another immediate pass. This gives * the TX and TX completion routines time to run, which * will reduce latency. */ if (npkts >= ATH_RX_MAX) sc->sc_rx.recv_sched(sc, resched); ATH_PCU_LOCK(sc); sc->sc_rxproc_cnt--; ATH_PCU_UNLOCK(sc); } #undef PA2DESC #undef ATH_RX_MAX /* * Only run the RX proc if it's not already running. * Since this may get run as part of the reset/flush path, * the task can't clash with an existing, running tasklet. */ static void ath_legacy_rx_tasklet(void *arg, int npending) { struct ath_softc *sc = arg; ATH_KTR(sc, ATH_KTR_RXPROC, 1, "ath_rx_proc: pending=%d", npending); DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: pending %u\n", __func__, npending); ATH_PCU_LOCK(sc); if (sc->sc_inreset_cnt > 0) { device_printf(sc->sc_dev, "%s: sc_inreset_cnt > 0; skipping\n", __func__); ATH_PCU_UNLOCK(sc); return; } ATH_PCU_UNLOCK(sc); ath_rx_proc(sc, 1); } static void ath_legacy_flushrecv(struct ath_softc *sc) { ath_rx_proc(sc, 0); } static void ath_legacy_flush_rxpending(struct ath_softc *sc) { /* XXX ATH_RX_LOCK_ASSERT(sc); */ if (sc->sc_rxedma[HAL_RX_QUEUE_LP].m_rxpending != NULL) { m_freem(sc->sc_rxedma[HAL_RX_QUEUE_LP].m_rxpending); sc->sc_rxedma[HAL_RX_QUEUE_LP].m_rxpending = NULL; } if (sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending != NULL) { m_freem(sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending); sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending = NULL; } } static int ath_legacy_flush_rxholdbf(struct ath_softc *sc) { struct ath_buf *bf; /* XXX ATH_RX_LOCK_ASSERT(sc); */ /* * If there are RX holding buffers, free them here and return * them to the list. * * XXX should just verify that bf->bf_m is NULL, as it must * be at this point! */ bf = sc->sc_rxedma[HAL_RX_QUEUE_HP].m_holdbf; if (bf != NULL) { if (bf->bf_m != NULL) m_freem(bf->bf_m); bf->bf_m = NULL; TAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list); (void) ath_rxbuf_init(sc, bf); } sc->sc_rxedma[HAL_RX_QUEUE_HP].m_holdbf = NULL; bf = sc->sc_rxedma[HAL_RX_QUEUE_LP].m_holdbf; if (bf != NULL) { if (bf->bf_m != NULL) m_freem(bf->bf_m); bf->bf_m = NULL; TAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list); (void) ath_rxbuf_init(sc, bf); } sc->sc_rxedma[HAL_RX_QUEUE_LP].m_holdbf = NULL; return (0); } /* * Disable the receive h/w in preparation for a reset. */ static void ath_legacy_stoprecv(struct ath_softc *sc, int dodelay) { #define PA2DESC(_sc, _pa) \ ((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \ ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr))) struct ath_hal *ah = sc->sc_ah; ATH_RX_LOCK(sc); ath_hal_stoppcurecv(ah); /* disable PCU */ ath_hal_setrxfilter(ah, 0); /* clear recv filter */ ath_hal_stopdmarecv(ah); /* disable DMA engine */ /* * TODO: see if this particular DELAY() is required; it may be * masking some missing FIFO flush or DMA sync. */ #if 0 if (dodelay) #endif DELAY(3000); /* 3ms is long enough for 1 frame */ #ifdef ATH_DEBUG if (sc->sc_debug & (ATH_DEBUG_RESET | ATH_DEBUG_FATAL)) { struct ath_buf *bf; u_int ix; device_printf(sc->sc_dev, "%s: rx queue %p, link %p\n", __func__, (caddr_t)(uintptr_t) ath_hal_getrxbuf(ah, HAL_RX_QUEUE_HP), sc->sc_rxlink); ix = 0; TAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list) { struct ath_desc *ds = bf->bf_desc; struct ath_rx_status *rs = &bf->bf_status.ds_rxstat; HAL_STATUS status = ath_hal_rxprocdesc(ah, ds, bf->bf_daddr, PA2DESC(sc, ds->ds_link), rs); if (status == HAL_OK || (sc->sc_debug & ATH_DEBUG_FATAL)) ath_printrxbuf(sc, bf, ix, status == HAL_OK); ix++; } } #endif (void) ath_legacy_flush_rxpending(sc); (void) ath_legacy_flush_rxholdbf(sc); sc->sc_rxlink = NULL; /* just in case */ ATH_RX_UNLOCK(sc); #undef PA2DESC } /* * XXX TODO: something was calling startrecv without calling * stoprecv. Let's figure out what/why. It was showing up * as a mbuf leak (rxpending) and ath_buf leak (holdbf.) */ /* * Enable the receive h/w following a reset. */ static int ath_legacy_startrecv(struct ath_softc *sc) { struct ath_hal *ah = sc->sc_ah; struct ath_buf *bf; ATH_RX_LOCK(sc); /* * XXX should verify these are already all NULL! */ sc->sc_rxlink = NULL; (void) ath_legacy_flush_rxpending(sc); (void) ath_legacy_flush_rxholdbf(sc); /* * Re-chain all of the buffers in the RX buffer list. */ TAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list) { int error = ath_rxbuf_init(sc, bf); if (error != 0) { DPRINTF(sc, ATH_DEBUG_RECV, "%s: ath_rxbuf_init failed %d\n", __func__, error); return error; } } bf = TAILQ_FIRST(&sc->sc_rxbuf); ath_hal_putrxbuf(ah, bf->bf_daddr, HAL_RX_QUEUE_HP); ath_hal_rxena(ah); /* enable recv descriptors */ ath_mode_init(sc); /* set filters, etc. */ - ath_hal_startpcurecv(ah); /* re-enable PCU/DMA engine */ + ath_hal_startpcurecv(ah, (!! sc->sc_scanning)); /* re-enable PCU/DMA engine */ ATH_RX_UNLOCK(sc); return 0; } static int ath_legacy_dma_rxsetup(struct ath_softc *sc) { int error; error = ath_descdma_setup(sc, &sc->sc_rxdma, &sc->sc_rxbuf, "rx", sizeof(struct ath_desc), ath_rxbuf, 1); if (error != 0) return (error); return (0); } static int ath_legacy_dma_rxteardown(struct ath_softc *sc) { if (sc->sc_rxdma.dd_desc_len != 0) ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf); return (0); } static void ath_legacy_recv_sched(struct ath_softc *sc, int dosched) { taskqueue_enqueue(sc->sc_tq, &sc->sc_rxtask); } static void ath_legacy_recv_sched_queue(struct ath_softc *sc, HAL_RX_QUEUE q, int dosched) { taskqueue_enqueue(sc->sc_tq, &sc->sc_rxtask); } void ath_recv_setup_legacy(struct ath_softc *sc) { /* Sensible legacy defaults */ /* * XXX this should be changed to properly support the * exact RX descriptor size for each HAL. */ sc->sc_rx_statuslen = sizeof(struct ath_desc); sc->sc_rx.recv_start = ath_legacy_startrecv; sc->sc_rx.recv_stop = ath_legacy_stoprecv; sc->sc_rx.recv_flush = ath_legacy_flushrecv; sc->sc_rx.recv_tasklet = ath_legacy_rx_tasklet; sc->sc_rx.recv_rxbuf_init = ath_legacy_rxbuf_init; sc->sc_rx.recv_setup = ath_legacy_dma_rxsetup; sc->sc_rx.recv_teardown = ath_legacy_dma_rxteardown; sc->sc_rx.recv_sched = ath_legacy_recv_sched; sc->sc_rx.recv_sched_queue = ath_legacy_recv_sched_queue; } Index: head/sys/dev/ath/if_ath_rx_edma.c =================================================================== --- head/sys/dev/ath/if_ath_rx_edma.c (revision 346469) +++ head/sys/dev/ath/if_ath_rx_edma.c (revision 346470) @@ -1,1010 +1,1010 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2012 Adrian Chadd * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. */ #include __FBSDID("$FreeBSD$"); /* * Driver for the Atheros Wireless LAN controller. * * This software is derived from work of Atsushi Onoe; his contribution * is greatly appreciated. */ #include "opt_inet.h" #include "opt_ath.h" /* * This is needed for register operations which are performed * by the driver - eg, calls to ath_hal_gettsf32(). * * It's also required for any AH_DEBUG checks in here, eg the * module dependencies. */ #include "opt_ah.h" #include "opt_wlan.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* for mp_ncpus */ #include #include #include #include #include #include #include #include #include #include #include #ifdef IEEE80211_SUPPORT_SUPERG #include #endif #ifdef IEEE80211_SUPPORT_TDMA #include #endif #include #ifdef INET #include #include #endif #include #include /* XXX for softled */ #include #include #include #include #include #include #include #include #include #include #include #include #ifdef ATH_TX99_DIAG #include #endif #include #ifdef ATH_DEBUG_ALQ #include #endif /* * some general macros */ #define INCR(_l, _sz) (_l) ++; (_l) &= ((_sz) - 1) #define DECR(_l, _sz) (_l) --; (_l) &= ((_sz) - 1) MALLOC_DECLARE(M_ATHDEV); /* * XXX TODO: * * + Make sure the FIFO is correctly flushed and reinitialised * through a reset; * + Verify multi-descriptor frames work! * + There's a "memory use after free" which needs to be tracked down * and fixed ASAP. I've seen this in the legacy path too, so it * may be a generic RX path issue. */ /* * XXX shuffle the function orders so these pre-declarations aren't * required! */ static int ath_edma_rxfifo_alloc(struct ath_softc *sc, HAL_RX_QUEUE qtype, int nbufs); static int ath_edma_rxfifo_flush(struct ath_softc *sc, HAL_RX_QUEUE qtype); static void ath_edma_rxbuf_free(struct ath_softc *sc, struct ath_buf *bf); static void ath_edma_recv_proc_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype, int dosched); static int ath_edma_recv_proc_deferred_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype, int dosched); static void ath_edma_stoprecv(struct ath_softc *sc, int dodelay) { struct ath_hal *ah = sc->sc_ah; ATH_RX_LOCK(sc); ath_hal_stoppcurecv(ah); ath_hal_setrxfilter(ah, 0); /* * */ if (ath_hal_stopdmarecv(ah) == AH_TRUE) sc->sc_rx_stopped = 1; /* * Give the various bus FIFOs (not EDMA descriptor FIFO) * time to finish flushing out data. */ DELAY(3000); /* Flush RX pending for each queue */ /* XXX should generic-ify this */ if (sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending) { m_freem(sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending); sc->sc_rxedma[HAL_RX_QUEUE_HP].m_rxpending = NULL; } if (sc->sc_rxedma[HAL_RX_QUEUE_LP].m_rxpending) { m_freem(sc->sc_rxedma[HAL_RX_QUEUE_LP].m_rxpending); sc->sc_rxedma[HAL_RX_QUEUE_LP].m_rxpending = NULL; } ATH_RX_UNLOCK(sc); } /* * Re-initialise the FIFO given the current buffer contents. * Specifically, walk from head -> tail, pushing the FIFO contents * back into the FIFO. */ static void ath_edma_reinit_fifo(struct ath_softc *sc, HAL_RX_QUEUE qtype) { struct ath_rx_edma *re = &sc->sc_rxedma[qtype]; struct ath_buf *bf; int i, j; ATH_RX_LOCK_ASSERT(sc); i = re->m_fifo_head; for (j = 0; j < re->m_fifo_depth; j++) { bf = re->m_fifo[i]; DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: Q%d: pos=%i, addr=0x%jx\n", __func__, qtype, i, (uintmax_t)bf->bf_daddr); ath_hal_putrxbuf(sc->sc_ah, bf->bf_daddr, qtype); INCR(i, re->m_fifolen); } /* Ensure this worked out right */ if (i != re->m_fifo_tail) { device_printf(sc->sc_dev, "%s: i (%d) != tail! (%d)\n", __func__, i, re->m_fifo_tail); } } /* * Start receive. */ static int ath_edma_startrecv(struct ath_softc *sc) { struct ath_hal *ah = sc->sc_ah; ATH_RX_LOCK(sc); /* * Sanity check - are we being called whilst RX * isn't stopped? If so, we may end up pushing * too many entries into the RX FIFO and * badness occurs. */ /* Enable RX FIFO */ ath_hal_rxena(ah); /* * In theory the hardware has been initialised, right? */ if (sc->sc_rx_resetted == 1) { DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: Re-initing HP FIFO\n", __func__); ath_edma_reinit_fifo(sc, HAL_RX_QUEUE_HP); DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: Re-initing LP FIFO\n", __func__); ath_edma_reinit_fifo(sc, HAL_RX_QUEUE_LP); sc->sc_rx_resetted = 0; } else { device_printf(sc->sc_dev, "%s: called without resetting chip?\n", __func__); } /* Add up to m_fifolen entries in each queue */ /* * These must occur after the above write so the FIFO buffers * are pushed/tracked in the same order as the hardware will * process them. * * XXX TODO: is this really necessary? We should've stopped * the hardware already and reinitialised it, so it's a no-op. */ ath_edma_rxfifo_alloc(sc, HAL_RX_QUEUE_HP, sc->sc_rxedma[HAL_RX_QUEUE_HP].m_fifolen); ath_edma_rxfifo_alloc(sc, HAL_RX_QUEUE_LP, sc->sc_rxedma[HAL_RX_QUEUE_LP].m_fifolen); ath_mode_init(sc); - ath_hal_startpcurecv(ah); + ath_hal_startpcurecv(ah, (!! sc->sc_scanning)); /* * We're now doing RX DMA! */ sc->sc_rx_stopped = 0; ATH_RX_UNLOCK(sc); return (0); } static void ath_edma_recv_sched_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype, int dosched) { ATH_LOCK(sc); ath_power_set_power_state(sc, HAL_PM_AWAKE); ATH_UNLOCK(sc); ath_edma_recv_proc_queue(sc, qtype, dosched); ATH_LOCK(sc); ath_power_restore_power_state(sc); ATH_UNLOCK(sc); taskqueue_enqueue(sc->sc_tq, &sc->sc_rxtask); } static void ath_edma_recv_sched(struct ath_softc *sc, int dosched) { ATH_LOCK(sc); ath_power_set_power_state(sc, HAL_PM_AWAKE); ATH_UNLOCK(sc); ath_edma_recv_proc_queue(sc, HAL_RX_QUEUE_HP, dosched); ath_edma_recv_proc_queue(sc, HAL_RX_QUEUE_LP, dosched); ATH_LOCK(sc); ath_power_restore_power_state(sc); ATH_UNLOCK(sc); taskqueue_enqueue(sc->sc_tq, &sc->sc_rxtask); } static void ath_edma_recv_flush(struct ath_softc *sc) { DPRINTF(sc, ATH_DEBUG_RECV, "%s: called\n", __func__); ATH_PCU_LOCK(sc); sc->sc_rxproc_cnt++; ATH_PCU_UNLOCK(sc); ATH_LOCK(sc); ath_power_set_power_state(sc, HAL_PM_AWAKE); ATH_UNLOCK(sc); /* * Flush any active frames from FIFO -> deferred list */ ath_edma_recv_proc_queue(sc, HAL_RX_QUEUE_HP, 0); ath_edma_recv_proc_queue(sc, HAL_RX_QUEUE_LP, 0); /* * Process what's in the deferred queue */ /* * XXX: If we read the tsf/channoise here and then pass it in, * we could restore the power state before processing * the deferred queue. */ ath_edma_recv_proc_deferred_queue(sc, HAL_RX_QUEUE_HP, 0); ath_edma_recv_proc_deferred_queue(sc, HAL_RX_QUEUE_LP, 0); ATH_LOCK(sc); ath_power_restore_power_state(sc); ATH_UNLOCK(sc); ATH_PCU_LOCK(sc); sc->sc_rxproc_cnt--; ATH_PCU_UNLOCK(sc); } /* * Process frames from the current queue into the deferred queue. */ static void ath_edma_recv_proc_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype, int dosched) { struct ath_rx_edma *re = &sc->sc_rxedma[qtype]; struct ath_rx_status *rs; struct ath_desc *ds; struct ath_buf *bf; struct mbuf *m; struct ath_hal *ah = sc->sc_ah; uint64_t tsf; uint16_t nf; int npkts = 0; tsf = ath_hal_gettsf64(ah); nf = ath_hal_getchannoise(ah, sc->sc_curchan); sc->sc_stats.ast_rx_noise = nf; ATH_RX_LOCK(sc); #if 1 if (sc->sc_rx_resetted == 1) { /* * XXX We shouldn't ever be scheduled if * receive has been stopped - so complain * loudly! */ device_printf(sc->sc_dev, "%s: sc_rx_resetted=1! Bad!\n", __func__); ATH_RX_UNLOCK(sc); return; } #endif do { bf = re->m_fifo[re->m_fifo_head]; /* This shouldn't occur! */ if (bf == NULL) { device_printf(sc->sc_dev, "%s: Q%d: NULL bf?\n", __func__, qtype); break; } m = bf->bf_m; ds = bf->bf_desc; /* * Sync descriptor memory - this also syncs the buffer for us. * EDMA descriptors are in cached memory. */ bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); rs = &bf->bf_status.ds_rxstat; bf->bf_rxstatus = ath_hal_rxprocdesc(ah, ds, bf->bf_daddr, NULL, rs); if (bf->bf_rxstatus == HAL_EINPROGRESS) break; #ifdef ATH_DEBUG if (sc->sc_debug & ATH_DEBUG_RECV_DESC) ath_printrxbuf(sc, bf, 0, bf->bf_rxstatus == HAL_OK); #endif /* ATH_DEBUG */ #ifdef ATH_DEBUG_ALQ if (if_ath_alq_checkdebug(&sc->sc_alq, ATH_ALQ_EDMA_RXSTATUS)) if_ath_alq_post(&sc->sc_alq, ATH_ALQ_EDMA_RXSTATUS, sc->sc_rx_statuslen, (char *) ds); #endif /* ATH_DEBUG */ /* * Completed descriptor. */ DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: Q%d: completed!\n", __func__, qtype); npkts++; /* * We've been synced already, so unmap. */ bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap); /* * Remove the FIFO entry and place it on the completion * queue. */ re->m_fifo[re->m_fifo_head] = NULL; TAILQ_INSERT_TAIL(&sc->sc_rx_rxlist[qtype], bf, bf_list); /* Bump the descriptor FIFO stats */ INCR(re->m_fifo_head, re->m_fifolen); re->m_fifo_depth--; /* XXX check it doesn't fall below 0 */ } while (re->m_fifo_depth > 0); /* Append some more fresh frames to the FIFO */ if (dosched) ath_edma_rxfifo_alloc(sc, qtype, re->m_fifolen); ATH_RX_UNLOCK(sc); /* rx signal state monitoring */ ath_hal_rxmonitor(ah, &sc->sc_halstats, sc->sc_curchan); ATH_KTR(sc, ATH_KTR_INTERRUPTS, 1, "ath edma rx proc: npkts=%d\n", npkts); return; } /* * Flush the deferred queue. * * This destructively flushes the deferred queue - it doesn't * call the wireless stack on each mbuf. */ static void ath_edma_flush_deferred_queue(struct ath_softc *sc) { struct ath_buf *bf; ATH_RX_LOCK_ASSERT(sc); /* Free in one set, inside the lock */ while (! TAILQ_EMPTY(&sc->sc_rx_rxlist[HAL_RX_QUEUE_LP])) { bf = TAILQ_FIRST(&sc->sc_rx_rxlist[HAL_RX_QUEUE_LP]); TAILQ_REMOVE(&sc->sc_rx_rxlist[HAL_RX_QUEUE_LP], bf, bf_list); /* Free the buffer/mbuf */ ath_edma_rxbuf_free(sc, bf); } while (! TAILQ_EMPTY(&sc->sc_rx_rxlist[HAL_RX_QUEUE_HP])) { bf = TAILQ_FIRST(&sc->sc_rx_rxlist[HAL_RX_QUEUE_HP]); TAILQ_REMOVE(&sc->sc_rx_rxlist[HAL_RX_QUEUE_HP], bf, bf_list); /* Free the buffer/mbuf */ ath_edma_rxbuf_free(sc, bf); } } static int ath_edma_recv_proc_deferred_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype, int dosched) { int ngood = 0; uint64_t tsf; struct ath_buf *bf, *next; struct ath_rx_status *rs; int16_t nf; ath_bufhead rxlist; struct mbuf *m; TAILQ_INIT(&rxlist); nf = ath_hal_getchannoise(sc->sc_ah, sc->sc_curchan); /* * XXX TODO: the NF/TSF should be stamped on the bufs themselves, * otherwise we may end up adding in the wrong values if this * is delayed too far.. */ tsf = ath_hal_gettsf64(sc->sc_ah); /* Copy the list over */ ATH_RX_LOCK(sc); TAILQ_CONCAT(&rxlist, &sc->sc_rx_rxlist[qtype], bf_list); ATH_RX_UNLOCK(sc); /* Handle the completed descriptors */ /* * XXX is this SAFE call needed? The ath_buf entries * aren't modified by ath_rx_pkt, right? */ TAILQ_FOREACH_SAFE(bf, &rxlist, bf_list, next) { /* * Skip the RX descriptor status - start at the data offset */ m_adj(bf->bf_m, sc->sc_rx_statuslen); /* Handle the frame */ rs = &bf->bf_status.ds_rxstat; m = bf->bf_m; bf->bf_m = NULL; if (ath_rx_pkt(sc, rs, bf->bf_rxstatus, tsf, nf, qtype, bf, m)) ngood++; } if (ngood) { sc->sc_lastrx = tsf; } ATH_KTR(sc, ATH_KTR_INTERRUPTS, 1, "ath edma rx deferred proc: ngood=%d\n", ngood); /* Free in one set, inside the lock */ ATH_RX_LOCK(sc); while (! TAILQ_EMPTY(&rxlist)) { bf = TAILQ_FIRST(&rxlist); TAILQ_REMOVE(&rxlist, bf, bf_list); /* Free the buffer/mbuf */ ath_edma_rxbuf_free(sc, bf); } ATH_RX_UNLOCK(sc); return (ngood); } static void ath_edma_recv_tasklet(void *arg, int npending) { struct ath_softc *sc = (struct ath_softc *) arg; #ifdef IEEE80211_SUPPORT_SUPERG struct ieee80211com *ic = &sc->sc_ic; #endif DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: called; npending=%d\n", __func__, npending); ATH_PCU_LOCK(sc); if (sc->sc_inreset_cnt > 0) { device_printf(sc->sc_dev, "%s: sc_inreset_cnt > 0; skipping\n", __func__); ATH_PCU_UNLOCK(sc); return; } sc->sc_rxproc_cnt++; ATH_PCU_UNLOCK(sc); ATH_LOCK(sc); ath_power_set_power_state(sc, HAL_PM_AWAKE); ATH_UNLOCK(sc); ath_edma_recv_proc_queue(sc, HAL_RX_QUEUE_HP, 1); ath_edma_recv_proc_queue(sc, HAL_RX_QUEUE_LP, 1); ath_edma_recv_proc_deferred_queue(sc, HAL_RX_QUEUE_HP, 1); ath_edma_recv_proc_deferred_queue(sc, HAL_RX_QUEUE_LP, 1); /* * XXX: If we read the tsf/channoise here and then pass it in, * we could restore the power state before processing * the deferred queue. */ ATH_LOCK(sc); ath_power_restore_power_state(sc); ATH_UNLOCK(sc); #ifdef IEEE80211_SUPPORT_SUPERG ieee80211_ff_age_all(ic, 100); #endif if (ath_dfs_tasklet_needed(sc, sc->sc_curchan)) taskqueue_enqueue(sc->sc_tq, &sc->sc_dfstask); ATH_PCU_LOCK(sc); sc->sc_rxproc_cnt--; ATH_PCU_UNLOCK(sc); } /* * Allocate an RX mbuf for the given ath_buf and initialise * it for EDMA. * * + Allocate a 4KB mbuf; * + Setup the DMA map for the given buffer; * + Return that. */ static int ath_edma_rxbuf_init(struct ath_softc *sc, struct ath_buf *bf) { struct mbuf *m; int error; int len; ATH_RX_LOCK_ASSERT(sc); m = m_getm(NULL, sc->sc_edma_bufsize, M_NOWAIT, MT_DATA); if (! m) return (ENOBUFS); /* XXX ?*/ /* XXX warn/enforce alignment */ len = m->m_ext.ext_size; #if 0 device_printf(sc->sc_dev, "%s: called: m=%p, size=%d, mtod=%p\n", __func__, m, len, mtod(m, char *)); #endif m->m_pkthdr.len = m->m_len = m->m_ext.ext_size; /* * Populate ath_buf fields. */ bf->bf_desc = mtod(m, struct ath_desc *); bf->bf_lastds = bf->bf_desc; /* XXX only really for TX? */ bf->bf_m = m; /* * Zero the descriptor and ensure it makes it out to the * bounce buffer if one is required. * * XXX PREWRITE will copy the whole buffer; we only needed it * to sync the first 32 DWORDS. Oh well. */ memset(bf->bf_desc, '\0', sc->sc_rx_statuslen); /* * Create DMA mapping. */ error = bus_dmamap_load_mbuf_sg(sc->sc_dmat, bf->bf_dmamap, m, bf->bf_segs, &bf->bf_nseg, BUS_DMA_NOWAIT); if (error != 0) { device_printf(sc->sc_dev, "%s: failed; error=%d\n", __func__, error); m_freem(m); return (error); } /* * Set daddr to the physical mapping page. */ bf->bf_daddr = bf->bf_segs[0].ds_addr; /* * Prepare for the upcoming read. * * We need to both sync some data into the buffer (the zero'ed * descriptor payload) and also prepare for the read that's going * to occur. */ bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); /* Finish! */ return (0); } /* * Allocate a RX buffer. */ static struct ath_buf * ath_edma_rxbuf_alloc(struct ath_softc *sc) { struct ath_buf *bf; int error; ATH_RX_LOCK_ASSERT(sc); /* Allocate buffer */ bf = TAILQ_FIRST(&sc->sc_rxbuf); /* XXX shouldn't happen upon startup? */ if (bf == NULL) { DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: nothing on rxbuf?!\n", __func__); return (NULL); } /* Remove it from the free list */ TAILQ_REMOVE(&sc->sc_rxbuf, bf, bf_list); /* Assign RX mbuf to it */ error = ath_edma_rxbuf_init(sc, bf); if (error != 0) { device_printf(sc->sc_dev, "%s: bf=%p, rxbuf alloc failed! error=%d\n", __func__, bf, error); TAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list); return (NULL); } return (bf); } static void ath_edma_rxbuf_free(struct ath_softc *sc, struct ath_buf *bf) { ATH_RX_LOCK_ASSERT(sc); /* * Only unload the frame if we haven't consumed * the mbuf via ath_rx_pkt(). */ if (bf->bf_m) { bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap); m_freem(bf->bf_m); bf->bf_m = NULL; } /* XXX lock? */ TAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list); } /* * Allocate up to 'n' entries and push them onto the hardware FIFO. * * Return how many entries were successfully pushed onto the * FIFO. */ static int ath_edma_rxfifo_alloc(struct ath_softc *sc, HAL_RX_QUEUE qtype, int nbufs) { struct ath_rx_edma *re = &sc->sc_rxedma[qtype]; struct ath_buf *bf; int i; ATH_RX_LOCK_ASSERT(sc); /* * Allocate buffers until the FIFO is full or nbufs is reached. */ for (i = 0; i < nbufs && re->m_fifo_depth < re->m_fifolen; i++) { /* Ensure the FIFO is already blank, complain loudly! */ if (re->m_fifo[re->m_fifo_tail] != NULL) { device_printf(sc->sc_dev, "%s: Q%d: fifo[%d] != NULL (%p)\n", __func__, qtype, re->m_fifo_tail, re->m_fifo[re->m_fifo_tail]); /* Free the slot */ ath_edma_rxbuf_free(sc, re->m_fifo[re->m_fifo_tail]); re->m_fifo_depth--; /* XXX check it's not < 0 */ re->m_fifo[re->m_fifo_tail] = NULL; } bf = ath_edma_rxbuf_alloc(sc); /* XXX should ensure the FIFO is not NULL? */ if (bf == NULL) { DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: Q%d: alloc failed: i=%d, nbufs=%d?\n", __func__, qtype, i, nbufs); break; } re->m_fifo[re->m_fifo_tail] = bf; /* Write to the RX FIFO */ DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: Q%d: putrxbuf=%p (0x%jx)\n", __func__, qtype, bf->bf_desc, (uintmax_t) bf->bf_daddr); ath_hal_putrxbuf(sc->sc_ah, bf->bf_daddr, qtype); re->m_fifo_depth++; INCR(re->m_fifo_tail, re->m_fifolen); } /* * Return how many were allocated. */ DPRINTF(sc, ATH_DEBUG_EDMA_RX, "%s: Q%d: nbufs=%d, nalloced=%d\n", __func__, qtype, nbufs, i); return (i); } static int ath_edma_rxfifo_flush(struct ath_softc *sc, HAL_RX_QUEUE qtype) { struct ath_rx_edma *re = &sc->sc_rxedma[qtype]; int i; ATH_RX_LOCK_ASSERT(sc); for (i = 0; i < re->m_fifolen; i++) { if (re->m_fifo[i] != NULL) { #ifdef ATH_DEBUG struct ath_buf *bf = re->m_fifo[i]; if (sc->sc_debug & ATH_DEBUG_RECV_DESC) ath_printrxbuf(sc, bf, 0, HAL_OK); #endif ath_edma_rxbuf_free(sc, re->m_fifo[i]); re->m_fifo[i] = NULL; re->m_fifo_depth--; } } if (re->m_rxpending != NULL) { m_freem(re->m_rxpending); re->m_rxpending = NULL; } re->m_fifo_head = re->m_fifo_tail = re->m_fifo_depth = 0; return (0); } /* * Setup the initial RX FIFO structure. */ static int ath_edma_setup_rxfifo(struct ath_softc *sc, HAL_RX_QUEUE qtype) { struct ath_rx_edma *re = &sc->sc_rxedma[qtype]; ATH_RX_LOCK_ASSERT(sc); if (! ath_hal_getrxfifodepth(sc->sc_ah, qtype, &re->m_fifolen)) { device_printf(sc->sc_dev, "%s: qtype=%d, failed\n", __func__, qtype); return (-EINVAL); } if (bootverbose) device_printf(sc->sc_dev, "%s: type=%d, FIFO depth = %d entries\n", __func__, qtype, re->m_fifolen); /* Allocate ath_buf FIFO array, pre-zero'ed */ re->m_fifo = malloc(sizeof(struct ath_buf *) * re->m_fifolen, M_ATHDEV, M_NOWAIT | M_ZERO); if (re->m_fifo == NULL) { device_printf(sc->sc_dev, "%s: malloc failed\n", __func__); return (-ENOMEM); } /* * Set initial "empty" state. */ re->m_rxpending = NULL; re->m_fifo_head = re->m_fifo_tail = re->m_fifo_depth = 0; return (0); } static int ath_edma_rxfifo_free(struct ath_softc *sc, HAL_RX_QUEUE qtype) { struct ath_rx_edma *re = &sc->sc_rxedma[qtype]; device_printf(sc->sc_dev, "%s: called; qtype=%d\n", __func__, qtype); free(re->m_fifo, M_ATHDEV); return (0); } static int ath_edma_dma_rxsetup(struct ath_softc *sc) { int error; /* * Create RX DMA tag and buffers. */ error = ath_descdma_setup_rx_edma(sc, &sc->sc_rxdma, &sc->sc_rxbuf, "rx", ath_rxbuf, sc->sc_rx_statuslen); if (error != 0) return error; ATH_RX_LOCK(sc); (void) ath_edma_setup_rxfifo(sc, HAL_RX_QUEUE_HP); (void) ath_edma_setup_rxfifo(sc, HAL_RX_QUEUE_LP); ATH_RX_UNLOCK(sc); return (0); } static int ath_edma_dma_rxteardown(struct ath_softc *sc) { ATH_RX_LOCK(sc); ath_edma_flush_deferred_queue(sc); ath_edma_rxfifo_flush(sc, HAL_RX_QUEUE_HP); ath_edma_rxfifo_free(sc, HAL_RX_QUEUE_HP); ath_edma_rxfifo_flush(sc, HAL_RX_QUEUE_LP); ath_edma_rxfifo_free(sc, HAL_RX_QUEUE_LP); ATH_RX_UNLOCK(sc); /* Free RX ath_buf */ /* Free RX DMA tag */ if (sc->sc_rxdma.dd_desc_len != 0) ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf); return (0); } void ath_recv_setup_edma(struct ath_softc *sc) { /* Set buffer size to 4k */ sc->sc_edma_bufsize = 4096; /* Fetch EDMA field and buffer sizes */ (void) ath_hal_getrxstatuslen(sc->sc_ah, &sc->sc_rx_statuslen); /* Configure the hardware with the RX buffer size */ (void) ath_hal_setrxbufsize(sc->sc_ah, sc->sc_edma_bufsize - sc->sc_rx_statuslen); if (bootverbose) { device_printf(sc->sc_dev, "RX status length: %d\n", sc->sc_rx_statuslen); device_printf(sc->sc_dev, "RX buffer size: %d\n", sc->sc_edma_bufsize); } sc->sc_rx.recv_stop = ath_edma_stoprecv; sc->sc_rx.recv_start = ath_edma_startrecv; sc->sc_rx.recv_flush = ath_edma_recv_flush; sc->sc_rx.recv_tasklet = ath_edma_recv_tasklet; sc->sc_rx.recv_rxbuf_init = ath_edma_rxbuf_init; sc->sc_rx.recv_setup = ath_edma_dma_rxsetup; sc->sc_rx.recv_teardown = ath_edma_dma_rxteardown; sc->sc_rx.recv_sched = ath_edma_recv_sched; sc->sc_rx.recv_sched_queue = ath_edma_recv_sched_queue; } Index: head/sys/dev/ath/if_athvar.h =================================================================== --- head/sys/dev/ath/if_athvar.h (revision 346469) +++ head/sys/dev/ath/if_athvar.h (revision 346470) @@ -1,1539 +1,1539 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. * * $FreeBSD$ */ /* * Defintions for the Atheros Wireless LAN controller driver. */ #ifndef _DEV_ATH_ATHVAR_H #define _DEV_ATH_ATHVAR_H #include #include #include #include #include #include #ifdef ATH_DEBUG_ALQ #include #endif #define ATH_TIMEOUT 1000 /* * There is a separate TX ath_buf pool for management frames. * This ensures that management frames such as probe responses * and BAR frames can be transmitted during periods of high * TX activity. */ #define ATH_MGMT_TXBUF 32 /* * 802.11n requires more TX and RX buffers to do AMPDU. */ #ifdef ATH_ENABLE_11N #define ATH_TXBUF 512 #define ATH_RXBUF 512 #endif #ifndef ATH_RXBUF #define ATH_RXBUF 40 /* number of RX buffers */ #endif #ifndef ATH_TXBUF #define ATH_TXBUF 200 /* number of TX buffers */ #endif #define ATH_BCBUF 4 /* number of beacon buffers */ #define ATH_TXDESC 10 /* number of descriptors per buffer */ #define ATH_TXMAXTRY 11 /* max number of transmit attempts */ #define ATH_TXMGTTRY 4 /* xmit attempts for mgt/ctl frames */ #define ATH_TXINTR_PERIOD 5 /* max number of batched tx descriptors */ #define ATH_BEACON_AIFS_DEFAULT 1 /* default aifs for ap beacon q */ #define ATH_BEACON_CWMIN_DEFAULT 0 /* default cwmin for ap beacon q */ #define ATH_BEACON_CWMAX_DEFAULT 0 /* default cwmax for ap beacon q */ /* * The following bits can be set during the PCI (and perhaps non-PCI * later) device probe path. * * It controls some of the driver and HAL behaviour. */ #define ATH_PCI_CUS198 0x0001 #define ATH_PCI_CUS230 0x0002 #define ATH_PCI_CUS217 0x0004 #define ATH_PCI_CUS252 0x0008 #define ATH_PCI_WOW 0x0010 #define ATH_PCI_BT_ANT_DIV 0x0020 #define ATH_PCI_D3_L1_WAR 0x0040 #define ATH_PCI_AR9565_1ANT 0x0080 #define ATH_PCI_AR9565_2ANT 0x0100 #define ATH_PCI_NO_PLL_PWRSAVE 0x0200 #define ATH_PCI_KILLER 0x0400 /* * The key cache is used for h/w cipher state and also for * tracking station state such as the current tx antenna. * We also setup a mapping table between key cache slot indices * and station state to short-circuit node lookups on rx. * Different parts have different size key caches. We handle * up to ATH_KEYMAX entries (could dynamically allocate state). */ #define ATH_KEYMAX 128 /* max key cache size we handle */ #define ATH_KEYBYTES (ATH_KEYMAX/NBBY) /* storage space in bytes */ struct taskqueue; struct kthread; struct ath_buf; #define ATH_TID_MAX_BUFS (2 * IEEE80211_AGGR_BAWMAX) /* * Per-TID state * * Note that TID 16 (WME_NUM_TID+1) is for handling non-QoS frames. */ struct ath_tid { TAILQ_HEAD(,ath_buf) tid_q; /* pending buffers */ struct ath_node *an; /* pointer to parent */ int tid; /* tid */ int ac; /* which AC gets this traffic */ int hwq_depth; /* how many buffers are on HW */ u_int axq_depth; /* SW queue depth */ struct { TAILQ_HEAD(,ath_buf) tid_q; /* filtered queue */ u_int axq_depth; /* SW queue depth */ } filtq; /* * Entry on the ath_txq; when there's traffic * to send */ TAILQ_ENTRY(ath_tid) axq_qelem; int sched; int paused; /* >0 if the TID has been paused */ /* * These are flags - perhaps later collapse * down to a single uint32_t ? */ int addba_tx_pending; /* TX ADDBA pending */ int bar_wait; /* waiting for BAR */ int bar_tx; /* BAR TXed */ int isfiltered; /* is this node currently filtered */ /* * Is the TID being cleaned up after a transition * from aggregation to non-aggregation? * When this is set to 1, this TID will be paused * and no further traffic will be queued until all * the hardware packets pending for this TID have been * TXed/completed; at which point (non-aggregation) * traffic will resume being TXed. */ int cleanup_inprogress; /* * How many hardware-queued packets are * waiting to be cleaned up. * This is only valid if cleanup_inprogress is 1. */ int incomp; /* * The following implements a ring representing * the frames in the current BAW. * To avoid copying the array content each time * the BAW is moved, the baw_head/baw_tail point * to the current BAW begin/end; when the BAW is * shifted the head/tail of the array are also * appropriately shifted. */ /* active tx buffers, beginning at current BAW */ struct ath_buf *tx_buf[ATH_TID_MAX_BUFS]; /* where the baw head is in the array */ int baw_head; /* where the BAW tail is in the array */ int baw_tail; }; /* driver-specific node state */ struct ath_node { struct ieee80211_node an_node; /* base class */ u_int8_t an_mgmtrix; /* min h/w rate index */ u_int8_t an_mcastrix; /* mcast h/w rate index */ uint32_t an_is_powersave; /* node is sleeping */ uint32_t an_stack_psq; /* net80211 psq isn't empty */ uint32_t an_tim_set; /* TIM has been set */ struct ath_buf *an_ff_buf[WME_NUM_AC]; /* ff staging area */ struct ath_tid an_tid[IEEE80211_TID_SIZE]; /* per-TID state */ char an_name[32]; /* eg "wlan0_a1" */ struct mtx an_mtx; /* protecting the rate control state */ uint32_t an_swq_depth; /* how many SWQ packets for this node */ int clrdmask; /* has clrdmask been set */ uint32_t an_leak_count; /* How many frames to leak during pause */ /* variable-length rate control state follows */ }; #define ATH_NODE(ni) ((struct ath_node *)(ni)) #define ATH_NODE_CONST(ni) ((const struct ath_node *)(ni)) #define ATH_RSSI_LPF_LEN 10 #define ATH_RSSI_DUMMY_MARKER 0x127 #define ATH_EP_MUL(x, mul) ((x) * (mul)) #define ATH_RSSI_IN(x) (ATH_EP_MUL((x), HAL_RSSI_EP_MULTIPLIER)) #define ATH_LPF_RSSI(x, y, len) \ ((x != ATH_RSSI_DUMMY_MARKER) ? (((x) * ((len) - 1) + (y)) / (len)) : (y)) #define ATH_RSSI_LPF(x, y) do { \ if ((y) >= -20) \ x = ATH_LPF_RSSI((x), ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN); \ } while (0) #define ATH_EP_RND(x,mul) \ ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) #define ATH_RSSI(x) ATH_EP_RND(x, HAL_RSSI_EP_MULTIPLIER) typedef enum { ATH_BUFTYPE_NORMAL = 0, ATH_BUFTYPE_MGMT = 1, } ath_buf_type_t; struct ath_buf { TAILQ_ENTRY(ath_buf) bf_list; struct ath_buf * bf_next; /* next buffer in the aggregate */ int bf_nseg; HAL_STATUS bf_rxstatus; uint16_t bf_flags; /* status flags (below) */ uint16_t bf_descid; /* 16 bit descriptor ID */ struct ath_desc *bf_desc; /* virtual addr of desc */ struct ath_desc_status bf_status; /* tx/rx status */ bus_addr_t bf_daddr; /* physical addr of desc */ bus_dmamap_t bf_dmamap; /* DMA map for mbuf chain */ struct mbuf *bf_m; /* mbuf for buf */ struct ieee80211_node *bf_node; /* pointer to the node */ struct ath_desc *bf_lastds; /* last descriptor for comp status */ struct ath_buf *bf_last; /* last buffer in aggregate, or self for non-aggregate */ bus_size_t bf_mapsize; #define ATH_MAX_SCATTER ATH_TXDESC /* max(tx,rx,beacon) desc's */ bus_dma_segment_t bf_segs[ATH_MAX_SCATTER]; uint32_t bf_nextfraglen; /* length of next fragment */ /* Completion function to call on TX complete (fail or not) */ /* * "fail" here is set to 1 if the queue entries were removed * through a call to ath_tx_draintxq(). */ void(* bf_comp) (struct ath_softc *sc, struct ath_buf *bf, int fail); /* This state is kept to support software retries and aggregation */ struct { uint16_t bfs_seqno; /* sequence number of this packet */ uint16_t bfs_ndelim; /* number of delims for padding */ uint8_t bfs_retries; /* retry count */ uint8_t bfs_tid; /* packet TID (or TID_MAX for no QoS) */ uint8_t bfs_nframes; /* number of frames in aggregate */ uint8_t bfs_pri; /* packet AC priority */ uint8_t bfs_tx_queue; /* destination hardware TX queue */ u_int32_t bfs_aggr:1, /* part of aggregate? */ bfs_aggrburst:1, /* part of aggregate burst? */ bfs_isretried:1, /* retried frame? */ bfs_dobaw:1, /* actually check against BAW? */ bfs_addedbaw:1, /* has been added to the BAW */ bfs_shpream:1, /* use short preamble */ bfs_istxfrag:1, /* is fragmented */ bfs_ismrr:1, /* do multi-rate TX retry */ bfs_doprot:1, /* do RTS/CTS based protection */ bfs_doratelookup:1; /* do rate lookup before each TX */ /* * These fields are passed into the * descriptor setup functions. */ /* Make this an 8 bit value? */ HAL_PKT_TYPE bfs_atype; /* packet type */ uint32_t bfs_pktlen; /* length of this packet */ uint16_t bfs_hdrlen; /* length of this packet header */ uint16_t bfs_al; /* length of aggregate */ uint16_t bfs_txflags; /* HAL (tx) descriptor flags */ uint8_t bfs_txrate0; /* first TX rate */ uint8_t bfs_try0; /* first try count */ uint16_t bfs_txpower; /* tx power */ uint8_t bfs_ctsrate0; /* Non-zero - use this as ctsrate */ uint8_t bfs_ctsrate; /* CTS rate */ /* 16 bit? */ int32_t bfs_keyix; /* crypto key index */ int32_t bfs_txantenna; /* TX antenna config */ /* Make this an 8 bit value? */ enum ieee80211_protmode bfs_protmode; /* 16 bit? */ uint32_t bfs_ctsduration; /* CTS duration (pre-11n NICs) */ struct ath_rc_series bfs_rc[ATH_RC_NUM]; /* non-11n TX series */ } bf_state; }; typedef TAILQ_HEAD(ath_bufhead_s, ath_buf) ath_bufhead; #define ATH_BUF_MGMT 0x00000001 /* (tx) desc is a mgmt desc */ #define ATH_BUF_BUSY 0x00000002 /* (tx) desc owned by h/w */ #define ATH_BUF_FIFOEND 0x00000004 #define ATH_BUF_FIFOPTR 0x00000008 #define ATH_BUF_TOA_PROBE 0x00000010 /* ToD/ToA exchange probe */ #define ATH_BUF_FLAGS_CLONE (ATH_BUF_MGMT | ATH_BUF_TOA_PROBE) /* * DMA state for tx/rx descriptors. */ struct ath_descdma { const char* dd_name; struct ath_desc *dd_desc; /* descriptors */ int dd_descsize; /* size of single descriptor */ bus_addr_t dd_desc_paddr; /* physical addr of dd_desc */ bus_size_t dd_desc_len; /* size of dd_desc */ bus_dma_segment_t dd_dseg; bus_dma_tag_t dd_dmat; /* bus DMA tag */ bus_dmamap_t dd_dmamap; /* DMA map for descriptors */ struct ath_buf *dd_bufptr; /* associated buffers */ }; /* * Data transmit queue state. One of these exists for each * hardware transmit queue. Packets sent to us from above * are assigned to queues based on their priority. Not all * devices support a complete set of hardware transmit queues. * For those devices the array sc_ac2q will map multiple * priorities to fewer hardware queues (typically all to one * hardware queue). */ struct ath_txq { struct ath_softc *axq_softc; /* Needed for scheduling */ u_int axq_qnum; /* hardware q number */ #define ATH_TXQ_SWQ (HAL_NUM_TX_QUEUES+1) /* qnum for s/w only queue */ u_int axq_ac; /* WME AC */ u_int axq_flags; //#define ATH_TXQ_PUTPENDING 0x0001 /* ath_hal_puttxbuf pending */ #define ATH_TXQ_PUTRUNNING 0x0002 /* ath_hal_puttxbuf has been called */ u_int axq_depth; /* queue depth (stat only) */ u_int axq_aggr_depth; /* how many aggregates are queued */ u_int axq_intrcnt; /* interrupt count */ u_int32_t *axq_link; /* link ptr in last TX desc */ TAILQ_HEAD(axq_q_s, ath_buf) axq_q; /* transmit queue */ struct mtx axq_lock; /* lock on q and link */ /* * This is the FIFO staging buffer when doing EDMA. * * For legacy chips, we just push the head pointer to * the hardware and we ignore this list. * * For EDMA, the staging buffer is treated as normal; * when it's time to push a list of frames to the hardware * we move that list here and we stamp buffers with * flags to identify the beginning/end of that particular * FIFO entry. */ struct { TAILQ_HEAD(axq_q_f_s, ath_buf) axq_q; u_int axq_depth; /* how many frames (1 per legacy, 1 per A-MPDU list) are in the FIFO queue */ } fifo; u_int axq_fifo_depth; /* how many FIFO slots are active */ /* * XXX the holdingbf field is protected by the TXBUF lock * for now, NOT the TXQ lock. * * Architecturally, it would likely be better to move * the holdingbf field to a separate array in ath_softc * just to highlight that it's not protected by the normal * TX path lock. */ struct ath_buf *axq_holdingbf; /* holding TX buffer */ char axq_name[12]; /* e.g. "ath0_txq4" */ /* Per-TID traffic queue for software -> hardware TX */ /* * This is protected by the general TX path lock, not (for now) * by the TXQ lock. */ TAILQ_HEAD(axq_t_s,ath_tid) axq_tidq; }; #define ATH_TXQ_LOCK_INIT(_sc, _tq) do { \ snprintf((_tq)->axq_name, sizeof((_tq)->axq_name), "%s_txq%u", \ device_get_nameunit((_sc)->sc_dev), (_tq)->axq_qnum); \ mtx_init(&(_tq)->axq_lock, (_tq)->axq_name, NULL, MTX_DEF); \ } while (0) #define ATH_TXQ_LOCK_DESTROY(_tq) mtx_destroy(&(_tq)->axq_lock) #define ATH_TXQ_LOCK(_tq) mtx_lock(&(_tq)->axq_lock) #define ATH_TXQ_UNLOCK(_tq) mtx_unlock(&(_tq)->axq_lock) #define ATH_TXQ_LOCK_ASSERT(_tq) mtx_assert(&(_tq)->axq_lock, MA_OWNED) #define ATH_TXQ_UNLOCK_ASSERT(_tq) mtx_assert(&(_tq)->axq_lock, \ MA_NOTOWNED) #define ATH_NODE_LOCK(_an) mtx_lock(&(_an)->an_mtx) #define ATH_NODE_UNLOCK(_an) mtx_unlock(&(_an)->an_mtx) #define ATH_NODE_LOCK_ASSERT(_an) mtx_assert(&(_an)->an_mtx, MA_OWNED) #define ATH_NODE_UNLOCK_ASSERT(_an) mtx_assert(&(_an)->an_mtx, \ MA_NOTOWNED) /* * These are for the hardware queue. */ #define ATH_TXQ_INSERT_HEAD(_tq, _elm, _field) do { \ TAILQ_INSERT_HEAD(&(_tq)->axq_q, (_elm), _field); \ (_tq)->axq_depth++; \ } while (0) #define ATH_TXQ_INSERT_TAIL(_tq, _elm, _field) do { \ TAILQ_INSERT_TAIL(&(_tq)->axq_q, (_elm), _field); \ (_tq)->axq_depth++; \ } while (0) #define ATH_TXQ_REMOVE(_tq, _elm, _field) do { \ TAILQ_REMOVE(&(_tq)->axq_q, _elm, _field); \ (_tq)->axq_depth--; \ } while (0) #define ATH_TXQ_FIRST(_tq) TAILQ_FIRST(&(_tq)->axq_q) #define ATH_TXQ_LAST(_tq, _field) TAILQ_LAST(&(_tq)->axq_q, _field) /* * These are for the TID software queue. */ #define ATH_TID_INSERT_HEAD(_tq, _elm, _field) do { \ TAILQ_INSERT_HEAD(&(_tq)->tid_q, (_elm), _field); \ (_tq)->axq_depth++; \ (_tq)->an->an_swq_depth++; \ } while (0) #define ATH_TID_INSERT_TAIL(_tq, _elm, _field) do { \ TAILQ_INSERT_TAIL(&(_tq)->tid_q, (_elm), _field); \ (_tq)->axq_depth++; \ (_tq)->an->an_swq_depth++; \ } while (0) #define ATH_TID_REMOVE(_tq, _elm, _field) do { \ TAILQ_REMOVE(&(_tq)->tid_q, _elm, _field); \ (_tq)->axq_depth--; \ (_tq)->an->an_swq_depth--; \ } while (0) #define ATH_TID_FIRST(_tq) TAILQ_FIRST(&(_tq)->tid_q) #define ATH_TID_LAST(_tq, _field) TAILQ_LAST(&(_tq)->tid_q, _field) /* * These are for the TID filtered frame queue */ #define ATH_TID_FILT_INSERT_HEAD(_tq, _elm, _field) do { \ TAILQ_INSERT_HEAD(&(_tq)->filtq.tid_q, (_elm), _field); \ (_tq)->axq_depth++; \ (_tq)->an->an_swq_depth++; \ } while (0) #define ATH_TID_FILT_INSERT_TAIL(_tq, _elm, _field) do { \ TAILQ_INSERT_TAIL(&(_tq)->filtq.tid_q, (_elm), _field); \ (_tq)->axq_depth++; \ (_tq)->an->an_swq_depth++; \ } while (0) #define ATH_TID_FILT_REMOVE(_tq, _elm, _field) do { \ TAILQ_REMOVE(&(_tq)->filtq.tid_q, _elm, _field); \ (_tq)->axq_depth--; \ (_tq)->an->an_swq_depth--; \ } while (0) #define ATH_TID_FILT_FIRST(_tq) TAILQ_FIRST(&(_tq)->filtq.tid_q) #define ATH_TID_FILT_LAST(_tq, _field) TAILQ_LAST(&(_tq)->filtq.tid_q,_field) struct ath_vap { struct ieee80211vap av_vap; /* base class */ int av_bslot; /* beacon slot index */ struct ath_buf *av_bcbuf; /* beacon buffer */ struct ath_txq av_mcastq; /* buffered mcast s/w queue */ void (*av_recv_mgmt)(struct ieee80211_node *, struct mbuf *, int, const struct ieee80211_rx_stats *, int, int); int (*av_newstate)(struct ieee80211vap *, enum ieee80211_state, int); void (*av_bmiss)(struct ieee80211vap *); void (*av_node_ps)(struct ieee80211_node *, int); int (*av_set_tim)(struct ieee80211_node *, int); void (*av_recv_pspoll)(struct ieee80211_node *, struct mbuf *); struct ieee80211_quiet_ie quiet_ie; }; #define ATH_VAP(vap) ((struct ath_vap *)(vap)) struct taskqueue; struct ath_tx99; /* * Whether to reset the TX/RX queue with or without * a queue flush. */ typedef enum { ATH_RESET_DEFAULT = 0, ATH_RESET_NOLOSS = 1, ATH_RESET_FULL = 2, } ATH_RESET_TYPE; struct ath_rx_methods { void (*recv_sched_queue)(struct ath_softc *sc, HAL_RX_QUEUE q, int dosched); void (*recv_sched)(struct ath_softc *sc, int dosched); void (*recv_stop)(struct ath_softc *sc, int dodelay); int (*recv_start)(struct ath_softc *sc); void (*recv_flush)(struct ath_softc *sc); void (*recv_tasklet)(void *arg, int npending); int (*recv_rxbuf_init)(struct ath_softc *sc, struct ath_buf *bf); int (*recv_setup)(struct ath_softc *sc); int (*recv_teardown)(struct ath_softc *sc); }; /* * Represent the current state of the RX FIFO. */ struct ath_rx_edma { struct ath_buf **m_fifo; int m_fifolen; int m_fifo_head; int m_fifo_tail; int m_fifo_depth; struct mbuf *m_rxpending; struct ath_buf *m_holdbf; }; struct ath_tx_edma_fifo { struct ath_buf **m_fifo; int m_fifolen; int m_fifo_head; int m_fifo_tail; int m_fifo_depth; }; struct ath_tx_methods { int (*xmit_setup)(struct ath_softc *sc); int (*xmit_teardown)(struct ath_softc *sc); void (*xmit_attach_comp_func)(struct ath_softc *sc); void (*xmit_dma_restart)(struct ath_softc *sc, struct ath_txq *txq); void (*xmit_handoff)(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf); void (*xmit_drain)(struct ath_softc *sc, ATH_RESET_TYPE reset_type); }; struct ath_softc { struct ieee80211com sc_ic; struct ath_stats sc_stats; /* device statistics */ struct ath_tx_aggr_stats sc_aggr_stats; struct ath_intr_stats sc_intr_stats; uint64_t sc_debug; uint64_t sc_ktrdebug; int sc_nvaps; /* # vaps */ int sc_nstavaps; /* # station vaps */ int sc_nmeshvaps; /* # mbss vaps */ u_int8_t sc_hwbssidmask[IEEE80211_ADDR_LEN]; u_int8_t sc_nbssid0; /* # vap's using base mac */ uint32_t sc_bssidmask; /* bssid mask */ struct ath_rx_methods sc_rx; struct ath_rx_edma sc_rxedma[HAL_NUM_RX_QUEUES]; /* HP/LP queues */ ath_bufhead sc_rx_rxlist[HAL_NUM_RX_QUEUES]; /* deferred RX completion */ struct ath_tx_methods sc_tx; struct ath_tx_edma_fifo sc_txedma[HAL_NUM_TX_QUEUES]; /* * This is (currently) protected by the TX queue lock; * it should migrate to a separate lock later * so as to minimise contention. */ ath_bufhead sc_txbuf_list; int sc_rx_statuslen; int sc_tx_desclen; int sc_tx_statuslen; int sc_tx_nmaps; /* Number of TX maps */ int sc_edma_bufsize; int sc_rx_stopped; /* XXX only for EDMA */ int sc_rx_resetted; /* XXX only for EDMA */ void (*sc_node_cleanup)(struct ieee80211_node *); void (*sc_node_free)(struct ieee80211_node *); device_t sc_dev; HAL_BUS_TAG sc_st; /* bus space tag */ HAL_BUS_HANDLE sc_sh; /* bus space handle */ bus_dma_tag_t sc_dmat; /* bus DMA tag */ struct mtx sc_mtx; /* master lock (recursive) */ struct mtx sc_pcu_mtx; /* PCU access mutex */ char sc_pcu_mtx_name[32]; struct mtx sc_rx_mtx; /* RX access mutex */ char sc_rx_mtx_name[32]; struct mtx sc_tx_mtx; /* TX handling/comp mutex */ char sc_tx_mtx_name[32]; struct mtx sc_tx_ic_mtx; /* TX queue mutex */ char sc_tx_ic_mtx_name[32]; struct taskqueue *sc_tq; /* private task queue */ struct ath_hal *sc_ah; /* Atheros HAL */ struct ath_ratectrl *sc_rc; /* tx rate control support */ struct ath_tx99 *sc_tx99; /* tx99 adjunct state */ void (*sc_setdefantenna)(struct ath_softc *, u_int); /* * First set of flags. */ uint32_t sc_invalid : 1,/* disable hardware accesses */ sc_mrretry : 1,/* multi-rate retry support */ sc_mrrprot : 1,/* MRR + protection support */ sc_softled : 1,/* enable LED gpio status */ sc_hardled : 1,/* enable MAC LED status */ sc_splitmic : 1,/* split TKIP MIC keys */ sc_needmib : 1,/* enable MIB stats intr */ sc_diversity: 1,/* enable rx diversity */ sc_hasveol : 1,/* tx VEOL support */ sc_ledstate : 1,/* LED on/off state */ sc_blinking : 1,/* LED blink operation active */ sc_mcastkey : 1,/* mcast key cache search */ sc_scanning : 1,/* scanning active */ sc_syncbeacon:1,/* sync/resync beacon timers */ sc_hasclrkey: 1,/* CLR key supported */ sc_xchanmode: 1,/* extended channel mode */ sc_outdoor : 1,/* outdoor operation */ sc_dturbo : 1,/* dynamic turbo in use */ sc_hasbmask : 1,/* bssid mask support */ sc_hasbmatch: 1,/* bssid match disable support*/ sc_hastsfadd: 1,/* tsf adjust support */ sc_beacons : 1,/* beacons running */ sc_swbmiss : 1,/* sta mode using sw bmiss */ sc_stagbeacons:1,/* use staggered beacons */ sc_wmetkipmic:1,/* can do WME+TKIP MIC */ sc_resume_up: 1,/* on resume, start all vaps */ sc_tdma : 1,/* TDMA in use */ sc_setcca : 1,/* set/clr CCA with TDMA */ sc_resetcal : 1,/* reset cal state next trip */ sc_rxslink : 1,/* do self-linked final descriptor */ sc_rxtsf32 : 1,/* RX dec TSF is 32 bits */ sc_isedma : 1,/* supports EDMA */ sc_do_mybeacon : 1; /* supports mybeacon */ /* * Second set of flags. */ u_int32_t sc_running : 1, /* initialized */ sc_use_ent : 1, sc_rx_stbc : 1, sc_tx_stbc : 1, sc_has_ldpc : 1, sc_hasenforcetxop : 1, /* support enforce TxOP */ sc_hasdivcomb : 1, /* RX diversity combining */ sc_rx_lnamixer : 1, /* RX using LNA mixing */ sc_btcoex_mci : 1; /* MCI bluetooth coex */ int sc_cabq_enable; /* Enable cabq transmission */ /* * Enterprise mode configuration for AR9380 and later chipsets. */ uint32_t sc_ent_cfg; uint32_t sc_eerd; /* regdomain from EEPROM */ uint32_t sc_eecc; /* country code from EEPROM */ /* rate tables */ const HAL_RATE_TABLE *sc_rates[IEEE80211_MODE_MAX]; const HAL_RATE_TABLE *sc_currates; /* current rate table */ enum ieee80211_phymode sc_curmode; /* current phy mode */ HAL_OPMODE sc_opmode; /* current operating mode */ u_int16_t sc_curtxpow; /* current tx power limit */ u_int16_t sc_curaid; /* current association id */ struct ieee80211_channel *sc_curchan; /* current installed channel */ u_int8_t sc_curbssid[IEEE80211_ADDR_LEN]; u_int8_t sc_rixmap[256]; /* IEEE to h/w rate table ix */ struct { u_int8_t ieeerate; /* IEEE rate */ u_int8_t rxflags; /* radiotap rx flags */ u_int8_t txflags; /* radiotap tx flags */ u_int16_t ledon; /* softled on time */ u_int16_t ledoff; /* softled off time */ } sc_hwmap[32]; /* h/w rate ix mappings */ u_int8_t sc_protrix; /* protection rate index */ u_int8_t sc_lastdatarix; /* last data frame rate index */ u_int sc_mcastrate; /* ieee rate for mcastrateix */ u_int sc_fftxqmin; /* min frames before staging */ u_int sc_fftxqmax; /* max frames before drop */ u_int sc_txantenna; /* tx antenna (fixed or auto) */ HAL_INT sc_imask; /* interrupt mask copy */ /* * These are modified in the interrupt handler as well as * the task queues and other contexts. Thus these must be * protected by a mutex, or they could clash. * * For now, access to these is behind the ATH_LOCK, * just to save time. */ uint32_t sc_txq_active; /* bitmap of active TXQs */ uint32_t sc_kickpcu; /* whether to kick the PCU */ uint32_t sc_rxproc_cnt; /* In RX processing */ uint32_t sc_txproc_cnt; /* In TX processing */ uint32_t sc_txstart_cnt; /* In TX output (raw/start) */ uint32_t sc_inreset_cnt; /* In active reset/chanchange */ uint32_t sc_txrx_cnt; /* refcount on stop/start'ing TX */ uint32_t sc_intr_cnt; /* refcount on interrupt handling */ u_int sc_keymax; /* size of key cache */ u_int8_t sc_keymap[ATH_KEYBYTES];/* key use bit map */ /* * Software based LED blinking */ u_int sc_ledpin; /* GPIO pin for driving LED */ u_int sc_ledon; /* pin setting for LED on */ u_int sc_ledidle; /* idle polling interval */ int sc_ledevent; /* time of last LED event */ u_int8_t sc_txrix; /* current tx rate for LED */ u_int16_t sc_ledoff; /* off time for current blink */ struct callout sc_ledtimer; /* led off timer */ /* * Hardware based LED blinking */ int sc_led_pwr_pin; /* MAC power LED GPIO pin */ int sc_led_net_pin; /* MAC network LED GPIO pin */ u_int sc_rfsilentpin; /* GPIO pin for rfkill int */ u_int sc_rfsilentpol; /* pin setting for rfkill on */ struct ath_descdma sc_rxdma; /* RX descriptors */ ath_bufhead sc_rxbuf; /* receive buffer */ u_int32_t *sc_rxlink; /* link ptr in last RX desc */ struct task sc_rxtask; /* rx int processing */ u_int8_t sc_defant; /* current default antenna */ u_int8_t sc_rxotherant; /* rx's on non-default antenna*/ u_int64_t sc_lastrx; /* tsf at last rx'd frame */ struct ath_rx_status *sc_lastrs; /* h/w status of last rx */ struct ath_rx_radiotap_header sc_rx_th; int sc_rx_th_len; u_int sc_monpass; /* frames to pass in mon.mode */ struct ath_descdma sc_txdma; /* TX descriptors */ uint16_t sc_txbuf_descid; ath_bufhead sc_txbuf; /* transmit buffer */ int sc_txbuf_cnt; /* how many buffers avail */ struct ath_descdma sc_txdma_mgmt; /* mgmt TX descriptors */ ath_bufhead sc_txbuf_mgmt; /* mgmt transmit buffer */ struct ath_descdma sc_txsdma; /* EDMA TX status desc's */ struct mtx sc_txbuflock; /* txbuf lock */ char sc_txname[12]; /* e.g. "ath0_buf" */ u_int sc_txqsetup; /* h/w queues setup */ u_int sc_txintrperiod;/* tx interrupt batching */ struct ath_txq sc_txq[HAL_NUM_TX_QUEUES]; struct ath_txq *sc_ac2q[5]; /* WME AC -> h/w q map */ struct task sc_txtask; /* tx int processing */ struct task sc_txqtask; /* tx proc processing */ struct ath_descdma sc_txcompdma; /* TX EDMA completion */ struct mtx sc_txcomplock; /* TX EDMA completion lock */ char sc_txcompname[12]; /* eg ath0_txcomp */ int sc_wd_timer; /* count down for wd timer */ struct callout sc_wd_ch; /* tx watchdog timer */ struct ath_tx_radiotap_header sc_tx_th; int sc_tx_th_len; struct ath_descdma sc_bdma; /* beacon descriptors */ ath_bufhead sc_bbuf; /* beacon buffers */ u_int sc_bhalq; /* HAL q for outgoing beacons */ u_int sc_bmisscount; /* missed beacon transmits */ u_int32_t sc_ant_tx[8]; /* recent tx frames/antenna */ struct ath_txq *sc_cabq; /* tx q for cab frames */ struct task sc_bmisstask; /* bmiss int processing */ struct task sc_bstucktask; /* stuck beacon processing */ struct task sc_resettask; /* interface reset task */ struct task sc_fataltask; /* fatal task */ enum { OK, /* no change needed */ UPDATE, /* update pending */ COMMIT /* beacon sent, commit change */ } sc_updateslot; /* slot time update fsm */ int sc_slotupdate; /* slot to advance fsm */ struct ieee80211vap *sc_bslot[ATH_BCBUF]; int sc_nbcnvaps; /* # vaps with beacons */ struct callout sc_cal_ch; /* callout handle for cals */ int sc_lastlongcal; /* last long cal completed */ int sc_lastcalreset;/* last cal reset done */ int sc_lastani; /* last ANI poll */ int sc_lastshortcal; /* last short calibration */ HAL_BOOL sc_doresetcal; /* Yes, we're doing a reset cal atm */ HAL_NODE_STATS sc_halstats; /* station-mode rssi stats */ u_int sc_tdmadbaprep; /* TDMA DBA prep time */ u_int sc_tdmaswbaprep;/* TDMA SWBA prep time */ u_int sc_tdmaswba; /* TDMA SWBA counter */ u_int32_t sc_tdmabintval; /* TDMA beacon interval (TU) */ u_int32_t sc_tdmaguard; /* TDMA guard time (usec) */ u_int sc_tdmaslotlen; /* TDMA slot length (usec) */ u_int32_t sc_avgtsfdeltap;/* TDMA slot adjust (+) */ u_int32_t sc_avgtsfdeltam;/* TDMA slot adjust (-) */ uint16_t *sc_eepromdata; /* Local eeprom data, if AR9100 */ uint32_t sc_txchainmask; /* hardware TX chainmask */ uint32_t sc_rxchainmask; /* hardware RX chainmask */ uint32_t sc_cur_txchainmask; /* currently configured TX chainmask */ uint32_t sc_cur_rxchainmask; /* currently configured RX chainmask */ uint32_t sc_rts_aggr_limit; /* TX limit on RTS aggregates */ int sc_aggr_limit; /* TX limit on all aggregates */ int sc_delim_min_pad; /* Minimum delimiter count */ /* Queue limits */ /* * To avoid queue starvation in congested conditions, * these parameters tune the maximum number of frames * queued to the data/mcastq before they're dropped. * * This is to prevent: * + a single destination overwhelming everything, including * management/multicast frames; * + multicast frames overwhelming everything (when the * air is sufficiently busy that cabq can't drain.) * + A node in powersave shouldn't be allowed to exhaust * all available mbufs; * * These implement: * + data_minfree is the maximum number of free buffers * overall to successfully allow a data frame. * * + mcastq_maxdepth is the maximum depth allowed of the cabq. */ int sc_txq_node_maxdepth; int sc_txq_data_minfree; int sc_txq_mcastq_maxdepth; int sc_txq_node_psq_maxdepth; /* * Software queue twiddles * * hwq_limit_nonaggr: * when to begin limiting non-aggregate frames to the * hardware queue, regardless of the TID. * hwq_limit_aggr: * when to begin limiting A-MPDU frames to the * hardware queue, regardless of the TID. * tid_hwq_lo: how low the per-TID hwq count has to be before the * TID will be scheduled again * tid_hwq_hi: how many frames to queue to the HWQ before the TID * stops being scheduled. */ int sc_hwq_limit_nonaggr; int sc_hwq_limit_aggr; int sc_tid_hwq_lo; int sc_tid_hwq_hi; /* DFS related state */ void *sc_dfs; /* Used by an optional DFS module */ int sc_dodfs; /* Whether to enable DFS rx filter bits */ struct task sc_dfstask; /* DFS processing task */ /* Spectral related state */ void *sc_spectral; int sc_dospectral; /* LNA diversity related state */ void *sc_lna_div; int sc_dolnadiv; /* ALQ */ #ifdef ATH_DEBUG_ALQ struct if_ath_alq sc_alq; #endif /* TX AMPDU handling */ int (*sc_addba_request)(struct ieee80211_node *, struct ieee80211_tx_ampdu *, int, int, int); int (*sc_addba_response)(struct ieee80211_node *, struct ieee80211_tx_ampdu *, int, int, int); void (*sc_addba_stop)(struct ieee80211_node *, struct ieee80211_tx_ampdu *); void (*sc_addba_response_timeout) (struct ieee80211_node *, struct ieee80211_tx_ampdu *); void (*sc_bar_response)(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, int status); /* * Powersave state tracking. * * target/cur powerstate is the chip power state. * target selfgen state is the self-generated frames * state. The chip can be awake but transmitted frames * can have the PWRMGT bit set to 1 so the destination * thinks the node is asleep. */ HAL_POWER_MODE sc_target_powerstate; HAL_POWER_MODE sc_target_selfgen_state; HAL_POWER_MODE sc_cur_powerstate; int sc_powersave_refcnt; /* ATH_PCI_* flags */ uint32_t sc_pci_devinfo; /* BT coex */ struct { struct ath_descdma buf; /* gpm/sched buffer, saved pointers */ char *sched_buf; bus_addr_t sched_paddr; char *gpm_buf; bus_addr_t gpm_paddr; uint32_t wlan_channels[4]; } sc_btcoex; }; #define ATH_LOCK_INIT(_sc) \ mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \ NULL, MTX_DEF | MTX_RECURSE) #define ATH_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx) #define ATH_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) #define ATH_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) #define ATH_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED) #define ATH_UNLOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_NOTOWNED) /* * The TX lock is non-reentrant and serialises the TX frame send * and completion operations. */ #define ATH_TX_LOCK_INIT(_sc) do {\ snprintf((_sc)->sc_tx_mtx_name, \ sizeof((_sc)->sc_tx_mtx_name), \ "%s TX lock", \ device_get_nameunit((_sc)->sc_dev)); \ mtx_init(&(_sc)->sc_tx_mtx, (_sc)->sc_tx_mtx_name, \ NULL, MTX_DEF); \ } while (0) #define ATH_TX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_tx_mtx) #define ATH_TX_LOCK(_sc) mtx_lock(&(_sc)->sc_tx_mtx) #define ATH_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_tx_mtx) #define ATH_TX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_tx_mtx, \ MA_OWNED) #define ATH_TX_UNLOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_tx_mtx, \ MA_NOTOWNED) #define ATH_TX_TRYLOCK(_sc) (mtx_owned(&(_sc)->sc_tx_mtx) != 0 && \ mtx_trylock(&(_sc)->sc_tx_mtx)) /* * The PCU lock is non-recursive and should be treated as a spinlock. * Although currently the interrupt code is run in netisr context and * doesn't require this, this may change in the future. * Please keep this in mind when protecting certain code paths * with the PCU lock. * * The PCU lock is used to serialise access to the PCU so things such * as TX, RX, state change (eg channel change), channel reset and updates * from interrupt context (eg kickpcu, txqactive bits) do not clash. * * Although the current single-thread taskqueue mechanism protects the * majority of these situations by simply serialising them, there are * a few others which occur at the same time. These include the TX path * (which only acquires ATH_LOCK when recycling buffers to the free list), * ath_set_channel, the channel scanning API and perhaps quite a bit more. */ #define ATH_PCU_LOCK_INIT(_sc) do {\ snprintf((_sc)->sc_pcu_mtx_name, \ sizeof((_sc)->sc_pcu_mtx_name), \ "%s PCU lock", \ device_get_nameunit((_sc)->sc_dev)); \ mtx_init(&(_sc)->sc_pcu_mtx, (_sc)->sc_pcu_mtx_name, \ NULL, MTX_DEF); \ } while (0) #define ATH_PCU_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_pcu_mtx) #define ATH_PCU_LOCK(_sc) mtx_lock(&(_sc)->sc_pcu_mtx) #define ATH_PCU_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_pcu_mtx) #define ATH_PCU_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_pcu_mtx, \ MA_OWNED) #define ATH_PCU_UNLOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_pcu_mtx, \ MA_NOTOWNED) /* * The RX lock is primarily a(nother) workaround to ensure that the * RX FIFO/list isn't modified by various execution paths. * Even though RX occurs in a single context (the ath taskqueue), the * RX path can be executed via various reset/channel change paths. */ #define ATH_RX_LOCK_INIT(_sc) do {\ snprintf((_sc)->sc_rx_mtx_name, \ sizeof((_sc)->sc_rx_mtx_name), \ "%s RX lock", \ device_get_nameunit((_sc)->sc_dev)); \ mtx_init(&(_sc)->sc_rx_mtx, (_sc)->sc_rx_mtx_name, \ NULL, MTX_DEF); \ } while (0) #define ATH_RX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_rx_mtx) #define ATH_RX_LOCK(_sc) mtx_lock(&(_sc)->sc_rx_mtx) #define ATH_RX_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_rx_mtx) #define ATH_RX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_rx_mtx, \ MA_OWNED) #define ATH_RX_UNLOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_rx_mtx, \ MA_NOTOWNED) #define ATH_TXQ_SETUP(sc, i) ((sc)->sc_txqsetup & (1<sc_txname, sizeof((_sc)->sc_txname), "%s_buf", \ device_get_nameunit((_sc)->sc_dev)); \ mtx_init(&(_sc)->sc_txbuflock, (_sc)->sc_txname, NULL, MTX_DEF); \ } while (0) #define ATH_TXBUF_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_txbuflock) #define ATH_TXBUF_LOCK(_sc) mtx_lock(&(_sc)->sc_txbuflock) #define ATH_TXBUF_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_txbuflock) #define ATH_TXBUF_LOCK_ASSERT(_sc) \ mtx_assert(&(_sc)->sc_txbuflock, MA_OWNED) #define ATH_TXBUF_UNLOCK_ASSERT(_sc) \ mtx_assert(&(_sc)->sc_txbuflock, MA_NOTOWNED) #define ATH_TXSTATUS_LOCK_INIT(_sc) do { \ snprintf((_sc)->sc_txcompname, sizeof((_sc)->sc_txcompname), \ "%s_buf", \ device_get_nameunit((_sc)->sc_dev)); \ mtx_init(&(_sc)->sc_txcomplock, (_sc)->sc_txcompname, NULL, \ MTX_DEF); \ } while (0) #define ATH_TXSTATUS_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_txcomplock) #define ATH_TXSTATUS_LOCK(_sc) mtx_lock(&(_sc)->sc_txcomplock) #define ATH_TXSTATUS_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_txcomplock) #define ATH_TXSTATUS_LOCK_ASSERT(_sc) \ mtx_assert(&(_sc)->sc_txcomplock, MA_OWNED) int ath_attach(u_int16_t, struct ath_softc *); int ath_detach(struct ath_softc *); void ath_resume(struct ath_softc *); void ath_suspend(struct ath_softc *); void ath_shutdown(struct ath_softc *); void ath_intr(void *); /* * HAL definitions to comply with local coding convention. */ #define ath_hal_detach(_ah) \ ((*(_ah)->ah_detach)((_ah))) #define ath_hal_reset(_ah, _opmode, _chan, _fullreset, _resettype, _pstatus) \ ((*(_ah)->ah_reset)((_ah), (_opmode), (_chan), (_fullreset), \ (_resettype), (_pstatus))) #define ath_hal_macversion(_ah) \ (((_ah)->ah_macVersion << 4) | ((_ah)->ah_macRev)) #define ath_hal_getratetable(_ah, _mode) \ ((*(_ah)->ah_getRateTable)((_ah), (_mode))) #define ath_hal_getmac(_ah, _mac) \ ((*(_ah)->ah_getMacAddress)((_ah), (_mac))) #define ath_hal_setmac(_ah, _mac) \ ((*(_ah)->ah_setMacAddress)((_ah), (_mac))) #define ath_hal_getbssidmask(_ah, _mask) \ ((*(_ah)->ah_getBssIdMask)((_ah), (_mask))) #define ath_hal_setbssidmask(_ah, _mask) \ ((*(_ah)->ah_setBssIdMask)((_ah), (_mask))) #define ath_hal_intrset(_ah, _mask) \ ((*(_ah)->ah_setInterrupts)((_ah), (_mask))) #define ath_hal_intrget(_ah) \ ((*(_ah)->ah_getInterrupts)((_ah))) #define ath_hal_intrpend(_ah) \ ((*(_ah)->ah_isInterruptPending)((_ah))) #define ath_hal_getisr(_ah, _pmask) \ ((*(_ah)->ah_getPendingInterrupts)((_ah), (_pmask))) #define ath_hal_updatetxtriglevel(_ah, _inc) \ ((*(_ah)->ah_updateTxTrigLevel)((_ah), (_inc))) #define ath_hal_setpower(_ah, _mode) \ ((*(_ah)->ah_setPowerMode)((_ah), (_mode), AH_TRUE)) #define ath_hal_setselfgenpower(_ah, _mode) \ ((*(_ah)->ah_setPowerMode)((_ah), (_mode), AH_FALSE)) #define ath_hal_keycachesize(_ah) \ ((*(_ah)->ah_getKeyCacheSize)((_ah))) #define ath_hal_keyreset(_ah, _ix) \ ((*(_ah)->ah_resetKeyCacheEntry)((_ah), (_ix))) #define ath_hal_keyset(_ah, _ix, _pk, _mac) \ ((*(_ah)->ah_setKeyCacheEntry)((_ah), (_ix), (_pk), (_mac), AH_FALSE)) #define ath_hal_keyisvalid(_ah, _ix) \ (((*(_ah)->ah_isKeyCacheEntryValid)((_ah), (_ix)))) #define ath_hal_keysetmac(_ah, _ix, _mac) \ ((*(_ah)->ah_setKeyCacheEntryMac)((_ah), (_ix), (_mac))) #define ath_hal_getrxfilter(_ah) \ ((*(_ah)->ah_getRxFilter)((_ah))) #define ath_hal_setrxfilter(_ah, _filter) \ ((*(_ah)->ah_setRxFilter)((_ah), (_filter))) #define ath_hal_setmcastfilter(_ah, _mfilt0, _mfilt1) \ ((*(_ah)->ah_setMulticastFilter)((_ah), (_mfilt0), (_mfilt1))) #define ath_hal_waitforbeacon(_ah, _bf) \ ((*(_ah)->ah_waitForBeaconDone)((_ah), (_bf)->bf_daddr)) #define ath_hal_putrxbuf(_ah, _bufaddr, _rxq) \ ((*(_ah)->ah_setRxDP)((_ah), (_bufaddr), (_rxq))) /* NB: common across all chips */ #define AR_TSF_L32 0x804c /* MAC local clock lower 32 bits */ #define ath_hal_gettsf32(_ah) \ OS_REG_READ(_ah, AR_TSF_L32) #define ath_hal_gettsf64(_ah) \ ((*(_ah)->ah_getTsf64)((_ah))) #define ath_hal_settsf64(_ah, _val) \ ((*(_ah)->ah_setTsf64)((_ah), (_val))) #define ath_hal_resettsf(_ah) \ ((*(_ah)->ah_resetTsf)((_ah))) #define ath_hal_rxena(_ah) \ ((*(_ah)->ah_enableReceive)((_ah))) #define ath_hal_puttxbuf(_ah, _q, _bufaddr) \ ((*(_ah)->ah_setTxDP)((_ah), (_q), (_bufaddr))) #define ath_hal_gettxbuf(_ah, _q) \ ((*(_ah)->ah_getTxDP)((_ah), (_q))) #define ath_hal_numtxpending(_ah, _q) \ ((*(_ah)->ah_numTxPending)((_ah), (_q))) #define ath_hal_getrxbuf(_ah, _rxq) \ ((*(_ah)->ah_getRxDP)((_ah), (_rxq))) #define ath_hal_txstart(_ah, _q) \ ((*(_ah)->ah_startTxDma)((_ah), (_q))) #define ath_hal_setchannel(_ah, _chan) \ ((*(_ah)->ah_setChannel)((_ah), (_chan))) #define ath_hal_calibrate(_ah, _chan, _iqcal) \ ((*(_ah)->ah_perCalibration)((_ah), (_chan), (_iqcal))) #define ath_hal_calibrateN(_ah, _chan, _lcal, _isdone) \ ((*(_ah)->ah_perCalibrationN)((_ah), (_chan), 0x1, (_lcal), (_isdone))) #define ath_hal_calreset(_ah, _chan) \ ((*(_ah)->ah_resetCalValid)((_ah), (_chan))) #define ath_hal_setledstate(_ah, _state) \ ((*(_ah)->ah_setLedState)((_ah), (_state))) #define ath_hal_beaconinit(_ah, _nextb, _bperiod) \ ((*(_ah)->ah_beaconInit)((_ah), (_nextb), (_bperiod))) #define ath_hal_beaconreset(_ah) \ ((*(_ah)->ah_resetStationBeaconTimers)((_ah))) #define ath_hal_beaconsettimers(_ah, _bt) \ ((*(_ah)->ah_setBeaconTimers)((_ah), (_bt))) #define ath_hal_beacontimers(_ah, _bs) \ ((*(_ah)->ah_setStationBeaconTimers)((_ah), (_bs))) #define ath_hal_getnexttbtt(_ah) \ ((*(_ah)->ah_getNextTBTT)((_ah))) #define ath_hal_setassocid(_ah, _bss, _associd) \ ((*(_ah)->ah_writeAssocid)((_ah), (_bss), (_associd))) #define ath_hal_phydisable(_ah) \ ((*(_ah)->ah_phyDisable)((_ah))) #define ath_hal_setopmode(_ah) \ ((*(_ah)->ah_setPCUConfig)((_ah))) #define ath_hal_stoptxdma(_ah, _qnum) \ ((*(_ah)->ah_stopTxDma)((_ah), (_qnum))) #define ath_hal_stoppcurecv(_ah) \ ((*(_ah)->ah_stopPcuReceive)((_ah))) -#define ath_hal_startpcurecv(_ah) \ - ((*(_ah)->ah_startPcuReceive)((_ah))) +#define ath_hal_startpcurecv(_ah, _is_scanning) \ + ((*(_ah)->ah_startPcuReceive)((_ah), (_is_scanning))) #define ath_hal_stopdmarecv(_ah) \ ((*(_ah)->ah_stopDmaReceive)((_ah))) #define ath_hal_getdiagstate(_ah, _id, _indata, _insize, _outdata, _outsize) \ ((*(_ah)->ah_getDiagState)((_ah), (_id), \ (_indata), (_insize), (_outdata), (_outsize))) #define ath_hal_getfatalstate(_ah, _outdata, _outsize) \ ath_hal_getdiagstate(_ah, 29, NULL, 0, (_outdata), _outsize) #define ath_hal_setuptxqueue(_ah, _type, _irq) \ ((*(_ah)->ah_setupTxQueue)((_ah), (_type), (_irq))) #define ath_hal_resettxqueue(_ah, _q) \ ((*(_ah)->ah_resetTxQueue)((_ah), (_q))) #define ath_hal_releasetxqueue(_ah, _q) \ ((*(_ah)->ah_releaseTxQueue)((_ah), (_q))) #define ath_hal_gettxqueueprops(_ah, _q, _qi) \ ((*(_ah)->ah_getTxQueueProps)((_ah), (_q), (_qi))) #define ath_hal_settxqueueprops(_ah, _q, _qi) \ ((*(_ah)->ah_setTxQueueProps)((_ah), (_q), (_qi))) /* NB: common across all chips */ #define AR_Q_TXE 0x0840 /* MAC Transmit Queue enable */ #define ath_hal_txqenabled(_ah, _qnum) \ (OS_REG_READ(_ah, AR_Q_TXE) & (1<<(_qnum))) #define ath_hal_getrfgain(_ah) \ ((*(_ah)->ah_getRfGain)((_ah))) #define ath_hal_getdefantenna(_ah) \ ((*(_ah)->ah_getDefAntenna)((_ah))) #define ath_hal_setdefantenna(_ah, _ant) \ ((*(_ah)->ah_setDefAntenna)((_ah), (_ant))) #define ath_hal_rxmonitor(_ah, _arg, _chan) \ ((*(_ah)->ah_rxMonitor)((_ah), (_arg), (_chan))) #define ath_hal_ani_poll(_ah, _chan) \ ((*(_ah)->ah_aniPoll)((_ah), (_chan))) #define ath_hal_mibevent(_ah, _stats) \ ((*(_ah)->ah_procMibEvent)((_ah), (_stats))) #define ath_hal_setslottime(_ah, _us) \ ((*(_ah)->ah_setSlotTime)((_ah), (_us))) #define ath_hal_getslottime(_ah) \ ((*(_ah)->ah_getSlotTime)((_ah))) #define ath_hal_setacktimeout(_ah, _us) \ ((*(_ah)->ah_setAckTimeout)((_ah), (_us))) #define ath_hal_getacktimeout(_ah) \ ((*(_ah)->ah_getAckTimeout)((_ah))) #define ath_hal_setctstimeout(_ah, _us) \ ((*(_ah)->ah_setCTSTimeout)((_ah), (_us))) #define ath_hal_getctstimeout(_ah) \ ((*(_ah)->ah_getCTSTimeout)((_ah))) #define ath_hal_getcapability(_ah, _cap, _param, _result) \ ((*(_ah)->ah_getCapability)((_ah), (_cap), (_param), (_result))) #define ath_hal_setcapability(_ah, _cap, _param, _v, _status) \ ((*(_ah)->ah_setCapability)((_ah), (_cap), (_param), (_v), (_status))) #define ath_hal_ciphersupported(_ah, _cipher) \ (ath_hal_getcapability(_ah, HAL_CAP_CIPHER, _cipher, NULL) == HAL_OK) #define ath_hal_getregdomain(_ah, _prd) \ (ath_hal_getcapability(_ah, HAL_CAP_REG_DMN, 0, (_prd)) == HAL_OK) #define ath_hal_setregdomain(_ah, _rd) \ ath_hal_setcapability(_ah, HAL_CAP_REG_DMN, 0, _rd, NULL) #define ath_hal_getcountrycode(_ah, _pcc) \ (*(_pcc) = (_ah)->ah_countryCode) #define ath_hal_gettkipmic(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_TKIP_MIC, 1, NULL) == HAL_OK) #define ath_hal_settkipmic(_ah, _v) \ ath_hal_setcapability(_ah, HAL_CAP_TKIP_MIC, 1, _v, NULL) #define ath_hal_hastkipsplit(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_TKIP_SPLIT, 0, NULL) == HAL_OK) #define ath_hal_gettkipsplit(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_TKIP_SPLIT, 1, NULL) == HAL_OK) #define ath_hal_settkipsplit(_ah, _v) \ ath_hal_setcapability(_ah, HAL_CAP_TKIP_SPLIT, 1, _v, NULL) #define ath_hal_haswmetkipmic(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_WME_TKIPMIC, 0, NULL) == HAL_OK) #define ath_hal_hwphycounters(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_PHYCOUNTERS, 0, NULL) == HAL_OK) #define ath_hal_hasdiversity(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_DIVERSITY, 0, NULL) == HAL_OK) #define ath_hal_getdiversity(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_DIVERSITY, 1, NULL) == HAL_OK) #define ath_hal_setdiversity(_ah, _v) \ ath_hal_setcapability(_ah, HAL_CAP_DIVERSITY, 1, _v, NULL) #define ath_hal_getantennaswitch(_ah) \ ((*(_ah)->ah_getAntennaSwitch)((_ah))) #define ath_hal_setantennaswitch(_ah, _v) \ ((*(_ah)->ah_setAntennaSwitch)((_ah), (_v))) #define ath_hal_getdiag(_ah, _pv) \ (ath_hal_getcapability(_ah, HAL_CAP_DIAG, 0, _pv) == HAL_OK) #define ath_hal_setdiag(_ah, _v) \ ath_hal_setcapability(_ah, HAL_CAP_DIAG, 0, _v, NULL) #define ath_hal_getnumtxqueues(_ah, _pv) \ (ath_hal_getcapability(_ah, HAL_CAP_NUM_TXQUEUES, 0, _pv) == HAL_OK) #define ath_hal_hasveol(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_VEOL, 0, NULL) == HAL_OK) #define ath_hal_hastxpowlimit(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_TXPOW, 0, NULL) == HAL_OK) #define ath_hal_settxpowlimit(_ah, _pow) \ ((*(_ah)->ah_setTxPowerLimit)((_ah), (_pow))) #define ath_hal_gettxpowlimit(_ah, _ppow) \ (ath_hal_getcapability(_ah, HAL_CAP_TXPOW, 1, _ppow) == HAL_OK) #define ath_hal_getmaxtxpow(_ah, _ppow) \ (ath_hal_getcapability(_ah, HAL_CAP_TXPOW, 2, _ppow) == HAL_OK) #define ath_hal_gettpscale(_ah, _scale) \ (ath_hal_getcapability(_ah, HAL_CAP_TXPOW, 3, _scale) == HAL_OK) #define ath_hal_settpscale(_ah, _v) \ ath_hal_setcapability(_ah, HAL_CAP_TXPOW, 3, _v, NULL) #define ath_hal_hastpc(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_TPC, 0, NULL) == HAL_OK) #define ath_hal_gettpc(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_TPC, 1, NULL) == HAL_OK) #define ath_hal_settpc(_ah, _v) \ ath_hal_setcapability(_ah, HAL_CAP_TPC, 1, _v, NULL) #define ath_hal_hasbursting(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_BURST, 0, NULL) == HAL_OK) #define ath_hal_setmcastkeysearch(_ah, _v) \ ath_hal_setcapability(_ah, HAL_CAP_MCAST_KEYSRCH, 0, _v, NULL) #define ath_hal_hasmcastkeysearch(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_MCAST_KEYSRCH, 0, NULL) == HAL_OK) #define ath_hal_getmcastkeysearch(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_MCAST_KEYSRCH, 1, NULL) == HAL_OK) #define ath_hal_hasfastframes(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_FASTFRAME, 0, NULL) == HAL_OK) #define ath_hal_hasbssidmask(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_BSSIDMASK, 0, NULL) == HAL_OK) #define ath_hal_hasbssidmatch(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_BSSIDMATCH, 0, NULL) == HAL_OK) #define ath_hal_hastsfadjust(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_TSF_ADJUST, 0, NULL) == HAL_OK) #define ath_hal_gettsfadjust(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_TSF_ADJUST, 1, NULL) == HAL_OK) #define ath_hal_settsfadjust(_ah, _onoff) \ ath_hal_setcapability(_ah, HAL_CAP_TSF_ADJUST, 1, _onoff, NULL) #define ath_hal_hasrfsilent(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_RFSILENT, 0, NULL) == HAL_OK) #define ath_hal_getrfkill(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_RFSILENT, 1, NULL) == HAL_OK) #define ath_hal_setrfkill(_ah, _onoff) \ ath_hal_setcapability(_ah, HAL_CAP_RFSILENT, 1, _onoff, NULL) #define ath_hal_getrfsilent(_ah, _prfsilent) \ (ath_hal_getcapability(_ah, HAL_CAP_RFSILENT, 2, _prfsilent) == HAL_OK) #define ath_hal_setrfsilent(_ah, _rfsilent) \ ath_hal_setcapability(_ah, HAL_CAP_RFSILENT, 2, _rfsilent, NULL) #define ath_hal_gettpack(_ah, _ptpack) \ (ath_hal_getcapability(_ah, HAL_CAP_TPC_ACK, 0, _ptpack) == HAL_OK) #define ath_hal_settpack(_ah, _tpack) \ ath_hal_setcapability(_ah, HAL_CAP_TPC_ACK, 0, _tpack, NULL) #define ath_hal_gettpcts(_ah, _ptpcts) \ (ath_hal_getcapability(_ah, HAL_CAP_TPC_CTS, 0, _ptpcts) == HAL_OK) #define ath_hal_settpcts(_ah, _tpcts) \ ath_hal_setcapability(_ah, HAL_CAP_TPC_CTS, 0, _tpcts, NULL) #define ath_hal_hasintmit(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_INTMIT, \ HAL_CAP_INTMIT_PRESENT, NULL) == HAL_OK) #define ath_hal_getintmit(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_INTMIT, \ HAL_CAP_INTMIT_ENABLE, NULL) == HAL_OK) #define ath_hal_setintmit(_ah, _v) \ ath_hal_setcapability(_ah, HAL_CAP_INTMIT, \ HAL_CAP_INTMIT_ENABLE, _v, NULL) #define ath_hal_hasmybeacon(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_DO_MYBEACON, 1, NULL) == HAL_OK) #define ath_hal_hasenforcetxop(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_ENFORCE_TXOP, 0, NULL) == HAL_OK) #define ath_hal_getenforcetxop(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_ENFORCE_TXOP, 1, NULL) == HAL_OK) #define ath_hal_setenforcetxop(_ah, _v) \ ath_hal_setcapability(_ah, HAL_CAP_ENFORCE_TXOP, 1, _v, NULL) #define ath_hal_hasrxlnamixer(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_RX_LNA_MIXING, 0, NULL) == HAL_OK) #define ath_hal_hasdivantcomb(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_ANT_DIV_COMB, 0, NULL) == HAL_OK) #define ath_hal_hasldpc(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_LDPC, 0, NULL) == HAL_OK) #define ath_hal_hasldpcwar(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_LDPCWAR, 0, NULL) == HAL_OK) /* EDMA definitions */ #define ath_hal_hasedma(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_ENHANCED_DMA_SUPPORT, \ 0, NULL) == HAL_OK) #define ath_hal_getrxfifodepth(_ah, _qtype, _req) \ (ath_hal_getcapability(_ah, HAL_CAP_RXFIFODEPTH, _qtype, _req) \ == HAL_OK) #define ath_hal_getntxmaps(_ah, _req) \ (ath_hal_getcapability(_ah, HAL_CAP_NUM_TXMAPS, 0, _req) \ == HAL_OK) #define ath_hal_gettxdesclen(_ah, _req) \ (ath_hal_getcapability(_ah, HAL_CAP_TXDESCLEN, 0, _req) \ == HAL_OK) #define ath_hal_gettxstatuslen(_ah, _req) \ (ath_hal_getcapability(_ah, HAL_CAP_TXSTATUSLEN, 0, _req) \ == HAL_OK) #define ath_hal_getrxstatuslen(_ah, _req) \ (ath_hal_getcapability(_ah, HAL_CAP_RXSTATUSLEN, 0, _req) \ == HAL_OK) #define ath_hal_setrxbufsize(_ah, _req) \ (ath_hal_setcapability(_ah, HAL_CAP_RXBUFSIZE, 0, _req, NULL) \ == AH_TRUE) #define ath_hal_getchannoise(_ah, _c) \ ((*(_ah)->ah_getChanNoise)((_ah), (_c))) /* 802.11n HAL methods */ #define ath_hal_getrxchainmask(_ah, _prxchainmask) \ (ath_hal_getcapability(_ah, HAL_CAP_RX_CHAINMASK, 0, _prxchainmask)) #define ath_hal_gettxchainmask(_ah, _ptxchainmask) \ (ath_hal_getcapability(_ah, HAL_CAP_TX_CHAINMASK, 0, _ptxchainmask)) #define ath_hal_setrxchainmask(_ah, _rx) \ (ath_hal_setcapability(_ah, HAL_CAP_RX_CHAINMASK, 1, _rx, NULL)) #define ath_hal_settxchainmask(_ah, _tx) \ (ath_hal_setcapability(_ah, HAL_CAP_TX_CHAINMASK, 1, _tx, NULL)) #define ath_hal_split4ktrans(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_SPLIT_4KB_TRANS, \ 0, NULL) == HAL_OK) #define ath_hal_self_linked_final_rxdesc(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_RXDESC_SELFLINK, \ 0, NULL) == HAL_OK) #define ath_hal_gtxto_supported(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_GTXTO, 0, NULL) == HAL_OK) #define ath_hal_get_rx_tsf_prec(_ah, _pr) \ (ath_hal_getcapability((_ah), HAL_CAP_RXTSTAMP_PREC, 0, (_pr)) \ == HAL_OK) #define ath_hal_get_tx_tsf_prec(_ah, _pr) \ (ath_hal_getcapability((_ah), HAL_CAP_TXTSTAMP_PREC, 0, (_pr)) \ == HAL_OK) #define ath_hal_setuprxdesc(_ah, _ds, _size, _intreq) \ ((*(_ah)->ah_setupRxDesc)((_ah), (_ds), (_size), (_intreq))) #define ath_hal_rxprocdesc(_ah, _ds, _dspa, _dsnext, _rs) \ ((*(_ah)->ah_procRxDesc)((_ah), (_ds), (_dspa), (_dsnext), 0, (_rs))) #define ath_hal_setuptxdesc(_ah, _ds, _plen, _hlen, _atype, _txpow, \ _txr0, _txtr0, _keyix, _ant, _flags, \ _rtsrate, _rtsdura) \ ((*(_ah)->ah_setupTxDesc)((_ah), (_ds), (_plen), (_hlen), (_atype), \ (_txpow), (_txr0), (_txtr0), (_keyix), (_ant), \ (_flags), (_rtsrate), (_rtsdura), 0, 0, 0)) #define ath_hal_setupxtxdesc(_ah, _ds, \ _txr1, _txtr1, _txr2, _txtr2, _txr3, _txtr3) \ ((*(_ah)->ah_setupXTxDesc)((_ah), (_ds), \ (_txr1), (_txtr1), (_txr2), (_txtr2), (_txr3), (_txtr3))) #define ath_hal_filltxdesc(_ah, _ds, _b, _l, _did, _qid, _first, _last, _ds0) \ ((*(_ah)->ah_fillTxDesc)((_ah), (_ds), (_b), (_l), (_did), (_qid), \ (_first), (_last), (_ds0))) #define ath_hal_txprocdesc(_ah, _ds, _ts) \ ((*(_ah)->ah_procTxDesc)((_ah), (_ds), (_ts))) #define ath_hal_gettxintrtxqs(_ah, _txqs) \ ((*(_ah)->ah_getTxIntrQueue)((_ah), (_txqs))) #define ath_hal_gettxcompletionrates(_ah, _ds, _rates, _tries) \ ((*(_ah)->ah_getTxCompletionRates)((_ah), (_ds), (_rates), (_tries))) #define ath_hal_settxdesclink(_ah, _ds, _link) \ ((*(_ah)->ah_setTxDescLink)((_ah), (_ds), (_link))) #define ath_hal_gettxdesclink(_ah, _ds, _link) \ ((*(_ah)->ah_getTxDescLink)((_ah), (_ds), (_link))) #define ath_hal_gettxdesclinkptr(_ah, _ds, _linkptr) \ ((*(_ah)->ah_getTxDescLinkPtr)((_ah), (_ds), (_linkptr))) #define ath_hal_setuptxstatusring(_ah, _tsstart, _tspstart, _size) \ ((*(_ah)->ah_setupTxStatusRing)((_ah), (_tsstart), (_tspstart), \ (_size))) #define ath_hal_gettxrawtxdesc(_ah, _txstatus) \ ((*(_ah)->ah_getTxRawTxDesc)((_ah), (_txstatus))) #define ath_hal_setupfirsttxdesc(_ah, _ds, _aggrlen, _flags, _txpower, \ _txr0, _txtr0, _antm, _rcr, _rcd) \ ((*(_ah)->ah_setupFirstTxDesc)((_ah), (_ds), (_aggrlen), (_flags), \ (_txpower), (_txr0), (_txtr0), (_antm), (_rcr), (_rcd))) #define ath_hal_chaintxdesc(_ah, _ds, _bl, _sl, _pktlen, _hdrlen, _type, \ _keyix, _cipher, _delims, _first, _last, _lastaggr) \ ((*(_ah)->ah_chainTxDesc)((_ah), (_ds), (_bl), (_sl), \ (_pktlen), (_hdrlen), (_type), (_keyix), (_cipher), (_delims), \ (_first), (_last), (_lastaggr))) #define ath_hal_setuplasttxdesc(_ah, _ds, _ds0) \ ((*(_ah)->ah_setupLastTxDesc)((_ah), (_ds), (_ds0))) #define ath_hal_set11nratescenario(_ah, _ds, _dur, _rt, _series, _ns, _flags) \ ((*(_ah)->ah_set11nRateScenario)((_ah), (_ds), (_dur), (_rt), \ (_series), (_ns), (_flags))) #define ath_hal_set11n_aggr_first(_ah, _ds, _len, _num) \ ((*(_ah)->ah_set11nAggrFirst)((_ah), (_ds), (_len), (_num))) #define ath_hal_set11n_aggr_middle(_ah, _ds, _num) \ ((*(_ah)->ah_set11nAggrMiddle)((_ah), (_ds), (_num))) #define ath_hal_set11n_aggr_last(_ah, _ds) \ ((*(_ah)->ah_set11nAggrLast)((_ah), (_ds))) #define ath_hal_set11nburstduration(_ah, _ds, _dur) \ ((*(_ah)->ah_set11nBurstDuration)((_ah), (_ds), (_dur))) #define ath_hal_clr11n_aggr(_ah, _ds) \ ((*(_ah)->ah_clr11nAggr)((_ah), (_ds))) #define ath_hal_set11n_virtmorefrag(_ah, _ds, _v) \ ((*(_ah)->ah_set11nVirtMoreFrag)((_ah), (_ds), (_v))) #define ath_hal_gpioCfgOutput(_ah, _gpio, _type) \ ((*(_ah)->ah_gpioCfgOutput)((_ah), (_gpio), (_type))) #define ath_hal_gpioset(_ah, _gpio, _b) \ ((*(_ah)->ah_gpioSet)((_ah), (_gpio), (_b))) #define ath_hal_gpioget(_ah, _gpio) \ ((*(_ah)->ah_gpioGet)((_ah), (_gpio))) #define ath_hal_gpiosetintr(_ah, _gpio, _b) \ ((*(_ah)->ah_gpioSetIntr)((_ah), (_gpio), (_b))) /* * PCIe suspend/resume/poweron/poweroff related macros */ #define ath_hal_enablepcie(_ah, _restore, _poweroff) \ ((*(_ah)->ah_configPCIE)((_ah), (_restore), (_poweroff))) #define ath_hal_disablepcie(_ah) \ ((*(_ah)->ah_disablePCIE)((_ah))) /* * This is badly-named; you need to set the correct parameters * to begin to receive useful radar events; and even then * it doesn't "enable" DFS. See the ath_dfs/null/ module for * more information. */ #define ath_hal_enabledfs(_ah, _param) \ ((*(_ah)->ah_enableDfs)((_ah), (_param))) #define ath_hal_getdfsthresh(_ah, _param) \ ((*(_ah)->ah_getDfsThresh)((_ah), (_param))) #define ath_hal_getdfsdefaultthresh(_ah, _param) \ ((*(_ah)->ah_getDfsDefaultThresh)((_ah), (_param))) #define ath_hal_procradarevent(_ah, _rxs, _fulltsf, _buf, _event) \ ((*(_ah)->ah_procRadarEvent)((_ah), (_rxs), (_fulltsf), \ (_buf), (_event))) #define ath_hal_is_fast_clock_enabled(_ah) \ ((*(_ah)->ah_isFastClockEnabled)((_ah))) #define ath_hal_radar_wait(_ah, _chan) \ ((*(_ah)->ah_radarWait)((_ah), (_chan))) #define ath_hal_get_mib_cycle_counts(_ah, _sample) \ ((*(_ah)->ah_getMibCycleCounts)((_ah), (_sample))) #define ath_hal_get_chan_ext_busy(_ah) \ ((*(_ah)->ah_get11nExtBusy)((_ah))) #define ath_hal_setchainmasks(_ah, _txchainmask, _rxchainmask) \ ((*(_ah)->ah_setChainMasks)((_ah), (_txchainmask), (_rxchainmask))) #define ath_hal_set_quiet(_ah, _p, _d, _o, _f) \ ((*(_ah)->ah_setQuiet)((_ah), (_p), (_d), (_o), (_f))) #define ath_hal_spectral_supported(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_SPECTRAL_SCAN, 0, NULL) == HAL_OK) #define ath_hal_spectral_get_config(_ah, _p) \ ((*(_ah)->ah_spectralGetConfig)((_ah), (_p))) #define ath_hal_spectral_configure(_ah, _p) \ ((*(_ah)->ah_spectralConfigure)((_ah), (_p))) #define ath_hal_spectral_start(_ah) \ ((*(_ah)->ah_spectralStart)((_ah))) #define ath_hal_spectral_stop(_ah) \ ((*(_ah)->ah_spectralStop)((_ah))) #define ath_hal_btcoex_supported(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_BT_COEX, 0, NULL) == HAL_OK) #define ath_hal_btcoex_set_info(_ah, _info) \ ((*(_ah)->ah_btCoexSetInfo)((_ah), (_info))) #define ath_hal_btcoex_set_config(_ah, _cfg) \ ((*(_ah)->ah_btCoexSetConfig)((_ah), (_cfg))) #define ath_hal_btcoex_set_qcu_thresh(_ah, _qcuid) \ ((*(_ah)->ah_btCoexSetQcuThresh)((_ah), (_qcuid))) #define ath_hal_btcoex_set_weights(_ah, _weight) \ ((*(_ah)->ah_btCoexSetWeights)((_ah), (_weight))) #define ath_hal_btcoex_set_bmiss_thresh(_ah, _thr) \ ((*(_ah)->ah_btCoexSetBmissThresh)((_ah), (_thr))) #define ath_hal_btcoex_set_parameter(_ah, _attrib, _val) \ ((*(_ah)->ah_btCoexSetParameter)((_ah), (_attrib), (_val))) #define ath_hal_btcoex_enable(_ah) \ ((*(_ah)->ah_btCoexEnable)((_ah))) #define ath_hal_btcoex_disable(_ah) \ ((*(_ah)->ah_btCoexDisable)((_ah))) #define ath_hal_btcoex_mci_setup(_ah, _gp, _gb, _gl, _sp) \ ((*(_ah)->ah_btMciSetup)((_ah), (_gp), (_gb), (_gl), (_sp))) #define ath_hal_btcoex_mci_send_message(_ah, _h, _f, _p, _l, _wd, _cbt) \ ((*(_ah)->ah_btMciSendMessage)((_ah), (_h), (_f), (_p), (_l), (_wd), (_cbt))) #define ath_hal_btcoex_mci_get_interrupt(_ah, _mi, _mm) \ ((*(_ah)->ah_btMciGetInterrupt)((_ah), (_mi), (_mm))) #define ath_hal_btcoex_mci_state(_ah, _st, _pd) \ ((*(_ah)->ah_btMciState)((_ah), (_st), (_pd))) #define ath_hal_btcoex_mci_detach(_ah) \ ((*(_ah)->ah_btMciDetach)((_ah))) #define ath_hal_div_comb_conf_get(_ah, _conf) \ ((*(_ah)->ah_divLnaConfGet)((_ah), (_conf))) #define ath_hal_div_comb_conf_set(_ah, _conf) \ ((*(_ah)->ah_divLnaConfSet)((_ah), (_conf))) #endif /* _DEV_ATH_ATHVAR_H */