1153317Ssam/*- 2186904Ssam * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 3153317Ssam * All rights reserved. 4153317Ssam * 5153317Ssam * Redistribution and use in source and binary forms, with or without 6153317Ssam * modification, are permitted provided that the following conditions 7153317Ssam * are met: 8153317Ssam * 1. Redistributions of source code must retain the above copyright 9153317Ssam * notice, this list of conditions and the following disclaimer, 10153317Ssam * without modification. 11153317Ssam * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12153317Ssam * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13153317Ssam * redistribution must be conditioned upon including a substantially 14153317Ssam * similar Disclaimer requirement for further binary redistribution. 15153317Ssam * 16153317Ssam * NO WARRANTY 17153317Ssam * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18153317Ssam * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19153317Ssam * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20153317Ssam * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21153317Ssam * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22153317Ssam * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23153317Ssam * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24153317Ssam * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25153317Ssam * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26153317Ssam * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27153317Ssam * THE POSSIBILITY OF SUCH DAMAGES. 28153317Ssam * 29153317Ssam * $FreeBSD$ 30153317Ssam */ 31153317Ssam 32153317Ssam/* 33153317Ssam * athdebug [-i interface] flags 34295363Sadrian * (default interface is wlan0). 35153317Ssam */ 36287297Srodrigc 37287297Srodrigc#include <sys/param.h> 38153317Ssam#include <sys/file.h> 39153317Ssam#include <sys/ioctl.h> 40153317Ssam#include <sys/socket.h> 41217680Sadrian#include <sys/sysctl.h> 42153317Ssam 43153317Ssam#include <ctype.h> 44287297Srodrigc#include <err.h> 45153317Ssam#include <getopt.h> 46287297Srodrigc#include <stdio.h> 47184370Ssam#include <stdlib.h> 48217680Sadrian#include <string.h> 49217680Sadrian#include <strings.h> 50153317Ssam 51153317Ssamconst char *progname; 52153317Ssam 53237143Sadrian/* XXX TODO: include if_ath_debug.h */ 54153317Ssamenum { 55153317Ssam ATH_DEBUG_XMIT = 0x00000001, /* basic xmit operation */ 56153317Ssam ATH_DEBUG_XMIT_DESC = 0x00000002, /* xmit descriptors */ 57153317Ssam ATH_DEBUG_RECV = 0x00000004, /* basic recv operation */ 58153317Ssam ATH_DEBUG_RECV_DESC = 0x00000008, /* recv descriptors */ 59153317Ssam ATH_DEBUG_RATE = 0x00000010, /* rate control */ 60153317Ssam ATH_DEBUG_RESET = 0x00000020, /* reset processing */ 61153317Ssam ATH_DEBUG_MODE = 0x00000040, /* mode init/setup */ 62153317Ssam ATH_DEBUG_BEACON = 0x00000080, /* beacon handling */ 63153317Ssam ATH_DEBUG_WATCHDOG = 0x00000100, /* watchdog timeout */ 64153317Ssam ATH_DEBUG_INTR = 0x00001000, /* ISR */ 65153317Ssam ATH_DEBUG_TX_PROC = 0x00002000, /* tx ISR proc */ 66153317Ssam ATH_DEBUG_RX_PROC = 0x00004000, /* rx ISR proc */ 67153317Ssam ATH_DEBUG_BEACON_PROC = 0x00008000, /* beacon ISR proc */ 68153317Ssam ATH_DEBUG_CALIBRATE = 0x00010000, /* periodic calibration */ 69153317Ssam ATH_DEBUG_KEYCACHE = 0x00020000, /* key cache management */ 70153317Ssam ATH_DEBUG_STATE = 0x00040000, /* 802.11 state transitions */ 71153317Ssam ATH_DEBUG_NODE = 0x00080000, /* node management */ 72153391Ssam ATH_DEBUG_LED = 0x00100000, /* led management */ 73153391Ssam ATH_DEBUG_FF = 0x00200000, /* fast frames */ 74153391Ssam ATH_DEBUG_DFS = 0x00400000, /* DFS processing */ 75174571Ssam ATH_DEBUG_TDMA = 0x00800000, /* TDMA processing */ 76186904Ssam ATH_DEBUG_TDMA_TIMER = 0x01000000, /* TDMA timer processing */ 77184370Ssam ATH_DEBUG_REGDOMAIN = 0x02000000, /* regulatory processing */ 78153317Ssam ATH_DEBUG_FATAL = 0x80000000, /* fatal errors */ 79153317Ssam ATH_DEBUG_ANY = 0xffffffff 80153317Ssam}; 81153317Ssam 82153317Ssamstatic struct { 83153317Ssam const char *name; 84237143Sadrian uint64_t bit; 85153317Ssam} flags[] = { 86153317Ssam { "xmit", ATH_DEBUG_XMIT }, 87153317Ssam { "xmit_desc", ATH_DEBUG_XMIT_DESC }, 88153317Ssam { "recv", ATH_DEBUG_RECV }, 89153317Ssam { "recv_desc", ATH_DEBUG_RECV_DESC }, 90153317Ssam { "rate", ATH_DEBUG_RATE }, 91153317Ssam { "reset", ATH_DEBUG_RESET }, 92153317Ssam { "mode", ATH_DEBUG_MODE }, 93153317Ssam { "beacon", ATH_DEBUG_BEACON }, 94153317Ssam { "watchdog", ATH_DEBUG_WATCHDOG }, 95153317Ssam { "intr", ATH_DEBUG_INTR }, 96153317Ssam { "xmit_proc", ATH_DEBUG_TX_PROC }, 97153317Ssam { "recv_proc", ATH_DEBUG_RX_PROC }, 98153317Ssam { "beacon_proc",ATH_DEBUG_BEACON_PROC }, 99153317Ssam { "calibrate", ATH_DEBUG_CALIBRATE }, 100153317Ssam { "keycache", ATH_DEBUG_KEYCACHE }, 101153317Ssam { "state", ATH_DEBUG_STATE }, 102153317Ssam { "node", ATH_DEBUG_NODE }, 103153391Ssam { "led", ATH_DEBUG_LED }, 104153391Ssam { "ff", ATH_DEBUG_FF }, 105153391Ssam { "dfs", ATH_DEBUG_DFS }, 106174571Ssam { "tdma", ATH_DEBUG_TDMA }, 107186904Ssam { "tdma_timer", ATH_DEBUG_TDMA_TIMER }, 108184370Ssam { "regdomain", ATH_DEBUG_REGDOMAIN }, 109153317Ssam { "fatal", ATH_DEBUG_FATAL }, 110153317Ssam}; 111153317Ssam 112237143Sadrianstatic uint64_t 113153317Ssamgetflag(const char *name, int len) 114153317Ssam{ 115153317Ssam int i; 116153317Ssam 117287297Srodrigc for (i = 0; i < nitems(flags); i++) 118153317Ssam if (strncasecmp(flags[i].name, name, len) == 0) 119153317Ssam return flags[i].bit; 120153317Ssam return 0; 121153317Ssam} 122153317Ssam 123153317Ssamstatic const char * 124153317Ssamgetflagname(u_int flag) 125153317Ssam{ 126153317Ssam int i; 127153317Ssam 128287297Srodrigc for (i = 0; i < nitems(flags); i++) 129153317Ssam if (flags[i].bit == flag) 130153317Ssam return flags[i].name; 131153317Ssam return "???"; 132153317Ssam} 133153317Ssam 134153317Ssamstatic void 135153317Ssamusage(void) 136153317Ssam{ 137153317Ssam int i; 138153317Ssam 139153317Ssam fprintf(stderr, "usage: %s [-i device] [flags]\n", progname); 140153317Ssam fprintf(stderr, "where flags are:\n"); 141287297Srodrigc for (i = 0; i < nitems(flags); i++) 142153317Ssam printf("%s\n", flags[i].name); 143153317Ssam exit(-1); 144153317Ssam} 145153317Ssam 146153317Ssamint 147153317Ssammain(int argc, char *argv[]) 148153317Ssam{ 149174571Ssam const char *ifname; 150153317Ssam const char *cp, *tp; 151153317Ssam const char *sep; 152153317Ssam int c, op, i; 153237143Sadrian uint64_t debug, ndebug; 154153317Ssam size_t debuglen; 155153317Ssam char oid[256]; 156153317Ssam 157174571Ssam ifname = getenv("ATH"); 158174571Ssam if (ifname == NULL) 159295363Sadrian ifname = ATH_DEFAULT; 160153317Ssam progname = argv[0]; 161153317Ssam if (argc > 1) { 162153317Ssam if (strcmp(argv[1], "-i") == 0) { 163153317Ssam if (argc < 2) 164153317Ssam errx(1, "missing interface name for -i option"); 165153317Ssam ifname = argv[2]; 166153317Ssam if (strncmp(ifname, "ath", 3) != 0) 167153317Ssam errx(2, "huh, this is for ath devices?"); 168153317Ssam argc -= 2, argv += 2; 169153317Ssam } else if (strcmp(argv[1], "-?") == 0) 170153317Ssam usage(); 171153317Ssam } 172153317Ssam 173153317Ssam#ifdef __linux__ 174153317Ssam snprintf(oid, sizeof(oid), "dev.%s.debug", ifname); 175153317Ssam#else 176153317Ssam snprintf(oid, sizeof(oid), "dev.ath.%s.debug", ifname+3); 177153317Ssam#endif 178153317Ssam debuglen = sizeof(debug); 179153317Ssam if (sysctlbyname(oid, &debug, &debuglen, NULL, 0) < 0) 180153317Ssam err(1, "sysctl-get(%s)", oid); 181153317Ssam ndebug = debug; 182153317Ssam for (; argc > 1; argc--, argv++) { 183153317Ssam cp = argv[1]; 184153317Ssam do { 185153317Ssam u_int bit; 186153317Ssam 187153317Ssam if (*cp == '-') { 188153317Ssam cp++; 189153317Ssam op = -1; 190153317Ssam } else if (*cp == '+') { 191153317Ssam cp++; 192153317Ssam op = 1; 193153317Ssam } else 194153317Ssam op = 0; 195153317Ssam for (tp = cp; *tp != '\0' && *tp != '+' && *tp != '-';) 196153317Ssam tp++; 197153317Ssam bit = getflag(cp, tp-cp); 198153317Ssam if (op < 0) 199153317Ssam ndebug &= ~bit; 200153317Ssam else if (op > 0) 201153317Ssam ndebug |= bit; 202153317Ssam else { 203153317Ssam if (bit == 0) { 204153317Ssam if (isdigit(*cp)) 205153317Ssam bit = strtoul(cp, NULL, 0); 206153317Ssam else 207153317Ssam errx(1, "unknown flag %.*s", 208244961Sadrian (int) (tp-cp), cp); 209153317Ssam } 210153317Ssam ndebug = bit; 211153317Ssam } 212153317Ssam } while (*(cp = tp) != '\0'); 213153317Ssam } 214153317Ssam if (debug != ndebug) { 215244961Sadrian printf("%s: 0x%llx => ", oid, (long long) debug); 216153317Ssam if (sysctlbyname(oid, NULL, NULL, &ndebug, sizeof(ndebug)) < 0) 217153317Ssam err(1, "sysctl-set(%s)", oid); 218244961Sadrian printf("0x%llx", (long long) ndebug); 219153317Ssam debug = ndebug; 220153317Ssam } else 221244961Sadrian printf("%s: 0x%llx", oid, (long long) debug); 222153317Ssam sep = "<"; 223287297Srodrigc for (i = 0; i < nitems(flags); i++) 224153317Ssam if (debug & flags[i].bit) { 225153317Ssam printf("%s%s", sep, flags[i].name); 226153317Ssam sep = ","; 227153317Ssam } 228153317Ssam printf("%s\n", *sep != '<' ? ">" : ""); 229153317Ssam return 0; 230153317Ssam} 231