#include <sys/param.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <ctype.h>
#include <err.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
const char *progname;
enum {
ATH_DEBUG_XMIT = 0x00000001,
ATH_DEBUG_XMIT_DESC = 0x00000002,
ATH_DEBUG_RECV = 0x00000004,
ATH_DEBUG_RECV_DESC = 0x00000008,
ATH_DEBUG_RATE = 0x00000010,
ATH_DEBUG_RESET = 0x00000020,
ATH_DEBUG_MODE = 0x00000040,
ATH_DEBUG_BEACON = 0x00000080,
ATH_DEBUG_WATCHDOG = 0x00000100,
ATH_DEBUG_INTR = 0x00001000,
ATH_DEBUG_TX_PROC = 0x00002000,
ATH_DEBUG_RX_PROC = 0x00004000,
ATH_DEBUG_BEACON_PROC = 0x00008000,
ATH_DEBUG_CALIBRATE = 0x00010000,
ATH_DEBUG_KEYCACHE = 0x00020000,
ATH_DEBUG_STATE = 0x00040000,
ATH_DEBUG_NODE = 0x00080000,
ATH_DEBUG_LED = 0x00100000,
ATH_DEBUG_FF = 0x00200000,
ATH_DEBUG_DFS = 0x00400000,
ATH_DEBUG_TDMA = 0x00800000,
ATH_DEBUG_TDMA_TIMER = 0x01000000,
ATH_DEBUG_REGDOMAIN = 0x02000000,
ATH_DEBUG_FATAL = 0x80000000,
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)
{
unsigned int i;
for (i = 0; i < nitems(flags); i++)
if (strncasecmp(flags[i].name, name, len) == 0)
return flags[i].bit;
return 0;
}
#if 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 "???";
}
#endif
static void
usage(void)
{
unsigned 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 op;
unsigned int i;
uint64_t debug, ndebug;
size_t debuglen;
char oid[256];
ifname = getenv("ATH");
if (ifname == NULL)
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;
}