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