Date: Mon, 20 Feb 2012 03:07:07 +0000 (UTC) From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r231927 - in head/sys: conf dev/ath/ath_hal/ar5416 modules/ath Message-ID: <201202200307.q1K377O9028541@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: adrian Date: Mon Feb 20 03:07:07 2012 New Revision: 231927 URL: http://svn.freebsd.org/changeset/base/231927 Log: Break out the radar code into a separate source file. This mirrors the internal HAL organisation and reduces the differences between the HAL codebases slightly. Obtained from: Atheros Added: head/sys/dev/ath/ath_hal/ar5416/ar5416_radar.c (contents, props changed) Modified: head/sys/conf/files head/sys/dev/ath/ath_hal/ar5416/ar5416.h head/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c head/sys/modules/ath/Makefile Modified: head/sys/conf/files ============================================================================== --- head/sys/conf/files Mon Feb 20 01:21:54 2012 (r231926) +++ head/sys/conf/files Mon Feb 20 03:07:07 2012 (r231927) @@ -773,6 +773,10 @@ dev/ath/ath_hal/ar5416/ar5416_power.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" +dev/ath/ath_hal/ar5416/ar5416_radar.c \ + optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ + ath_ar9287 \ + compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_recv.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ Modified: head/sys/dev/ath/ath_hal/ar5416/ar5416.h ============================================================================== --- head/sys/dev/ath/ath_hal/ar5416/ar5416.h Mon Feb 20 01:21:54 2012 (r231926) +++ head/sys/dev/ath/ath_hal/ar5416/ar5416.h Mon Feb 20 03:07:07 2012 (r231927) @@ -215,6 +215,7 @@ extern HAL_BOOL ar5416GetDiagState(struc 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 void ar5416GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe); extern HAL_BOOL ar5416ProcessRadarEvent(struct ath_hal *ah, Modified: head/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c ============================================================================== --- head/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c Mon Feb 20 01:21:54 2012 (r231926) +++ head/sys/dev/ath/ath_hal/ar5416/ar5416_misc.c Mon Feb 20 03:07:07 2012 (r231927) @@ -720,361 +720,3 @@ ar5416DetectBBHang(struct ath_hal *ah) #undef N } #undef NUM_STATUS_READS - -/* - * Get the radar parameter values and return them in the pe - * structure - */ -void -ar5416GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe) -{ - uint32_t val, temp; - - val = OS_REG_READ(ah, AR_PHY_RADAR_0); - - temp = MS(val,AR_PHY_RADAR_0_FIRPWR); - temp |= 0xFFFFFF80; - pe->pe_firpwr = temp; - pe->pe_rrssi = MS(val, AR_PHY_RADAR_0_RRSSI); - pe->pe_height = MS(val, AR_PHY_RADAR_0_HEIGHT); - pe->pe_prssi = MS(val, AR_PHY_RADAR_0_PRSSI); - pe->pe_inband = MS(val, AR_PHY_RADAR_0_INBAND); - - /* RADAR_1 values */ - val = OS_REG_READ(ah, AR_PHY_RADAR_1); - pe->pe_relpwr = MS(val, AR_PHY_RADAR_1_RELPWR_THRESH); - pe->pe_relstep = MS(val, AR_PHY_RADAR_1_RELSTEP_THRESH); - pe->pe_maxlen = MS(val, AR_PHY_RADAR_1_MAXLEN); - - pe->pe_extchannel = !! (OS_REG_READ(ah, AR_PHY_RADAR_EXT) & - AR_PHY_RADAR_EXT_ENA); - - pe->pe_usefir128 = !! (OS_REG_READ(ah, AR_PHY_RADAR_1) & - AR_PHY_RADAR_1_USE_FIR128); - pe->pe_blockradar = !! (OS_REG_READ(ah, AR_PHY_RADAR_1) & - AR_PHY_RADAR_1_BLOCK_CHECK); - pe->pe_enmaxrssi = !! (OS_REG_READ(ah, AR_PHY_RADAR_1) & - AR_PHY_RADAR_1_MAX_RRSSI); - pe->pe_enabled = !! - (OS_REG_READ(ah, AR_PHY_RADAR_0) & AR_PHY_RADAR_0_ENA); - pe->pe_enrelpwr = !! (OS_REG_READ(ah, AR_PHY_RADAR_1) & - AR_PHY_RADAR_1_RELPWR_ENA); - pe->pe_en_relstep_check = !! (OS_REG_READ(ah, AR_PHY_RADAR_1) & - AR_PHY_RADAR_1_RELSTEP_CHECK); -} - -/* - * Enable radar detection and set the radar parameters per the - * values in pe - */ -void -ar5416EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe) -{ - uint32_t val; - - val = OS_REG_READ(ah, AR_PHY_RADAR_0); - - if (pe->pe_firpwr != HAL_PHYERR_PARAM_NOVAL) { - val &= ~AR_PHY_RADAR_0_FIRPWR; - val |= SM(pe->pe_firpwr, AR_PHY_RADAR_0_FIRPWR); - } - if (pe->pe_rrssi != HAL_PHYERR_PARAM_NOVAL) { - val &= ~AR_PHY_RADAR_0_RRSSI; - val |= SM(pe->pe_rrssi, AR_PHY_RADAR_0_RRSSI); - } - if (pe->pe_height != HAL_PHYERR_PARAM_NOVAL) { - val &= ~AR_PHY_RADAR_0_HEIGHT; - val |= SM(pe->pe_height, AR_PHY_RADAR_0_HEIGHT); - } - if (pe->pe_prssi != HAL_PHYERR_PARAM_NOVAL) { - val &= ~AR_PHY_RADAR_0_PRSSI; - val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI); - } - if (pe->pe_inband != HAL_PHYERR_PARAM_NOVAL) { - val &= ~AR_PHY_RADAR_0_INBAND; - val |= SM(pe->pe_inband, AR_PHY_RADAR_0_INBAND); - } - - /*Enable FFT data*/ - val |= AR_PHY_RADAR_0_FFT_ENA; - OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); - - /* Implicitly enable */ - if (pe->pe_enabled == 1) - OS_REG_SET_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_ENA); - else if (pe->pe_enabled == 0) - OS_REG_CLR_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_ENA); - - if (pe->pe_usefir128 == 1) - OS_REG_SET_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_USE_FIR128); - else if (pe->pe_usefir128 == 0) - OS_REG_CLR_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_USE_FIR128); - - if (pe->pe_enmaxrssi == 1) - OS_REG_SET_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_MAX_RRSSI); - else if (pe->pe_enmaxrssi == 0) - OS_REG_CLR_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_MAX_RRSSI); - - if (pe->pe_blockradar == 1) - OS_REG_SET_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_BLOCK_CHECK); - else if (pe->pe_blockradar == 0) - OS_REG_CLR_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_BLOCK_CHECK); - - if (pe->pe_relstep != HAL_PHYERR_PARAM_NOVAL) { - val = OS_REG_READ(ah, AR_PHY_RADAR_1); - val &= ~AR_PHY_RADAR_1_RELSTEP_THRESH; - val |= SM(pe->pe_relstep, AR_PHY_RADAR_1_RELSTEP_THRESH); - OS_REG_WRITE(ah, AR_PHY_RADAR_1, val); - } - if (pe->pe_relpwr != HAL_PHYERR_PARAM_NOVAL) { - val = OS_REG_READ(ah, AR_PHY_RADAR_1); - val &= ~AR_PHY_RADAR_1_RELPWR_THRESH; - val |= SM(pe->pe_relpwr, AR_PHY_RADAR_1_RELPWR_THRESH); - OS_REG_WRITE(ah, AR_PHY_RADAR_1, val); - } - - if (pe->pe_en_relstep_check == 1) - OS_REG_SET_BIT(ah, AR_PHY_RADAR_1, - AR_PHY_RADAR_1_RELSTEP_CHECK); - else if (pe->pe_en_relstep_check == 0) - OS_REG_CLR_BIT(ah, AR_PHY_RADAR_1, - AR_PHY_RADAR_1_RELSTEP_CHECK); - - if (pe->pe_enrelpwr == 1) - OS_REG_SET_BIT(ah, AR_PHY_RADAR_1, - AR_PHY_RADAR_1_RELPWR_ENA); - else if (pe->pe_enrelpwr == 0) - OS_REG_CLR_BIT(ah, AR_PHY_RADAR_1, - AR_PHY_RADAR_1_RELPWR_ENA); - - if (pe->pe_maxlen != HAL_PHYERR_PARAM_NOVAL) { - val = OS_REG_READ(ah, AR_PHY_RADAR_1); - val &= ~AR_PHY_RADAR_1_MAXLEN; - val |= SM(pe->pe_maxlen, AR_PHY_RADAR_1_MAXLEN); - OS_REG_WRITE(ah, AR_PHY_RADAR_1, val); - } - - /* - * Enable HT/40 if the upper layer asks; - * it should check the channel is HT/40 and HAL_CAP_EXT_CHAN_DFS - * is available. - */ - if (pe->pe_extchannel == 1) - OS_REG_SET_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA); - else if (pe->pe_extchannel == 0) - OS_REG_CLR_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA); -} - -/* - * Extract the radar event information from the given phy error. - * - * Returns AH_TRUE if the phy error was actually a phy error, - * AH_FALSE if the phy error wasn't a phy error. - */ - -/* Flags for pulse_bw_info */ -#define PRI_CH_RADAR_FOUND 0x01 -#define EXT_CH_RADAR_FOUND 0x02 -#define EXT_CH_RADAR_EARLY_FOUND 0x04 - -HAL_BOOL -ar5416ProcessRadarEvent(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; -} - -/* - * Return whether fast-clock is currently enabled for this - * channel. - */ -HAL_BOOL -ar5416IsFastClockEnabled(struct ath_hal *ah) -{ - struct ath_hal_private *ahp = AH_PRIVATE(ah); - - return IS_5GHZ_FAST_CLOCK_EN(ah, ahp->ah_curchan); -} Added: head/sys/dev/ath/ath_hal/ar5416/ar5416_radar.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/dev/ath/ath_hal/ar5416/ar5416_radar.c Mon Feb 20 03:07:07 2012 (r231927) @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2010-2011 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_devid.h" +#include "ah_desc.h" /* NB: for HAL_PHYERR* */ + +#include "ar5416/ar5416.h" +#include "ar5416/ar5416reg.h" +#include "ar5416/ar5416phy.h" + +#include "ah_eeprom_v14.h" /* for owl_get_ntxchains() */ + +/* + * Get the radar parameter values and return them in the pe + * structure + */ +void +ar5416GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe) +{ + uint32_t val, temp; + + val = OS_REG_READ(ah, AR_PHY_RADAR_0); + + temp = MS(val,AR_PHY_RADAR_0_FIRPWR); + temp |= 0xFFFFFF80; + pe->pe_firpwr = temp; + pe->pe_rrssi = MS(val, AR_PHY_RADAR_0_RRSSI); + pe->pe_height = MS(val, AR_PHY_RADAR_0_HEIGHT); + pe->pe_prssi = MS(val, AR_PHY_RADAR_0_PRSSI); + pe->pe_inband = MS(val, AR_PHY_RADAR_0_INBAND); + + /* RADAR_1 values */ + val = OS_REG_READ(ah, AR_PHY_RADAR_1); + pe->pe_relpwr = MS(val, AR_PHY_RADAR_1_RELPWR_THRESH); + pe->pe_relstep = MS(val, AR_PHY_RADAR_1_RELSTEP_THRESH); + pe->pe_maxlen = MS(val, AR_PHY_RADAR_1_MAXLEN); + + pe->pe_extchannel = !! (OS_REG_READ(ah, AR_PHY_RADAR_EXT) & + AR_PHY_RADAR_EXT_ENA); + + pe->pe_usefir128 = !! (OS_REG_READ(ah, AR_PHY_RADAR_1) & + AR_PHY_RADAR_1_USE_FIR128); + pe->pe_blockradar = !! (OS_REG_READ(ah, AR_PHY_RADAR_1) & + AR_PHY_RADAR_1_BLOCK_CHECK); + pe->pe_enmaxrssi = !! (OS_REG_READ(ah, AR_PHY_RADAR_1) & + AR_PHY_RADAR_1_MAX_RRSSI); + pe->pe_enabled = !! + (OS_REG_READ(ah, AR_PHY_RADAR_0) & AR_PHY_RADAR_0_ENA); + pe->pe_enrelpwr = !! (OS_REG_READ(ah, AR_PHY_RADAR_1) & + AR_PHY_RADAR_1_RELPWR_ENA); + pe->pe_en_relstep_check = !! (OS_REG_READ(ah, AR_PHY_RADAR_1) & + AR_PHY_RADAR_1_RELSTEP_CHECK); +} + +/* + * Enable radar detection and set the radar parameters per the + * values in pe + */ +void +ar5416EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe) +{ + uint32_t val; + + val = OS_REG_READ(ah, AR_PHY_RADAR_0); + + if (pe->pe_firpwr != HAL_PHYERR_PARAM_NOVAL) { + val &= ~AR_PHY_RADAR_0_FIRPWR; + val |= SM(pe->pe_firpwr, AR_PHY_RADAR_0_FIRPWR); + } + if (pe->pe_rrssi != HAL_PHYERR_PARAM_NOVAL) { + val &= ~AR_PHY_RADAR_0_RRSSI; + val |= SM(pe->pe_rrssi, AR_PHY_RADAR_0_RRSSI); + } + if (pe->pe_height != HAL_PHYERR_PARAM_NOVAL) { + val &= ~AR_PHY_RADAR_0_HEIGHT; + val |= SM(pe->pe_height, AR_PHY_RADAR_0_HEIGHT); + } + if (pe->pe_prssi != HAL_PHYERR_PARAM_NOVAL) { + val &= ~AR_PHY_RADAR_0_PRSSI; + val |= SM(pe->pe_prssi, AR_PHY_RADAR_0_PRSSI); + } + if (pe->pe_inband != HAL_PHYERR_PARAM_NOVAL) { + val &= ~AR_PHY_RADAR_0_INBAND; + val |= SM(pe->pe_inband, AR_PHY_RADAR_0_INBAND); + } + + /*Enable FFT data*/ + val |= AR_PHY_RADAR_0_FFT_ENA; + OS_REG_WRITE(ah, AR_PHY_RADAR_0, val); + + /* Implicitly enable */ + if (pe->pe_enabled == 1) + OS_REG_SET_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_ENA); + else if (pe->pe_enabled == 0) + OS_REG_CLR_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_ENA); + + if (pe->pe_usefir128 == 1) + OS_REG_SET_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_USE_FIR128); + else if (pe->pe_usefir128 == 0) + OS_REG_CLR_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_USE_FIR128); + + if (pe->pe_enmaxrssi == 1) + OS_REG_SET_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_MAX_RRSSI); + else if (pe->pe_enmaxrssi == 0) + OS_REG_CLR_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_MAX_RRSSI); + + if (pe->pe_blockradar == 1) + OS_REG_SET_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_BLOCK_CHECK); + else if (pe->pe_blockradar == 0) + OS_REG_CLR_BIT(ah, AR_PHY_RADAR_1, AR_PHY_RADAR_1_BLOCK_CHECK); + + if (pe->pe_relstep != HAL_PHYERR_PARAM_NOVAL) { + val = OS_REG_READ(ah, AR_PHY_RADAR_1); + val &= ~AR_PHY_RADAR_1_RELSTEP_THRESH; + val |= SM(pe->pe_relstep, AR_PHY_RADAR_1_RELSTEP_THRESH); + OS_REG_WRITE(ah, AR_PHY_RADAR_1, val); + } + if (pe->pe_relpwr != HAL_PHYERR_PARAM_NOVAL) { + val = OS_REG_READ(ah, AR_PHY_RADAR_1); + val &= ~AR_PHY_RADAR_1_RELPWR_THRESH; + val |= SM(pe->pe_relpwr, AR_PHY_RADAR_1_RELPWR_THRESH); + OS_REG_WRITE(ah, AR_PHY_RADAR_1, val); + } + + if (pe->pe_en_relstep_check == 1) + OS_REG_SET_BIT(ah, AR_PHY_RADAR_1, + AR_PHY_RADAR_1_RELSTEP_CHECK); + else if (pe->pe_en_relstep_check == 0) + OS_REG_CLR_BIT(ah, AR_PHY_RADAR_1, + AR_PHY_RADAR_1_RELSTEP_CHECK); + + if (pe->pe_enrelpwr == 1) + OS_REG_SET_BIT(ah, AR_PHY_RADAR_1, + AR_PHY_RADAR_1_RELPWR_ENA); + else if (pe->pe_enrelpwr == 0) + OS_REG_CLR_BIT(ah, AR_PHY_RADAR_1, + AR_PHY_RADAR_1_RELPWR_ENA); + + if (pe->pe_maxlen != HAL_PHYERR_PARAM_NOVAL) { + val = OS_REG_READ(ah, AR_PHY_RADAR_1); + val &= ~AR_PHY_RADAR_1_MAXLEN; + val |= SM(pe->pe_maxlen, AR_PHY_RADAR_1_MAXLEN); + OS_REG_WRITE(ah, AR_PHY_RADAR_1, val); + } + + /* + * Enable HT/40 if the upper layer asks; + * it should check the channel is HT/40 and HAL_CAP_EXT_CHAN_DFS + * is available. + */ + if (pe->pe_extchannel == 1) + OS_REG_SET_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA); + else if (pe->pe_extchannel == 0) + OS_REG_CLR_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA); +} + +/* + * Extract the radar event information from the given phy error. + * + * Returns AH_TRUE if the phy error was actually a phy error, + * AH_FALSE if the phy error wasn't a phy error. + */ + +/* Flags for pulse_bw_info */ +#define PRI_CH_RADAR_FOUND 0x01 +#define EXT_CH_RADAR_FOUND 0x02 +#define EXT_CH_RADAR_EARLY_FOUND 0x04 + +HAL_BOOL +ar5416ProcessRadarEvent(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; +} + +/* + * Return whether fast-clock is currently enabled for this + * channel. + */ +HAL_BOOL +ar5416IsFastClockEnabled(struct ath_hal *ah) +{ + struct ath_hal_private *ahp = AH_PRIVATE(ah); + + return IS_5GHZ_FAST_CLOCK_EN(ah, ahp->ah_curchan); +} Modified: head/sys/modules/ath/Makefile ============================================================================== --- head/sys/modules/ath/Makefile Mon Feb 20 01:21:54 2012 (r231926) +++ head/sys/modules/ath/Makefile Mon Feb 20 03:07:07 2012 (r231927) @@ -88,8 +88,8 @@ SRCS+= ah_eeprom_v14.c ah_eeprom_v4k.c \ ar5416_ani.c ar5416_attach.c ar5416_beacon.c ar5416_cal.c \ ar5416_cal_iq.c ar5416_cal_adcgain.c ar5416_cal_adcdc.c \ ar5416_eeprom.c ar5416_gpio.c ar5416_interrupts.c ar5416_keycache.c \ - ar5416_misc.c ar5416_phy.c ar5416_power.c ar5416_recv.c \ - ar5416_reset.c ar5416_xmit.c + ar5416_misc.c ar5416_phy.c ar5416_power.c ar5416_radar.c \ + ar5416_recv.c ar5416_reset.c ar5416_xmit.c # RF backend for 5416, 9130 and 9160 SRCS+= ar2133.c
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202200307.q1K377O9028541>