From owner-svn-src-head@FreeBSD.ORG Wed Jun 1 20:09:49 2011 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BAFA21065670; Wed, 1 Jun 2011 20:09:49 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id A85C68FC0A; Wed, 1 Jun 2011 20:09:49 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p51K9nGM085223; Wed, 1 Jun 2011 20:09:49 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p51K9nD9085216; Wed, 1 Jun 2011 20:09:49 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201106012009.p51K9nD9085216@svn.freebsd.org> From: Adrian Chadd Date: Wed, 1 Jun 2011 20:09:49 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r222585 - in head/sys: conf dev/ath dev/ath/ath_dfs dev/ath/ath_dfs/null modules/ath X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 01 Jun 2011 20:09:49 -0000 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 +__FBSDID("$FreeBSD$"); + +/* + * This implements an empty DFS module. + */ +#include "opt_inet.h" +#include "opt_wlan.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include /* XXX for ether_sprintf */ + +#include + +#include + +#ifdef INET +#include +#include +#endif + +#include +#include + +#include + +/* + * 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 #include #include +#include #ifdef ATH_TX99_DIAG #include #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: