svn commit: r222585 - in head/sys: conf dev/ath dev/ath/ath_dfs dev/ath/ath_dfs/null modules/ath

Adrian Chadd adrian at FreeBSD.org
Wed Jun 1 20:09:49 UTC 2011


Author: adrian
Date: Wed Jun  1 20:09:49 2011
New Revision: 222585
URL: http://svn.freebsd.org/changeset/base/222585

Log:
  Flesh out the radar detection related operations for the ath driver.
  
  This is in no way a complete DFS/radar detection implementation!
  It merely creates an abstracted interface which allows for future
  development of the DFS radar detection code.
  
  Note: Net80211 already handles the bulk of the DFS machinery,
  all we need to do here is figure out that a radar event has occured
  and inform it as such. It then drives the DFS state engine for us.
  
  The "null" DFS radar detection module is included by default;
  it doesn't require a device line.
  
  This commit:
  
  * Adds a simple abstracted layer for radar detection state -
    sys/dev/ath/ath_dfs/;
  * Implements a null DFS module which doesn't do anything;
    (ie, implements the exact behaviour at the moment);
  * Adds hooks to the ath driver to process received radar events
    and gives the DFS module a chance to determine whether
    a radar has been detected.
  
  Obtained from:	Atheros

Added:
  head/sys/dev/ath/ath_dfs/
  head/sys/dev/ath/ath_dfs/null/
  head/sys/dev/ath/ath_dfs/null/dfs_null.c   (contents, props changed)
  head/sys/dev/ath/if_athdfs.h   (contents, props changed)
Modified:
  head/sys/conf/files
  head/sys/dev/ath/if_ath.c
  head/sys/dev/ath/if_athvar.h
  head/sys/modules/ath/Makefile

Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files	Wed Jun  1 20:01:02 2011	(r222584)
+++ head/sys/conf/files	Wed Jun  1 20:09:49 2011	(r222585)
@@ -846,7 +846,10 @@ dev/ath/ath_rate/onoe/onoe.c	optional at
 	compile-with "${NORMAL_C} -I$S/dev/ath"
 dev/ath/ath_rate/sample/sample.c	optional ath_rate_sample \
 	compile-with "${NORMAL_C} -I$S/dev/ath"
-#
+# ath DFS modules
+dev/ath/ath_dfs/null/dfs_null.c	optional	ath \
+	compile-with "${NORMAL_C} -I$S/dev/ath"
+# 
 dev/bce/if_bce.c		optional bce
 dev/bfe/if_bfe.c		optional bfe
 dev/bge/if_bge.c		optional bge

Added: head/sys/dev/ath/ath_dfs/null/dfs_null.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/ath/ath_dfs/null/dfs_null.c	Wed Jun  1 20:09:49 2011	(r222585)
@@ -0,0 +1,160 @@
+/*-
+ * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd
+ * 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$
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * This implements an empty DFS module.
+ */
+#include "opt_inet.h"
+#include "opt_wlan.h"
+
+#include <sys/param.h>
+#include <sys/systm.h> 
+#include <sys/sysctl.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/errno.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/bus.h>
+
+#include <sys/socket.h>
+ 
+#include <net/if.h>
+#include <net/if_media.h>
+#include <net/if_arp.h>
+#include <net/ethernet.h>		/* XXX for ether_sprintf */
+
+#include <net80211/ieee80211_var.h>
+
+#include <net/bpf.h>
+
+#ifdef INET
+#include <netinet/in.h> 
+#include <netinet/if_ether.h>
+#endif
+
+#include <dev/ath/if_athvar.h>
+#include <dev/ath/if_athdfs.h>
+
+#include <dev/ath/ath_hal/ah_desc.h>
+
+/*
+ * Methods which are required
+ */
+
+/*
+ * Attach DFS to the given interface
+ */
+int
+ath_dfs_attach(struct ath_softc *sc)
+{
+	return 1;
+}
+
+/*
+ * Detach DFS from the given interface
+ */
+int
+ath_dfs_detach(struct ath_softc *sc)
+{
+	return 1;
+}
+
+/*
+ * Enable radar check
+ */
+void
+ath_dfs_radar_enable(struct ath_softc *sc, struct ieee80211_channel *chan)
+{
+	/* Check if the current channel is radar-enabled */
+	if (! IEEE80211_IS_CHAN_DFS(chan))
+		return;
+}
+
+/*
+ * Process DFS related PHY errors
+ */
+void
+ath_dfs_process_phy_err(struct ath_softc *sc, struct ath_desc *ds,
+    uint64_t tsf, struct ath_rx_status *rxstat)
+{
+
+}
+
+/*
+ * Process the radar events and determine whether a DFS event has occured.
+ *
+ * This is designed to run outside of the RX processing path.
+ * The RX path will call ath_dfs_tasklet_needed() to see whether
+ * the task/callback running this routine needs to be called.
+ */
+int
+ath_dfs_process_radar_event(struct ath_softc *sc,
+    struct ieee80211_channel *chan)
+{
+	return 0;
+}
+
+/*
+ * Determine whether the the DFS check task needs to be queued.
+ *
+ * This is called in the RX task when the current batch of packets
+ * have been received. It will return whether there are any radar
+ * events for ath_dfs_process_radar_event() to handle.
+ */
+int
+ath_dfs_tasklet_needed(struct ath_softc *sc, struct ieee80211_channel *chan)
+{
+	return 0;
+}
+
+/*
+ * Handle ioctl requests from the diagnostic interface
+ */
+int
+ath_ioctl_phyerr(struct ath_softc *sc, struct ath_diag *ad)
+{
+	return 1;
+}
+
+/*
+ * Get the current DFS thresholds from the HAL
+ */
+int
+ath_dfs_get_thresholds(struct ath_softc *sc, HAL_PHYERR_PARAM *param)
+{
+	ath_hal_getdfsthresh(sc->sc_ah, param);
+	return 1;
+}

Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c	Wed Jun  1 20:01:02 2011	(r222584)
+++ head/sys/dev/ath/if_ath.c	Wed Jun  1 20:09:49 2011	(r222585)
@@ -95,11 +95,13 @@ __FBSDID("$FreeBSD$");
 #include <dev/ath/if_ath_tx.h>
 #include <dev/ath/if_ath_sysctl.h>
 #include <dev/ath/if_ath_keycache.h>
