svn commit: r231927 - in head/sys: conf dev/ath/ath_hal/ar5416 modules/ath

Adrian Chadd adrian at FreeBSD.org
Mon Feb 20 03:07:08 UTC 2012


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


More information about the svn-src-head mailing list