main.c revision 262423
1262423Sadrian/*-
2262423Sadrian * Copyright (c) 2014 Adrian Chadd <adrian@FreeBSD.org>
3262423Sadrian * All rights reserved.
4262423Sadrian *
5262423Sadrian * Redistribution and use in source and binary forms, with or without
6262423Sadrian * modification, are permitted provided that the following conditions
7262423Sadrian * are met:
8262423Sadrian * 1. Redistributions of source code must retain the above copyright
9262423Sadrian *    notice, this list of conditions and the following disclaimer,
10262423Sadrian *    without modification.
11262423Sadrian * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12262423Sadrian *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13262423Sadrian *    redistribution must be conditioned upon including a substantially
14262423Sadrian *    similar Disclaimer requirement for further binary redistribution.
15262423Sadrian *
16262423Sadrian * NO WARRANTY
17262423Sadrian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18262423Sadrian * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19262423Sadrian * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20262423Sadrian * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21262423Sadrian * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22262423Sadrian * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23262423Sadrian * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24262423Sadrian * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25262423Sadrian * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26262423Sadrian * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27262423Sadrian * THE POSSIBILITY OF SUCH DAMAGES.
28262423Sadrian *
29262423Sadrian * $FreeBSD: head/tools/tools/iwn/iwnstats/main.c 262423 2014-02-24 02:38:43Z adrian $
30262423Sadrian */
31262423Sadrian
32262423Sadrian#include <stdio.h>
33262423Sadrian#include <stdlib.h>
34262423Sadrian#include <signal.h>
35262423Sadrian#include <unistd.h>
36262423Sadrian#include <string.h>
37262423Sadrian#include <err.h>
38262423Sadrian#include <net/if.h>
39262423Sadrian#include <sys/endian.h>
40262423Sadrian
41262423Sadrian#include "net80211/ieee80211_ioctl.h"
42262423Sadrian#include "net80211/ieee80211_radiotap.h"
43262423Sadrian
44262423Sadrian#include "if_iwn_ioctl.h"
45262423Sadrian#include "if_iwnreg.h"
46262423Sadrian#include "iwnstats.h"
47262423Sadrian#include "iwn_ioctl.h"
48262423Sadrian
49262423Sadrian#define	IWN_DEFAULT_IF		"iwn0"
50262423Sadrian
51262423Sadrianstruct iwnstats *
52262423Sadrianiwnstats_new(const char *ifname)
53262423Sadrian{
54262423Sadrian	struct iwnstats *is;
55262423Sadrian
56262423Sadrian	is = calloc(1, sizeof(struct iwnstats));
57262423Sadrian	if (is == NULL)
58262423Sadrian		return (NULL);
59262423Sadrian
60262423Sadrian	is->s = socket(AF_INET, SOCK_DGRAM, 0);
61262423Sadrian	if (is->s < 0)
62262423Sadrian		err(1, "socket");
63262423Sadrian
64262423Sadrian	iwn_setifname(is, ifname);
65262423Sadrian	return (is);
66262423Sadrian}
67262423Sadrian
68262423Sadrianstatic void
69262423Sadrianiwn_stats_phy_print(struct iwnstats *is, struct iwn_rx_phy_stats *rxphy,
70262423Sadrian    const char *prefix)
71262423Sadrian{
72262423Sadrian
73262423Sadrian	printf("%s: %s: ina=%d, fina=%d, bad_plcp=%d, bad_crc32=%d, overrun=%d, eoverrun=%d\n",
74262423Sadrian	        __func__,
75262423Sadrian		prefix,
76262423Sadrian		le32toh(rxphy->ina),
77262423Sadrian		le32toh(rxphy->fina),
78262423Sadrian		le32toh(rxphy->bad_plcp),
79262423Sadrian		le32toh(rxphy->bad_crc32),
80262423Sadrian		le32toh(rxphy->overrun),
81262423Sadrian		le32toh(rxphy->eoverrun));
82262423Sadrian
83262423Sadrian	printf("%s: %s: fa=%d, bad_fina_sync=%d, sfd_timeout=%d, fina_timeout=%d, no_rts_ack=%d\n",
84262423Sadrian	        __func__,
85262423Sadrian		prefix,
86262423Sadrian		le32toh(rxphy->fa),
87262423Sadrian		le32toh(rxphy->bad_fina_sync),
88262423Sadrian		le32toh(rxphy->sfd_timeout),
89262423Sadrian		le32toh(rxphy->fina_timeout),
90262423Sadrian		le32toh(rxphy->no_rts_ack));
91262423Sadrian
92262423Sadrian	printf("%s: %s: rxe_limit=%d, ack=%d, cts=%d, ba_resp=%d, dsp_kill=%d, bad_mh=%d, rssi_sum=%d\n",
93262423Sadrian	        __func__,
94262423Sadrian		prefix,
95262423Sadrian		le32toh(rxphy->rxe_limit),
96262423Sadrian		le32toh(rxphy->ack),
97262423Sadrian		le32toh(rxphy->cts),
98262423Sadrian		le32toh(rxphy->ba_resp),
99262423Sadrian		le32toh(rxphy->dsp_kill),
100262423Sadrian		le32toh(rxphy->bad_mh),
101262423Sadrian		le32toh(rxphy->rssi_sum));
102262423Sadrian}
103262423Sadrian
104262423Sadrianstatic void
105262423Sadrianiwn_stats_rx_general_print(struct iwnstats *is, struct iwn_rx_general_stats *g)
106262423Sadrian{
107262423Sadrian
108262423Sadrian	printf("%s: bad_cts=%d, bad_ack=%d, not_bss=%d, filtered=%d, bad_chan=%d, beacons=%d\n",
109262423Sadrian	    __func__,
110262423Sadrian	    le32toh(g->bad_cts),
111262423Sadrian	    le32toh(g->bad_ack),
112262423Sadrian	    le32toh(g->not_bss),
113262423Sadrian	    le32toh(g->filtered),
114262423Sadrian	    le32toh(g->bad_chan),
115262423Sadrian	    le32toh(g->beacons));
116262423Sadrian
117262423Sadrian	/* XXX it'd be nice to have adc/ina saturated as a % of time */
118262423Sadrian	printf("%s: missed_beacons=%d, adc_saturated=%d, ina_searched=%d\n",
119262423Sadrian	    __func__,
120262423Sadrian	    le32toh(g->missed_beacons),
121262423Sadrian	    le32toh(g->adc_saturated),
122262423Sadrian	    le32toh(g->ina_searched));
123262423Sadrian
124262423Sadrian	printf("%s: noise=[%d, %d, %d] flags=0x%08x, load=%d, fa=%d\n",
125262423Sadrian	    __func__,
126262423Sadrian	    le32toh(g->noise[0]),
127262423Sadrian	    le32toh(g->noise[1]),
128262423Sadrian	    le32toh(g->noise[2]),
129262423Sadrian	    le32toh(g->flags),
130262423Sadrian	    le32toh(g->load),
131262423Sadrian	    le32toh(g->fa));
132262423Sadrian
133262423Sadrian	printf("%s: rssi=[%d, %d, %d] energy=[%d %d %d]\n",
134262423Sadrian	    __func__,
135262423Sadrian	    le32toh(g->rssi[0]),
136262423Sadrian	    le32toh(g->rssi[1]),
137262423Sadrian	    le32toh(g->rssi[2]),
138262423Sadrian	    le32toh(g->energy[0]),
139262423Sadrian	    le32toh(g->energy[1]),
140262423Sadrian	    le32toh(g->energy[2]));
141262423Sadrian}
142262423Sadrian
143262423Sadrianstatic void
144262423Sadrianiwn_stats_tx_print(struct iwnstats *is, struct iwn_tx_stats *tx)
145262423Sadrian{
146262423Sadrian
147262423Sadrian	printf("%s: preamble=%d, rx_detected=%d, bt_defer=%d, bt_kill=%d, short_len=%d\n",
148262423Sadrian	    __func__,
149262423Sadrian	    le32toh(tx->preamble),
150262423Sadrian	    le32toh(tx->rx_detected),
151262423Sadrian	    le32toh(tx->bt_defer),
152262423Sadrian	    le32toh(tx->bt_kill),
153262423Sadrian	    le32toh(tx->short_len));
154262423Sadrian
155262423Sadrian	printf("%s: cts_timeout=%d, ack_timeout=%d, exp_ack=%d, ack=%d, msdu=%d\n",
156262423Sadrian	    __func__,
157262423Sadrian	    le32toh(tx->cts_timeout),
158262423Sadrian	    le32toh(tx->ack_timeout),
159262423Sadrian	    le32toh(tx->exp_ack),
160262423Sadrian	    le32toh(tx->ack),
161262423Sadrian	    le32toh(tx->msdu));
162262423Sadrian
163262423Sadrian	printf("%s: burst_err1=%d, burst_err2=%d, cts_collision=%d, ack_collision=%d\n",
164262423Sadrian	    __func__,
165262423Sadrian	    le32toh(tx->burst_err1),
166262423Sadrian	    le32toh(tx->burst_err2),
167262423Sadrian	    le32toh(tx->cts_collision),
168262423Sadrian	    le32toh(tx->ack_collision));
169262423Sadrian
170262423Sadrian	printf("%s: ba_timeout=%d, ba_resched=%d, query_ampdu=%d, query=%d, query_ampdu_frag=%d\n",
171262423Sadrian	    __func__,
172262423Sadrian	    le32toh(tx->ba_timeout),
173262423Sadrian	    le32toh(tx->ba_resched),
174262423Sadrian	    le32toh(tx->query_ampdu),
175262423Sadrian	    le32toh(tx->query),
176262423Sadrian	    le32toh(tx->query_ampdu_frag));
177262423Sadrian
178262423Sadrian	printf("%s: query_mismatch=%d, not_ready=%d, underrun=%d, bt_ht_kill=%d, rx_ba_resp=%d\n",
179262423Sadrian	    __func__,
180262423Sadrian	    le32toh(tx->query_mismatch),
181262423Sadrian	    le32toh(tx->not_ready),
182262423Sadrian	    le32toh(tx->underrun),
183262423Sadrian	    le32toh(tx->bt_ht_kill),
184262423Sadrian	    le32toh(tx->rx_ba_resp));
185262423Sadrian}
186262423Sadrian
187262423Sadrianstatic void
188262423Sadrianiwn_stats_ht_phy_print(struct iwnstats *is, struct iwn_rx_ht_phy_stats *ht)
189262423Sadrian{
190262423Sadrian
191262423Sadrian	printf("%s: bad_plcp=%d, overrun=%d, eoverrun=%d, good_crc32=%d, bad_crc32=%d\n",
192262423Sadrian	    __func__,
193262423Sadrian	    le32toh(ht->bad_plcp),
194262423Sadrian	    le32toh(ht->overrun),
195262423Sadrian	    le32toh(ht->eoverrun),
196262423Sadrian	    le32toh(ht->good_crc32),
197262423Sadrian	    le32toh(ht->bad_crc32));
198262423Sadrian
199262423Sadrian	printf("%s: bad_mh=%d, good_ampdu_crc32=%d, ampdu=%d, fragment=%d\n",
200262423Sadrian	    __func__,
201262423Sadrian	    le32toh(ht->bad_plcp),
202262423Sadrian	    le32toh(ht->good_ampdu_crc32),
203262423Sadrian	    le32toh(ht->ampdu),
204262423Sadrian	    le32toh(ht->fragment));
205262423Sadrian}
206262423Sadrian
207262423Sadrian
208262423Sadrianstatic void
209262423Sadrianiwn_stats_general_print(struct iwnstats *is, struct iwn_stats *stats)
210262423Sadrian{
211262423Sadrian
212262423Sadrian	/* General */
213262423Sadrian	printf("%s: temp=%d, temp_m=%d, burst_check=%d, burst=%d, sleep=%d, slot_out=%d, slot_idle=%d\n",
214262423Sadrian	        __func__,
215262423Sadrian		le32toh(stats->general.temp),
216262423Sadrian		le32toh(stats->general.temp_m),
217262423Sadrian		le32toh(stats->general.burst_check),
218262423Sadrian		le32toh(stats->general.burst),
219262423Sadrian		le32toh(stats->general.sleep),
220262423Sadrian		le32toh(stats->general.slot_out),
221262423Sadrian		le32toh(stats->general.slot_idle));
222262423Sadrian	printf("%s: slot_out=%d, ttl_tstamp=0x%08x, tx_ant_a=%d, tx_ant_b=%d, exec=%d, probe=%d\n",
223262423Sadrian	        __func__,
224262423Sadrian		le32toh(stats->general.slot_out),
225262423Sadrian		le32toh(stats->general.ttl_tstamp),
226262423Sadrian		le32toh(stats->general.tx_ant_a),
227262423Sadrian		le32toh(stats->general.tx_ant_b),
228262423Sadrian		le32toh(stats->general.exec),
229262423Sadrian		le32toh(stats->general.probe));
230262423Sadrian	printf("%s: rx_enabled=%d\n",
231262423Sadrian	        __func__,
232262423Sadrian		le32toh(stats->general.rx_enabled));
233262423Sadrian}
234262423Sadrian
235262423Sadrianstatic void
236262423Sadrianiwn_print(struct iwnstats *is)
237262423Sadrian{
238262423Sadrian	struct iwn_stats *s;
239262423Sadrian
240262423Sadrian	s = &is->st;
241262423Sadrian
242262423Sadrian	iwn_stats_general_print(is, s);
243262423Sadrian
244262423Sadrian	/* RX */
245262423Sadrian	iwn_stats_phy_print(is, &s->rx.ofdm, "ofdm");
246262423Sadrian	iwn_stats_phy_print(is, &s->rx.cck, "cck");
247262423Sadrian	iwn_stats_ht_phy_print(is, &s->rx.ht);
248262423Sadrian	iwn_stats_rx_general_print(is, &s->rx.general);
249262423Sadrian
250262423Sadrian	/* TX */
251262423Sadrian	iwn_stats_tx_print(is, &s->tx);
252262423Sadrian	printf("--\n");
253262423Sadrian}
254262423Sadrian
255262423Sadrianint
256262423Sadrianmain(int argc, const char *argv[])
257262423Sadrian{
258262423Sadrian	struct iwnstats *is;
259262423Sadrian
260262423Sadrian	is = iwnstats_new(IWN_DEFAULT_IF);
261262423Sadrian
262262423Sadrian	if (is == NULL) {
263262423Sadrian		fprintf(stderr, "%s: couldn't allocate new stats structure\n",
264262423Sadrian		    argv[0]);
265262423Sadrian		exit(127);
266262423Sadrian	}
267262423Sadrian
268262423Sadrian	/* begin fetching data */
269262423Sadrian	while (1) {
270262423Sadrian		if (iwn_collect(is) != 0) {
271262423Sadrian			fprintf(stderr, "%s: fetch failed\n", argv[0]);
272262423Sadrian			goto next;
273262423Sadrian		}
274262423Sadrian
275262423Sadrian		iwn_print(is);
276262423Sadrian
277262423Sadrian	next:
278262423Sadrian		usleep(100 * 1000);
279262423Sadrian	}
280262423Sadrian
281262423Sadrian	exit(0);
282262423Sadrian}
283