summaryrefslogtreecommitdiffstats
path: root/sys/dev/iwn
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2014-02-24 02:37:04 +0000
committeradrian <adrian@FreeBSD.org>2014-02-24 02:37:04 +0000
commit9033c92af50ae00453322644b5ec1d0e4d387eca (patch)
tree0eb5161963afa7d7b0591c17c46b9ba671c24334 /sys/dev/iwn
parent764774a005a41fdd6b72c6ad90caa13fd653c8d1 (diff)
downloadFreeBSD-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.c27
-rw-r--r--sys/dev/iwn/if_iwn_ioctl.h25
-rw-r--r--sys/dev/iwn/if_iwnvar.h16
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;
OpenPOWER on IntegriCloud