]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/tools/iwn/iwnstats/main.c
Update to Zstandard 1.3.8
[FreeBSD/FreeBSD.git] / tools / tools / iwn / iwnstats / main.c
1 /*-
2  * Copyright (c) 2014 Adrian Chadd <adrian@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer,
10  *    without modification.
11  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13  *    redistribution must be conditioned upon including a substantially
14  *    similar Disclaimer requirement for further binary redistribution.
15  *
16  * NO WARRANTY
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27  * THE POSSIBILITY OF SUCH DAMAGES.
28  *
29  * $FreeBSD$
30  */
31
32 #include <stdbool.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <signal.h>
36 #include <fcntl.h>
37 #include <unistd.h>
38 #include <string.h>
39 #include <err.h>
40 #include <net/if.h>
41 #include <sys/endian.h>
42 #include <sys/time.h>
43 #include <sys/types.h>
44 #include <sys/sysctl.h>
45
46 #include "net80211/ieee80211_ioctl.h"
47 #include "net80211/ieee80211_radiotap.h"
48
49 #include "if_iwn_ioctl.h"
50 #include "if_iwnreg.h"
51 #include "iwnstats.h"
52 #include "iwn_ioctl.h"
53
54 #define IWN_DEFAULT_IF          "iwn0"
55
56 static struct iwnstats *
57 iwnstats_new(const char *ifname)
58 {
59         struct iwnstats *is;
60         char buf[128];
61
62         is = calloc(1, sizeof(struct iwnstats));
63         if (is == NULL)
64                 return (NULL);
65
66         snprintf(buf, sizeof(buf), "/dev/%s", ifname);
67         is->s = open(buf, O_RDWR);
68         if (is->s < 0)
69                 err(1, "open");
70
71         return (is);
72 }
73
74 static void
75 iwn_stats_phy_print(struct iwnstats *is, struct iwn_rx_phy_stats *rxphy,
76     const char *prefix)
77 {
78
79         printf("%s: %s: ina=%d, fina=%d, bad_plcp=%d, bad_crc32=%d, overrun=%d, eoverrun=%d\n",
80                 __func__,
81                 prefix,
82                 le32toh(rxphy->ina),
83                 le32toh(rxphy->fina),
84                 le32toh(rxphy->bad_plcp),
85                 le32toh(rxphy->bad_crc32),
86                 le32toh(rxphy->overrun),
87                 le32toh(rxphy->eoverrun));
88
89         printf("%s: %s: fa=%d, bad_fina_sync=%d, sfd_timeout=%d, fina_timeout=%d, no_rts_ack=%d\n",
90                 __func__,
91                 prefix,
92                 le32toh(rxphy->fa),
93                 le32toh(rxphy->bad_fina_sync),
94                 le32toh(rxphy->sfd_timeout),
95                 le32toh(rxphy->fina_timeout),
96                 le32toh(rxphy->no_rts_ack));
97
98         printf("%s: %s: rxe_limit=%d, ack=%d, cts=%d, ba_resp=%d, dsp_kill=%d, bad_mh=%d, rssi_sum=%d\n",
99                 __func__,
100                 prefix,
101                 le32toh(rxphy->rxe_limit),
102                 le32toh(rxphy->ack),
103                 le32toh(rxphy->cts),
104                 le32toh(rxphy->ba_resp),
105                 le32toh(rxphy->dsp_kill),
106                 le32toh(rxphy->bad_mh),
107                 le32toh(rxphy->rssi_sum));
108 }
109
110 static void
111 iwn_stats_rx_general_print(struct iwnstats *is, struct iwn_rx_general_stats *g)
112 {
113
114         printf("%s: bad_cts=%d, bad_ack=%d, not_bss=%d, filtered=%d, bad_chan=%d, beacons=%d\n",
115             __func__,
116             le32toh(g->bad_cts),
117             le32toh(g->bad_ack),
118             le32toh(g->not_bss),
119             le32toh(g->filtered),
120             le32toh(g->bad_chan),
121             le32toh(g->beacons));
122
123         /* XXX it'd be nice to have adc/ina saturated as a % of time */
124         printf("%s: missed_beacons=%d, adc_saturated=%d, ina_searched=%d\n",
125             __func__,
126             le32toh(g->missed_beacons),
127             le32toh(g->adc_saturated),
128             le32toh(g->ina_searched));
129
130         printf("%s: noise=[%d, %d, %d] flags=0x%08x, load=%d, fa=%d\n",
131             __func__,
132             le32toh(g->noise[0]),
133             le32toh(g->noise[1]),
134             le32toh(g->noise[2]),
135             le32toh(g->flags),
136             le32toh(g->load),
137             le32toh(g->fa));
138
139         printf("%s: rssi=[%d, %d, %d] energy=[%d %d %d]\n",
140             __func__,
141             le32toh(g->rssi[0]),
142             le32toh(g->rssi[1]),
143             le32toh(g->rssi[2]),
144             le32toh(g->energy[0]),
145             le32toh(g->energy[1]),
146             le32toh(g->energy[2]));
147 }
148
149 static void
150 iwn_stats_tx_print(struct iwnstats *is, struct iwn_tx_stats *tx)
151 {
152
153         printf("%s: preamble=%d, rx_detected=%d, bt_defer=%d, bt_kill=%d, short_len=%d\n",
154             __func__,
155             le32toh(tx->preamble),
156             le32toh(tx->rx_detected),
157             le32toh(tx->bt_defer),
158             le32toh(tx->bt_kill),
159             le32toh(tx->short_len));
160
161         printf("%s: cts_timeout=%d, ack_timeout=%d, exp_ack=%d, ack=%d, msdu=%d\n",
162             __func__,
163             le32toh(tx->cts_timeout),
164             le32toh(tx->ack_timeout),
165             le32toh(tx->exp_ack),
166             le32toh(tx->ack),
167             le32toh(tx->msdu));
168
169         printf("%s: burst_err1=%d, burst_err2=%d, cts_collision=%d, ack_collision=%d\n",
170             __func__,
171             le32toh(tx->burst_err1),
172             le32toh(tx->burst_err2),
173             le32toh(tx->cts_collision),
174             le32toh(tx->ack_collision));
175
176         printf("%s: ba_timeout=%d, ba_resched=%d, query_ampdu=%d, query=%d, query_ampdu_frag=%d\n",
177             __func__,
178             le32toh(tx->ba_timeout),
179             le32toh(tx->ba_resched),
180             le32toh(tx->query_ampdu),
181             le32toh(tx->query),
182             le32toh(tx->query_ampdu_frag));
183
184         printf("%s: query_mismatch=%d, not_ready=%d, underrun=%d, bt_ht_kill=%d, rx_ba_resp=%d\n",
185             __func__,
186             le32toh(tx->query_mismatch),
187             le32toh(tx->not_ready),
188             le32toh(tx->underrun),
189             le32toh(tx->bt_ht_kill),
190             le32toh(tx->rx_ba_resp));
191 }
192
193 static void
194 iwn_stats_ht_phy_print(struct iwnstats *is, struct iwn_rx_ht_phy_stats *ht)
195 {
196
197         printf("%s: bad_plcp=%d, overrun=%d, eoverrun=%d, good_crc32=%d, bad_crc32=%d\n",
198             __func__,
199             le32toh(ht->bad_plcp),
200             le32toh(ht->overrun),
201             le32toh(ht->eoverrun),
202             le32toh(ht->good_crc32),
203             le32toh(ht->bad_crc32));
204
205         printf("%s: bad_mh=%d, good_ampdu_crc32=%d, ampdu=%d, fragment=%d\n",
206             __func__,
207             le32toh(ht->bad_plcp),
208             le32toh(ht->good_ampdu_crc32),
209             le32toh(ht->ampdu),
210             le32toh(ht->fragment));
211 }
212
213
214 static void
215 iwn_stats_general_print(struct iwnstats *is, struct iwn_stats *stats)
216 {
217
218         /* General */
219         printf("%s: temp=%d, temp_m=%d, burst_check=%d, burst=%d, sleep=%d, slot_out=%d, slot_idle=%d\n",
220                 __func__,
221                 le32toh(stats->general.temp),
222                 le32toh(stats->general.temp_m),
223                 le32toh(stats->general.burst_check),
224                 le32toh(stats->general.burst),
225                 le32toh(stats->general.sleep),
226                 le32toh(stats->general.slot_out),
227                 le32toh(stats->general.slot_idle));
228         printf("%s: slot_out=%d, ttl_tstamp=0x%08x, tx_ant_a=%d, tx_ant_b=%d, exec=%d, probe=%d\n",
229                 __func__,
230                 le32toh(stats->general.slot_out),
231                 le32toh(stats->general.ttl_tstamp),
232                 le32toh(stats->general.tx_ant_a),
233                 le32toh(stats->general.tx_ant_b),
234                 le32toh(stats->general.exec),
235                 le32toh(stats->general.probe));
236         printf("%s: rx_enabled=%d\n",
237                 __func__,
238                 le32toh(stats->general.rx_enabled));
239 }
240
241 static void
242 iwn_print(struct iwnstats *is)
243 {
244         struct iwn_stats *s;
245         struct timeval tv;
246
247         s = &is->st;
248
249         gettimeofday(&tv, NULL);
250         printf("time=%ld.%.6ld\n", (long)tv.tv_sec, (long)tv.tv_usec);
251
252         iwn_stats_general_print(is, s);
253
254         /* RX */
255         iwn_stats_phy_print(is, &s->rx.ofdm, "ofdm");
256         iwn_stats_phy_print(is, &s->rx.cck, "cck");
257         iwn_stats_ht_phy_print(is, &s->rx.ht);
258         iwn_stats_rx_general_print(is, &s->rx.general);
259
260         /* TX */
261         iwn_stats_tx_print(is, &s->tx);
262         printf("--\n");
263 }
264
265 static void
266 usage(void)
267 {
268         printf("Usage: iwnstats [-h] [-i ifname]\n");
269         printf("    -h:                 Help\n");
270         printf("    -i <ifname>:        Use ifname (default %s)\n",
271             IWN_DEFAULT_IF);
272 }
273
274 int
275 main(int argc, char *argv[])
276 {
277         struct iwnstats *is;
278         int ch;
279         char *ifname;
280         bool first;
281         char *sysctlname;
282         size_t len;
283         int ret;
284
285         ifname = strdup(IWN_DEFAULT_IF);
286
287         /* Parse command line arguments */
288         while ((ch = getopt(argc, argv,
289             "hi:")) != -1) {
290                 switch (ch) {
291                 case 'i':
292                         if (ifname)
293                                 free(ifname);
294                         ifname = strdup(optarg);
295                         break;
296                 default:
297                 case '?':
298                 case 'h':
299                         usage();
300                         exit(1);
301                 }
302         }
303
304         is = iwnstats_new(ifname);
305
306         if (is == NULL) {
307                 fprintf(stderr, "%s: couldn't allocate new stats structure\n",
308                     argv[0]);
309                 exit(127);
310         }
311
312         /* begin fetching data */
313         first = true;
314         while (1) {
315                 if (iwn_collect(is) != 0) {
316                         fprintf(stderr, "%s: fetch failed\n", argv[0]);
317                         if (first)
318                                 return 1;
319                         goto next;
320                 }
321
322                 iwn_print(is);
323
324         next:
325                 usleep(100 * 1000);
326                 first = false;
327         }
328
329         exit(0);
330 }