svn commit: r262423 - in head/tools/tools/iwn: . iwnstats

Adrian Chadd adrian at FreeBSD.org
Mon Feb 24 02:38:45 UTC 2014


Author: adrian
Date: Mon Feb 24 02:38:43 2014
New Revision: 262423
URL: http://svnweb.freebsd.org/changeset/base/262423

Log:
  Add a very basic and totally hacked up iwnstats program.
  
  This just extracts the current statistics out from the NIC via
  the new ioctl API and displays them.  It runs every 100ms to hopefully
  grab the latest statistics.
  
  I may eventually teach this to use libstatfoo like what has been done
  for athstats and such; but this is good enough for now for people to
  do some basic investigation.
  
  Tested:
  
  * Intel Centrino 6205

Added:
  head/tools/tools/iwn/
  head/tools/tools/iwn/Makefile   (contents, props changed)
  head/tools/tools/iwn/iwnstats/
  head/tools/tools/iwn/iwnstats/Makefile   (contents, props changed)
  head/tools/tools/iwn/iwnstats/iwn_ioctl.c   (contents, props changed)
  head/tools/tools/iwn/iwnstats/iwn_ioctl.h   (contents, props changed)
  head/tools/tools/iwn/iwnstats/iwnstats.h   (contents, props changed)
  head/tools/tools/iwn/iwnstats/main.c   (contents, props changed)

Added: head/tools/tools/iwn/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/tools/iwn/Makefile	Mon Feb 24 02:38:43 2014	(r262423)
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+SUBDIR=	iwnstats
+
+.include <bsd.subdir.mk>

Added: head/tools/tools/iwn/iwnstats/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/tools/iwn/iwnstats/Makefile	Mon Feb 24 02:38:43 2014	(r262423)
@@ -0,0 +1,22 @@
+# $FreeBSD$
+
+NO_MAN=1
+
+.include <bsd.own.mk>
+
+.PATH:	${.CURDIR}/../../../../sys/dev/iwn/
+
+CFLAGS+=-I${.CURDIR}/../../../../sys/dev/iwn/
+CFLAGS+=-I${.CURDIR}/../../../../sys/
+
+PROG=	iwnstats
+
+# Because of a clang preprocessor parser limitation causing this
+# to not compile, use gcc for now.
+#CC=	gcc
+
+SRCS=	main.c iwn_ioctl.c
+
+# CFLAGS.clang+= -fbracket-depth=512
+
+.include <bsd.prog.mk>

Added: head/tools/tools/iwn/iwnstats/iwn_ioctl.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/tools/iwn/iwnstats/iwn_ioctl.c	Mon Feb 24 02:38:43 2014	(r262423)
@@ -0,0 +1,91 @@
+/*-
+ * Copyright (c) 2014 Adrian Chadd <adrian at FreeBSD.org>
+ * 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$
+ */
+
+/*
+ * iwn ioctl API.
+ */
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/sockio.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/if_media.h>
+#include <net/if_var.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+#include <err.h>
+
+
+#include "net80211/ieee80211_ioctl.h"
+#include "net80211/ieee80211_radiotap.h"
+
+#include "if_iwn_ioctl.h"
+
+/*
+ * This contains the register definitions for iwn; including
+ * the statistics definitions.
+ */
+#include "if_iwnreg.h"
+
+#include "iwnstats.h"
+
+#include "iwn_ioctl.h"
+
+void
+iwn_setifname(struct iwnstats *is, const char *ifname)
+{
+
+	strncpy(is->ifr.ifr_name, ifname, sizeof (is->ifr.ifr_name));
+}
+
+void
+iwn_zerostats(struct iwnstats *is)
+{
+
+	if (ioctl(is->s, SIOCZIWNSTATS, &is->ifr) < 0)
+		err(-1, "ioctl: %s", is->ifr.ifr_name);
+}
+
+int
+iwn_collect(struct iwnstats *is)
+{
+	int err;
+
+	is->ifr.ifr_data = (caddr_t) &is->st;
+	err = ioctl(is->s, SIOCGIWNSTATS, &is->ifr);
+	if (err < 0)
+		warn("ioctl: %s", is->ifr.ifr_name);
+	return (err);
+}

Added: head/tools/tools/iwn/iwnstats/iwn_ioctl.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/tools/iwn/iwnstats/iwn_ioctl.h	Mon Feb 24 02:38:43 2014	(r262423)
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 2014 Adrian Chadd <adrian at FreeBSD.org>
+ * 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	__IWN_IOCTL_H__
+#define	__IWN_IOCTL_H__
+
+extern	void iwn_setifname(struct iwnstats *is, const char *ifname);
+extern	void iwn_zerostats(struct iwnstats *is);
+extern	int iwn_collect(struct iwnstats *is);
+
+#endif	/* __IWN_IOCTL_H__ */

Added: head/tools/tools/iwn/iwnstats/iwnstats.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/tools/iwn/iwnstats/iwnstats.h	Mon Feb 24 02:38:43 2014	(r262423)
@@ -0,0 +1,40 @@
+/*-
+ * Copyright (c) 2014 Adrian Chadd <adrian at FreeBSD.org>
+ * 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	__IWNSTATS_H__
+#define	__IWNSTATS_H__
+
+struct iwnstats {
+	int s;
+	struct ifreq ifr;
+	struct iwn_stats st;
+};
+
+#endif	/* __IWNSTATS_H__ */

