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 34153317Ssam * (default interface is ath0). 35153317Ssam */ 36153317Ssam#include <sys/types.h> 37153317Ssam#include <sys/file.h> 38153317Ssam#include <sys/ioctl.h> 39153317Ssam#include <sys/socket.h> 40217680Sadrian#include <sys/sysctl.h> 41153317Ssam 42153317Ssam#include <stdio.h> 43153317Ssam#include <ctype.h> 44153317Ssam#include <getopt.h> 45184370Ssam#include <stdlib.h> 46217680Sadrian#include <string.h> 47217680Sadrian#include <strings.h> 48217680Sadrian#include <err.h> 49153317Ssam 50153317Ssam#define N(a) (sizeof(a)/sizeof(a[0])) 51153317Ssam 52153317Ssamconst char *progname; 53153317Ssam 54237143Sadrian/* XXX TODO: include if_ath_debug.h */ 55153317Ssamenum { 56153317Ssam ATH_DEBUG_XMIT = 0x00000001, /* basic xmit operation */ 57153317Ssam ATH_DEBUG_XMIT_DESC = 0x00000002, /* xmit descriptors */ 58153317Ssam ATH_DEBUG_RECV = 0x00000004, /* basic recv operation */ 59153317Ssam ATH_DEBUG_RECV_DESC = 0x00000008, /* recv descriptors */ 60153317Ssam ATH_DEBUG_RATE = 0x00000010, /* rate control */ 61153317Ssam ATH_DEBUG_RESET = 0x00000020, /* reset processing */ 62153317Ssam ATH_DEBUG_MODE = 0x00000040, /* mode init/setup */ 63153317Ssam ATH_DEBUG_BEACON = 0x00000080, /* beacon handling */ 64153317Ssam ATH_DEBUG_WATCHDOG = 0x00000100, /* watchdog timeout */ 65153317Ssam ATH_DEBUG_INTR = 0x00001000, /* ISR */ 66153317Ssam ATH_DEBUG_TX_PROC = 0x00002000, /* tx ISR proc */ 67153317Ssam ATH_DEBUG_RX_PROC = 0x00004000, /* rx ISR proc */ 68153317Ssam ATH_DEBUG_BEACON_PROC = 0x00008000, /* beacon ISR proc */ 69153317Ssam ATH_DEBUG_CALIBRATE = 0x00010000, /* periodic calibration */ 70153317Ssam ATH_DEBUG_KEYCACHE = 0x00020000, /* key cache management */ 71153317Ssam ATH_DEBUG_STATE = 0x00040000, /* 802.11 state transitions */ 72153317Ssam ATH_DEBUG_NODE = 0x00080000, /* node management */ 73153391Ssam ATH_DEBUG_LED = 0x00100000, /* led management */ 74153391Ssam ATH_DEBUG_FF = 0x00200000, /* fast frames */ 75153391Ssam ATH_DEBUG_DFS = 0x00400000, /* DFS processing */ 76174571Ssam ATH_DEBUG_TDMA = 0x00800000, /* TDMA processing */ 77186904Ssam ATH_DEBUG_TDMA_TIMER = 0x01000000, /* TDMA timer processing */ 78184370Ssam ATH_DEBUG_REGDOMAIN = 0x02000000, /* regulatory processing */ 79153317Ssam ATH_DEBUG_FATAL = 0x80000000, /* fatal errors */ 80153317Ssam ATH_DEBUG_ANY = 0xffffffff 81153317Ssam}; 82153317Ssam 83153317Ssamstatic struct { 84153317Ssam const char *name; 85237143Sadrian uint64_t bit; 86153317Ssam} flags[] = { 87153317Ssam { "xmit", ATH_DEBUG_XMIT }, 88153317Ssam { "xmit_desc", ATH_DEBUG_XMIT_DESC }, 89153317Ssam { "recv", ATH_DEBUG_RECV }, 90153317Ssam { "recv_desc", ATH_DEBUG_RECV_DESC }, 91153317Ssam { "rate", ATH_DEBUG_RATE }, 92153317Ssam { "reset", ATH_DEBUG_RESET }, 93153317Ssam { "mode", ATH_DEBUG_MODE }, 94153317Ssam { "beacon", ATH_DEBUG_BEACON }, 95153317Ssam { "watchdog", ATH_DEBUG_WATCHDOG }, 96153317Ssam { "intr", ATH_DEBUG_INTR }, 97153317Ssam { "xmit_proc", ATH_DEBUG_TX_PROC }, 98153317Ssam { "recv_proc", ATH_DEBUG_RX_PROC }, 99153317Ssam { "beacon_proc",ATH_DEBUG_BEACON_PROC }, 100153317Ssam { "calibrate", ATH_DEBUG_CALIBRATE }, 101153317Ssam { "keycache", ATH_DEBUG_KEYCACHE }, 102153317Ssam { "state", ATH_DEBUG_STATE }, 103153317Ssam { "node", ATH_DEBUG_NODE }, 104153391Ssam { "led", ATH_DEBUG_LED }, 105153391Ssam { "ff", ATH_DEBUG_FF }, 106153391Ssam { "dfs", ATH_DEBUG_DFS }, 107174571Ssam { "tdma", ATH_DEBUG_TDMA }, 108186904Ssam { "tdma_timer", ATH_DEBUG_TDMA_TIMER }, 109184370Ssam { "regdomain", ATH_DEBUG_REGDOMAIN }, 110153317Ssam { "fatal", ATH_DEBUG_FATAL }, 111153317Ssam}; 112153317Ssam 113237143Sadrianstatic uint64_t 114153317Ssamgetflag(const char *name, int len) 115153317Ssam{ 116153317Ssam int i; 117153317Ssam 118153317Ssam for (i = 0; i < N(flags); i++) 119153317Ssam if (strncasecmp(flags[i].name, name, len) == 0) 120153317Ssam return flags[i].bit; 121153317Ssam return 0; 122153317Ssam} 123153317Ssam 124153317Ssamstatic const char * 125153317Ssamgetflagname(u_int flag) 126153317Ssam{ 127153317Ssam int i; 128153317Ssam 129153317Ssam for (i = 0; i < N(flags); i++) 130153317Ssam if (flags[i].bit == flag) 131153317Ssam return flags[i].name; 132153317Ssam return "???"; 133153317Ssam} 134153317Ssam 135153317Ssamstatic void 136153317Ssamusage(void) 137153317Ssam{ 138153317Ssam int i; 139153317Ssam 140153317Ssam fprintf(stderr, "usage: %s [-i device] [flags]\n", progname); 141153317Ssam fprintf(stderr, "where flags are:\n"); 142153317Ssam for (i = 0; i < N(flags); i++) 143153317Ssam printf("%s\n", flags[i].name); 144153317Ssam exit(-1); 145153317Ssam} 146153317Ssam 147153317Ssamint 148153317Ssammain(int argc, char *argv[]) 149153317Ssam{ 150174571Ssam const char *ifname; 151153317Ssam const char *cp, *tp; 152153317Ssam const char *sep; 153153317Ssam int c, op, i; 154237143Sadrian uint64_t debug, ndebug; 155153317Ssam size_t debuglen; 156153317Ssam char oid[256]; 157153317Ssam 158174571Ssam ifname = getenv("ATH"); 159174571Ssam if (ifname == NULL) 160174571Ssam ifname = "ath0"; 161153317Ssam progname = argv[0]; 162153317Ssam if (argc > 1) { 163153317Ssam if (strcmp(argv[1], "-i") == 0) { 164153317Ssam if (argc < 2) 165153317Ssam errx(1, "missing interface name for -i option"); 166153317Ssam ifname = argv[2]; 167153317Ssam if (strncmp(ifname, "ath", 3) != 0) 168153317Ssam errx(2, "huh, this is for ath devices?"); 169153317Ssam argc -= 2, argv += 2; 170153317Ssam } else if (strcmp(argv[1], "-?") == 0) 171153317Ssam usage(); 172153317Ssam } 173153317Ssam 174153317Ssam#ifdef __linux__ 175153317Ssam snprintf(oid, sizeof(oid), "dev.%s.debug", ifname); 176153317Ssam#else 177153317Ssam snprintf(oid, sizeof(oid), "dev.ath.%s.debug", ifname+3); 178153317Ssam#endif 179153317Ssam debuglen = sizeof(debug); 180153317Ssam if (sysctlbyname(oid, &debug, &debuglen, NULL, 0) < 0) 181153317Ssam err(1, "sysctl-get(%s)", oid); 182153317Ssam ndebug = debug; 183153317Ssam for (; argc > 1; argc--, argv++) { 184153317Ssam cp = argv[1]; 185153317Ssam do { 186153317Ssam u_int bit; 187153317Ssam 188153317Ssam if (*cp == '-') { 189153317Ssam cp++; 190153317Ssam op = -1; 191153317Ssam } else if (*cp == '+') { 192153317Ssam cp++; 193153317Ssam op = 1; 194153317Ssam } else 195153317Ssam op = 0; 196153317Ssam for (tp = cp; *tp != '\0' && *tp != '+' && *tp != '-';) 197153317Ssam tp++; 198153317Ssam bit = getflag(cp, tp-cp); 199153317Ssam if (op < 0) 200153317Ssam ndebug &= ~bit; 201153317Ssam else if (op > 0) 202153317Ssam ndebug |= bit; 203153317Ssam else { 204153317Ssam if (bit == 0) { 205153317Ssam if (isdigit(*cp)) 206153317Ssam bit = strtoul(cp, NULL, 0); 207153317Ssam else 208153317Ssam errx(1, "unknown flag %.*s", 209244961Sadrian (int) (tp-cp), cp); 210153317Ssam } 211153317Ssam ndebug = bit; 212153317Ssam } 213153317Ssam } while (*(cp = tp) != '\0'); 214153317Ssam } 215153317Ssam if (debug != ndebug) { 216244961Sadrian printf("%s: 0x%llx => ", oid, (long long) debug); 217153317Ssam if (sysctlbyname(oid, NULL, NULL, &ndebug, sizeof(ndebug)) < 0) 218153317Ssam err(1, "sysctl-set(%s)", oid); 219244961Sadrian printf("0x%llx", (long long) ndebug); 220153317Ssam debug = ndebug; 221153317Ssam } else 222244961Sadrian printf("%s: 0x%llx", oid, (long long) debug); 223153317Ssam sep = "<"; 224153317Ssam for (i = 0; i < N(flags); i++) 225153317Ssam if (debug & flags[i].bit) { 226153317Ssam printf("%s%s", sep, flags[i].name); 227153317Ssam sep = ","; 228153317Ssam } 229153317Ssam printf("%s\n", *sep != '<' ? ">" : ""); 230153317Ssam return 0; 231153317Ssam} 232