+#include <dev/ath/if_athdfs.h>
 
 #ifdef ATH_TX99_DIAG
 #include <dev/ath/ath_tx99/ath_tx99.h>
 #endif
 
+
 /*
  * ATH_BCBUF determines the number of vap's that can transmit
  * beacons and also (currently) the number of vap's that can
@@ -199,6 +201,8 @@ static void	ath_setcurmode(struct ath_so
 
 static void	ath_announce(struct ath_softc *);
 
+static void	ath_dfs_tasklet(void *, int);
+
 #ifdef IEEE80211_SUPPORT_TDMA
 static void	ath_tdma_settimers(struct ath_softc *sc, u_int32_t nexttbtt,
 		    u_int32_t bintval);
@@ -471,6 +475,16 @@ ath_attach(u_int16_t devid, struct ath_s
 		goto bad2;
 	}
 
+	/* Attach DFS module */
+	if (! ath_dfs_attach(sc)) {
+		device_printf(sc->sc_dev, "%s: unable to attach DFS\n", __func__);
+		error = EIO;
+		goto bad2;
+	}
+
+	/* Start DFS processing tasklet */
+	TASK_INIT(&sc->sc_dfstask, 0, ath_dfs_tasklet, sc);
+
 	sc->sc_blinking = 0;
 	sc->sc_ledstate = 1;
 	sc->sc_ledon = 0;			/* low true */
@@ -771,6 +785,8 @@ ath_detach(struct ath_softc *sc)
 		sc->sc_tx99->detach(sc->sc_tx99);
 #endif
 	ath_rate_detach(sc->sc_rc);
+
+	ath_dfs_detach(sc);
 	ath_desc_free(sc);
 	ath_tx_cleanup(sc);
 	ath_hal_detach(sc->sc_ah);	/* NB: sets chip in full sleep */
@@ -1554,6 +1570,9 @@ ath_init(void *arg)
 	}
 	ath_chan_change(sc, ic->ic_curchan);
 
+	/* Let DFS at it in case it's a DFS channel */
+	ath_dfs_radar_enable(sc, ic->ic_curchan);
+
 	/*
 	 * Likewise this is set during reset so update
 	 * state cached in the driver.
@@ -1699,6 +1718,10 @@ ath_reset(struct ifnet *ifp)
 		if_printf(ifp, "%s: unable to reset hardware; hal status %u\n",
 			__func__, status);
 	sc->sc_diversity = ath_hal_getdiversity(ah);
+
+	/* Let DFS at it in case it's a DFS channel */
+	ath_dfs_radar_enable(sc, ic->ic_curchan);
+
 	if (ath_startrecv(sc) != 0)	/* restart recv */
 		if_printf(ifp, "%s: unable to start recv logic\n", __func__);
 	/*
@@ -3441,6 +3464,9 @@ ath_rx_proc(void *arg, int npending)
 				sc->sc_stats.ast_rx_fifoerr++;
 			if (rs->rs_status & HAL_RXERR_PHY) {
 				sc->sc_stats.ast_rx_phyerr++;
+				/* Process DFS radar events */
+				ath_dfs_process_phy_err(sc, ds, tsf, 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]++;
@@ -3682,6 +3708,10 @@ rx_next:
 	if (ngood)
 		sc->sc_lastrx = tsf;
 
