diff options
author | adrian <adrian@FreeBSD.org> | 2014-02-24 02:37:04 +0000 |
---|---|---|
committer | adrian <adrian@FreeBSD.org> | 2014-02-24 02:37:04 +0000 |
commit | 9033c92af50ae00453322644b5ec1d0e4d387eca (patch) | |
tree | 0eb5161963afa7d7b0591c17c46b9ba671c24334 /sys/dev/iwn | |
parent | 764774a005a41fdd6b72c6ad90caa13fd653c8d1 (diff) | |
download | FreeBSD-src-9033c92af50ae00453322644b5ec1d0e4d387eca.zip FreeBSD-src-9033c92af50ae00453322644b5ec1d0e4d387eca.tar.gz |
Track and expose the latest statistics from the firmware.
Tested:
* Intel Centrino 6205
Diffstat (limited to 'sys/dev/iwn')
-rw-r--r-- | sys/dev/iwn/if_iwn.c | 27 | ||||
-rw-r--r-- | sys/dev/iwn/if_iwn_ioctl.h | 25 | ||||
-rw-r--r-- | sys/dev/iwn/if_iwnvar.h | 16 |
3 files changed, 68 insertions, 0 deletions
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c index b2a6e99..361e4a3 100644 --- a/sys/dev/iwn/if_iwn.c +++ b/sys/dev/iwn/if_iwn.c @@ -79,6 +79,7 @@ __FBSDID("$FreeBSD$"); #include <dev/iwn/if_iwn_devid.h> #include <dev/iwn/if_iwn_chip_cfg.h> #include <dev/iwn/if_iwn_debug.h> +#include <dev/iwn/if_iwn_ioctl.h> struct iwn_ident { uint16_t vendor; @@ -3140,6 +3141,16 @@ iwn5000_rx_calib_results(struct iwn_softc *sc, struct iwn_rx_desc *desc, memcpy(sc->calibcmd[idx].buf, calib, len); } +static void +iwn_stats_update(struct iwn_softc *sc, struct iwn_calib_state *calib, + struct iwn_stats *stats) +{ + + /* XXX lock assert */ + memcpy(&sc->last_stat, stats, sizeof(struct iwn_stats)); + sc->last_stat_valid = 1; +} + /* * Process an RX_STATISTICS or BEACON_STATISTICS firmware notification. * The latter is sent by the firmware after each received beacon. @@ -3172,6 +3183,9 @@ iwn_rx_statistics(struct iwn_softc *sc, struct iwn_rx_desc *desc, __func__, desc->type); sc->calib_cnt = 0; /* Reset TX power calibration timeout. */ + /* Collect/track general statistics for reporting */ + iwn_stats_update(sc, calib, stats); + /* Test if temperature has changed. */ if (stats->general.temp != sc->rawtemp) { /* Convert "raw" temperature to degC. */ @@ -4712,6 +4726,19 @@ iwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) case SIOCGIFMEDIA: error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); break; + case SIOCGIWNSTATS: + IWN_LOCK(sc); + /* XXX validate permissions/memory/etc? */ + error = copyout(&sc->last_stat, ifr->ifr_data, + sizeof(struct iwn_stats)); + IWN_UNLOCK(sc); + break; + case SIOCZIWNSTATS: + IWN_LOCK(sc); + memset(&sc->last_stat, 0, sizeof(struct iwn_stats)); + IWN_UNLOCK(sc); + error = 0; + break; default: error = EINVAL; break; diff --git a/sys/dev/iwn/if_iwn_ioctl.h b/sys/dev/iwn/if_iwn_ioctl.h new file mode 100644 index 0000000..1acf464 --- /dev/null +++ b/sys/dev/iwn/if_iwn_ioctl.h @@ -0,0 +1,25 @@ +/*- + * Copyright (c) 2014 Adrian Chadd <adrian@FreeBSD.org> + * + * Permission to use, copy, modify, and 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$ + */ +#ifndef __IF_IWN_IOCTL_H__ +#define __IF_IWN_IOCTL_H__ + +/* XXX how should I pick appropriate ioctl numbers? */ +#define SIOCGIWNSTATS _IOWR('i', 145, struct ifreq) +#define SIOCZIWNSTATS _IOWR('i', 146, struct ifreq) + +#endif /* __IF_IWN_IOCTL_H__ */ diff --git a/sys/dev/iwn/if_iwnvar.h b/sys/dev/iwn/if_iwnvar.h index f146feb..bcc01b2 100644 --- a/sys/dev/iwn/if_iwnvar.h +++ b/sys/dev/iwn/if_iwnvar.h @@ -328,6 +328,22 @@ struct iwn_softc { int ctx; struct ieee80211vap *ivap[IWN_NUM_RXON_CTX]; + /* General statistics */ + /* + * The statistics are reset after each channel + * change. So it may be zeroed after things like + * a background scan. + * + * So for now, this is just a cheap hack to + * expose the last received statistics dump + * via an ioctl(). Later versions of this + * could expose the last 'n' messages, or just + * provide a pipeline for the firmware responses + * via something like BPF. + */ + struct iwn_stats last_stat; + int last_stat_valid; + uint8_t uc_scan_progress; uint32_t rawtemp; int temp; |