Added: head/tools/tools/iwn/iwnstats/main.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/tools/iwn/iwnstats/main.c	Mon Feb 24 02:38:43 2014	(r262423)
@@ -0,0 +1,282 @@
+/*-
+ * Copyright (c) 2014 Adrian Chadd <adrian at FreeBSD.org>
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+#include <string.h>
+#include <err.h>
+#include <net/if.h>
+#include <sys/endian.h>
+
+#include "net80211/ieee80211_ioctl.h"
+#include "net80211/ieee80211_radiotap.h"
+
+#include "if_iwn_ioctl.h"
+#include "if_iwnreg.h"
+#include "iwnstats.h"
+#include "iwn_ioctl.h"
+
+#define	IWN_DEFAULT_IF		"iwn0"
+
+struct iwnstats *
+iwnstats_new(const char *ifname)
+{
+	struct iwnstats *is;
+
+	is = calloc(1, sizeof(struct iwnstats));
+	if (is == NULL)
+		return (NULL);
+
+	is->s = socket(AF_INET, SOCK_DGRAM, 0);
+	if (is->s < 0)
+		err(1, "socket");
+
+	iwn_setifname(is, ifname);
+	return (is);
+}
+
+static void
+iwn_stats_phy_print(struct iwnstats *is, struct iwn_rx_phy_stats *rxphy,
+    const char *prefix)
+{
+
+	printf("%s: %s: ina=%d, fina=%d, bad_plcp=%d, bad_crc32=%d, overrun=%d, eoverrun=%d\n",
+	        __func__,
+		prefix,
+		le32toh(rxphy->ina),
+		le32toh(rxphy->fina),
+		le32toh(rxphy->bad_plcp),
+		le32toh(rxphy->bad_crc32),
+		le32toh(rxphy->overrun),
+		le32toh(rxphy->eoverrun));
+
+	printf("%s: %s: fa=%d, bad_fina_sync=%d, sfd_timeout=%d, fina_timeout=%d, no_rts_ack=%d\n",
+	        __func__,
+		prefix,
+		le32toh(rxphy->fa),
+		le32toh(rxphy->bad_fina_sync),
+		le32toh(rxphy->sfd_timeout),
+		le32toh(rxphy->fina_timeout),
+		le32toh(rxphy->no_rts_ack));
+
+	printf("%s: %s: rxe_limit=%d, ack=%d, cts=%d, ba_resp=%d, dsp_kill=%d, bad_mh=%d, rssi_sum=%d\n",
+	        __func__,
+		prefix,
+		le32toh(rxphy->rxe_limit),
+		le32toh(rxphy->ack),
+		le32toh(rxphy->cts),
+		le32toh(rxphy->ba_resp),
+		le32toh(rxphy->dsp_kill),
+		le32toh(rxphy->bad_mh),
+		le32toh(rxphy->rssi_sum));
+}
+
+static void
+iwn_stats_rx_general_print(struct iwnstats *is, struct iwn_rx_general_stats *g)
+{
+
+	printf("%s: bad_cts=%d, bad_ack=%d, not_bss=%d, filtered=%d, bad_chan=%d, beacons=%d\n",
+	    __func__,
+	    le32toh(g->bad_cts),
+	    le32toh(g->bad_ack),
+	    le32toh(g->not_bss),
+	    le32toh(g->filtered),
+	    le32toh(g->bad_chan),
+	    le32toh(g->beacons));
+
+	/* XXX it'd be nice to have adc/ina saturated as a % of time */
+	printf("%s: missed_beacons=%d, adc_saturated=%d, ina_searched=%d\n",
+	    __func__,
+	    le32toh(g->missed_beacons),
+	    le32toh(g->adc_saturated),
+	    le32toh(g->ina_searched));
+
+	printf("%s: noise=[%d, %d, %d] flags=0x%08x, load=%d, fa=%d\n",
+	    __func__,
+	    le32toh(g->noise[0]),
+	    le32toh(g->noise[1]),
+	    le32toh(g->noise[2]),
+	    le32toh(g->flags),
+	    le32toh(g->load),
+	    le32toh(g->fa));
+
+	printf("%s: rssi=[%d, %d, %d] energy=[%d %d %d]\n",
+	    __func__,
+	    le32toh(g->rssi[0]),
+	    le32toh(g->rssi[1]),
+	    le32toh(g->rssi[2]),
+	    le32toh(g->energy[0]),
+	    le32toh(g->energy[1]),
+	    le32toh(g->energy[2]));
+}
+
+static void
+iwn_stats_tx_print(struct iwnstats *is, struct iwn_tx_stats *tx)
+{
+
+	printf("%s: preamble=%d, rx_detected=%d, bt_defer=%d, bt_kill=%d, short_len=%d\n",
+	    __func__,
+	    le32toh(tx->preamble),
+	    le32toh(tx->rx_detected),
+	    le32toh(tx->bt_defer),
+	    le32toh(tx->bt_kill),
+	    le32toh(tx->short_len));
+
+	printf("%s: cts_timeout=%d, ack_timeout=%d, exp_ack=%d, ack=%d, msdu=%d\n",
+	    __func__,
+	    le32toh(tx->cts_timeout),
+	    le32toh(tx->ack_timeout),
+	    le32toh(tx->exp_ack),
+	    le32toh(tx->ack),
+	    le32toh(tx->msdu));
+
+	printf("%s: burst_err1=%d, burst_err2=%d, cts_collision=%d, ack_collision=%d\n",
+	    __func__,
+	    le32toh(tx->burst_err1),
+	    le32toh(tx->burst_err2),
+	    le32toh(tx->cts_collision),
+	    le32toh(tx->ack_collision));
+
+	printf("%s: ba_timeout=%d, ba_resched=%d, query_ampdu=%d, query=%d, query_ampdu_frag=%d\n",
+	    __func__,
+	    le32toh(tx->ba_timeout),
+	    le32toh(tx->ba_resched),
+	    le32toh(tx->query_ampdu),
+	    le32toh(tx->query),
+	    le32toh(tx->query_ampdu_frag));
+
+	printf("%s: query_mismatch=%d, not_ready=%d, underrun=%d, bt_ht_kill=%d, rx_ba_resp=%d\n",
+	    __func__,
+	    le32toh(tx->query_mismatch),
+	    le32toh(tx->not_ready),
+	    le32toh(tx->underrun),
+	    le32toh(tx->bt_ht_kill),
+	    le32toh(tx->rx_ba_resp));
+}
+
+static void
+iwn_stats_ht_phy_print(struct iwnstats *is, struct iwn_rx_ht_phy_stats *ht)
+{
+
+	printf("%s: bad_plcp=%d, overrun=%d, eoverrun=%d, good_crc32=%d, bad_crc32=%d\n",
+	    __func__,
+	    le32toh(ht->bad_plcp),
+	    le32toh(ht->overrun),
+	    le32toh(ht->eoverrun),
+	    le32toh(ht->good_crc32),
+	    le32toh(ht->bad_crc32));
+
+	printf("%s: bad_mh=%d, good_ampdu_crc32=%d, ampdu=%d, fragment=%d\n",
+	    __func__,
+	    le32toh(ht->bad_plcp),
+	    le32toh(ht->good_ampdu_crc32),
+	    le32toh(ht->ampdu),
+	    le32toh(ht->fragment));
+}
+
+
+static void
+iwn_stats_general_print(struct iwnstats *is, struct iwn_stats *stats)
+{
+
+	/* General */
+	printf("%s: temp=%d, temp_m=%d, burst_check=%d, burst=%d, sleep=%d, slot_out=%d, slot_idle=%d\n",
+	        __func__,
+		le32toh(stats->general.temp),
+		le32toh(stats->general.temp_m),
+		le32toh(stats->general.burst_check),
+		le32toh(stats->general.burst),
+		le32toh(stats->general.sleep),
+		le32toh(stats->general.slot_out),
+		le32toh(stats->general.slot_idle));
+	printf("%s: slot_out=%d, ttl_tstamp=0x%08x, tx_ant_a=%d, tx_ant_b=%d, exec=%d, probe=%d\n",
+	        __func__,
+		le32toh(stats->general.slot_out),
+		le32toh(stats->general.ttl_tstamp),
+		le32toh(stats->general.tx_ant_a),
+		le32toh(stats->general.tx_ant_b),
+		le32toh(stats->general.exec),
+		le32toh(stats->general.probe));
+	printf("%s: rx_enabled=%d\n",
+	        __func__,
+		le32toh(stats->general.rx_enabled));
+}
+
+static void
+iwn_print(struct iwnstats *is)
+{
+	struct iwn_stats *s;
+
+	s = &is->st;
+
+	iwn_stats_general_print(is, s);
+
+	/* RX */
+	iwn_stats_phy_print(is, &s->rx.ofdm, "ofdm");
+	iwn_stats_phy_print(is, &s->rx.cck, "cck");
+	iwn_stats_ht_phy_print(is, &s->rx.ht);
+	iwn_stats_rx_general_print(is, &s->rx.general);
+
+	/* TX */
+	iwn_stats_tx_print(is, &s->tx);
+	printf("--\n");
+}
+
+int
+main(int argc, const char *argv[])
+{
+	struct iwnstats *is;
+
+	is = iwnstats_new(IWN_DEFAULT_IF);
+
+	if (is == NULL) {
+		fprintf(stderr, "%s: couldn't allocate new stats structure\n",
+		    argv[0]);
+		exit(127);
+	}
+
+	/* begin fetching data */
+	while (1) {
+		if (iwn_collect(is) != 0) {
+			fprintf(stderr, "%s: fetch failed\n", argv[0]);
+			goto next;
+		}
+
+		iwn_print(is);
+
+	next:
+		usleep(100 * 1000);
+	}
+
+	exit(0);
+}


More information about the svn-src-head mailing list