+	/* Queue DFS tasklet if needed */
+	if (ath_dfs_tasklet_needed(sc, sc->sc_curchan))
+		taskqueue_enqueue(sc->sc_tq, &sc->sc_dfstask);
+
 	if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
 #ifdef IEEE80211_SUPPORT_SUPERG
 		ieee80211_ff_age_all(ic, 100);
@@ -4399,6 +4429,9 @@ ath_chan_set(struct ath_softc *sc, struc
 		}
 		sc->sc_diversity = ath_hal_getdiversity(ah);
 
+		/* Let DFS at it in case it's a DFS channel */
+		ath_dfs_radar_enable(sc, ic->ic_curchan);
+
 		/*
 		 * Re-enable rx framework.
 		 */
@@ -5665,5 +5698,23 @@ ath_tdma_beacon_send(struct ath_softc *s
 }
 #endif /* IEEE80211_SUPPORT_TDMA */
 
+static void
+ath_dfs_tasklet(void *p, int npending)
+{
+	struct ath_softc *sc = (struct ath_softc *) p;
+	struct ifnet *ifp = sc->sc_ifp;
+	struct ieee80211com *ic = ifp->if_l2com;
+
+	/*
+	 * If previous processing has found a radar event,
+	 * signal this to the net80211 layer to begin DFS
+	 * processing.
+	 */
+	if (ath_dfs_process_radar_event(sc, sc->sc_curchan)) {
+		/* DFS event found, initiate channel change */
+		ieee80211_dfs_notify_radar(ic, sc->sc_curchan);
+	}
+}
+
 MODULE_VERSION(if_ath, 1);
 MODULE_DEPEND(if_ath, wlan, 1, 1, 1);          /* 802.11 media layer */

Added: head/sys/dev/ath/if_athdfs.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/ath/if_athdfs.h	Wed Jun  1 20:09:49 2011	(r222585)
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd
+ * 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$
+ */
+#ifndef	__IF_ATHDFS_H__
+#define	__IF_ATHDFS_H__
+
+extern	int ath_dfs_attach(struct ath_softc *sc);
+extern	int ath_dfs_detach(struct ath_softc *sc);
+extern	void ath_dfs_radar_enable(struct ath_softc *,
+    struct ieee80211_channel *chan);
+extern	void ath_dfs_process_phy_err(struct ath_softc *sc, struct ath_desc *ds,
+    uint64_t tsf, struct ath_rx_status *rxstat);
+extern	int ath_dfs_process_radar_event(struct ath_softc *sc,
+    struct ieee80211_channel *chan);
+extern	int ath_dfs_tasklet_needed(struct ath_softc *sc,
+    struct ieee80211_channel *chan);
+extern	int ath_ioctl_phyerr(struct ath_softc *sc, struct ath_diag *ad);
+extern	int ath_dfs_get_thresholds(struct ath_softc *sc, HAL_PHYERR_PARAM *param);
+
+#endif	/* __IF_ATHDFS_H__ */

Modified: head/sys/dev/ath/if_athvar.h
==============================================================================
--- head/sys/dev/ath/if_athvar.h	Wed Jun  1 20:01:02 2011	(r222584)
+++ head/sys/dev/ath/if_athvar.h	Wed Jun  1 20:09:49 2011	(r222585)
@@ -357,6 +357,10 @@ struct ath_softc {
 	uint16_t		*sc_eepromdata;	/* Local eeprom data, if AR9100 */
 	int			sc_txchainmask;	/* currently configured TX chainmask */
 	int			sc_rxchainmask;	/* currently configured RX chainmask */
+
+	/* DFS related state */
+	void			*sc_dfs;	/* Used by an optional DFS module */
+	struct task		sc_dfstask;	/* DFS processing task */
 };
 
 #define	ATH_LOCK_INIT(_sc) \
@@ -694,6 +698,17 @@ void	ath_intr(void *);
 #define	ath_hal_set11nburstduration(_ah, _ds, _dur) \
 	((*(_ah)->ah_set11nBurstDuration)((_ah), (_ds), (_dur)))
 
+/*
+ * 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_gpioCfgOutput(_ah, _gpio, _type) \
         ((*(_ah)->ah_gpioCfgOutput)((_ah), (_gpio), (_type)))
 #define ath_hal_gpioset(_ah, _gpio, _b) \

Modified: head/sys/modules/ath/Makefile
==============================================================================
--- head/sys/modules/ath/Makefile	Wed Jun  1 20:01:02 2011	(r222584)
+++ head/sys/modules/ath/Makefile	Wed Jun  1 20:09:49 2011	(r222585)
@@ -134,6 +134,10 @@ SRCS+=	onoe.c
 SRCS+=	amrr.c
 .endif
 
+# DFS
+.PATH: ${.CURDIR}/../../dev/ath/ath_dfs/null
+SRCS+=	dfs_null.c
+
 CFLAGS+=  -I. -I${.CURDIR}/../../dev/ath -I${.CURDIR}/../../dev/ath/ath_hal
 
 opt_ah.h:


More information about the svn-src-all mailing list