Index: head/tools/tools/ath/athaggrstats/main.c =================================================================== --- head/tools/tools/ath/athaggrstats/main.c (revision 295362) +++ head/tools/tools/ath/athaggrstats/main.c (revision 295363) @@ -1,159 +1,159 @@ /*- * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting * 2012, Adrian Chadd * 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$ */ /* * Simple Atheros-specific tool to inspect and monitor software queue * and aggregate statistics. * * athaggrstats [-i interface] [-bz] [-l] [-o fmtstring] [interval] * * (default interface is ath0). If interval is specified a rolling output * a la netstat -i is displayed every interval seconds. The format of * the rolling display can be controlled a la ps. The -l option will * print a list of all possible statistics for use with the -o option. */ #include #include #include #include #include #include #include #include "athaggrstats.h" static struct { const char *tag; const char *fmt; } tags[] = { { "default", "singlepkt,nonbawpkt,aggrpkt,bawclosedpkt,lhsinglepkt,schednopkt,rtsaggrlimit" }, }; static const char * getfmt(const char *tag) { int i; for (i = 0; i < nitems(tags); i++) if (strcasecmp(tags[i].tag, tag) == 0) return tags[i].fmt; return tag; } static int signalled; static void catchalarm(int signo __unused) { signalled = 1; } int main(int argc, char *argv[]) { struct athaggrstatfoo *wf; const char *ifname; int c, banner = 1; ifname = getenv("ATH"); if (ifname == NULL) - ifname = "ath0"; + ifname = ATH_DEFAULT; wf = athaggrstats_new(ifname, getfmt("default")); while ((c = getopt(argc, argv, "bi:lo:z")) != -1) { switch (c) { case 'b': banner = 0; break; case 'i': wf->setifname(wf, optarg); break; case 'l': wf->print_fields(wf, stdout); return 0; case 'o': wf->setfmt(wf, getfmt(optarg)); break; case 'z': wf->zerostats(wf); break; default: errx(-1, "usage: %s [-a] [-i ifname] [-l] [-o fmt] [-z] [interval]\n", argv[0]); /*NOTREACHED*/ } } argc -= optind; argv += optind; if (argc > 0) { u_long interval = strtoul(argv[0], NULL, 0); int line, omask; if (interval < 1) interval = 1; signal(SIGALRM, catchalarm); signalled = 0; alarm(interval); banner: if (banner) wf->print_header(wf, stdout); line = 0; loop: if (line != 0) { wf->collect_cur(wf); wf->print_current(wf, stdout); wf->update_tot(wf); } else { wf->collect_tot(wf); wf->print_total(wf, stdout); } fflush(stdout); omask = sigblock(sigmask(SIGALRM)); if (!signalled) sigpause(0); sigsetmask(omask); signalled = 0; alarm(interval); line++; if (line == 21) /* XXX tty line count */ goto banner; else goto loop; /*NOTREACHED*/ } else { wf->collect_tot(wf); wf->print_verbose(wf, stdout); } return 0; } Index: head/tools/tools/ath/athdebug/athdebug.c =================================================================== --- head/tools/tools/ath/athdebug/athdebug.c (revision 295362) +++ head/tools/tools/ath/athdebug/athdebug.c (revision 295363) @@ -1,230 +1,230 @@ /*- * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting * 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$ */ /* * athdebug [-i interface] flags - * (default interface is ath0). + * (default interface is wlan0). */ #include #include #include #include #include #include #include #include #include #include #include #include const char *progname; /* XXX TODO: include if_ath_debug.h */ enum { ATH_DEBUG_XMIT = 0x00000001, /* basic xmit operation */ ATH_DEBUG_XMIT_DESC = 0x00000002, /* xmit descriptors */ ATH_DEBUG_RECV = 0x00000004, /* basic recv operation */ ATH_DEBUG_RECV_DESC = 0x00000008, /* recv descriptors */ ATH_DEBUG_RATE = 0x00000010, /* rate control */ ATH_DEBUG_RESET = 0x00000020, /* reset processing */ ATH_DEBUG_MODE = 0x00000040, /* mode init/setup */ ATH_DEBUG_BEACON = 0x00000080, /* beacon handling */ ATH_DEBUG_WATCHDOG = 0x00000100, /* watchdog timeout */ ATH_DEBUG_INTR = 0x00001000, /* ISR */ ATH_DEBUG_TX_PROC = 0x00002000, /* tx ISR proc */ ATH_DEBUG_RX_PROC = 0x00004000, /* rx ISR proc */ ATH_DEBUG_BEACON_PROC = 0x00008000, /* beacon ISR proc */ ATH_DEBUG_CALIBRATE = 0x00010000, /* periodic calibration */ ATH_DEBUG_KEYCACHE = 0x00020000, /* key cache management */ ATH_DEBUG_STATE = 0x00040000, /* 802.11 state transitions */ ATH_DEBUG_NODE = 0x00080000, /* node management */ ATH_DEBUG_LED = 0x00100000, /* led management */ ATH_DEBUG_FF = 0x00200000, /* fast frames */ ATH_DEBUG_DFS = 0x00400000, /* DFS processing */ ATH_DEBUG_TDMA = 0x00800000, /* TDMA processing */ ATH_DEBUG_TDMA_TIMER = 0x01000000, /* TDMA timer processing */ ATH_DEBUG_REGDOMAIN = 0x02000000, /* regulatory processing */ ATH_DEBUG_FATAL = 0x80000000, /* fatal errors */ ATH_DEBUG_ANY = 0xffffffff }; static struct { const char *name; uint64_t bit; } flags[] = { { "xmit", ATH_DEBUG_XMIT }, { "xmit_desc", ATH_DEBUG_XMIT_DESC }, { "recv", ATH_DEBUG_RECV }, { "recv_desc", ATH_DEBUG_RECV_DESC }, { "rate", ATH_DEBUG_RATE }, { "reset", ATH_DEBUG_RESET }, { "mode", ATH_DEBUG_MODE }, { "beacon", ATH_DEBUG_BEACON }, { "watchdog", ATH_DEBUG_WATCHDOG }, { "intr", ATH_DEBUG_INTR }, { "xmit_proc", ATH_DEBUG_TX_PROC }, { "recv_proc", ATH_DEBUG_RX_PROC }, { "beacon_proc",ATH_DEBUG_BEACON_PROC }, { "calibrate", ATH_DEBUG_CALIBRATE }, { "keycache", ATH_DEBUG_KEYCACHE }, { "state", ATH_DEBUG_STATE }, { "node", ATH_DEBUG_NODE }, { "led", ATH_DEBUG_LED }, { "ff", ATH_DEBUG_FF }, { "dfs", ATH_DEBUG_DFS }, { "tdma", ATH_DEBUG_TDMA }, { "tdma_timer", ATH_DEBUG_TDMA_TIMER }, { "regdomain", ATH_DEBUG_REGDOMAIN }, { "fatal", ATH_DEBUG_FATAL }, }; static uint64_t getflag(const char *name, int len) { int i; for (i = 0; i < nitems(flags); i++) if (strncasecmp(flags[i].name, name, len) == 0) return flags[i].bit; return 0; } static const char * getflagname(u_int flag) { int i; for (i = 0; i < nitems(flags); i++) if (flags[i].bit == flag) return flags[i].name; return "???"; } static void usage(void) { int i; fprintf(stderr, "usage: %s [-i device] [flags]\n", progname); fprintf(stderr, "where flags are:\n"); for (i = 0; i < nitems(flags); i++) printf("%s\n", flags[i].name); exit(-1); } int main(int argc, char *argv[]) { const char *ifname; const char *cp, *tp; const char *sep; int c, op, i; uint64_t debug, ndebug; size_t debuglen; char oid[256]; ifname = getenv("ATH"); if (ifname == NULL) - ifname = "ath0"; + ifname = ATH_DEFAULT; progname = argv[0]; if (argc > 1) { if (strcmp(argv[1], "-i") == 0) { if (argc < 2) errx(1, "missing interface name for -i option"); ifname = argv[2]; if (strncmp(ifname, "ath", 3) != 0) errx(2, "huh, this is for ath devices?"); argc -= 2, argv += 2; } else if (strcmp(argv[1], "-?") == 0) usage(); } #ifdef __linux__ snprintf(oid, sizeof(oid), "dev.%s.debug", ifname); #else snprintf(oid, sizeof(oid), "dev.ath.%s.debug", ifname+3); #endif debuglen = sizeof(debug); if (sysctlbyname(oid, &debug, &debuglen, NULL, 0) < 0) err(1, "sysctl-get(%s)", oid); ndebug = debug; for (; argc > 1; argc--, argv++) { cp = argv[1]; do { u_int bit; if (*cp == '-') { cp++; op = -1; } else if (*cp == '+') { cp++; op = 1; } else op = 0; for (tp = cp; *tp != '\0' && *tp != '+' && *tp != '-';) tp++; bit = getflag(cp, tp-cp); if (op < 0) ndebug &= ~bit; else if (op > 0) ndebug |= bit; else { if (bit == 0) { if (isdigit(*cp)) bit = strtoul(cp, NULL, 0); else errx(1, "unknown flag %.*s", (int) (tp-cp), cp); } ndebug = bit; } } while (*(cp = tp) != '\0'); } if (debug != ndebug) { printf("%s: 0x%llx => ", oid, (long long) debug); if (sysctlbyname(oid, NULL, NULL, &ndebug, sizeof(ndebug)) < 0) err(1, "sysctl-set(%s)", oid); printf("0x%llx", (long long) ndebug); debug = ndebug; } else printf("%s: 0x%llx", oid, (long long) debug); sep = "<"; for (i = 0; i < nitems(flags); i++) if (debug & flags[i].bit) { printf("%s%s", sep, flags[i].name); sep = ","; } printf("%s\n", *sep != '<' ? ">" : ""); return 0; } Index: head/tools/tools/ath/athradar/athradar.c =================================================================== --- head/tools/tools/ath/athradar/athradar.c (revision 295362) +++ head/tools/tools/ath/athradar/athradar.c (revision 295363) @@ -1,311 +1,307 @@ /* * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd. * * 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. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE. * * $FreeBSD$ */ #include "diag.h" #include "ah.h" #include "ah_internal.h" -#ifndef ATH_DEFAULT -#define ATH_DEFAULT "ath0" -#endif - #include #include #include #include #include #include #include struct radarhandler { struct ath_diag atd; int s; struct ifreq ifr; int ah_devid; }; int radar_opendev(struct radarhandler *radar, const char *devid) { HAL_REVS revs; radar->s = socket(AF_INET, SOCK_DGRAM, 0); if (radar->s < 0) { warn("socket"); return 0; } strncpy(radar->atd.ad_name, devid, sizeof (radar->atd.ad_name)); /* Get the hardware revision, just to verify things are working */ radar->atd.ad_id = HAL_DIAG_REVS; radar->atd.ad_out_data = (caddr_t) &revs; radar->atd.ad_out_size = sizeof(revs); if (ioctl(radar->s, SIOCGATHDIAG, &radar->atd) < 0) { warn(radar->atd.ad_name); return 0; } radar->ah_devid = revs.ah_devid; return 1; } void radar_closedev(struct radarhandler *radar) { close(radar->s); radar->s = -1; } void radarset(struct radarhandler *radar, int op, u_int32_t param) { HAL_PHYERR_PARAM pe; pe.pe_firpwr = HAL_PHYERR_PARAM_NOVAL; pe.pe_rrssi = HAL_PHYERR_PARAM_NOVAL; pe.pe_height = HAL_PHYERR_PARAM_NOVAL; pe.pe_prssi = HAL_PHYERR_PARAM_NOVAL; pe.pe_inband = HAL_PHYERR_PARAM_NOVAL; pe.pe_enabled = HAL_PHYERR_PARAM_NOVAL; pe.pe_relpwr = HAL_PHYERR_PARAM_NOVAL; pe.pe_relstep = HAL_PHYERR_PARAM_NOVAL; pe.pe_maxlen = HAL_PHYERR_PARAM_NOVAL; pe.pe_usefir128 = HAL_PHYERR_PARAM_NOVAL; pe.pe_blockradar = HAL_PHYERR_PARAM_NOVAL; pe.pe_enmaxrssi = HAL_PHYERR_PARAM_NOVAL; pe.pe_extchannel = HAL_PHYERR_PARAM_NOVAL; pe.pe_enrelpwr = HAL_PHYERR_PARAM_NOVAL; pe.pe_en_relstep_check = HAL_PHYERR_PARAM_NOVAL; switch (op) { case DFS_PARAM_ENABLE: pe.pe_enabled = param; break; case DFS_PARAM_FIRPWR: pe.pe_firpwr = param; break; case DFS_PARAM_RRSSI: pe.pe_rrssi = param; break; case DFS_PARAM_HEIGHT: pe.pe_height = param; break; case DFS_PARAM_PRSSI: pe.pe_prssi = param; break; case DFS_PARAM_INBAND: pe.pe_inband = param; break; case DFS_PARAM_RELPWR: pe.pe_relpwr = param; break; case DFS_PARAM_RELSTEP: pe.pe_relstep = param; break; case DFS_PARAM_MAXLEN: pe.pe_maxlen = param; break; case DFS_PARAM_USEFIR128: pe.pe_usefir128 = param; break; case DFS_PARAM_BLOCKRADAR: pe.pe_blockradar = param; break; case DFS_PARAM_MAXRSSI_EN: pe.pe_enmaxrssi = param; break; case DFS_PARAM_EN_EXTCH: pe.pe_extchannel = param; break; case DFS_PARAM_RELPWR_EN: pe.pe_enrelpwr = param; break; case DFS_PARAM_RELSTEP_EN: pe.pe_en_relstep_check = param; break; } radar->atd.ad_id = DFS_SET_THRESH | ATH_DIAG_IN; radar->atd.ad_out_data = NULL; radar->atd.ad_out_size = 0; radar->atd.ad_in_data = (caddr_t) &pe; radar->atd.ad_in_size = sizeof(HAL_PHYERR_PARAM); if (ioctl(radar->s, SIOCGATHPHYERR, &radar->atd) < 0) err(1, radar->atd.ad_name); } static void radar_get(struct radarhandler *radar) { HAL_PHYERR_PARAM pe; radar->atd.ad_id = DFS_GET_THRESH | ATH_DIAG_DYN; memset(&pe, 0, sizeof(pe)); radar->atd.ad_in_data = NULL; radar->atd.ad_in_size = 0; radar->atd.ad_out_data = (caddr_t) &pe; radar->atd.ad_out_size = sizeof(pe); if (ioctl(radar->s, SIOCGATHPHYERR, &radar->atd) < 0) err(1, radar->atd.ad_name); printf("Radar parameters (raw):\n"); printf(" pe_enabled: %d\n", pe.pe_enabled); printf(" pe_firpwr: %d\n", pe.pe_firpwr); printf(" pe_rrssi: %d\n", pe.pe_rrssi); printf(" pe_height: %d\n", pe.pe_height); printf(" pe_prssi: %d\n", pe.pe_prssi); printf(" pe_inband: %d\n", pe.pe_inband); printf(" pe_relpwr: %d\n", pe.pe_relpwr); printf(" pe_relstep: %d\n", pe.pe_relstep); printf(" pe_maxlen: %d\n", pe.pe_maxlen); printf(" pe_usefir128: %d\n", pe.pe_usefir128); printf(" pe_blockradar: %d\n", pe.pe_blockradar); printf(" pe_enmaxrssi: %d\n", pe.pe_enmaxrssi); printf(" pe_extchannel: %d\n", pe.pe_extchannel); printf(" pe_enrelpwr: %d\n", pe.pe_enrelpwr); printf(" pe_en_relstep_check: %d\n", pe.pe_en_relstep_check); } static int radar_set_param(struct radarhandler *radar, const char *param, const char *val) { int v; v = atoi(val); if (strcmp(param, "enabled") == 0) { radarset(radar, DFS_PARAM_ENABLE, v); } else if (strcmp(param, "firpwr") == 0) { radarset(radar, DFS_PARAM_FIRPWR, v); } else if (strcmp(param, "rrssi") == 0) { radarset(radar, DFS_PARAM_RRSSI, v); } else if (strcmp(param, "height") == 0) { radarset(radar, DFS_PARAM_HEIGHT, v); } else if (strcmp(param, "prssi") == 0) { radarset(radar, DFS_PARAM_PRSSI, v); } else if (strcmp(param, "inband") == 0) { radarset(radar, DFS_PARAM_INBAND, v); } else if (strcmp(param, "relpwr") == 0) { radarset(radar, DFS_PARAM_RELPWR, v); } else if (strcmp(param, "relstep") == 0) { radarset(radar, DFS_PARAM_RELSTEP, v); } else if (strcmp(param, "maxlen") == 0) { radarset(radar, DFS_PARAM_MAXLEN, v); } else if (strcmp(param, "usefir128") == 0) { radarset(radar, DFS_PARAM_USEFIR128, v); } else if (strcmp(param, "blockradar") == 0) { radarset(radar, DFS_PARAM_BLOCKRADAR, v); } else if (strcmp(param, "enmaxrssi") == 0) { radarset(radar, DFS_PARAM_MAXRSSI_EN, v); } else if (strcmp(param, "extchannel") == 0) { radarset(radar, DFS_PARAM_EN_EXTCH, v); } else if (strcmp(param, "enrelpwr") == 0) { radarset(radar, DFS_PARAM_RELPWR_EN, v); } else if (strcmp(param, "en_relstep_check") == 0) { radarset(radar, DFS_PARAM_RELSTEP_EN, v); } else { return 0; } return 1; } void usage(const char *progname) { printf("Usage:\n"); printf("\t%s: [-i ] ()\n", progname); printf("\t%s: [-h]\n", progname); printf("\n"); printf("Valid commands:\n"); printf("\tget:\t\tGet current radar parameters\n"); printf("\tset :\t\tSet radar parameter\n"); } int main(int argc, char *argv[]) { struct radarhandler radar; const char *devname = ATH_DEFAULT; const char *progname = argv[0]; memset(&radar, 0, sizeof(radar)); /* Parse command line options */ if (argc >= 2 && strcmp(argv[1], "-h") == 0) { usage(progname); exit(0); } if (argc >= 2 && strcmp(argv[1], "-?") == 0) { usage(progname); exit(0); } if (argc >= 2 && strcmp(argv[1], "-i") == 0) { if (argc == 2) { usage(progname); exit(127); } devname = argv[2]; argc -= 2; argv += 2; } /* At this point we require at least one command */ if (argc == 1) { usage(progname); exit(127); } if (radar_opendev(&radar, devname) == 0) exit(127); if (strcasecmp(argv[1], "get") == 0) { radar_get(&radar); } else if (strcasecmp(argv[1], "set") == 0) { if (argc < 4) { usage(progname); exit(127); } if (radar_set_param(&radar, argv[2], argv[3]) == 0) { usage(progname); exit(127); } } else { usage(progname); exit(127); } /* wrap up */ radar_closedev(&radar); exit(0); } Index: head/tools/tools/ath/athratestats/main.c =================================================================== --- head/tools/tools/ath/athratestats/main.c (revision 295362) +++ head/tools/tools/ath/athratestats/main.c (revision 295363) @@ -1,401 +1,401 @@ /*- * Copyright (c) 2012, Adrian Chadd. * 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 "opt_ah.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ah.h" #include "ah_desc.h" #include "net80211/ieee80211_ioctl.h" #include "net80211/ieee80211_radiotap.h" #include "if_athioctl.h" #include "if_athrate.h" #include "ath_rate/sample/sample.h" static int do_loop = 0; /* * This needs to be big enough to fit the two TLVs, the rate table * and the rate statistics table for a single node. */ #define STATS_BUF_SIZE 8192 #define PRINTMSG(...) do { \ if (do_loop == 0) \ printf(__VA_ARGS__); \ else \ printw(__VA_ARGS__); \ } while (0) #define PRINTATTR_ON(_x) do { \ if (do_loop) \ attron(_x); \ } while(0) #define PRINTATTR_OFF(_x) do { \ if (do_loop) \ attroff(_x); \ } while(0) struct ath_ratestats { int s; struct ath_rateioctl re; }; static inline int dot11rate(struct ath_rateioctl_rt *rt, int rix) { if (rt->ratecode[rix] & IEEE80211_RATE_MCS) return rt->ratecode[rix] & ~(IEEE80211_RATE_MCS); else return (rt->ratecode[rix] / 2); } static const char * dot11str(struct ath_rateioctl_rt *rt, int rix) { if (rix == -1) return ""; else if (rt->ratecode[rix] & IEEE80211_RATE_MCS) return "MCS"; else return " Mb"; } static void ath_sample_stats(struct ath_ratestats *r, struct ath_rateioctl_rt *rt, struct sample_node *sn) { uint64_t mask; int rix, y; PRINTMSG("static_rix (%d) ratemask 0x%llx\n", sn->static_rix, (long long) sn->ratemask); for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) { PRINTATTR_ON(COLOR_PAIR(y+4) | A_BOLD); PRINTMSG("[%4u] cur rate %d %s since switch: " "packets %d ticks %u\n", bin_to_size(y), dot11rate(rt, sn->current_rix[y]), dot11str(rt, sn->current_rix[y]), sn->packets_since_switch[y], sn->ticks_since_switch[y]); PRINTMSG("[%4u] last sample (%d %s) cur sample (%d %s) " "packets sent %d\n", bin_to_size(y), dot11rate(rt, sn->last_sample_rix[y]), dot11str(rt, sn->last_sample_rix[y]), dot11rate(rt, sn->current_sample_rix[y]), dot11str(rt, sn->current_sample_rix[y]), sn->packets_sent[y]); PRINTATTR_OFF(COLOR_PAIR(y+4) | A_BOLD); PRINTATTR_ON(COLOR_PAIR(3) | A_BOLD); PRINTMSG("[%4u] packets since sample %d sample tt %u\n", bin_to_size(y), sn->packets_since_sample[y], sn->sample_tt[y]); PRINTATTR_OFF(COLOR_PAIR(3) | A_BOLD); PRINTMSG("\n"); } PRINTMSG(" TX Rate TXTOTAL:TXOK EWMA T/ F" " avg last xmit\n"); for (mask = sn->ratemask, rix = 0; mask != 0; mask >>= 1, rix++) { if ((mask & 1) == 0) continue; for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) { if (sn->stats[y][rix].total_packets == 0) continue; if (rix == sn->current_rix[y]) PRINTATTR_ON(COLOR_PAIR(y+4) | A_BOLD); else if (rix == sn->last_sample_rix[y]) PRINTATTR_ON(COLOR_PAIR(3) | A_BOLD); #if 0 else if (sn->stats[y][rix].ewma_pct / 10 < 50) PRINTATTR_ON(COLOR_PAIR(2) | A_BOLD); else if (sn->stats[y][rix].ewma_pct / 10 < 75) PRINTATTR_ON(COLOR_PAIR(1) | A_BOLD); #endif PRINTMSG("[%2u %s:%4u] %8ju:%-8ju " "(%3d.%1d%%) %8ju/%4d %5uuS %u\n", dot11rate(rt, rix), dot11str(rt, rix), bin_to_size(y), (uintmax_t) sn->stats[y][rix].total_packets, (uintmax_t) sn->stats[y][rix].packets_acked, sn->stats[y][rix].ewma_pct / 10, sn->stats[y][rix].ewma_pct % 10, (uintmax_t) sn->stats[y][rix].tries, sn->stats[y][rix].successive_failures, sn->stats[y][rix].average_tx_time, sn->stats[y][rix].last_tx); if (rix == sn->current_rix[y]) PRINTATTR_OFF(COLOR_PAIR(y+4) | A_BOLD); else if (rix == sn->last_sample_rix[y]) PRINTATTR_OFF(COLOR_PAIR(3) | A_BOLD); #if 0 else if (sn->stats[y][rix].ewma_pct / 10 < 50) PRINTATTR_OFF(COLOR_PAIR(2) | A_BOLD); else if (sn->stats[y][rix].ewma_pct / 10 < 75) PRINTATTR_OFF(COLOR_PAIR(1) | A_BOLD); #endif } } } static void ath_setifname(struct ath_ratestats *r, const char *ifname) { strncpy(r->re.if_name, ifname, sizeof (r->re.if_name)); } static void ath_setsta(struct ath_ratestats *r, uint8_t *mac) { memcpy(&r->re.is_u.macaddr, mac, sizeof(r->re.is_u.macaddr)); } static void ath_rate_ioctl(struct ath_ratestats *r) { if (ioctl(r->s, SIOCGATHNODERATESTATS, &r->re) < 0) err(1, "ioctl"); } static int rate_node_stats(struct ath_ratestats *r, struct ether_addr *e) { struct ath_rateioctl_tlv *av; struct sample_node *sn = NULL; struct ath_rateioctl_rt *rt = NULL; int error = 0; uint8_t *buf = (uint8_t *) r->re.buf; /* * For now, hard-code the TLV order and contents. Ew! */ av = (struct ath_rateioctl_tlv *) buf; if (av->tlv_id != ATH_RATE_TLV_RATETABLE) { fprintf(stderr, "unexpected rate control TLV (got 0x%x, " "expected 0x%x\n", av->tlv_id, ATH_RATE_TLV_RATETABLE); exit(127); } if (av->tlv_len != sizeof(struct ath_rateioctl_rt)) { fprintf(stderr, "unexpected TLV len (got %d bytes, " "expected %d bytes\n", av->tlv_len, (int) sizeof(struct ath_rateioctl_rt)); exit(127); } rt = (void *) (buf + sizeof(struct ath_rateioctl_tlv)); /* Next */ av = (void *) (buf + sizeof(struct ath_rateioctl_tlv) + sizeof(struct ath_rateioctl_rt)); if (av->tlv_id != ATH_RATE_TLV_SAMPLENODE) { fprintf(stderr, "unexpected rate control TLV (got 0x%x, " "expected 0x%x\n", av->tlv_id, ATH_RATE_TLV_SAMPLENODE); exit(127); } if (av->tlv_len != sizeof(struct sample_node)) { fprintf(stderr, "unexpected TLV len (got %d bytes, " "expected %d bytes\n", av->tlv_len, (int) sizeof(struct sample_node)); exit(127); } sn = (void *) (buf + sizeof(struct ath_rateioctl_tlv) + sizeof(struct ath_rateioctl_rt) + sizeof(struct ath_rateioctl_tlv)); ath_sample_stats(r, rt, sn); return (0); } static void fetch_and_print_stats(struct ath_ratestats *r, struct ether_addr *e, uint8_t *buf) { /* Zero the buffer before it's passed in */ memset(buf, '\0', STATS_BUF_SIZE); /* * Set the station address for this lookup. */ ath_setsta(r, e->octet); /* * Fetch the data from the driver. */ ath_rate_ioctl(r); /* * Decode and parse statistics. */ rate_node_stats(r, e); } int main(int argc, char *argv[]) { char const *ifname = NULL, *macaddr = NULL; int c; int do_all = 0; struct ether_addr *e; struct ath_ratestats r; uint8_t *buf; useconds_t sleep_period; float f; short cf, cb; ifname = getenv("ATH"); if (ifname == NULL) - ifname = "ath0"; + ifname = ATH_DEFAULT; while ((c = getopt(argc, argv, "ahi:m:s:")) != -1) { switch (c) { case 'a': do_all = 1; break; case 'i': ifname = optarg; break; case 'm': macaddr = optarg; break; case 's': sscanf(optarg, "%f", &f); do_loop = 1; sleep_period = (useconds_t) (f * 1000000.0); break; default: errx(1, "usage: %s [-h] [-i ifname] [-a] [-m macaddr] [-s sleep period]\n", argv[0]); /* NOTREACHED */ } } if (macaddr == NULL) { errx(1, "%s: macaddress wasn't supplied and no -a given\n", argv[0]); /* NOTREACHED */ } e = ether_aton(macaddr); if (e == NULL) err(1, "ether_aton"); bzero(&r, sizeof(r)); /* * Persistent buffer for each lookup */ buf = malloc(STATS_BUF_SIZE); if (buf == NULL) err(1, "calloc"); r.re.buf = (char *) buf; r.re.len = STATS_BUF_SIZE; r.s = socket(AF_INET, SOCK_DGRAM, 0); if (r.s < 0) { err(1, "socket"); } /* XXX error check */ ath_setifname(&r, ifname); if (do_loop) { initscr(); start_color(); use_default_colors(); pair_content(0, &cf, &cb); /* Error - medium */ init_pair(1, COLOR_YELLOW, cb); /* Error - high */ init_pair(2, COLOR_RED, cb); /* Sample */ init_pair(3, COLOR_CYAN, cb); /* 250 byte frames */ init_pair(4, COLOR_BLUE, cb); /* 1600 byte frames */ init_pair(5, COLOR_MAGENTA, cb); cbreak(); noecho(); nonl(); nodelay(stdscr, 1); intrflush(stdscr, FALSE); keypad(stdscr, TRUE); while (1) { clear(); move(0, 0); fetch_and_print_stats(&r, e, buf); refresh(); usleep(sleep_period); } } else fetch_and_print_stats(&r, e, buf); exit(0); } Index: head/tools/tools/ath/athspectral/athspectral.c =================================================================== --- head/tools/tools/ath/athspectral/athspectral.c (revision 295362) +++ head/tools/tools/ath/athspectral/athspectral.c (revision 295363) @@ -1,353 +1,349 @@ /* * Copyright (c) 2013 Adrian Chadd * * 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. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE. * * $FreeBSD$ */ #include "diag.h" #include "ah.h" #include "ah_internal.h" -#ifndef ATH_DEFAULT -#define ATH_DEFAULT "ath0" -#endif - #include #include #include #include #include #include #include struct spectralhandler { struct ath_diag atd; int s; struct ifreq ifr; int ah_devid; }; int spectral_opendev(struct spectralhandler *spectral, const char *devid) { HAL_REVS revs; spectral->s = socket(AF_INET, SOCK_DGRAM, 0); if (spectral->s < 0) { warn("socket"); return 0; } strncpy(spectral->atd.ad_name, devid, sizeof (spectral->atd.ad_name)); /* Get the hardware revision, just to verify things are working */ spectral->atd.ad_id = HAL_DIAG_REVS; spectral->atd.ad_out_data = (caddr_t) &revs; spectral->atd.ad_out_size = sizeof(revs); if (ioctl(spectral->s, SIOCGATHDIAG, &spectral->atd) < 0) { warn("%s", spectral->atd.ad_name); return 0; } spectral->ah_devid = revs.ah_devid; return 1; } void spectral_closedev(struct spectralhandler *spectral) { close(spectral->s); spectral->s = -1; } void spectralset(struct spectralhandler *spectral, int op, u_int32_t param) { HAL_SPECTRAL_PARAM pe; pe.ss_fft_period = HAL_SPECTRAL_PARAM_NOVAL; pe.ss_period = HAL_SPECTRAL_PARAM_NOVAL; pe.ss_count = HAL_SPECTRAL_PARAM_NOVAL; pe.ss_short_report = HAL_SPECTRAL_PARAM_NOVAL; pe.ss_spectral_pri = HAL_SPECTRAL_PARAM_NOVAL; pe.ss_fft_period = HAL_SPECTRAL_PARAM_NOVAL; pe.ss_enabled = HAL_SPECTRAL_PARAM_NOVAL; pe.ss_active = HAL_SPECTRAL_PARAM_NOVAL; switch (op) { case SPECTRAL_PARAM_FFT_PERIOD: pe.ss_fft_period = param; break; case SPECTRAL_PARAM_SS_PERIOD: pe.ss_period = param; break; case SPECTRAL_PARAM_SS_COUNT: pe.ss_count = param; break; case SPECTRAL_PARAM_SS_SHORT_RPT: pe.ss_short_report = param; break; } spectral->atd.ad_id = SPECTRAL_CONTROL_SET_PARAMS | ATH_DIAG_IN; spectral->atd.ad_out_data = NULL; spectral->atd.ad_out_size = 0; spectral->atd.ad_in_data = (caddr_t) &pe; spectral->atd.ad_in_size = sizeof(HAL_SPECTRAL_PARAM); if (ioctl(spectral->s, SIOCGATHSPECTRAL, &spectral->atd) < 0) err(1, "%s", spectral->atd.ad_name); } static void spectral_get(struct spectralhandler *spectral) { HAL_SPECTRAL_PARAM pe; spectral->atd.ad_id = SPECTRAL_CONTROL_GET_PARAMS | ATH_DIAG_DYN; memset(&pe, 0, sizeof(pe)); spectral->atd.ad_in_data = NULL; spectral->atd.ad_in_size = 0; spectral->atd.ad_out_data = (caddr_t) &pe; spectral->atd.ad_out_size = sizeof(pe); if (ioctl(spectral->s, SIOCGATHSPECTRAL, &spectral->atd) < 0) err(1, "%s", spectral->atd.ad_name); printf("Spectral parameters (raw):\n"); printf(" ss_enabled: %d\n", pe.ss_enabled); printf(" ss_active: %d\n", pe.ss_active); printf(" ss_count: %d\n", pe.ss_count); printf(" ss_fft_period: %d\n", pe.ss_fft_period); printf(" ss_period: %d\n", pe.ss_period); printf(" ss_short_report: %d\n", pe.ss_short_report); printf(" radar_bin_thresh_sel: %d\n", pe.radar_bin_thresh_sel); } static void spectral_start(struct spectralhandler *spectral) { HAL_SPECTRAL_PARAM pe; spectral->atd.ad_id = SPECTRAL_CONTROL_START | ATH_DIAG_DYN; memset(&pe, 0, sizeof(pe)); /* * XXX don't need these, but need to eliminate the ATH_DIAG_DYN flag * and debug */ spectral->atd.ad_in_data = NULL; spectral->atd.ad_in_size = 0; spectral->atd.ad_out_data = (caddr_t) &pe; spectral->atd.ad_out_size = sizeof(pe); if (ioctl(spectral->s, SIOCGATHSPECTRAL, &spectral->atd) < 0) err(1, "%s", spectral->atd.ad_name); } static void spectral_stop(struct spectralhandler *spectral) { HAL_SPECTRAL_PARAM pe; spectral->atd.ad_id = SPECTRAL_CONTROL_STOP | ATH_DIAG_DYN; memset(&pe, 0, sizeof(pe)); /* * XXX don't need these, but need to eliminate the ATH_DIAG_DYN flag * and debug */ spectral->atd.ad_in_data = NULL; spectral->atd.ad_in_size = 0; spectral->atd.ad_out_data = (caddr_t) &pe; spectral->atd.ad_out_size = sizeof(pe); if (ioctl(spectral->s, SIOCGATHSPECTRAL, &spectral->atd) < 0) err(1, "%s", spectral->atd.ad_name); } static void spectral_enable_at_reset(struct spectralhandler *spectral, int val) { int v = val; spectral->atd.ad_id = SPECTRAL_CONTROL_ENABLE_AT_RESET | ATH_DIAG_IN; /* * XXX don't need these, but need to eliminate the ATH_DIAG_DYN flag * and debug */ spectral->atd.ad_out_data = NULL; spectral->atd.ad_out_size = 0; spectral->atd.ad_in_data = (caddr_t) &v; spectral->atd.ad_in_size = sizeof(v); printf("%s: val=%d\n", __func__, v); if (ioctl(spectral->s, SIOCGATHSPECTRAL, &spectral->atd) < 0) err(1, "%s", spectral->atd.ad_name); } static int spectral_set_param(struct spectralhandler *spectral, const char *param, const char *val) { int v; v = atoi(val); if (strcmp(param, "ss_short_report") == 0) { spectralset(spectral, SPECTRAL_PARAM_SS_SHORT_RPT, v); } else if (strcmp(param, "ss_fft_period") == 0) { spectralset(spectral, SPECTRAL_PARAM_FFT_PERIOD, v); } else if (strcmp(param, "ss_period") == 0) { spectralset(spectral, SPECTRAL_PARAM_SS_PERIOD, v); } else if (strcmp(param, "ss_count") == 0) { spectralset(spectral, SPECTRAL_PARAM_SS_COUNT, v); } else { return (0); } #if 0 if (strcmp(param, "enabled") == 0) { spectralset(spectral, DFS_PARAM_ENABLE, v); } else if (strcmp(param, "firpwr") == 0) { spectralset(spectral, DFS_PARAM_FIRPWR, v); } else if (strcmp(param, "rrssi") == 0) { spectralset(spectral, DFS_PARAM_RRSSI, v); } else if (strcmp(param, "height") == 0) { spectralset(spectral, DFS_PARAM_HEIGHT, v); } else if (strcmp(param, "prssi") == 0) { spectralset(spectral, DFS_PARAM_PRSSI, v); } else if (strcmp(param, "inband") == 0) { spectralset(spectral, DFS_PARAM_INBAND, v); } else if (strcmp(param, "relpwr") == 0) { spectralset(spectral, DFS_PARAM_RELPWR, v); } else if (strcmp(param, "relstep") == 0) { spectralset(spectral, DFS_PARAM_RELSTEP, v); } else if (strcmp(param, "maxlen") == 0) { spectralset(spectral, DFS_PARAM_MAXLEN, v); } else if (strcmp(param, "usefir128") == 0) { spectralset(spectral, DFS_PARAM_USEFIR128, v); } else if (strcmp(param, "blockspectral") == 0) { spectralset(spectral, DFS_PARAM_BLOCKRADAR, v); } else if (strcmp(param, "enmaxrssi") == 0) { spectralset(spectral, DFS_PARAM_MAXRSSI_EN, v); } else if (strcmp(param, "extchannel") == 0) { spectralset(spectral, DFS_PARAM_EN_EXTCH, v); } else if (strcmp(param, "enrelpwr") == 0) { spectralset(spectral, DFS_PARAM_RELPWR_EN, v); } else if (strcmp(param, "en_relstep_check") == 0) { spectralset(spectral, DFS_PARAM_RELSTEP_EN, v); } else { return 0; } #endif return 1; } void usage(const char *progname) { printf("Usage:\n"); printf("\t%s: [-i ] ()\n", progname); printf("\t%s: [-h]\n", progname); printf("\n"); printf("Valid commands:\n"); printf("\tget:\t\tGet current spectral parameters\n"); printf("\tset :\t\tSet spectral parameter\n"); printf("\tstart: Start spectral scan\n"); printf("\tstop: Stop spectral scan\n"); printf("\tenable_at_reset <0|1>: enable reporting upon channel reset\n"); } int main(int argc, char *argv[]) { struct spectralhandler spectral; const char *devname = ATH_DEFAULT; const char *progname = argv[0]; memset(&spectral, 0, sizeof(spectral)); /* Parse command line options */ if (argc >= 2 && strcmp(argv[1], "-h") == 0) { usage(progname); exit(0); } if (argc >= 2 && strcmp(argv[1], "-?") == 0) { usage(progname); exit(0); } if (argc >= 2 && strcmp(argv[1], "-i") == 0) { if (argc == 2) { usage(progname); exit(127); } devname = argv[2]; argc -= 2; argv += 2; } /* At this point we require at least one command */ if (argc == 1) { usage(progname); exit(127); } if (spectral_opendev(&spectral, devname) == 0) exit(127); if (strcasecmp(argv[1], "get") == 0) { spectral_get(&spectral); } else if (strcasecmp(argv[1], "set") == 0) { if (argc < 4) { usage(progname); exit(127); } if (spectral_set_param(&spectral, argv[2], argv[3]) == 0) { usage(progname); exit(127); } } else if (strcasecmp(argv[1], "start") == 0) { spectral_start(&spectral); } else if (strcasecmp(argv[1], "stop") == 0) { spectral_stop(&spectral); } else if (strcasecmp(argv[1], "enable_at_reset") == 0) { if (argc < 3) { usage(progname); exit(127); } spectral_enable_at_reset(&spectral, atoi(argv[2])); } else { usage(progname); exit(127); } /* wrap up */ spectral_closedev(&spectral); exit(0); } Index: head/tools/tools/ath/athstats/main.c =================================================================== --- head/tools/tools/ath/athstats/main.c (revision 295362) +++ head/tools/tools/ath/athstats/main.c (revision 295363) @@ -1,164 +1,164 @@ /*- * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting * 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$ */ /* * Simple Atheros-specific tool to inspect and monitor network traffic * statistics. * * athstats [-i interface] [-bz] [-l] [-o fmtstring] [interval] * * (default interface is ath0). If interval is specified a rolling output * a la netstat -i is displayed every interval seconds. The format of * the rolling display can be controlled a la ps. The -l option will * print a list of all possible statistics for use with the -o option. */ #include #include #include #include #include #include #include #include "athstats.h" static struct { const char *tag; const char *fmt; } tags[] = { { "default", "input,output,altrate,short,long,xretry,crcerr,crypt,phyerr,rssi,rate" }, { "ani", "avgbrssi,avgrssi,avgtxrssi,NI,SI,step,owsd,cwst,NI+,NI-,SI+,SI-,OFDM,CCK,LISTEN" }, { "tdma", "input,output,bexmit,tdmau,tdmadj,crcerr,phyerr,phytor,rssi,noise,rate" }, }; static const char * getfmt(const char *tag) { int i; for (i = 0; i < nitems(tags); i++) if (strcasecmp(tags[i].tag, tag) == 0) return tags[i].fmt; return tag; } static int signalled; static void catchalarm(int signo __unused) { signalled = 1; } int main(int argc, char *argv[]) { struct athstatfoo *wf; const char *ifname; int c, banner = 1; ifname = getenv("ATH"); if (ifname == NULL) - ifname = "ath0"; + ifname = ATH_DEFAULT; wf = athstats_new(ifname, getfmt("default")); while ((c = getopt(argc, argv, "bi:lo:z")) != -1) { switch (c) { case 'b': banner = 0; break; case 'i': wf->setifname(wf, optarg); break; case 'l': wf->print_fields(wf, stdout); return 0; case 'o': wf->setfmt(wf, getfmt(optarg)); break; case 'z': wf->zerostats(wf); break; default: errx(-1, "usage: %s [-a] [-i ifname] [-l] [-o fmt] [-z] [interval]\n", argv[0]); /*NOTREACHED*/ } } argc -= optind; argv += optind; if (argc > 0) { u_long interval = strtoul(argv[0], NULL, 0); int line, omask; if (interval < 1) interval = 1; signal(SIGALRM, catchalarm); signalled = 0; alarm(interval); banner: if (banner) wf->print_header(wf, stdout); line = 0; loop: if (line != 0) { wf->collect_cur(wf); wf->print_current(wf, stdout); wf->update_tot(wf); } else { wf->collect_tot(wf); wf->print_total(wf, stdout); } fflush(stdout); omask = sigblock(sigmask(SIGALRM)); if (!signalled) sigpause(0); sigsetmask(omask); signalled = 0; alarm(interval); line++; if (line == 21) /* XXX tty line count */ goto banner; else goto loop; /*NOTREACHED*/ } else { wf->collect_tot(wf); wf->print_verbose(wf, stdout); } return 0; }