From 5fd18f70ab267770589101678c7fb01c98bdfe76 Mon Sep 17 00:00:00 2001 From: adrian Date: Wed, 2 Jan 2013 03:59:02 +0000 Subject: Add a new (skeleton) spectral mode manager module. --- sys/dev/ath/if_ath.c | 25 +++++ sys/dev/ath/if_ath_spectral.c | 224 ++++++++++++++++++++++++++++++++++++++++++ sys/dev/ath/if_ath_spectral.h | 40 ++++++++ sys/dev/ath/if_athioctl.h | 22 +++++ sys/dev/ath/if_athvar.h | 4 + 5 files changed, 315 insertions(+) create mode 100644 sys/dev/ath/if_ath_spectral.c create mode 100644 sys/dev/ath/if_ath_spectral.h (limited to 'sys/dev/ath') diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index 78a1519..bd2580f 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -111,6 +111,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #ifdef ATH_TX99_DIAG @@ -510,6 +511,14 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) goto bad2; } + /* Attach spectral module */ + if (ath_spectral_attach(sc) < 0) { + device_printf(sc->sc_dev, + "%s: unable to attach spectral\n", __func__); + error = EIO; + goto bad2; + } + /* Start DFS processing tasklet */ TASK_INIT(&sc->sc_dfstask, 0, ath_dfs_tasklet, sc); @@ -967,6 +976,7 @@ ath_detach(struct ath_softc *sc) if_ath_alq_tidyup(&sc->sc_alq); #endif + ath_spectral_detach(sc); ath_dfs_detach(sc); ath_desc_free(sc); ath_txdma_teardown(sc); @@ -1489,6 +1499,9 @@ ath_resume(struct ath_softc *sc) /* Let DFS at it in case it's a DFS channel */ ath_dfs_radar_enable(sc, ic->ic_curchan); + /* Let spectral at in case spectral is enabled */ + ath_spectral_enable(sc, ic->ic_curchan); + /* Restore the LED configuration */ ath_led_config(sc); ath_hal_setledstate(ah, HAL_LED_INIT); @@ -1918,6 +1931,9 @@ ath_init(void *arg) /* Let DFS at it in case it's a DFS channel */ ath_dfs_radar_enable(sc, ic->ic_curchan); + /* Let spectral at in case spectral is enabled */ + ath_spectral_enable(sc, ic->ic_curchan); + /* * Likewise this is set during reset so update * state cached in the driver. @@ -2226,6 +2242,9 @@ ath_reset(struct ifnet *ifp, ATH_RESET_TYPE reset_type) /* Let DFS at it in case it's a DFS channel */ ath_dfs_radar_enable(sc, ic->ic_curchan); + /* Let spectral at in case spectral is enabled */ + ath_spectral_enable(sc, ic->ic_curchan); + if (ath_startrecv(sc) != 0) /* restart recv */ if_printf(ifp, "%s: unable to start recv logic\n", __func__); /* @@ -4402,6 +4421,9 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan) /* Let DFS at it in case it's a DFS channel */ ath_dfs_radar_enable(sc, chan); + /* Let spectral at in case spectral is enabled */ + ath_spectral_enable(sc, chan); + /* * Re-enable rx framework. */ @@ -5384,6 +5406,9 @@ ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) error = ath_ioctl_phyerr(sc,(struct ath_diag*) ifr); break; #endif + case SIOCGATHSPECTRAL: + error = ath_ioctl_spectral(sc,(struct ath_diag*) ifr); + break; case SIOCGATHNODERATESTATS: error = ath_ioctl_ratestats(sc, (struct ath_rateioctl *) ifr); break; diff --git a/sys/dev/ath/if_ath_spectral.c b/sys/dev/ath/if_ath_spectral.c new file mode 100644 index 0000000..12fb87a7 --- /dev/null +++ b/sys/dev/ath/if_ath_spectral.c @@ -0,0 +1,224 @@ +/*- + * Copyright (c) 2013 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. + * + * $FreeBSD$ + */ +#include +__FBSDID("$FreeBSD$"); + +/* + * Implement some basic spectral scan control logic. + */ +#include "opt_ath.h" +#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 + +struct ath_spectral_state { + HAL_SPECTRAL_PARAM spectral_state; + int spectral_active; + int spectral_enabled; +}; + +/* + * Methods which are required + */ + +/* + * Attach DFS to the given interface + */ +int +ath_spectral_attach(struct ath_softc *sc) +{ + struct ath_spectral_state *ss; + + ss = malloc(sizeof(struct ath_spectral_state), + M_TEMP, M_WAITOK | M_ZERO); + + if (ss == NULL) { + device_printf(sc->sc_dev, "%s: failed to alloc memory\n", + __func__); + return (-ENOMEM); + } + + sc->sc_spectral = ss; + + (void) ath_hal_spectral_get_config(sc->sc_ah, &ss->spectral_state); + + return (0); +} + +/* + * Detach DFS from the given interface + */ +int +ath_spectral_detach(struct ath_softc *sc) +{ + if (sc->sc_spectral != NULL) { + free(sc->sc_spectral, M_TEMP); + } + return (0); +} + +/* + * Check whether spectral needs enabling and if so, + * flip it on. + */ +int +ath_spectral_enable(struct ath_softc *sc, struct ieee80211_channel *ch) +{ + + return (0); +} + +/* + * Handle ioctl requests from the diagnostic interface. + * + * The initial part of this code resembles ath_ioctl_diag(); + * it's likely a good idea to reduce duplication between + * these two routines. + */ +int +ath_ioctl_spectral(struct ath_softc *sc, struct ath_diag *ad) +{ + unsigned int id = ad->ad_id & ATH_DIAG_ID; + void *indata = NULL; + void *outdata = NULL; + u_int32_t insize = ad->ad_in_size; + u_int32_t outsize = ad->ad_out_size; + int error = 0; + HAL_SPECTRAL_PARAM peout; + HAL_SPECTRAL_PARAM *pe; + struct ath_spectral_state *ss = sc->sc_spectral; + + if (ad->ad_id & ATH_DIAG_IN) { + /* + * Copy in data. + */ + indata = malloc(insize, M_TEMP, M_NOWAIT); + if (indata == NULL) { + error = ENOMEM; + goto bad; + } + error = copyin(ad->ad_in_data, indata, insize); + if (error) + goto bad; + } + if (ad->ad_id & ATH_DIAG_DYN) { + /* + * Allocate a buffer for the results (otherwise the HAL + * returns a pointer to a buffer where we can read the + * results). Note that we depend on the HAL leaving this + * pointer for us to use below in reclaiming the buffer; + * may want to be more defensive. + */ + outdata = malloc(outsize, M_TEMP, M_NOWAIT); + if (outdata == NULL) { + error = ENOMEM; + goto bad; + } + } + switch (id) { + case SPECTRAL_CONTROL_GET_PARAMS: + memset(&peout, 0, sizeof(peout)); + outsize = sizeof(HAL_SPECTRAL_PARAM); + ath_hal_spectral_get_config(sc->sc_ah, &peout); + pe = (HAL_SPECTRAL_PARAM *) outdata; + memcpy(pe, &peout, sizeof(*pe)); + break; + case SPECTRAL_CONTROL_SET_PARAMS: + if (insize < sizeof(HAL_SPECTRAL_PARAM)) { + error = EINVAL; + break; + } + pe = (HAL_SPECTRAL_PARAM *) indata; + ath_hal_spectral_configure(sc->sc_ah, pe); + /* Save a local copy of the updated parameters */ + ath_hal_spectral_get_config(sc->sc_ah, + &ss->spectral_state); + break; + case SPECTRAL_CONTROL_START: + ath_hal_spectral_configure(sc->sc_ah, + &ss->spectral_state); + (void) ath_hal_spectral_start(sc->sc_ah); + break; + case SPECTRAL_CONTROL_STOP: + (void) ath_hal_spectral_stop(sc->sc_ah); + break; + case SPECTRAL_CONTROL_ENABLE: + /* XXX TODO */ + case SPECTRAL_CONTROL_DISABLE: + /* XXX TODO */ + break; + default: + error = EINVAL; + } + if (outsize < ad->ad_out_size) + ad->ad_out_size = outsize; + if (outdata && copyout(outdata, ad->ad_out_data, ad->ad_out_size)) + error = EFAULT; +bad: + if ((ad->ad_id & ATH_DIAG_IN) && indata != NULL) + free(indata, M_TEMP); + if ((ad->ad_id & ATH_DIAG_DYN) && outdata != NULL) + free(outdata, M_TEMP); + return (error); +} + diff --git a/sys/dev/ath/if_ath_spectral.h b/sys/dev/ath/if_ath_spectral.h new file mode 100644 index 0000000..3e069db --- /dev/null +++ b/sys/dev/ath/if_ath_spectral.h @@ -0,0 +1,40 @@ +/*- + * Copyright (c) 2013 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. + * + * $FreeBSD$ + */ +#ifndef __IF_ATH_SPECTRAL_H__ +#define __IF_ATH_SPECTRAL_H__ + +extern int ath_spectral_attach(struct ath_softc *sc); +extern int ath_spectral_detach(struct ath_softc *sc); +extern int ath_ioctl_spectral(struct ath_softc *sc, struct ath_diag *ad); +extern int ath_spectral_enable(struct ath_softc *sc, + struct ieee80211_channel *ch); + +#endif /* __IF_ATH_SPECTRAL_H__ */ diff --git a/sys/dev/ath/if_athioctl.h b/sys/dev/ath/if_athioctl.h index 911bb97..d6adf94 100644 --- a/sys/dev/ath/if_athioctl.h +++ b/sys/dev/ath/if_athioctl.h @@ -406,4 +406,26 @@ struct ath_tx_radiotap_header { #define DFS_PARAM_ENABLE 32 #define DFS_PARAM_EN_EXTCH 33 +/* + * Spectral ioctl parameter types + */ +#define SPECTRAL_PARAM_FFT_PERIOD 1 +#define SPECTRAL_PARAM_SS_PERIOD 2 +#define SPECTRAL_PARAM_SS_COUNT 3 +#define SPECTRAL_PARAM_SS_SHORT_RPT 4 +#define SPECTRAL_PARAM_ENABLED 5 +#define SPECTRAL_PARAM_ACTIVE 6 + +/* + * Spectral control parameters + */ +#define SIOCGATHSPECTRAL _IOWR('i', 151, struct ath_diag) + +#define SPECTRAL_CONTROL_ENABLE 2 +#define SPECTRAL_CONTROL_DISABLE 3 +#define SPECTRAL_CONTROL_START 4 +#define SPECTRAL_CONTROL_STOP 5 +#define SPECTRAL_CONTROL_GET_PARAMS 6 +#define SPECTRAL_CONTROL_SET_PARAMS 7 + #endif /* _DEV_ATH_ATHIOCTL_H */ diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h index 86dd91a..12252ed 100644 --- a/sys/dev/ath/if_athvar.h +++ b/sys/dev/ath/if_athvar.h @@ -750,6 +750,10 @@ struct ath_softc { 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; + /* ALQ */ #ifdef ATH_DEBUG_ALQ struct if_ath_alq sc_alq; -- cgit v1.1