diff options
Diffstat (limited to 'tools/tools')
472 files changed, 129381 insertions, 0 deletions
diff --git a/tools/tools/README b/tools/tools/README new file mode 100644 index 000000000000..9c3db2fc5364 --- /dev/null +++ b/tools/tools/README @@ -0,0 +1,73 @@ +# $FreeBSD$ + +This directory is for tools. + +A tool is something which is sometimes useful, and doesn't fit any of +the other categories. + +Please make a subdir per program, and add a brief description to this +file. + +ansify Convert K&R-style function definitions to ANSI style +ath Tools specific to the Atheros 802.11 support +backout_commit A tool for reading in a commit message and generating + a script that will backout the commit. +cfi Common Flash Interface (CFI) tool +commitsdb A tool for reconstructing commit history using md5 + checksums of the commit logs. +crypto Test and exercise tools related to the crypto framework +cxgbetool A tool for the cxgbe(4) driver. +cxgbtool A tool for the cxgb(4) driver. +diffburst OBSOLETE: equivalent functionality is available via split -p. + For example: "split -p ^diff < patchfile". See split(1). +editing Editor modes and the like to help editing FreeBSD code. +epfe Extract printing filter examples from printing.sgml. +ether_reflect An Ethernet packet reflector for low level testing. +find-sb Scan a disk for possible filesystem superblocks. +gdb_regofs A simple tool that prints out a register offset table + for mapping gdb(1) register numbers to struct reg and + struct fpreg offsets. The tool is useful on selected + platforms only. +genericize Turn a kernel config into something that can more easily + be diffed against the appropriate GENERIC. +hcomp Compress header files by removing comments and whitespace. +html-mv Rename HTML generated filenames to human readable filenames. +ifinfo Uses the interface MIB to print out all the information + an interface exports in an ugly form. +iso Tool to compare the iso3166 and iso639 files in + /usr/share/misc with the data from the master sites. +iwi Tools specific to the Intel PRO/Wireless 2200BG/2225BG/2915ABG + support. +kdrv KernelDriver; add/list/remove third-party kernel driver + source to/in/from a kernel source tree. +kernelcruft Shellscript to find orphaned *.c files in /sys +kerninclude Shellscript to find unused #includes in the kernel. +kernxref Shellscript to cross reference symbols in the LINT kernel. +kttcp An in-kernel version of the ttcp network performance tool +mctest A multicast test program +mfc Merge a directory from HEAD to a branch where it does not + already exist and other MFC related script(s). +mid Create a Message-ID database for mailing lists. +mwl Tools specific to the Marvell 88W8363 support +ncpus Count the number of processors +netmap Test applications for netmap(4) +notescheck Check for missing devices and options in NOTES files. +npe Tools specific to the Intel IXP4XXX NPE device +nxge A diagnostic tool for the nxge(4) driver +pciid Generate src/share/misc/pci_vendors. +pciroms A tool for dumping PCI ROM images. WARNING: alpha quality. +pirtool A tool for dumping the $PIR table on i386 machines at runtime. +portsinfo Generate list of new ports for last two weeks. +prstats Generate statistics about the PR database. +recoverdisk Copy as much data as possible from a defective disk. +scsi-defects Get at the primary or grown defect list of a SCSI disk. +sysdoc Build a manual page with available sysctls for a specific + kernel configuration. +tinybsd Script to build FreeBSD embedded systems. +track Track the progress of a world / kernel build +vimage An interim utility for managing the virtualized network + stack infrastructure. +vop_table Generates a HTML document that shows all the VOP's in + the kernel. +vxge A diagnostic tool for the vxge(4) driver +whereintheworld Summarizes "make world" output. diff --git a/tools/tools/aac/Makefile b/tools/tools/aac/Makefile new file mode 100644 index 000000000000..7a472321a039 --- /dev/null +++ b/tools/tools/aac/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +PROG= aac_checkq +NO_MAN= +WARNS?=6 +BINDIR?=/usr/local/bin + +.include <bsd.prog.mk> diff --git a/tools/tools/aac/aac_checkq.c b/tools/tools/aac/aac_checkq.c new file mode 100644 index 000000000000..62eedb20aa51 --- /dev/null +++ b/tools/tools/aac/aac_checkq.c @@ -0,0 +1,84 @@ +/*- + * Copyright (c) 2004 Scott Long + * + * 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/fcntl.h> +#include <sys/ioctl.h> +#include <sys/aac_ioctl.h> + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <unistd.h> + +void usage(void); + +/* + * Simple program to print out the queue stats on the given queue index. + * See /sys/sys/aac_ioctl.h for the definitions of each queue index. + */ + +void +usage(void) +{ + printf("Usage: aac_checkq <queue_number>\n"); + exit(1); +} + +int +main(int argc, char **argv) +{ + union aac_statrequest sr; + int fd, retval, queue; + + if (argc != 2) + usage(); + + fd = open("/dev/aac0", O_RDWR); + if (fd == -1) { + printf("couldn't open aac0: %s\n", strerror(errno)); + return (-1); + } + + queue = atoi(argv[1]); + printf("Getting stats for queue %d\n", queue); + bzero(&sr, sizeof(union aac_statrequest)); + sr.as_item = queue; + retval = ioctl(fd, AACIO_STATS, &sr); + if (retval == -1) { + printf("error on ioctl: %s\n", strerror(errno)); + return (-1); + } + + printf("length= %d, max= %d\n",sr.as_qstat.q_length, sr.as_qstat.q_max); + + close(fd); + return 0; +} diff --git a/tools/tools/ansify/Makefile b/tools/tools/ansify/Makefile new file mode 100644 index 000000000000..9519a4ce9fb2 --- /dev/null +++ b/tools/tools/ansify/Makefile @@ -0,0 +1,6 @@ +# $FreeBSD$ + +SCRIPTS= ansify.pl +BINDIR?= /usr/local/bin + +.include <bsd.prog.mk> diff --git a/tools/tools/ansify/ansify.pl b/tools/tools/ansify/ansify.pl new file mode 100644 index 000000000000..e35546548425 --- /dev/null +++ b/tools/tools/ansify/ansify.pl @@ -0,0 +1,162 @@ +#!/usr/bin/perl -w +#- +# Copyright (c) 2005 Dag-Erling Coïdan Smørgrav +# 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 +# in this position and unchanged. +# 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$ +# + +use v5.6.0; +use strict; + +use Getopt::Long; + +my $caddr_t; + +sub ansify($$$) { + my $ifh = shift; + my $ofh = shift; + my $fn = shift; + + my $line = 0; + OUTER: + while (<$ifh>) { + # look for K&R-style function definitions + if (m/^(\w+)\s*\(([\w,\s]+)\)$/) { + my @saved = ($_); + my $func = $1; + my @args = split(/\s*,\s*/, $2); + my $arglist = ""; + # capture K&R-style argument list + while (<$ifh>) { + push(@saved, $_); + last if (m/^\{\s*$/); + $arglist .= $_; + } + # remove comments (common in vfs code) + $arglist =~ s/\/\*([^*]|\*[^\/])*\*\// /gs; + # identify type of each argument + my %type; + foreach (split('\n', $arglist)) { + s/\s+/ /g; + if (!/^\s*([\w\s\*]+?)\s*(\w+?);\s*$/) { + warn("[$fn:$line] $func(): can't parse argument list\n"); + print $ofh @saved; + $line += @saved; + next OUTER; + } + $type{$2} = $1; + } + # construct ANSI-style function definition + my $repl = "$func("; + foreach my $arg (@args) { + # missing arguments in argument list + if (!exists($type{$arg})) { + warn("[$fn:$line] $func(): unknown type for '$arg' argument\n"); + print $ofh @saved; + $line += @saved; + next OUTER; + } + if ($caddr_t) { + $type{$arg} = "void *" + if $type{$arg} eq "caddr_t"; + } + $repl .= $type{$arg}; + $repl .= " " + unless ($type{$arg} =~ m/\*$/); + $repl .= $arg; + $repl .= ", " + unless $arg eq $args[-1]; + delete $type{$arg}; + } + $repl .= ")"; + # extra arguments in argument list + if (%type) { + warn("[$fn:$line] $func(): too many arguments\n"); + print $ofh @saved; + $line += @saved; + next OUTER; + } + print $ofh "$repl\n"; + ++$line; + # warn about long lines so they can be fixed up manually + warn("[$fn:$line] $func(): definition exceeds 80 characters\n") + if length($repl) >= 80; + print $ofh "{\n"; + ++$line; + } else { + print $ofh $_; + ++$line; + } + } +} + +sub ansify_file($) { + my $fn = shift; + + my $tfn = "$fn.ansify"; + local *IN; + local *OUT; + + if (open(IN, "<", $fn)) { + if (open(OUT, ">", $tfn)) { + ansify(*IN{IO}, *OUT{IO}, $fn); + if (!rename($tfn, $fn)) { + warn("$fn: $!\n"); + unlink($tfn); + } + } else { + warn("$fn.ansify: $!\n"); + } + } else { + warn("$fn: $!\n"); + } +} + +sub usage() { + print STDERR "usage: ansify [options] [file ...] + +Options: + -c, --caddr_t Replace caddr_t with void * in converted + function definitions +"; + exit(1); +} + +MAIN:{ + Getopt::Long::Configure("auto_abbrev", "bundling"); + GetOptions( + "c|caddr_t" => \$caddr_t, + ) + or usage(); + + if (@ARGV) { + foreach (@ARGV) { + ansify_file($_); + } + } else { + ansify(*STDIN{IO}, *STDOUT{IO}, "(stdin)"); + } +} diff --git a/tools/tools/ath/Makefile b/tools/tools/ath/Makefile new file mode 100644 index 000000000000..3d603e656d8a --- /dev/null +++ b/tools/tools/ath/Makefile @@ -0,0 +1,7 @@ +# $FreeBSD$ + +SUBDIR= arcode athdebug athdecode athkey athpoke athprom athrd athregs +SUBDIR+= athstats ath_prom_read athradar +SUBDIR+= ath_ee_v14_print ath_ee_v4k_print ath_ee_9287_print + +.include <bsd.subdir.mk> diff --git a/tools/tools/ath/Makefile.inc b/tools/tools/ath/Makefile.inc new file mode 100644 index 000000000000..901844ea7f72 --- /dev/null +++ b/tools/tools/ath/Makefile.inc @@ -0,0 +1,14 @@ +# $FreeBSD$ + +BINDIR= /usr/local/bin +NO_MAN= + +ATH_DEFAULT= ath0 + +CFLAGS+=-DATH_DEFAULT='"${ATH_DEFAULT}"' +CFLAGS+=-I${.CURDIR} +CFLAGS+=-I${.CURDIR}/../common +CFLAGS+=-I${.CURDIR}/../../../../sys +CFLAGS+=-I${.CURDIR}/../../../../sys/dev/ath +CFLAGS+=-I${.CURDIR}/../../../../sys/dev/ath/ath_hal +CFLAGS+=-I${.OBJDIR} diff --git a/tools/tools/ath/arcode/Makefile b/tools/tools/ath/arcode/Makefile new file mode 100644 index 000000000000..9611a6ff9c36 --- /dev/null +++ b/tools/tools/ath/arcode/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +PROG= arcode +NOMAN= yes + +.include <../Makefile.inc> + +.include <bsd.prog.mk> diff --git a/tools/tools/ath/arcode/arcode.c b/tools/tools/ath/arcode/arcode.c new file mode 100644 index 000000000000..31e02cdb84eb --- /dev/null +++ b/tools/tools/ath/arcode/arcode.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> + +#include <sys/types.h> +#include <sys/alq.h> + +#include "ah_decode.h" + +#define MAX_MARKERS 9 + +const char *markers[] = { + "AH_MARK_RESET", /* ar*Reset entry, bChannelChange */ + "AH_MARK_RESET_LINE", /* ar*_reset.c, line %d */ + "AH_MARK_RESET_DONE", /* ar*Reset exit, error code */ + "AH_MARK_CHIPRESET", /* ar*ChipReset, channel num */ + "AH_MARK_PERCAL", /* ar*PerCalibration, channel num */ + "AH_MARK_SETCHANNEL", /* ar*SetChannel, channel num */ + "AH_MARK_ANI_RESET", /* ar*AniReset, opmode */ + "AH_MARK_ANI_POLL", /* ar*AniReset, listen time */ + "AH_MARK_ANI_CONTROL", /* ar*AniReset, cmd */ +}; + +static void +op_read(struct athregrec *a) +{ + printf("read\t%.8x = %.8x\n", a->reg, a->val); +} + +static void +op_write(struct athregrec *a) +{ + printf("write\t%.8x = %.8x\n", a->reg, a->val); +} + +static void +op_device(struct athregrec *a) +{ + printf("device\t0x%x/0x%x\n", a->reg, a->val); +} + +static void +op_mark(struct athregrec *a) +{ + const char *s = "UNKNOWN"; + if (a->reg <= MAX_MARKERS) + s = markers[a->reg]; + + printf("mark\t%s (%d): %d\n", s, a->reg, a->val); +} + +int +main(int argc, const char *argv[]) +{ + const char *file = argv[1]; + int fd; + struct athregrec a; + int r; + + if (argc < 2) { + printf("usage: %s <ahq log>\n", argv[0]); + exit(127); + } + + fd = open(file, O_RDONLY); + if (fd < 0) { + perror("open"); + exit(127); + } + + while (1) { + r = read(fd, &a, sizeof(a)); + if (r != sizeof(a)) + break; + switch (a.op) { + case OP_READ: + op_read(&a); + break; + case OP_WRITE: + op_write(&a); + break; + case OP_DEVICE: + op_device(&a); + break; + case OP_MARK: + op_mark(&a); + break; + default: + printf("op: %s; reg: %x; val: %x\n", + a.op, a.reg, a.val); + } + } + close(fd); +} diff --git a/tools/tools/ath/ath_ee_9287_print/9287.c b/tools/tools/ath/ath_ee_9287_print/9287.c new file mode 100644 index 000000000000..3ed970cba65d --- /dev/null +++ b/tools/tools/ath/ath_ee_9287_print/9287.c @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2010-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 <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <err.h> + +typedef enum { + AH_FALSE = 0, /* NB: lots of code assumes false is zero */ + AH_TRUE = 1, +} HAL_BOOL; + +typedef enum { + HAL_OK = 0, /* No error */ +} HAL_STATUS; + +struct ath_hal; + +#include "ah_eeprom_v14.h" +#include "ah_eeprom_9287.h" + +void +eeprom_9287_base_print(uint16_t *buf) +{ + HAL_EEPROM_9287 *eep = (HAL_EEPROM_9287 *) buf; + BASE_EEP_9287_HEADER *eh = &eep->ee_base.baseEepHeader; + int i; + + printf("| Version: 0x%.4x | Length: 0x%.4x | Checksum: 0x%.4x ", + eh->version, eh->length, eh->checksum); + printf("| CapFlags: 0x%.2x | eepMisc: 0x%.2x | RegDomain: 0x%.4x 0x%.4x | \n", + eh->opCapFlags, eh->eepMisc, eh->regDmn[0], eh->regDmn[1]); + printf("| MAC: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x ", + eh->macAddr[0], eh->macAddr[1], eh->macAddr[2], + eh->macAddr[3], eh->macAddr[4], eh->macAddr[5]); + printf("| RxMask: 0x%.2x | TxMask: 0x%.2x | RfSilent: 0x%.4x | btOptions: 0x%.4x |\n", + eh->rxMask, eh->txMask, eh->rfSilent, eh->blueToothOptions); + printf("| DeviceCap: 0x%.4x | binBuildNumber: %.8x | deviceType: 0x%.2x | openLoopPwrCntl 0x%.2x |\n", + eh->deviceCap, eh->binBuildNumber, eh->deviceType, eh->openLoopPwrCntl); + printf("| pwrTableOffset: %d | tempSensSlope: %d | tempSensSlopePalOn: %d |\n", + eh->pwrTableOffset, eh->tempSensSlope, eh->tempSensSlopePalOn); + + printf("Future:\n"); + for (i = 0; i < sizeof(eh->futureBase) / sizeof(uint16_t); i++) { + printf("0x%.2x ", eh->futureBase[i]); + } + printf("\n"); +} + +void +eeprom_9287_custdata_print(uint16_t *buf) +{ + HAL_EEPROM_9287 *eep = (HAL_EEPROM_9287 *) buf; + uint8_t *custdata = (uint8_t *) &eep->ee_base.custData; + int i; + + printf("\n| Custdata: |\n"); + for (i = 0; i < 20; i++) { + printf("%s0x%.2x %s", + i % 16 == 0 ? "| " : "", + custdata[i], + i % 16 == 15 ? "|\n" : ""); + } + printf("\n"); +} + +void +eeprom_9287_modal_print(uint16_t *buf) +{ + HAL_EEPROM_9287 *eep = (HAL_EEPROM_9287 *) buf; + MODAL_EEP_9287_HEADER *mh = &eep->ee_base.modalHeader; + int i; + + printf("| antCtrlCommon: 0x%.8x |\n", mh->antCtrlCommon); + printf("| switchSettling: 0x%.2x |\n", mh->switchSettling); + printf("| adcDesiredSize: %d |\n", mh->adcDesiredSize); + + for (i = 0; i < AR9287_MAX_CHAINS; i++) { + printf("| Chain %d:\n", i); + printf("| antCtrlChain: 0:0x%.4x |\n", mh->antCtrlChain[i]); + printf("| antennaGainCh: 0:0x%.2x |\n", mh->antennaGainCh[i]); + printf("| txRxAttenCh: 0:0x%.2x |\n", mh->txRxAttenCh[i]); + printf("| rxTxMarginCh: 0:0x%.2x |\n", mh->rxTxMarginCh[i]); + printf("| noiseFloorThresCh: 0:0x%.2x |\n", mh->noiseFloorThreshCh[i]); + printf("| iqCalICh: 0:0x%.2x |\n", mh->iqCalICh[i]); + printf("| iqCalQCh: 0:0x%.2x |\n", mh->iqCalQCh[i]); + printf("| bswAtten: 0:0x%.2x |\n", mh->bswAtten[i]); + printf("| bswMargin: 0:0x%.2x |\n", mh->bswMargin[i]); + printf("\n"); + } + + printf("| txEndToXpaOff: 0x%.2x | txEndToRxOn: 0x%.2x | txFrameToXpaOn: 0x%.2x |\n", + mh->txEndToXpaOff, mh->txEndToRxOn, mh->txFrameToXpaOn); + printf("| thres62: 0x%.2x\n", mh->thresh62); + printf("| xpdGain: 0x%.2x | xpd: 0x%.2x |\n", mh->xpdGain, mh->xpd); + + printf("| pdGainOverlap: 0x%.2x xpaBiasLvl: 0x%.2x |\n", mh->pdGainOverlap, mh->xpaBiasLvl); + printf("| txFrameToDataStart: 0x%.2x | txFrameToPaOn: 0x%.2x |\n", mh->txFrameToDataStart, mh->txFrameToPaOn); + printf("| ht40PowerIncForPdadc: 0x%.2x |\n", mh->ht40PowerIncForPdadc); + printf("| swSettleHt40: 0x%.2x |\n", mh->swSettleHt40); + + printf("| Modal Version: %.2x |\n", mh->version); + printf("| db1 = %d | db2 = %d |\n", mh->db1, mh->db2); + printf("| ob_cck = %d | ob_psk = %d | ob_qam = %d | ob_pal_off = %d |\n", + mh->ob_cck, mh->ob_psk, mh->ob_qam, mh->ob_pal_off); + + printf("| futureModal: "); + for (i = 0; i < sizeof(mh->futureModal) / sizeof(uint16_t); i++) { + printf("0x%.2x ", mh->futureModal[i]); + } + printf("\n"); + + /* and now, spur channels */ + for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { + printf("| Spur %d: spurChan: 0x%.4x spurRangeLow: 0x%.2x spurRangeHigh: 0x%.2x |\n", + i, mh->spurChans[i].spurChan, + (int) mh->spurChans[i].spurRangeLow, + (int) mh->spurChans[i].spurRangeHigh); + } +} + +static void +eeprom_9287_print_caldata_oploop(struct cal_data_op_loop_ar9287 *f) +{ + int i, j; + + /* XXX flesh out the rest */ + for (i = 0; i < 2; i++) { + printf(" pwrPdg:"); + for (j = 0; j < 5; j++) { + printf("[%d][%d]=%d, ", i, j, f->pwrPdg[i][j]); + } + printf("\n"); + + printf(" vpdPdg:"); + for (j = 0; j < 5; j++) { + printf("[%d][%d]=%d, ", i, j, f->vpdPdg[i][j]); + } + printf("\n"); + + printf(" pcdac:"); + for (j = 0; j < 5; j++) { + printf("[%d][%d]=%d, ", i, j, f->pcdac[i][j]); + } + printf("\n"); + + printf(" empty:"); + for (j = 0; j < 5; j++) { + printf("[%d][%d]=%d, ", i, j, f->empty[i][j]); + } + printf("\n\n"); + } +} + +void +eeprom_9287_calfreqpiers_print(uint16_t *buf) +{ + HAL_EEPROM_9287 *eep = (HAL_EEPROM_9287 *) buf; + int i, n; + + /* 2ghz cal piers */ + printf("calFreqPier2G: "); + for (i = 0; i < AR9287_NUM_2G_CAL_PIERS; i++) { + printf(" 0x%.2x ", eep->ee_base.calFreqPier2G[i]); + } + printf("|\n"); + + for (i = 0; i < AR9287_NUM_2G_CAL_PIERS; i++) { + if (eep->ee_base.calFreqPier2G[i] == 0xff) + continue; + printf("2Ghz Cal Pier %d\n", i); + for (n = 0; n < AR9287_MAX_CHAINS; n++) { + printf(" Chain %d:\n", n); + eeprom_9287_print_caldata_oploop((void *)&eep->ee_base.calPierData2G[n][i]); + } + } + + printf("\n"); +} + +/* XXX these should just reference the v14 print routines */ +static void +eeprom_v14_target_legacy_print(CAL_TARGET_POWER_LEG *l) +{ + int i; + if (l->bChannel == 0xff) + return; + printf(" bChannel: %d;", l->bChannel); + for (i = 0; i < 4; i++) { + printf(" %.2f", (float) l->tPow2x[i] / 2.0); + } + printf(" (dBm)\n"); +} + +static void +eeprom_v14_target_ht_print(CAL_TARGET_POWER_HT *l) +{ + int i; + if (l->bChannel == 0xff) + return; + printf(" bChannel: %d;", l->bChannel); + for (i = 0; i < 8; i++) { + printf(" %.2f", (float) l->tPow2x[i] / 2.0); + } + printf(" (dBm)\n"); +} + +void +eeprom_9287_print_targets(uint16_t *buf) +{ + HAL_EEPROM_9287 *eep = (HAL_EEPROM_9287 *) buf; + int i; + + /* 2ghz rates */ + printf("2Ghz CCK:\n"); + for (i = 0; i < AR9287_NUM_2G_CCK_TARGET_POWERS; i++) { + eeprom_v14_target_legacy_print(&eep->ee_base.calTargetPowerCck[i]); + } + printf("2Ghz 11g:\n"); + for (i = 0; i < AR9287_NUM_2G_20_TARGET_POWERS; i++) { + eeprom_v14_target_legacy_print(&eep->ee_base.calTargetPower2G[i]); + } + printf("2Ghz HT20:\n"); + for (i = 0; i < AR9287_NUM_2G_20_TARGET_POWERS; i++) { + eeprom_v14_target_ht_print(&eep->ee_base.calTargetPower2GHT20[i]); + } + printf("2Ghz HT40:\n"); + for (i = 0; i < AR9287_NUM_2G_40_TARGET_POWERS; i++) { + eeprom_v14_target_ht_print(&eep->ee_base.calTargetPower2GHT40[i]); + } + +} + +static void +eeprom_9287_ctl_edge_print(struct cal_ctl_data_ar9287 *ctl) +{ + int i, j; + uint8_t pow, flag; + + for (i = 0; i < AR9287_MAX_CHAINS; i++) { + printf(" chain %d: ", i); + for (j = 0; j < AR9287_NUM_BAND_EDGES; j++) { + pow = ctl->ctlEdges[i][j].tPowerFlag & 0x3f; + flag = (ctl->ctlEdges[i][j].tPowerFlag & 0xc0) >> 6; + printf(" %d:pow=%d,flag=%.2x", j, pow, flag); + } + printf("\n"); + } +} + +void +eeprom_9287_ctl_print(uint16_t *buf) +{ + HAL_EEPROM_9287 *eep = (HAL_EEPROM_9287 *) buf; + int i; + + for (i = 0; i < AR9287_NUM_CTLS; i++) { + if (eep->ee_base.ctlIndex[i] == 0) + continue; + printf("| ctlIndex: offset %d, value %d\n", i, eep->ee_base.ctlIndex[i]); + eeprom_9287_ctl_edge_print(&eep->ee_base.ctlData[i]); + } +} + +void +eeprom_9287_print_edges(uint16_t *buf) +{ + HAL_EEPROM_9287 *eep = (HAL_EEPROM_9287 *) buf; + int i; + + printf("| eeNumCtls: %d\n", eep->ee_numCtls); + for (i = 0; i < NUM_EDGES*eep->ee_numCtls; i++) { + /* XXX is flag 8 or 32 bits? */ + printf("| edge %2d/%2d: rdEdge: %5d EdgePower: %.2f dBm Flag: 0x%.8x\n", + i / NUM_EDGES, i % NUM_EDGES, + eep->ee_rdEdgesPower[i].rdEdge, + (float) eep->ee_rdEdgesPower[i].twice_rdEdgePower / 2.0, + eep->ee_rdEdgesPower[i].flag); + + if (i % NUM_EDGES == (NUM_EDGES -1)) + printf("|\n"); + } +} + +void +eeprom_9287_print_other(uint16_t *buf) +{ + HAL_EEPROM_9287 *eep = (HAL_EEPROM_9287 *) buf; +} diff --git a/tools/tools/ath/ath_ee_9287_print/9287.h b/tools/tools/ath/ath_ee_9287_print/9287.h new file mode 100644 index 000000000000..4cfc4241fdf3 --- /dev/null +++ b/tools/tools/ath/ath_ee_9287_print/9287.h @@ -0,0 +1,15 @@ +/* $FreeBSD$ */ + +#ifndef __9287_H__ +#define __9287_H__ + +extern void eeprom_9287_base_print(uint16_t *buf); +extern void eeprom_9287_custdata_print(uint16_t *buf); +extern void eeprom_9287_modal_print(uint16_t *buf); +extern void eeprom_9287_calfreqpiers_print(uint16_t *buf); +extern void eeprom_9287_ctl_print(uint16_t *buf); +extern void eeprom_9287_print_targets(uint16_t *buf); +extern void eeprom_9287_print_edges(uint16_t *buf); +extern void eeprom_9287_print_other(uint16_t *buf); + +#endif diff --git a/tools/tools/ath/ath_ee_9287_print/Makefile b/tools/tools/ath/ath_ee_9287_print/Makefile new file mode 100644 index 000000000000..b25172bfead5 --- /dev/null +++ b/tools/tools/ath/ath_ee_9287_print/Makefile @@ -0,0 +1,12 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../../../sys/dev/ath/ath_hal + +PROG= ath_ee_9287_print +SRCS= main.c eeprom.c 9287.c +NOMAN= yes +NO_MAN= yes + +.include <../Makefile.inc> + +.include <bsd.prog.mk> diff --git a/tools/tools/ath/ath_ee_9287_print/eeprom.c b/tools/tools/ath/ath_ee_9287_print/eeprom.c new file mode 100644 index 000000000000..9e5c865a48da --- /dev/null +++ b/tools/tools/ath/ath_ee_9287_print/eeprom.c @@ -0,0 +1,72 @@ + +/* + * Copyright (c) 2010-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 <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <err.h> + +#include "eeprom.h" + +void +load_eeprom_dump(const char *file, uint16_t *buf) +{ + unsigned int r[8]; + FILE *fp; + char b[1024]; + int i; + + fp = fopen(file, "r"); + if (!fp) + err(1, "fopen"); + + while (!feof(fp)) { + if (fgets(b, 1024, fp) == NULL) + break; + if (feof(fp)) + break; + if (strlen(b) > 0) + b[strlen(b)-1] = '\0'; + if (strlen(b) == 0) + break; + sscanf(b, "%x: %x %x %x %x %x %x %x %x\n", + &i, &r[0], &r[1], &r[2], &r[3], &r[4], + &r[5], &r[6], &r[7]); + buf[i++] = r[0]; + buf[i++] = r[1]; + buf[i++] = r[2]; + buf[i++] = r[3]; + buf[i++] = r[4]; + buf[i++] = r[5]; + buf[i++] = r[6]; + buf[i++] = r[7]; + } + fclose(fp); +} diff --git a/tools/tools/ath/ath_ee_9287_print/eeprom.h b/tools/tools/ath/ath_ee_9287_print/eeprom.h new file mode 100644 index 000000000000..a5fc76a9b58d --- /dev/null +++ b/tools/tools/ath/ath_ee_9287_print/eeprom.h @@ -0,0 +1,8 @@ +/* $FreeBSD$ */ + +#ifndef __EEPROM_H__ +#define __EEPROM_H__ + +extern void load_eeprom_dump(const char *file, uint16_t *buf); + +#endif diff --git a/tools/tools/ath/ath_ee_9287_print/main.c b/tools/tools/ath/ath_ee_9287_print/main.c new file mode 100644 index 000000000000..128b01fe4092 --- /dev/null +++ b/tools/tools/ath/ath_ee_9287_print/main.c @@ -0,0 +1,85 @@ + +/* + * Copyright (c) 2010-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 <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <err.h> + +#include "eeprom.h" +#include "9287.h" + +void +usage(char *argv[]) +{ + printf("Usage: %s <eeprom dump file>\n", argv[0]); + printf("\n"); + printf(" The eeprom dump file is a text hexdump of an EEPROM.\n"); + printf(" The lines must be formatted as follows:\n"); + printf(" 0xAAAA: 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD\n"); + printf(" where each line must have exactly eight data bytes.\n"); + exit(127); +} + +int +main(int argc, char *argv[]) +{ + uint16_t *eep = NULL; + eep = calloc(4096, sizeof(int16_t)); + + if (argc < 2) + usage(argv); + + load_eeprom_dump(argv[1], eep); + + eeprom_9287_base_print(eep); + eeprom_9287_custdata_print(eep); + printf("\n2.4ghz:\n"); + eeprom_9287_modal_print(eep); + printf("\n"); + + eeprom_9287_calfreqpiers_print(eep); + printf("\n"); + + eeprom_9287_print_targets(eep); + printf("\n"); + + eeprom_9287_ctl_print(eep); + printf("\n"); + + eeprom_9287_print_edges(eep); + printf("\n"); + + eeprom_9287_print_other(eep); + printf("\n"); + + free(eep); + exit(0); +} diff --git a/tools/tools/ath/ath_ee_v14_print/Makefile b/tools/tools/ath/ath_ee_v14_print/Makefile new file mode 100644 index 000000000000..552aaa0313f7 --- /dev/null +++ b/tools/tools/ath/ath_ee_v14_print/Makefile @@ -0,0 +1,11 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../../../sys/dev/ath/ath_hal + +PROG= ath_ee_v14_print +NOMAN= yes +NO_MAN= yes + +.include <../Makefile.inc> + +.include <bsd.prog.mk> diff --git a/tools/tools/ath/ath_ee_v14_print/ath_ee_v14_print.c b/tools/tools/ath/ath_ee_v14_print/ath_ee_v14_print.c new file mode 100644 index 000000000000..1340c78a814a --- /dev/null +++ b/tools/tools/ath/ath_ee_v14_print/ath_ee_v14_print.c @@ -0,0 +1,473 @@ + +/* + * Copyright (c) 2010-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 <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <err.h> + +typedef enum { + AH_FALSE = 0, /* NB: lots of code assumes false is zero */ + AH_TRUE = 1, +} HAL_BOOL; + +typedef enum { + HAL_OK = 0, /* No error */ +} HAL_STATUS; + +struct ath_hal; + +#include "ah_eeprom_v14.h" + +void +load_eeprom_dump(const char *file, uint16_t *buf) +{ + unsigned int r[8]; + FILE *fp; + char b[1024]; + int i; + + fp = fopen(file, "r"); + if (!fp) + err(1, "fopen"); + + while (!feof(fp)) { + if (fgets(b, 1024, fp) == NULL) + break; + if (feof(fp)) + break; + if (strlen(b) > 0) + b[strlen(b)-1] = '\0'; + if (strlen(b) == 0) + break; + sscanf(b, "%x: %x %x %x %x %x %x %x %x\n", + &i, &r[0], &r[1], &r[2], &r[3], &r[4], + &r[5], &r[6], &r[7]); + buf[i++] = r[0]; + buf[i++] = r[1]; + buf[i++] = r[2]; + buf[i++] = r[3]; + buf[i++] = r[4]; + buf[i++] = r[5]; + buf[i++] = r[6]; + buf[i++] = r[7]; + } + fclose(fp); +} + +static void +eeprom_v14_base_print(uint16_t *buf) +{ + HAL_EEPROM_v14 *eep = (HAL_EEPROM_v14 *) buf; + BASE_EEP_HEADER *eh = &eep->ee_base.baseEepHeader; + int i; + + printf("| Version: 0x%.4x | Length: 0x%.4x | Checksum: 0x%.4x ", + eh->version, eh->length, eh->checksum); + printf("| CapFlags: 0x%.2x\n", eh->opCapFlags); + + printf("| eepMisc: 0x%.2x | RegDomain: 0x%.4x 0x%.4x | \n", + eh->eepMisc, eh->regDmn[0], eh->regDmn[1]); + printf("| MAC: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x ", + eh->macAddr[0], eh->macAddr[1], eh->macAddr[2], + eh->macAddr[3], eh->macAddr[4], eh->macAddr[5]); + printf("| RxMask: 0x%.2x | TxMask: 0x%.2x | RfSilent: 0x%.4x | btOptions: 0x%.4x |\n", + eh->rxMask, eh->txMask, eh->rfSilent, eh->blueToothOptions); + printf("| DeviceCap: 0x%.4x | binBuildNumber: %.8x | deviceType: 0x%.2x |\n", + eh->deviceCap, eh->binBuildNumber, eh->deviceType); + + printf("| pwdclkind: 0x%.2x | fastClk5g: 0x%.2x | divChain: 0x%.2x | rxGainType: 0x%.2x |\n", + (int) eh->pwdclkind, (int) eh->fastClk5g, (int) eh->divChain, + (int) eh->rxGainType); + + printf("| dacHiPwrMode_5G: 0x%.2x | openLoopPwrCntl: 0x%.2x | dacLpMode: 0x%.2x\n", + (int) eh->dacHiPwrMode_5G, (int) eh->openLoopPwrCntl, (int) eh->dacLpMode); + printf("| txGainType: 0x%.2x | rcChainMask: 0x%.2x |\n", + (int) eh->txGainType, (int) eh->rcChainMask); + + printf("| desiredScaleCCK: 0x%.2x | pwr_table_offset: 0x%.2x | frac_n_5g: %.2x\n", + (int) eh->desiredScaleCCK, (int) eh->pwr_table_offset, (int) eh->frac_n_5g); + + /* because it's convienent */ + printf("| antennaGainMax[0]: 0x%.2x antennaGainMax[1]: 0x%.2x |\n", + eep->ee_antennaGainMax[0], eep->ee_antennaGainMax[1]); + + printf(" | futureBase:"); + for (i = 0; i < sizeof(eh->futureBase) / sizeof(uint8_t); i++) + printf(" %.2x", (int) eh->futureBase[i]); + printf("\n"); +} + +static void +eeprom_v14_custdata_print(uint16_t *buf) +{ + HAL_EEPROM_v14 *eep = (HAL_EEPROM_v14 *) buf; + uint8_t *custdata = (uint8_t *) &eep->ee_base.custData; + int i; + + printf("\n| Custdata: |\n"); + for (i = 0; i < 64; i++) { + printf("%s0x%.2x %s", + i % 16 == 0 ? "| " : "", + custdata[i], + i % 16 == 15 ? "|\n" : ""); + } +} + +static void +eeprom_v14_modal_print(uint16_t *buf, int m) +{ + HAL_EEPROM_v14 *eep = (HAL_EEPROM_v14 *) buf; + MODAL_EEP_HEADER *mh = &eep->ee_base.modalHeader[m]; + int i; + + printf("| antCtrlCommon: 0x%.8x |\n", mh->antCtrlCommon); + printf("| switchSettling: 0x%.2x |\n", mh->switchSettling); + printf("| adcDesiredSize: %d |\n| pgaDesiredSize: %.2f dBm |\n", + mh->adcDesiredSize, (float) mh->pgaDesiredSize / 2.0); + + printf("| antCtrlChain: 0:0x%.8x 1:0x%.8x 2:0x%.8x |\n", + mh->antCtrlChain[0], mh->antCtrlChain[1], mh->antCtrlChain[2]); + printf("| antennaGainCh: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n", + mh->antennaGainCh[0], mh->antennaGainCh[1], mh->antennaGainCh[2]); + printf("| txRxAttenCh: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n", + mh->txRxAttenCh[0], mh->txRxAttenCh[1], mh->txRxAttenCh[2]); + printf("| rxTxMarginCh: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n", + mh->rxTxMarginCh[0], mh->rxTxMarginCh[1], mh->rxTxMarginCh[2]); + printf("| noiseFloorThresCh: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n", + mh->noiseFloorThreshCh[0], mh->noiseFloorThreshCh[1], mh->noiseFloorThreshCh[2]); + printf("| xlnaGainCh: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n", + mh->xlnaGainCh[0], mh->xlnaGainCh[1], mh->xlnaGainCh[2]); + printf("| iqCalICh: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n| iqCalQCh: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n", + mh->iqCalICh[0], mh->iqCalICh[1], mh->iqCalICh[2], + mh->iqCalQCh[0], mh->iqCalQCh[1], mh->iqCalQCh[2]); + printf("| bswAtten: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n", + mh->bswAtten[0], mh->bswAtten[1], mh->bswAtten[2]); + printf("| bswMargin: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n", + mh->bswMargin[0], mh->bswMargin[1], mh->bswMargin[2]); + printf("| xatten2Db: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n", + mh->xatten2Db[0], mh->xatten2Db[1], mh->xatten2Db[2]); + printf("| xatten2Margin: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n", + mh->xatten2Margin[0], mh->xatten2Margin[1], mh->xatten2Margin[2]); + + printf("| txEndToXpaOff: 0x%.2x | txEndToRxOn: 0x%.2x | txFrameToXpaOn: 0x%.2x |\n", + mh->txEndToXpaOff, mh->txEndToRxOn, mh->txFrameToXpaOn); + + printf("| thres62: 0x%.2x\n", mh->thresh62); + + printf("| xpdGain: 0x%.2x | xpd: 0x%.2x |\n", mh->xpdGain, mh->xpd); + printf("| xpaBiasLvlFreq: 0:0x%.4x 1:0x%.4x 2:0x%.4x |\n", + mh->xpaBiasLvlFreq[0], mh->xpaBiasLvlFreq[1], mh->xpaBiasLvlFreq[2]); + + printf("| pdGainOverlap: 0x%.2x | ob: 0x%.2x | db: 0x%.2x | xpaBiasLvl: 0x%.2x |\n", + mh->pdGainOverlap, mh->ob, mh->db, mh->xpaBiasLvl); + + printf("| pwrDecreaseFor2Chain: 0x%.2x | pwrDecreaseFor3Chain: 0x%.2x | txFrameToDataStart: 0x%.2x | txFrameToPaOn: 0x%.2x |\n", + mh->pwrDecreaseFor2Chain, mh->pwrDecreaseFor3Chain, mh->txFrameToDataStart, + mh->txFrameToPaOn); + + printf("| ht40PowerIncForPdadc: 0x%.2x |\n", mh->ht40PowerIncForPdadc); + + printf("| swSettleHt40: 0x%.2x |\n", mh->swSettleHt40); + + printf("| ob_ch1: 0x%.2x | db_ch1: 0x%.2x |\n", mh->ob_ch1, mh->db_ch1); + + printf("| flagBits: 0x%.2x | miscBits: 0x%.2x |\n", mh->flagBits, mh->miscBits); + + + printf("| futureModal: 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x |\n", + mh->futureModal[0], + mh->futureModal[1], + mh->futureModal[2], + mh->futureModal[3], + mh->futureModal[4], + mh->futureModal[5]); + + /* and now, spur channels */ + for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { + printf("| Spur %d: spurChan: 0x%.4x spurRangeLow: 0x%.2x spurRangeHigh: 0x%.2x |\n", + i, mh->spurChans[i].spurChan, + (int) mh->spurChans[i].spurRangeLow, + (int) mh->spurChans[i].spurRangeHigh); + } +} + +static void +eeprom_v14_print_caldata_perfreq_op_loop(CAL_DATA_PER_FREQ_OP_LOOP *f) +{ + int i, j; + for (i = 0; i < 2; i++) { + printf(" Gain: %d:\n", i); + for (j = 0; j < 5; j++) { + printf(" %d: pwrPdg: %d, vpdPdg: %d, pcdac: %d, empty: %d\n", + j, f->pwrPdg[i][j], f->vpdPdg[i][j], f->pcdac[i][j], f->empty[i][j]); + } + printf("\n"); + } +} + +static void +eeprom_v14_print_caldata_perfreq(CAL_DATA_PER_FREQ *f) +{ + int i, j; + + for (i = 0; i < AR5416_NUM_PD_GAINS; i++) { + printf(" Gain %d: pwr dBm/vpd: ", i); + for (j = 0; j < AR5416_PD_GAIN_ICEPTS; j++) { + /* These are stored in 0.25dBm increments */ + printf("%d:(%.2f/%d) ", j, (float) f->pwrPdg[i][j] / 4.00, + f->vpdPdg[i][j]); + } + printf("\n"); + } +} + +static void +eeprom_v14_calfreqpiers_print(uint16_t *buf) +{ + HAL_EEPROM_v14 *eep = (HAL_EEPROM_v14 *) buf; + int i, n; + + /* 2ghz cal piers */ + printf("calFreqPier2G: "); + for (i = 0; i < AR5416_NUM_2G_CAL_PIERS; i++) { + printf(" 0x%.2x ", eep->ee_base.calFreqPier2G[i]); + } + printf("|\n"); + + for (i = 0; i < AR5416_NUM_2G_CAL_PIERS; i++) { + if (eep->ee_base.calFreqPier2G[i] == 0xff) + continue; + printf("2Ghz Cal Pier %d\n", i); + for (n = 0; n < AR5416_MAX_CHAINS; n++) { + printf(" Chain %d:\n", n); + if (eep->ee_base.baseEepHeader.openLoopPwrCntl) + eeprom_v14_print_caldata_perfreq_op_loop((void *) (&eep->ee_base.calPierData2G[n][i])); + else + eeprom_v14_print_caldata_perfreq(&eep->ee_base.calPierData2G[n][i]); + } + } + + printf("\n"); + + /* 5ghz cal piers */ + printf("calFreqPier5G: "); + for (i = 0; i < AR5416_NUM_5G_CAL_PIERS; i++) { + printf(" 0x%.2x ", eep->ee_base.calFreqPier5G[i]); + } + printf("|\n"); + for (i = 0; i < AR5416_NUM_5G_CAL_PIERS; i++) { + if (eep->ee_base.calFreqPier5G[i] == 0xff) + continue; + printf("5Ghz Cal Pier %d\n", i); + for (n = 0; n < AR5416_MAX_CHAINS; n++) { + printf(" Chain %d:\n", n); + if (eep->ee_base.baseEepHeader.openLoopPwrCntl) + eeprom_v14_print_caldata_perfreq_op_loop((void *) (&eep->ee_base.calPierData5G[n][i])); + else + eeprom_v14_print_caldata_perfreq(&eep->ee_base.calPierData5G[n][i]); + } + } +} + +static void +eeprom_v14_target_legacy_print(CAL_TARGET_POWER_LEG *l) +{ + int i; + if (l->bChannel == 0xff) + return; + printf(" bChannel: %d;", l->bChannel); + for (i = 0; i < 4; i++) { + printf(" %.2f", (float) l->tPow2x[i] / 2.0); + } + printf(" (dBm)\n"); +} + +static void +eeprom_v14_target_ht_print(CAL_TARGET_POWER_HT *l) +{ + int i; + if (l->bChannel == 0xff) + return; + printf(" bChannel: %d;", l->bChannel); + for (i = 0; i < 8; i++) { + printf(" %.2f", (float) l->tPow2x[i] / 2.0); + } + printf(" (dBm)\n"); +} + +static void +eeprom_v14_print_targets(uint16_t *buf) +{ + HAL_EEPROM_v14 *eep = (HAL_EEPROM_v14 *) buf; + int i; + + /* 2ghz rates */ + printf("2Ghz CCK:\n"); + for (i = 0; i < AR5416_NUM_2G_CCK_TARGET_POWERS; i++) { + eeprom_v14_target_legacy_print(&eep->ee_base.calTargetPowerCck[i]); + } + printf("2Ghz 11g:\n"); + for (i = 0; i < AR5416_NUM_2G_20_TARGET_POWERS; i++) { + eeprom_v14_target_legacy_print(&eep->ee_base.calTargetPower2G[i]); + } + printf("2Ghz HT20:\n"); + for (i = 0; i < AR5416_NUM_2G_20_TARGET_POWERS; i++) { + eeprom_v14_target_ht_print(&eep->ee_base.calTargetPower2GHT20[i]); + } + printf("2Ghz HT40:\n"); + for (i = 0; i < AR5416_NUM_2G_40_TARGET_POWERS; i++) { + eeprom_v14_target_ht_print(&eep->ee_base.calTargetPower2GHT40[i]); + } + + /* 5ghz rates */ + printf("5Ghz 11a:\n"); + for (i = 0; i < AR5416_NUM_5G_20_TARGET_POWERS; i++) { + eeprom_v14_target_legacy_print(&eep->ee_base.calTargetPower5G[i]); + } + printf("5Ghz HT20:\n"); + for (i = 0; i < AR5416_NUM_5G_20_TARGET_POWERS; i++) { + eeprom_v14_target_ht_print(&eep->ee_base.calTargetPower5GHT20[i]); + } + printf("5Ghz HT40:\n"); + for (i = 0; i < AR5416_NUM_5G_40_TARGET_POWERS; i++) { + eeprom_v14_target_ht_print(&eep->ee_base.calTargetPower5GHT40[i]); + } + +} + +static void +eeprom_v14_ctl_edge_print(CAL_CTL_DATA *ctl) +{ + int i, j; + uint8_t pow, flag; + + for (i = 0; i < AR5416_MAX_CHAINS; i++) { + printf(" chain %d: ", i); + for (j = 0; j < AR5416_NUM_BAND_EDGES; j++) { + pow = ctl->ctlEdges[i][j].tPowerFlag & 0x3f; + flag = (ctl->ctlEdges[i][j].tPowerFlag & 0xc0) >> 6; + printf(" %d:pow=%d,flag=%.2x", j, pow, flag); + } + printf("\n"); + } +} + +static void +eeprom_v14_ctl_print(uint16_t *buf) +{ + HAL_EEPROM_v14 *eep = (HAL_EEPROM_v14 *) buf; + int i; + + for (i = 0; i < AR5416_NUM_CTLS; i++) { + if (eep->ee_base.ctlIndex[i] == 0) + continue; + printf("| ctlIndex: offset %d, value %d\n", i, eep->ee_base.ctlIndex[i]); + eeprom_v14_ctl_edge_print(&eep->ee_base.ctlData[i]); + } +} + +static void +eeprom_v14_print_edges(uint16_t *buf) +{ + HAL_EEPROM_v14 *eep = (HAL_EEPROM_v14 *) buf; + int i; + + printf("| eeNumCtls: %d\n", eep->ee_numCtls); + for (i = 0; i < NUM_EDGES*eep->ee_numCtls; i++) { + /* XXX is flag 8 or 32 bits? */ + printf("| edge %2d/%2d: rdEdge: %5d EdgePower: %.2f dBm Flag: 0x%.8x\n", + i / NUM_EDGES, i % NUM_EDGES, + eep->ee_rdEdgesPower[i].rdEdge, + (float) eep->ee_rdEdgesPower[i].twice_rdEdgePower / 2.0, + eep->ee_rdEdgesPower[i].flag); + + if (i % NUM_EDGES == (NUM_EDGES -1)) + printf("|\n"); + } +#if 0 +typedef struct { + uint16_t rdEdge; + uint16_t twice_rdEdgePower; + HAL_BOOL flag; + } RD_EDGES_POWER; + +#endif +} + +void +usage(char *argv[]) +{ + printf("Usage: %s <eeprom dump file>\n", argv[0]); + printf("\n"); + printf(" The eeprom dump file is a text hexdump of an EEPROM.\n"); + printf(" The lines must be formatted as follows:\n"); + printf(" 0xAAAA: 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD\n"); + printf(" where each line must have exactly eight data bytes.\n"); + exit(127); +} + +int +main(int argc, char *argv[]) +{ + uint16_t *eep = NULL; + eep = calloc(4096, sizeof(int16_t)); + + if (argc < 2) + usage(argv); + + load_eeprom_dump(argv[1], eep); + + eeprom_v14_base_print(eep); + eeprom_v14_custdata_print(eep); + + /* 2.4ghz */ + printf("\n2.4ghz:\n"); + eeprom_v14_modal_print(eep, 1); + /* 5ghz */ + printf("\n5ghz:\n"); + eeprom_v14_modal_print(eep, 0); + printf("\n"); + + eeprom_v14_calfreqpiers_print(eep); + printf("\n"); + + eeprom_v14_print_targets(eep); + printf("\n"); + + eeprom_v14_ctl_print(eep); + printf("\n"); + + eeprom_v14_print_edges(eep); + printf("\n"); + + free(eep); + exit(0); +} diff --git a/tools/tools/ath/ath_ee_v4k_print/Makefile b/tools/tools/ath/ath_ee_v4k_print/Makefile new file mode 100644 index 000000000000..4bb3225b80b6 --- /dev/null +++ b/tools/tools/ath/ath_ee_v4k_print/Makefile @@ -0,0 +1,12 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../../../sys/dev/ath/ath_hal + +PROG= ath_ee_v4k_print +SRCS= main.c eeprom.c v4k.c +NOMAN= yes +NO_MAN= yes + +.include <../Makefile.inc> + +.include <bsd.prog.mk> diff --git a/tools/tools/ath/ath_ee_v4k_print/eeprom.c b/tools/tools/ath/ath_ee_v4k_print/eeprom.c new file mode 100644 index 000000000000..9e5c865a48da --- /dev/null +++ b/tools/tools/ath/ath_ee_v4k_print/eeprom.c @@ -0,0 +1,72 @@ + +/* + * Copyright (c) 2010-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 <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <err.h> + +#include "eeprom.h" + +void +load_eeprom_dump(const char *file, uint16_t *buf) +{ + unsigned int r[8]; + FILE *fp; + char b[1024]; + int i; + + fp = fopen(file, "r"); + if (!fp) + err(1, "fopen"); + + while (!feof(fp)) { + if (fgets(b, 1024, fp) == NULL) + break; + if (feof(fp)) + break; + if (strlen(b) > 0) + b[strlen(b)-1] = '\0'; + if (strlen(b) == 0) + break; + sscanf(b, "%x: %x %x %x %x %x %x %x %x\n", + &i, &r[0], &r[1], &r[2], &r[3], &r[4], + &r[5], &r[6], &r[7]); + buf[i++] = r[0]; + buf[i++] = r[1]; + buf[i++] = r[2]; + buf[i++] = r[3]; + buf[i++] = r[4]; + buf[i++] = r[5]; + buf[i++] = r[6]; + buf[i++] = r[7]; + } + fclose(fp); +} diff --git a/tools/tools/ath/ath_ee_v4k_print/eeprom.h b/tools/tools/ath/ath_ee_v4k_print/eeprom.h new file mode 100644 index 000000000000..a5fc76a9b58d --- /dev/null +++ b/tools/tools/ath/ath_ee_v4k_print/eeprom.h @@ -0,0 +1,8 @@ +/* $FreeBSD$ */ + +#ifndef __EEPROM_H__ +#define __EEPROM_H__ + +extern void load_eeprom_dump(const char *file, uint16_t *buf); + +#endif diff --git a/tools/tools/ath/ath_ee_v4k_print/main.c b/tools/tools/ath/ath_ee_v4k_print/main.c new file mode 100644 index 000000000000..5ce3c3347766 --- /dev/null +++ b/tools/tools/ath/ath_ee_v4k_print/main.c @@ -0,0 +1,85 @@ + +/* + * Copyright (c) 2010-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 <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <err.h> + +#include "eeprom.h" +#include "v4k.h" + +void +usage(char *argv[]) +{ + printf("Usage: %s <eeprom dump file>\n", argv[0]); + printf("\n"); + printf(" The eeprom dump file is a text hexdump of an EEPROM.\n"); + printf(" The lines must be formatted as follows:\n"); + printf(" 0xAAAA: 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD\n"); + printf(" where each line must have exactly eight data bytes.\n"); + exit(127); +} + +int +main(int argc, char *argv[]) +{ + uint16_t *eep = NULL; + eep = calloc(4096, sizeof(int16_t)); + + if (argc < 2) + usage(argv); + + load_eeprom_dump(argv[1], eep); + + eeprom_v4k_base_print(eep); + eeprom_v4k_custdata_print(eep); + printf("\n2.4ghz:\n"); + eeprom_v4k_modal_print(eep); + printf("\n"); + + eeprom_v4k_calfreqpiers_print(eep); + printf("\n"); + + eeprom_v4k_print_targets(eep); + printf("\n"); + + eeprom_v4k_ctl_print(eep); + printf("\n"); + + eeprom_v4k_print_edges(eep); + printf("\n"); + + eeprom_v4k_print_other(eep); + printf("\n"); + + free(eep); + exit(0); +} diff --git a/tools/tools/ath/ath_ee_v4k_print/v4k.c b/tools/tools/ath/ath_ee_v4k_print/v4k.c new file mode 100644 index 000000000000..a3a8e6d28b3b --- /dev/null +++ b/tools/tools/ath/ath_ee_v4k_print/v4k.c @@ -0,0 +1,300 @@ + +/* + * Copyright (c) 2010-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 <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <err.h> + +typedef enum { + AH_FALSE = 0, /* NB: lots of code assumes false is zero */ + AH_TRUE = 1, +} HAL_BOOL; + +typedef enum { + HAL_OK = 0, /* No error */ +} HAL_STATUS; + +struct ath_hal; + +#include "ah_eeprom_v4k.h" + +void +eeprom_v4k_base_print(uint16_t *buf) +{ + HAL_EEPROM_v4k *eep = (HAL_EEPROM_v4k *) buf; + BASE_EEP4K_HEADER *eh = &eep->ee_base.baseEepHeader; + + printf("| Version: 0x%.4x | Length: 0x%.4x | Checksum: 0x%.4x ", + eh->version, eh->length, eh->checksum); + printf("| CapFlags: 0x%.2x | eepMisc: 0x%.2x | RegDomain: 0x%.4x 0x%.4x | \n", + eh->opCapFlags, eh->eepMisc, eh->regDmn[0], eh->regDmn[1]); + printf("| MAC: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x ", + eh->macAddr[0], eh->macAddr[1], eh->macAddr[2], + eh->macAddr[3], eh->macAddr[4], eh->macAddr[5]); + printf("| RxMask: 0x%.2x | TxMask: 0x%.2x | RfSilent: 0x%.4x | btOptions: 0x%.4x |\n", + eh->rxMask, eh->txMask, eh->rfSilent, eh->blueToothOptions); + printf("| DeviceCap: 0x%.4x | binBuildNumber: %.8x | deviceType: 0x%.2x | txGainType 0x%.2x |\n", + eh->deviceCap, eh->binBuildNumber, eh->deviceType, eh->txGainType); +} + +void +eeprom_v4k_custdata_print(uint16_t *buf) +{ + HAL_EEPROM_v4k *eep = (HAL_EEPROM_v4k *) buf; + uint8_t *custdata = (uint8_t *) &eep->ee_base.custData; + int i; + + printf("\n| Custdata: |\n"); + for (i = 0; i < 20; i++) { + printf("%s0x%.2x %s", + i % 16 == 0 ? "| " : "", + custdata[i], + i % 16 == 15 ? "|\n" : ""); + } + printf("\n"); +} + +void +eeprom_v4k_modal_print(uint16_t *buf) +{ + HAL_EEPROM_v4k *eep = (HAL_EEPROM_v4k *) buf; + MODAL_EEP4K_HEADER *mh = &eep->ee_base.modalHeader; + int i; + + printf("| antCtrlCommon: 0x%.8x |\n", mh->antCtrlCommon); + printf("| switchSettling: 0x%.2x |\n", mh->switchSettling); + printf("| adcDesiredSize: %d |\n| pgaDesiredSize: %.2f dBm |\n", + mh->adcDesiredSize, (float) mh->pgaDesiredSize / 2.0); + + printf("| antCtrlChain: 0:0x%.4x |\n", mh->antCtrlChain[0]); + printf("| antennaGainCh: 0:0x%.2x |\n", mh->antennaGainCh[0]); + printf("| txRxAttenCh: 0:0x%.2x |\n", mh->txRxAttenCh[0]); + printf("| rxTxMarginCh: 0:0x%.2x |\n", mh->rxTxMarginCh[0]); + printf("| noiseFloorThresCh: 0:0x%.2x |\n", mh->noiseFloorThreshCh[0]); + printf("| xlnaGainCh: 0:0x%.2x |\n", mh->xlnaGainCh[0]); + printf("| iqCalICh: 0:0x%.2x |\n", mh->iqCalICh[0]); + printf("| iqCalQCh: 0:0x%.2x |\n", mh->iqCalQCh[0]); + printf("| bswAtten: 0:0x%.2x |\n", mh->bswAtten[0]); + printf("| bswMargin: 0:0x%.2x |\n", mh->bswMargin[0]); + printf("| xatten2Db: 0:0x%.2x |\n", mh->xatten2Db[0]); + printf("| xatten2Margin: 0:0x%.2x |\n", mh->xatten2Margin[0]); + + printf("| txEndToXpaOff: 0x%.2x | txEndToRxOn: 0x%.2x | txFrameToXpaOn: 0x%.2x |\n", + mh->txEndToXpaOff, mh->txEndToRxOn, mh->txFrameToXpaOn); + printf("| thres62: 0x%.2x\n", mh->thresh62); + printf("| xpdGain: 0x%.2x | xpd: 0x%.2x |\n", mh->xpdGain, mh->xpd); + + printf("| pdGainOverlap: 0x%.2x xpaBiasLvl: 0x%.2x |\n", mh->pdGainOverlap, mh->xpaBiasLvl); + printf("| txFrameToDataStart: 0x%.2x | txFrameToPaOn: 0x%.2x |\n", mh->txFrameToDataStart, mh->txFrameToPaOn); + printf("| ht40PowerIncForPdadc: 0x%.2x |\n", mh->ht40PowerIncForPdadc); + printf("| swSettleHt40: 0x%.2x |\n", mh->swSettleHt40); + + printf("| ob_0: 0x%.2x | ob_1: 0x%.2x | ob_2: 0x%.2x | ob_3: 0x%.2x |\n", + mh->ob_0, mh->ob_1, mh->ob_2, mh->ob_3); + printf("| db_1_0: 0x%.2x | db_1_1: 0x%.2x | db_1_2: 0x%.2x | db_1_3: 0x%.2x db_1_4: 0x%.2x|\n", + mh->db1_0, mh->db1_1, mh->db1_2, mh->db1_3, mh->db1_4); + printf("| db_1_0: 0x%.2x | db_1_1: 0x%.2x | db_1_2: 0x%.2x | db_1_3: 0x%.2x db_1_4: 0x%.2x|\n", + mh->db2_0, mh->db2_1, mh->db2_2, mh->db2_3, mh->db2_4); + + printf("| antdiv_ctl1: 0x%.2x antdiv_ctl2: 0x%.2x |\n", mh->antdiv_ctl1, mh->antdiv_ctl2); + + printf("| Modal Version: %.2x |\n", mh->version); + + printf("| futureModal: 0x%.2x 0x%.2x 0x%.2x 0x%.2x |\n", + mh->futureModal[0], + mh->futureModal[1], + mh->futureModal[2], + mh->futureModal[3] + ); + + /* and now, spur channels */ + for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { + printf("| Spur %d: spurChan: 0x%.4x spurRangeLow: 0x%.2x spurRangeHigh: 0x%.2x |\n", + i, mh->spurChans[i].spurChan, + (int) mh->spurChans[i].spurRangeLow, + (int) mh->spurChans[i].spurRangeHigh); + } +} + +static void +eeprom_v4k_print_caldata_perfreq(CAL_DATA_PER_FREQ_4K *f) +{ + int i, j; + + for (i = 0; i < AR5416_4K_NUM_PD_GAINS; i++) { + printf(" Gain %d: pwr dBm/vpd: ", i); + for (j = 0; j < AR5416_PD_GAIN_ICEPTS; j++) { + /* These are stored in 0.25dBm increments */ + /* XXX is this assumption correct for ar9285? */ + /* XXX shouldn't we care about the power table offset, if there is one? */ + printf("%d:(%.2f/%d) ", j, (float) f->pwrPdg[i][j] / 4.00, + f->vpdPdg[i][j]); + } + printf("\n"); + } +} + +void +eeprom_v4k_calfreqpiers_print(uint16_t *buf) +{ + HAL_EEPROM_v4k *eep = (HAL_EEPROM_v4k *) buf; + int i, n; + + /* 2ghz cal piers */ + printf("calFreqPier2G: "); + for (i = 0; i < AR5416_4K_NUM_2G_CAL_PIERS; i++) { + printf(" 0x%.2x ", eep->ee_base.calFreqPier2G[i]); + } + printf("|\n"); + + for (i = 0; i < AR5416_4K_NUM_2G_CAL_PIERS; i++) { + if (eep->ee_base.calFreqPier2G[i] == 0xff) + continue; + printf("2Ghz Cal Pier %d\n", i); + for (n = 0; n < AR5416_4K_MAX_CHAINS; n++) { + printf(" Chain %d:\n", n); + eeprom_v4k_print_caldata_perfreq(&eep->ee_base.calPierData2G[n][i]); + } + } + + printf("\n"); +} + +/* XXX these should just reference the v14 print routines */ +static void +eeprom_v14_target_legacy_print(CAL_TARGET_POWER_LEG *l) +{ + int i; + if (l->bChannel == 0xff) + return; + printf(" bChannel: %d;", l->bChannel); + for (i = 0; i < 4; i++) { + printf(" %.2f", (float) l->tPow2x[i] / 2.0); + } + printf(" (dBm)\n"); +} + +static void +eeprom_v14_target_ht_print(CAL_TARGET_POWER_HT *l) +{ + int i; + if (l->bChannel == 0xff) + return; + printf(" bChannel: %d;", l->bChannel); + for (i = 0; i < 8; i++) { + printf(" %.2f", (float) l->tPow2x[i] / 2.0); + } + printf(" (dBm)\n"); +} + +void +eeprom_v4k_print_targets(uint16_t *buf) +{ + HAL_EEPROM_v4k *eep = (HAL_EEPROM_v4k *) buf; + int i; + + /* 2ghz rates */ + printf("2Ghz CCK:\n"); + for (i = 0; i < AR5416_4K_NUM_2G_CCK_TARGET_POWERS; i++) { + eeprom_v14_target_legacy_print(&eep->ee_base.calTargetPowerCck[i]); + } + printf("2Ghz 11g:\n"); + for (i = 0; i < AR5416_4K_NUM_2G_20_TARGET_POWERS; i++) { + eeprom_v14_target_legacy_print(&eep->ee_base.calTargetPower2G[i]); + } + printf("2Ghz HT20:\n"); + for (i = 0; i < AR5416_4K_NUM_2G_20_TARGET_POWERS; i++) { + eeprom_v14_target_ht_print(&eep->ee_base.calTargetPower2GHT20[i]); + } + printf("2Ghz HT40:\n"); + for (i = 0; i < AR5416_4K_NUM_2G_40_TARGET_POWERS; i++) { + eeprom_v14_target_ht_print(&eep->ee_base.calTargetPower2GHT40[i]); + } + +} + +static void +eeprom_v4k_ctl_edge_print(CAL_CTL_DATA_4K *ctl) +{ + int i, j; + uint8_t pow, flag; + + for (i = 0; i < AR5416_4K_MAX_CHAINS; i++) { + printf(" chain %d: ", i); + for (j = 0; j < AR5416_4K_NUM_BAND_EDGES; j++) { + pow = ctl->ctlEdges[i][j].tPowerFlag & 0x3f; + flag = (ctl->ctlEdges[i][j].tPowerFlag & 0xc0) >> 6; + printf(" %d:pow=%d,flag=%.2x", j, pow, flag); + } + printf("\n"); + } +} + +void +eeprom_v4k_ctl_print(uint16_t *buf) +{ + HAL_EEPROM_v4k *eep = (HAL_EEPROM_v4k *) buf; + int i; + + for (i = 0; i < AR5416_4K_NUM_CTLS; i++) { + if (eep->ee_base.ctlIndex[i] == 0) + continue; + printf("| ctlIndex: offset %d, value %d\n", i, eep->ee_base.ctlIndex[i]); + eeprom_v4k_ctl_edge_print(&eep->ee_base.ctlData[i]); + } +} + +void +eeprom_v4k_print_edges(uint16_t *buf) +{ + HAL_EEPROM_v4k *eep = (HAL_EEPROM_v4k *) buf; + int i; + + printf("| eeNumCtls: %d\n", eep->ee_numCtls); + for (i = 0; i < NUM_EDGES*eep->ee_numCtls; i++) { + /* XXX is flag 8 or 32 bits? */ + printf("| edge %2d/%2d: rdEdge: %5d EdgePower: %.2f dBm Flag: 0x%.8x\n", + i / NUM_EDGES, i % NUM_EDGES, + eep->ee_rdEdgesPower[i].rdEdge, + (float) eep->ee_rdEdgesPower[i].twice_rdEdgePower / 2.0, + eep->ee_rdEdgesPower[i].flag); + + if (i % NUM_EDGES == (NUM_EDGES -1)) + printf("|\n"); + } +} + +void +eeprom_v4k_print_other(uint16_t *buf) +{ + HAL_EEPROM_v4k *eep = (HAL_EEPROM_v4k *) buf; + printf("| ee_antennaGainMax: %.2x\n", eep->ee_antennaGainMax); +} diff --git a/tools/tools/ath/ath_ee_v4k_print/v4k.h b/tools/tools/ath/ath_ee_v4k_print/v4k.h new file mode 100644 index 000000000000..efe2dc945b86 --- /dev/null +++ b/tools/tools/ath/ath_ee_v4k_print/v4k.h @@ -0,0 +1,15 @@ +/* $FreeBSD$ */ + +#ifndef __V4K_H__ +#define __V4K_H__ + +extern void eeprom_v4k_base_print(uint16_t *buf); +extern void eeprom_v4k_custdata_print(uint16_t *buf); +extern void eeprom_v4k_modal_print(uint16_t *buf); +extern void eeprom_v4k_calfreqpiers_print(uint16_t *buf); +extern void eeprom_v4k_ctl_print(uint16_t *buf); +extern void eeprom_v4k_print_targets(uint16_t *buf); +extern void eeprom_v4k_print_edges(uint16_t *buf); +extern void eeprom_v4k_print_other(uint16_t *buf); + +#endif diff --git a/tools/tools/ath/ath_prom_read/Makefile b/tools/tools/ath/ath_prom_read/Makefile new file mode 100644 index 000000000000..8183200f6f36 --- /dev/null +++ b/tools/tools/ath/ath_prom_read/Makefile @@ -0,0 +1,22 @@ +# $FreeBSD$ + +PROG= ath_prom_read + +.include <bsd.prog.mk> + +.include <../Makefile.inc> + +CLEANFILES+= opt_ah.h ah_osdep.h + +CFLAGS+=-DATH_SUPPORT_ANI +CFLAGS+=-DATH_SUPPORT_TDMA + +CFLAGS+=-I${.CURDIR} +CFLAGS+=-I${SRCDIR}/sys/net80211 + +opt_ah.h: + touch opt_ah.h +ah_osdep.h: + echo 'typedef void *HAL_SOFTC;' >ah_osdep.h + echo 'typedef int HAL_BUS_TAG;' >>ah_osdep.h + echo 'typedef void *HAL_BUS_HANDLE;' >>ah_osdep.h diff --git a/tools/tools/ath/ath_prom_read/ath_prom_read.c b/tools/tools/ath/ath_prom_read/ath_prom_read.c new file mode 100644 index 000000000000..f123aaa186b3 --- /dev/null +++ b/tools/tools/ath/ath_prom_read/ath_prom_read.c @@ -0,0 +1,134 @@ +/*- + * Copyright (c) 2008 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$ + */ +#include "diag.h" + +#include "ah.h" +#include "ah_diagcodes.h" + +#include <getopt.h> +#include <errno.h> +#include <err.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +struct ath_diag atd; +int s; +const char *progname; + +/* XXX this should likely be defined somewhere in the HAL */ +/* XXX This is a lot larger than the v14 ROM */ +#define MAX_EEPROM_SIZE 16384 + +uint16_t eep[MAX_EEPROM_SIZE]; + +static void +usage() +{ + fprintf(stderr, " %s [-i ifname] -d <dumpfile>\n", progname); + exit(-1); +} + +#define NUM_PER_LINE 8 + +static void +do_eeprom_dump(const char *dumpfile, uint16_t *eebuf, int eelen) +{ + FILE *fp; + int i; + + fp = fopen(dumpfile, "w"); + if (!fp) { + err(1, "fopen"); + } + + /* eelen is in bytes; eebuf is in 2 byte words */ + for (i = 0; i < eelen / 2; i++) { + if (i % NUM_PER_LINE == 0) + fprintf(fp, "%.4x: ", i); + fprintf(fp, "%.4x%s", (int32_t)(eebuf[i]), i % NUM_PER_LINE == (NUM_PER_LINE - 1) ? "\n" : " "); + } + fprintf(fp, "\n"); + fclose(fp); +} + +int +main(int argc, char *argv[]) +{ + FILE *fd = NULL; + const char *ifname; + int c; + const char *dumpname = NULL; + + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) + err(1, "socket"); + ifname = getenv("ATH"); + if (!ifname) + ifname = ATH_DEFAULT; + + progname = argv[0]; + while ((c = getopt(argc, argv, "d:i:t:")) != -1) + switch (c) { + case 'd': + dumpname = optarg; + break; + case 'i': + ifname = optarg; + break; + case 't': + fd = fopen(optarg, "r"); + if (fd == NULL) + err(-1, "Cannot open %s", optarg); + break; + default: + usage(); + /*NOTREACHED*/ + } + argc -= optind; + argv += optind; + + strncpy(atd.ad_name, ifname, sizeof (atd.ad_name)); + + /* Read in the entire EEPROM */ + atd.ad_id = HAL_DIAG_EEPROM; + atd.ad_out_data = (caddr_t) eep; + atd.ad_out_size = sizeof(eep); + if (ioctl(s, SIOCGATHDIAG, &atd) < 0) + err(1, atd.ad_name); + + /* Dump file? Then just write to it */ + if (dumpname != NULL) { + do_eeprom_dump(dumpname, (uint16_t *) &eep, sizeof(eep)); + } + return 0; +} + diff --git a/tools/tools/ath/athctrl.sh b/tools/tools/ath/athctrl.sh new file mode 100644 index 000000000000..5adee1c3c4a4 --- /dev/null +++ b/tools/tools/ath/athctrl.sh @@ -0,0 +1,42 @@ +#! /bin/sh +# +# Set the IFS parameters for an interface configured for +# point-to-point use at a specific distance. Based on a +# program by Gunter Burchardt. +# +# $FreeBSD$ +# +DEV=ath0 +d=0 + +usage() +{ + echo "Usage: $0 [-i athX] [-d meters]" + exit 2 +} + +args=`getopt d:i: $*` +test $? -ne 0 && usage + +set -- $args +for i; do + case "$i" in + -i) DEV="$2"; shift; shift;; + -d) d="$2"; shift; shift;; + --) shift; break; + esac +done + +test $d -eq 0 && usage + +slottime=`expr 9 + \( $d / 300 \)` +if expr \( $d % 300 \) != 0 >/dev/null 2>&1; then + slottime=`expr $slottime + 1` +fi +timeout=`expr $slottime \* 2 + 3` + +printf "Setup IFS parameters on interface ${DEV} for %i meter p-2-p link\n" $d +ATHN=`echo $DEV | sed 's/ath//'` +sysctl dev.ath.$ATHN.slottime=$slottime +sysctl dev.ath.$ATHN.acktimeout=$timeout +sysctl dev.ath.$ATHN.ctstimeout=$timeout diff --git a/tools/tools/ath/athdebug/Makefile b/tools/tools/ath/athdebug/Makefile new file mode 100644 index 000000000000..0b75f26662b0 --- /dev/null +++ b/tools/tools/ath/athdebug/Makefile @@ -0,0 +1,7 @@ +# $FreeBSD$ + +PROG= athdebug + +.include <../Makefile.inc> + +.include <bsd.prog.mk> diff --git a/tools/tools/ath/athdebug/athdebug.c b/tools/tools/ath/athdebug/athdebug.c new file mode 100644 index 000000000000..d1c2c1482614 --- /dev/null +++ b/tools/tools/ath/athdebug/athdebug.c @@ -0,0 +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). + */ +#include <sys/types.h> +#include <sys/file.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <sys/sysctl.h> + +#include <stdio.h> +#include <ctype.h> +#include <getopt.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <err.h> + +#define N(a) (sizeof(a)/sizeof(a[0])) + +const char *progname; + +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; + u_int 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 u_int +getflag(const char *name, int len) +{ + int i; + + for (i = 0; i < N(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 < N(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 < N(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; + u_int32_t debug, ndebug; + size_t debuglen; + char oid[256]; + + ifname = getenv("ATH"); + if (ifname == NULL) + ifname = "ath0"; + 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", + tp-cp, cp); + } + ndebug = bit; + } + } while (*(cp = tp) != '\0'); + } + if (debug != ndebug) { + printf("%s: 0x%x => ", oid, debug); + if (sysctlbyname(oid, NULL, NULL, &ndebug, sizeof(ndebug)) < 0) + err(1, "sysctl-set(%s)", oid); + printf("0x%x", ndebug); + debug = ndebug; + } else + printf("%s: 0x%x", oid, debug); + sep = "<"; + for (i = 0; i < N(flags); i++) + if (debug & flags[i].bit) { + printf("%s%s", sep, flags[i].name); + sep = ","; + } + printf("%s\n", *sep != '<' ? ">" : ""); + return 0; +} diff --git a/tools/tools/ath/athdecode/Makefile b/tools/tools/ath/athdecode/Makefile new file mode 100644 index 000000000000..00c452497a5c --- /dev/null +++ b/tools/tools/ath/athdecode/Makefile @@ -0,0 +1,24 @@ +# +# $FreeBSD$ + +PROG= athdecode + +.PATH.c: ${.CURDIR}/../common + +SRCS= main.c +SRCS+= dumpregs_5210.c +SRCS+= dumpregs_5211.c +SRCS+= dumpregs_5212.c +SRCS+= dumpregs_5416.c +SRCS+= opt_ah.h + +CLEANFILES+= opt_ah.h + +opt_ah.h: + echo "#define AH_DEBUG 1" > opt_ah.h + echo "#define AH_DEBUG_COUNTRY 1" >> opt_ah.h + echo "#define AH_SUPPORT_AR5416 1" >> opt_ah.h + +.include <../Makefile.inc> + +.include <bsd.prog.mk> diff --git a/tools/tools/ath/athdecode/main.c b/tools/tools/ath/athdecode/main.c new file mode 100644 index 000000000000..1ab5c6d317c0 --- /dev/null +++ b/tools/tools/ath/athdecode/main.c @@ -0,0 +1,425 @@ +/*- + * 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$ + */ +#include "diag.h" + +#include "ah.h" +#include "ah_internal.h" +#include "ah_decode.h" + +#include "dumpregs.h" + +#include <stdlib.h> +#include <string.h> +#include <err.h> +#include <sys/file.h> +#include <sys/stat.h> +#include <sys/mman.h> + +typedef struct { + HAL_REVS revs; + int chipnum; +#define MAXREGS 5*1024 + struct dumpreg *regs[MAXREGS]; + u_int nregs; +} dumpregs_t; +static dumpregs_t state; + +static void opdevice(const struct athregrec *r); +static const char* opmark(FILE *, int, const struct athregrec *); +static void oprw(FILE *fd, int recnum, struct athregrec *r); + +int +main(int argc, char *argv[]) +{ + int fd, i, nrecs, same; + struct stat sb; + void *addr; + const char *filename = "/tmp/ath_hal.log"; + struct athregrec *rprev; + + if (argc > 1) + filename = argv[1]; + fd = open(filename, O_RDONLY); + if (fd < 0) + err(1, filename); + if (fstat(fd, &sb) < 0) + err(1, "fstat"); + addr = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE|MAP_NOCORE, fd, 0); + if (addr == MAP_FAILED) + err(1, "mmap"); + nrecs = sb.st_size / sizeof (struct athregrec); + printf("%u records", nrecs); + rprev = NULL; + same = 0; + state.chipnum = 5210; + for (i = 0; i < nrecs; i++) { + struct athregrec *r = &((struct athregrec *) addr)[i]; + if (rprev && bcmp(r, rprev, sizeof (*r)) == 0) { + same++; + continue; + } + if (same) + printf("\t\t+%u time%s", same, same == 1 ? "" : "s"); + switch (r->op) { + case OP_DEVICE: + opdevice(r); + break; + case OP_READ: + case OP_WRITE: + oprw(stdout, i, r); + break; + case OP_MARK: + opmark(stdout, i, r); + break; + } + rprev = r; + same = 0; + } + putchar('\n'); + return 0; +} + +static const char* +opmark(FILE *fd, int i, const struct athregrec *r) +{ + fprintf(fd, "\n%05d: ", i); + switch (r->reg) { + case AH_MARK_RESET: + fprintf(fd, "ar%uReset %s", state.chipnum, + r->val ? "change channel" : "no channel change"); + break; + case AH_MARK_RESET_LINE: + fprintf(fd, "ar%u_reset.c; line %u", state.chipnum, r->val); + break; + case AH_MARK_RESET_DONE: + if (r->val) + fprintf(fd, "ar%uReset (done), FAIL, error %u", + state.chipnum, r->val); + else + fprintf(fd, "ar%uReset (done), OK", state.chipnum); + break; + case AH_MARK_CHIPRESET: + fprintf(fd, "ar%uChipReset, channel %u MHz", state.chipnum, r->val); + break; + case AH_MARK_PERCAL: + fprintf(fd, "ar%uPerCalibration, channel %u MHz", state.chipnum, r->val); + break; + case AH_MARK_SETCHANNEL: + fprintf(fd, "ar%uSetChannel, channel %u MHz", state.chipnum, r->val); + break; + case AH_MARK_ANI_RESET: + switch (r->val) { + case HAL_M_STA: + fprintf(fd, "ar%uAniReset, HAL_M_STA", state.chipnum); + break; + case HAL_M_IBSS: + fprintf(fd, "ar%uAniReset, HAL_M_IBSS", state.chipnum); + break; + case HAL_M_HOSTAP: + fprintf(fd, "ar%uAniReset, HAL_M_HOSTAP", state.chipnum); + break; + case HAL_M_MONITOR: + fprintf(fd, "ar%uAniReset, HAL_M_MONITOR", state.chipnum); + break; + default: + fprintf(fd, "ar%uAniReset, opmode %u", state.chipnum, r->val); + break; + } + break; + case AH_MARK_ANI_POLL: + fprintf(fd, "ar%uAniPoll, listenTime %u", state.chipnum, r->val); + break; + case AH_MARK_ANI_CONTROL: + switch (r->val) { + case HAL_ANI_PRESENT: + fprintf(fd, "ar%uAniControl, PRESENT", state.chipnum); + break; + case HAL_ANI_NOISE_IMMUNITY_LEVEL: + fprintf(fd, "ar%uAniControl, NOISE_IMMUNITY", state.chipnum); + break; + case HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION: + fprintf(fd, "ar%uAniControl, OFDM_WEAK_SIGNAL", state.chipnum); + break; + case HAL_ANI_CCK_WEAK_SIGNAL_THR: + fprintf(fd, "ar%uAniControl, CCK_WEAK_SIGNAL", state.chipnum); + break; + case HAL_ANI_FIRSTEP_LEVEL: + fprintf(fd, "ar%uAniControl, FIRSTEP_LEVEL", state.chipnum); + break; + case HAL_ANI_SPUR_IMMUNITY_LEVEL: + fprintf(fd, "ar%uAniControl, SPUR_IMMUNITY", state.chipnum); + break; + case HAL_ANI_MODE: + fprintf(fd, "ar%uAniControl, MODE", state.chipnum); + break; + case HAL_ANI_PHYERR_RESET: + fprintf(fd, "ar%uAniControl, PHYERR_RESET", state.chipnum); + break; + default: + fprintf(fd, "ar%uAniControl, cmd %u", state.chipnum, r->val); + break; + } + break; + default: + fprintf(fd, "mark #%u value %u/0x%x", r->reg, r->val, r->val); + break; + } +} + +#include "ah_devid.h" + +static void +opdevice(const struct athregrec *r) +{ + switch (r->val) { + case AR5210_PROD: + case AR5210_DEFAULT: + state.chipnum = 5210; + state.revs.ah_macVersion = 1; + state.revs.ah_macRev = 0; + break; + case AR5211_DEVID: + case AR5311_DEVID: + case AR5211_DEFAULT: + case AR5211_FPGA11B: + state.chipnum = 5211; + state.revs.ah_macVersion = 2; + state.revs.ah_macRev = 0; + break; + /* AR5212 */ + case AR5212_DEFAULT: + case AR5212_DEVID: + case AR5212_FPGA: + case AR5212_DEVID_IBM: + case AR5212_AR5312_REV2: + case AR5212_AR5312_REV7: + case AR5212_AR2313_REV8: + case AR5212_AR2315_REV6: + case AR5212_AR2315_REV7: + case AR5212_AR2317_REV1: + case AR5212_AR2317_REV2: + + /* AR5212 compatible devid's also attach to 5212 */ + case AR5212_DEVID_0014: + case AR5212_DEVID_0015: + case AR5212_DEVID_0016: + case AR5212_DEVID_0017: + case AR5212_DEVID_0018: + case AR5212_DEVID_0019: + case AR5212_AR2413: + case AR5212_AR5413: + case AR5212_AR5424: + case AR5212_AR2417: + case AR5212_DEVID_FF19: + state.chipnum = 5212; + state.revs.ah_macVersion = 4; + state.revs.ah_macRev = 5; + break; + + /* AR5213 */ + case AR5213_SREV_1_0: + case AR5213_SREV_REG: + state.chipnum = 5213; + state.revs.ah_macVersion = 5; + state.revs.ah_macRev = 9; + break; + + /* AR5416 compatible devid's */ + case AR5416_DEVID_PCI: + case AR5416_DEVID_PCIE: + case AR9160_DEVID_PCI: + case AR9280_DEVID_PCI: + case AR9280_DEVID_PCIE: + case AR9285_DEVID_PCIE: + state.chipnum = 5416; + state.revs.ah_macVersion = 13; + state.revs.ah_macRev = 8; + break; + default: + printf("Unknown device id 0x%x\n", r->val); + exit(-1); + } +} + +static int +regcompar(const void *a, const void *b) +{ + const struct dumpreg *ra = *(const struct dumpreg **)a; + const struct dumpreg *rb = *(const struct dumpreg **)b; + return ra->addr - rb->addr; +} + +void +register_regs(struct dumpreg *chipregs, u_int nchipregs, + int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max) +{ + const int existing_regs = state.nregs; + int i, j; + + for (i = 0; i < nchipregs; i++) { + struct dumpreg *nr = &chipregs[i]; + if (nr->srevMin == 0) + nr->srevMin = def_srev_min; + if (nr->srevMax == 0) + nr->srevMax = def_srev_max; + if (nr->phyMin == 0) + nr->phyMin = def_phy_min; + if (nr->phyMax == 0) + nr->phyMax = def_phy_max; + for (j = 0; j < existing_regs; j++) { + struct dumpreg *r = state.regs[j]; + /* + * Check if we can just expand the mac+phy + * coverage for the existing entry. + */ + if (nr->addr == r->addr && + (nr->name == r->name || + nr->name != NULL && r->name != NULL && + strcmp(nr->name, r->name) == 0)) { + if (nr->srevMin < r->srevMin && + (r->srevMin <= nr->srevMax && + nr->srevMax+1 <= r->srevMax)) { + r->srevMin = nr->srevMin; + goto skip; + } + if (nr->srevMax > r->srevMax && + (r->srevMin <= nr->srevMin && + nr->srevMin <= r->srevMax)) { + r->srevMax = nr->srevMax; + goto skip; + } + } + if (r->addr > nr->addr) + break; + } + /* + * New item, add to the end, it'll be sorted below. + */ + if (state.nregs == MAXREGS) + errx(-1, "too many registers; bump MAXREGS"); + state.regs[state.nregs++] = nr; + skip: + ; + } + qsort(state.regs, state.nregs, sizeof(struct dumpreg *), regcompar); +} + +void +register_keycache(u_int nslots, + int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max) +{ + /* discard, no use */ +} + +void +register_range(u_int brange, u_int erange, int type, + int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max) +{ + /* discard, no use */ +} + +static const struct dumpreg * +findreg(int reg) +{ + const HAL_REVS *revs = &state.revs; + int i; + + for (i = 0; i < state.nregs; i++) { + const struct dumpreg *dr = state.regs[i]; + if (dr->addr == reg && + MAC_MATCH(dr, revs->ah_macVersion, revs->ah_macRev)) + return dr; + } + return NULL; +} + +/* XXX cheat, 5212 has a superset of the key table defs */ +#include "ar5212/ar5212reg.h" +#include "ar5212/ar5212phy.h" + +#define PWR_TABLE_SIZE 64 + +static void +oprw(FILE *fd, int recnum, struct athregrec *r) +{ + const struct dumpreg *dr; + char buf[64]; + const char* bits; + int i; + + fprintf(fd, "\n%05d: [%d] ", recnum, r->threadid); + dr = findreg(r->reg); + if (dr != NULL && dr->name != NULL) { + snprintf(buf, sizeof (buf), "AR_%s (0x%x)", dr->name, r->reg); + bits = dr->bits; + } else if (AR_KEYTABLE(0) <= r->reg && r->reg < AR_KEYTABLE(128)) { + snprintf(buf, sizeof (buf), "AR_KEYTABLE%u(%u) (0x%x)", + ((r->reg - AR_KEYTABLE_0) >> 2) & 7, + (r->reg - AR_KEYTABLE_0) >> 5, r->reg); + bits = NULL; +#if 0 + } else if (AR_PHY_PCDAC_TX_POWER(0) <= r->reg && r->reg < AR_PHY_PCDAC_TX_POWER(PWR_TABLE_SIZE/2)) { + snprintf(buf, sizeof (buf), "AR_PHY_PCDAC_TX_POWER(%u) (0x%x)", + (r->reg - AR_PHY_PCDAC_TX_POWER_0) >> 2, r->reg); + bits = NULL; +#endif + } else if (AR_RATE_DURATION(0) <= r->reg && r->reg < AR_RATE_DURATION(32)) { + snprintf(buf, sizeof (buf), "AR_RATE_DURATION(0x%x) (0x%x)", + (r->reg - AR_RATE_DURATION_0) >> 2, r->reg); + bits = NULL; + } else if (AR_PHY_BASE <= r->reg) { + snprintf(buf, sizeof (buf), "AR_PHY(%u) (0x%x)", + (r->reg - AR_PHY_BASE) >> 2, r->reg); + bits = NULL; + } else { + snprintf(buf, sizeof (buf), "0x%x", r->reg); + bits = NULL; + } + fprintf(fd, "%-30s %s 0x%x", buf, r->op ? "<=" : "=>", r->val); + if (bits) { + const char *p = bits; + int tmp, n; + + for (tmp = 0, p++; *p;) { + n = *p++; + if (r->val & (1 << (n - 1))) { + putc(tmp ? ',' : '<', fd); + for (; (n = *p) > ' '; ++p) + putc(n, fd); + tmp = 1; + } else + for (; *p > ' '; ++p) + continue; + } + if (tmp) + putc('>', fd); + } +} diff --git a/tools/tools/ath/athkey/Makefile b/tools/tools/ath/athkey/Makefile new file mode 100644 index 000000000000..7aee04837957 --- /dev/null +++ b/tools/tools/ath/athkey/Makefile @@ -0,0 +1,18 @@ +# $FreeBSD$ + +PROG= athkey + +SRCS= athkey.c +SRCS+= opt_ah.h + +CLEANFILES+= opt_ah.h + +opt_ah.h: + echo "#define AH_DEBUG 1" > opt_ah.h + echo "#define AH_DEBUG_COUNTRY 1" >> opt_ah.h + echo "#define AH_SUPPORT_AR5416 1" >> opt_ah.h + + +.include <../Makefile.inc> + +.include <bsd.prog.mk> diff --git a/tools/tools/ath/athkey/athkey.c b/tools/tools/ath/athkey/athkey.c new file mode 100644 index 000000000000..d25410554d72 --- /dev/null +++ b/tools/tools/ath/athkey/athkey.c @@ -0,0 +1,203 @@ +/*- + * Copyright (c) 2002-2008 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$ + */ + +#include "diag.h" + +#include "ah.h" +#include "ah_internal.h" + +#include <string.h> +#include <stdlib.h> +#include <err.h> +#include <ctype.h> +#include <getopt.h> + +const char *progname; + +static int +toint(int c) +{ + return isdigit(c) ? c - '0' : isupper(c) ? c - 'A' + 10 : c - 'a' + 10; +} + +static int +getdata(const char *arg, u_int8_t *data, size_t maxlen) +{ + const char *cp = arg; + int len; + + if (cp[0] == '0' && (cp[1] == 'x' || cp[1] == 'X')) + cp += 2; + len = 0; + while (*cp) { + int b0, b1; + if (cp[0] == ':' || cp[0] == '-' || cp[0] == '.') { + cp++; + continue; + } + if (!isxdigit(cp[0])) { + fprintf(stderr, "%s: invalid data value %c (not hex)\n", + progname, cp[0]); + exit(-1); + } + b0 = toint(cp[0]); + if (cp[1] != '\0') { + if (!isxdigit(cp[1])) { + fprintf(stderr, "%s: invalid data value %c " + "(not hex)\n", progname, cp[1]); + exit(-1); + } + b1 = toint(cp[1]); + cp += 2; + } else { /* fake up 0<n> */ + b1 = b0, b0 = 0; + cp += 1; + } + if (len > maxlen) { + fprintf(stderr, + "%s: too much data in %s, max %u bytes\n", + progname, arg, maxlen); + } + data[len++] = (b0<<4) | b1; + } + return len; +} + +/* XXX this assumes 5212 key types are common to 5211 and 5210 */ + +static int +getcipher(const char *name) +{ +#define streq(a,b) (strcasecmp(a,b) == 0) + + if (streq(name, "wep")) + return HAL_CIPHER_WEP; + if (streq(name, "tkip")) + return HAL_CIPHER_TKIP; + if (streq(name, "aes-ocb") || streq(name, "ocb")) + return HAL_CIPHER_AES_OCB; + if (streq(name, "aes-ccm") || streq(name, "ccm") || + streq(name, "aes")) + return HAL_CIPHER_AES_CCM; + if (streq(name, "ckip")) + return HAL_CIPHER_CKIP; + if (streq(name, "none") || streq(name, "clr")) + return HAL_CIPHER_CLR; + + fprintf(stderr, "%s: unknown cipher %s\n", progname, name); + exit(-1); +#undef streq +} + +static void +usage(void) +{ + fprintf(stderr, "usage: %s [-i device] keyix cipher keyval [mac]\n", + progname); + exit(-1); +} + +int +main(int argc, char *argv[]) +{ + const char *ifname; + struct ath_diag atd; + HAL_DIAG_KEYVAL setkey; + const char *cp; + int s, c; + u_int16_t keyix; + int op = HAL_DIAG_SETKEY; + int xor = 0; + + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) + err(1, "socket"); + ifname = getenv("ATH"); + if (!ifname) + ifname = ATH_DEFAULT; + + progname = argv[0]; + while ((c = getopt(argc, argv, "di:x")) != -1) + switch (c) { + case 'd': + op = HAL_DIAG_RESETKEY; + break; + case 'i': + ifname = optarg; + break; + case 'x': + xor = 1; + break; + default: + usage(); + /*NOTREACHED*/ + } + argc -= optind; + argv += optind; + if (argc < 1) + usage(); + + keyix = (u_int16_t) atoi(argv[0]); + if (keyix > 127) + errx(-1, "%s: invalid key index %s, must be [0..127]", + progname, argv[0]); + strncpy(atd.ad_name, ifname, sizeof (atd.ad_name)); + atd.ad_id = op | ATH_DIAG_IN | ATH_DIAG_DYN; + atd.ad_out_data = NULL; + atd.ad_out_size = 0; + switch (op) { + case HAL_DIAG_RESETKEY: + atd.ad_in_data = (caddr_t) &keyix; + atd.ad_in_size = sizeof(u_int16_t); + if (ioctl(s, SIOCGATHDIAG, &atd) < 0) + err(1, atd.ad_name); + return 0; + case HAL_DIAG_SETKEY: + if (argc != 3 && argc != 4) + usage(); + memset(&setkey, 0, sizeof(setkey)); + setkey.dk_keyix = keyix; + setkey.dk_xor = xor; + setkey.dk_keyval.kv_type = getcipher(argv[1]); + setkey.dk_keyval.kv_len = getdata(argv[2], + setkey.dk_keyval.kv_val, sizeof(setkey.dk_keyval.kv_val)); + /* XXX MIC */ + if (argc == 4) + (void) getdata(argv[3], setkey.dk_mac, + IEEE80211_ADDR_LEN); + atd.ad_in_data = (caddr_t) &setkey; + atd.ad_in_size = sizeof(setkey); + if (ioctl(s, SIOCGATHDIAG, &atd) < 0) + err(1, atd.ad_name); + return 0; + } + return -1; +} diff --git a/tools/tools/ath/athpoke/Makefile b/tools/tools/ath/athpoke/Makefile new file mode 100644 index 000000000000..a33c7396348b --- /dev/null +++ b/tools/tools/ath/athpoke/Makefile @@ -0,0 +1,24 @@ +# $FreeBSD$ + +PROG= athpoke +LINKS= ${BINDIR}/${PROG} ${BINDIR}/athpeek + +.PATH.c: ${.CURDIR}/../common + +SRCS= athpoke.c +SRCS+= dumpregs_5210.c +SRCS+= dumpregs_5211.c +SRCS+= dumpregs_5212.c +SRCS+= dumpregs_5416.c +SRCS+= opt_ah.h + +CLEANFILES+= opt_ah.h + +opt_ah.h: + echo "#define AH_DEBUG 1" > opt_ah.h + echo "#define AH_DEBUG_COUNTRY 1" >> opt_ah.h + echo "#define AH_SUPPORT_AR5416 1" >> opt_ah.h + +.include <../Makefile.inc> + +.include <bsd.prog.mk> diff --git a/tools/tools/ath/athpoke/athpoke.c b/tools/tools/ath/athpoke/athpoke.c new file mode 100644 index 000000000000..1749b7b52b78 --- /dev/null +++ b/tools/tools/ath/athpoke/athpoke.c @@ -0,0 +1,247 @@ +/*- + * Copyright (c) 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$ + */ +#include "diag.h" + +#include "ah.h" +#include "ah_internal.h" + +#include "dumpregs.h" + +#include <getopt.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <err.h> +#include <errno.h> + +typedef struct { + HAL_REVS revs; +#define MAXREGS 5*1024 + struct dumpreg *regs[MAXREGS]; + u_int nregs; +} dumpregs_t; +static dumpregs_t state; + +static uint32_t regread(int s, struct ath_diag *atd, uint32_t r); +static void regwrite(int s, struct ath_diag *atd, uint32_t r, uint32_t v); +static const struct dumpreg *reglookup(const char *v); + +static void +usage(void) +{ + fprintf(stderr, "usage: athpoke [-i interface] [reg[=value]] ...\n"); + exit(-1); +} + +int +main(int argc, char *argv[]) +{ + struct ath_diag atd; + const char *ifname; + char *eptr; + int c, s; + + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) + err(1, "socket"); + ifname = getenv("ATH"); + if (!ifname) + ifname = ATH_DEFAULT; + + while ((c = getopt(argc, argv, "i:")) != -1) + switch (c) { + case 'i': + ifname = optarg; + break; + default: + usage(); + /*NOTREACHED*/ + } + strncpy(atd.ad_name, ifname, sizeof (atd.ad_name)); + + atd.ad_id = HAL_DIAG_REVS; + atd.ad_out_data = (caddr_t) &state.revs; + atd.ad_out_size = sizeof(state.revs); + if (ioctl(s, SIOCGATHDIAG, &atd) < 0) + err(1, atd.ad_name); + + argc -= optind; + argv += optind; + + for (; argc > 0; argc--, argv++) { + char *cp; + const struct dumpreg *dr; + uint32_t reg; + + cp = strchr(argv[0], '='); + if (cp != NULL) + *cp++ = '\0'; + dr = reglookup(argv[0]); + if (dr == NULL) { + errno = 0; + reg = (uint32_t) strtoul(argv[0], &eptr, 0); + if (argv[0] == eptr || eptr[0] != '\0') + errx(1, "invalid register \"%s\"", argv[0]); + } else + reg = dr->addr; + if (cp != NULL) + regwrite(s, &atd, reg, (uint32_t) strtoul(cp, NULL, 0)); + printf("%s = %08x\n", argv[0], regread(s, &atd, reg)); + } + return 0; +} + +static uint32_t +regread(int s, struct ath_diag *atd, uint32_t r) +{ + HAL_REGRANGE ra; + uint32_t v[2]; + + ra.start = r; + ra.end = 0; + + atd->ad_in_data = (caddr_t) &ra; + atd->ad_in_size = sizeof(ra); + atd->ad_out_data = (caddr_t) v; + atd->ad_out_size = sizeof(v); + atd->ad_id = HAL_DIAG_REGS | ATH_DIAG_IN | ATH_DIAG_DYN; + if (ioctl(s, SIOCGATHDIAG, atd) < 0) + err(1, atd->ad_name); + return v[1]; +} + +static void +regwrite(int s, struct ath_diag *atd, uint32_t r, uint32_t v) +{ + HAL_REGWRITE rw; + + rw.addr = r; + rw.value = v; + atd->ad_in_data = (caddr_t) &rw; + atd->ad_in_size = sizeof(rw); + atd->ad_id = HAL_DIAG_SETREGS | ATH_DIAG_IN; + if (ioctl(s, SIOCGATHDIAG, atd) < 0) + err(1, atd->ad_name); +} + +static int +regcompar(const void *a, const void *b) +{ + const struct dumpreg *ra = *(const struct dumpreg **)a; + const struct dumpreg *rb = *(const struct dumpreg **)b; + return ra->addr - rb->addr; +} + +void +register_regs(struct dumpreg *chipregs, u_int nchipregs, + int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max) +{ + const int existing_regs = state.nregs; + int i, j; + + for (i = 0; i < nchipregs; i++) { + struct dumpreg *nr = &chipregs[i]; + if (nr->srevMin == 0) + nr->srevMin = def_srev_min; + if (nr->srevMax == 0) + nr->srevMax = def_srev_max; + if (nr->phyMin == 0) + nr->phyMin = def_phy_min; + if (nr->phyMax == 0) + nr->phyMax = def_phy_max; + for (j = 0; j < existing_regs; j++) { + struct dumpreg *r = state.regs[j]; + /* + * Check if we can just expand the mac+phy + * coverage for the existing entry. + */ + if (nr->addr == r->addr && + (nr->name == r->name || + nr->name != NULL && r->name != NULL && + strcmp(nr->name, r->name) == 0)) { + if (nr->srevMin < r->srevMin && + (r->srevMin <= nr->srevMax && + nr->srevMax+1 <= r->srevMax)) { + r->srevMin = nr->srevMin; + goto skip; + } + if (nr->srevMax > r->srevMax && + (r->srevMin <= nr->srevMin && + nr->srevMin <= r->srevMax)) { + r->srevMax = nr->srevMax; + goto skip; + } + } + if (r->addr > nr->addr) + break; + } + /* + * New item, add to the end, it'll be sorted below. + */ + if (state.nregs == MAXREGS) + errx(-1, "too many registers; bump MAXREGS"); + state.regs[state.nregs++] = nr; + skip: + ; + } + qsort(state.regs, state.nregs, sizeof(struct dumpreg *), regcompar); +} + +void +register_keycache(u_int nslots, + int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max) +{ + /* discard, no use */ +} + +void +register_range(u_int brange, u_int erange, int type, + int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max) +{ + /* discard, no use */ +} + +static const struct dumpreg * +reglookup(const char *v) +{ + const HAL_REVS *revs = &state.revs; + int i; + + if (strncasecmp(v, "AR_", 3) == 0) + v += 3; + for (i = 0; i < state.nregs; i++) { + const struct dumpreg *dr = state.regs[i]; + if (MAC_MATCH(dr, revs->ah_macVersion, revs->ah_macRev) && + strcasecmp(v, dr->name) == 0) + return dr; + } + return NULL; +} diff --git a/tools/tools/ath/athpow/Makefile b/tools/tools/ath/athpow/Makefile new file mode 100644 index 000000000000..f3b36731db16 --- /dev/null +++ b/tools/tools/ath/athpow/Makefile @@ -0,0 +1,7 @@ +# $FreeBSD$ + +PROG= athpow + +.include <../Makefile.inc> + +.include <bsd.prog.mk> diff --git a/tools/tools/ath/athpow/athpow.c b/tools/tools/ath/athpow/athpow.c new file mode 100644 index 000000000000..2b2683d9e6da --- /dev/null +++ b/tools/tools/ath/athpow/athpow.c @@ -0,0 +1,198 @@ +/*- + * Copyright (c) 2002-2008 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$ + */ +#include "diag.h" + +#include <getopt.h> +#include <stdlib.h> +#include <string.h> + +#include "ah.h" +#include "ah_internal.h" +#include "ah_eeprom.h" +#include "ah_eeprom_v1.h" +#include "ah_eeprom_v3.h" +#include "ah_eeprom_v14.h" +#include "ar5212/ar5212reg.h" +#define IS_5112(ah) \ + (((ah)->ah_analog5GhzRev&0xf0) >= AR_RAD5112_SREV_MAJOR \ + && ((ah)->ah_analog5GhzRev&0xf0) < AR_RAD2316_SREV_MAJOR ) +#define IS_2316(ah) \ + ((ah)->ah_macVersion == AR_SREV_2415) +#define IS_2413(ah) \ + ((ah)->ah_macVersion == AR_SREV_2413 || IS_2316(ah)) +#define IS_5424(ah) \ + ((ah)->ah_macVersion == AR_SREV_5424 || \ + ((ah)->ah_macVersion == AR_SREV_5413 && \ + (ah)->ah_macRev <= AR_SREV_D2PLUS_MS)) +#define IS_5413(ah) \ + ((ah)->ah_macVersion == AR_SREV_5413 || IS_5424(ah)) + +#ifndef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +static void printPcdacTable(FILE *fd, u_int16_t pcdac[], u_int n); +static void printPowerPerRate(FILE *fd, u_int16_t ratesArray[], u_int n); +static void printRevs(FILE *fd, const HAL_REVS *revs); + +static void +usage(const char *progname) +{ + fprintf(stderr, "usage: %s [-v] [-i dev]\n", progname); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + int s, i, verbose = 0, c; + struct ath_diag atd; + const char *ifname; + HAL_REVS revs; + u_int16_t pcdacTable[MAX(PWR_TABLE_SIZE,PWR_TABLE_SIZE_2413)]; + u_int16_t ratesArray[37]; + u_int nrates, npcdac; + + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) + err(1, "socket"); + ifname = getenv("ATH"); + if (!ifname) + ifname = ATH_DEFAULT; + while ((c = getopt(argc, argv, "i:v")) != -1) + switch (c) { + case 'i': + ifname = optarg; + break; + case 'v': + verbose++; + break; + default: + usage(argv[0]); + } + strncpy(atd.ad_name, ifname, sizeof (atd.ad_name)); + + atd.ad_id = HAL_DIAG_REVS; + atd.ad_out_data = (caddr_t) &revs; + atd.ad_out_size = sizeof(revs); + if (ioctl(s, SIOCGATHDIAG, &atd) < 0) + err(1, atd.ad_name); + + if (verbose) + printRevs(stdout, &revs); + + atd.ad_id = HAL_DIAG_TXRATES; + atd.ad_out_data = (caddr_t) ratesArray; + atd.ad_out_size = sizeof(ratesArray); + if (ioctl(s, SIOCGATHDIAG, &atd) < 0) + err(1, atd.ad_name); + nrates = sizeof(ratesArray) / sizeof(u_int16_t); + + atd.ad_id = HAL_DIAG_PCDAC; + atd.ad_out_data = (caddr_t) pcdacTable; + atd.ad_out_size = sizeof(pcdacTable); + if (ioctl(s, SIOCGATHDIAG, &atd) < 0) + err(1, atd.ad_name); + if (IS_2413(&revs) || IS_5413(&revs)) + npcdac = PWR_TABLE_SIZE_2413; + else + npcdac = PWR_TABLE_SIZE; + + printf("PCDAC table:\n"); + printPcdacTable(stdout, pcdacTable, npcdac); + + printf("Power per rate table:\n"); + printPowerPerRate(stdout, ratesArray, nrates); + + return 0; +} + +static void +printPcdacTable(FILE *fd, u_int16_t pcdac[], u_int n) +{ + int i, halfRates = n/2; + + for (i = 0; i < halfRates; i += 2) + fprintf(fd, "[%2u] %04x %04x [%2u] %04x %04x\n", + i, pcdac[2*i + 1], pcdac[2*i], + i+1, pcdac[2*(i+1) + 1], pcdac[2*(i+1)]); +} + +static void +printPowerPerRate(FILE *fd, u_int16_t ratesArray[], u_int n) +{ + const char *rateString[] = { + " 6mb OFDM", " 9mb OFDM", "12mb OFDM", "18mb OFDM", + "24mb OFDM", "36mb OFDM", "48mb OFDM", "54mb OFDM", + "1L CCK ", "2L CCK ", "2S CCK ", "5.5L CCK ", + "5.5S CCK ", "11L CCK ", "11S CCK ", "XR " + }; + int i, halfRates = n/2; + + for (i = 0; i < halfRates; i++) + fprintf(fd, " %s %3d.%1d dBm | %s %3d.%1d dBm\n", + rateString[i], ratesArray[i]/2, + (ratesArray[i] %2) * 5, + rateString[i + halfRates], + ratesArray[i + halfRates]/2, + (ratesArray[i + halfRates] %2) *5); +} + +static void +printRevs(FILE *fd, const HAL_REVS *revs) +{ + const char *rfbackend; + + fprintf(fd, "PCI device id 0x%x subvendor id 0x%x\n", + revs->ah_devid, revs->ah_subvendorid); + fprintf(fd, "mac %d.%d phy %d.%d" + , revs->ah_macVersion, revs->ah_macRev + , revs->ah_phyRev >> 4, revs->ah_phyRev & 0xf + ); + rfbackend = IS_5413(revs) ? "5413" : + IS_2413(revs) ? "2413" : + IS_5112(revs) ? "5112" : + "5111"; + if (revs->ah_analog5GhzRev && revs->ah_analog2GhzRev) + fprintf(fd, " 5ghz radio %d.%d 2ghz radio %d.%d (%s)\n" + , revs->ah_analog5GhzRev >> 4 + , revs->ah_analog5GhzRev & 0xf + , revs->ah_analog2GhzRev >> 4 + , revs->ah_analog2GhzRev & 0xf + , rfbackend + ); + else + fprintf(fd, " radio %d.%d (%s)\n" + , revs->ah_analog5GhzRev >> 4 + , revs->ah_analog5GhzRev & 0xf + , rfbackend + ); +} diff --git a/tools/tools/ath/athprom/Makefile b/tools/tools/ath/athprom/Makefile new file mode 100644 index 000000000000..f7b596728699 --- /dev/null +++ b/tools/tools/ath/athprom/Makefile @@ -0,0 +1,26 @@ +# $FreeBSD$ + +PROG= athprom + +.include <../Makefile.inc> + +TEMPLATEDIR= /usr/local/libdata/athprom +TEXTMODE?= 444 + +SRCS= athprom.c +SRCS+= opt_ah.h +CLEANFILES+= opt_ah.h + +opt_ah.h: + echo "#define AH_DEBUG 1" > opt_ah.h + echo "#define AH_DEBUG_COUNTRY 1" >> opt_ah.h + echo "#define AH_SUPPORT_AR5416 1" >> opt_ah.h + +CFLAGS+=-DDIR_TEMPLATE='"${TEMPLATEDIR}"' + +beforeinstall: + mkdir -p ${DESTDIR}${TEMPLATEDIR} + ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m ${TEXTMODE} \ + ${.CURDIR}/eeprom-* ${DESTDIR}${TEMPLATEDIR}/ + +.include <bsd.prog.mk> diff --git a/tools/tools/ath/athprom/athprom.c b/tools/tools/ath/athprom/athprom.c new file mode 100644 index 000000000000..6f2b32b1252c --- /dev/null +++ b/tools/tools/ath/athprom/athprom.c @@ -0,0 +1,979 @@ +/*- + * Copyright (c) 2008 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$ + */ +#include "diag.h" + +#include "ah.h" +#include "ah_internal.h" +#include "ah_eeprom_v1.h" +#include "ah_eeprom_v3.h" +#include "ah_eeprom_v14.h" + +#define IS_VERS(op, v) (eeprom.ee_version op (v)) + +#include <getopt.h> +#include <errno.h> +#include <err.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#ifndef DIR_TEMPLATE +#define DIR_TEMPLATE "/usr/local/libdata/athprom" +#endif + +struct ath_diag atd; +int s; +const char *progname; +union { + HAL_EEPROM legacy; /* format v3.x ... v5.x */ + struct ar5416eeprom v14; /* 11n format v14.x ... */ +} eep; +#define eeprom eep.legacy +#define eepromN eep.v14 + +static void parseTemplate(FILE *ftemplate, FILE *fd); +static uint16_t eeread(uint16_t); +static void eewrite(uint16_t, uint16_t); + +static void +usage() +{ + fprintf(stderr, "usage: %s [-i ifname] [-t pathname] [offset | offset=value]\n", progname); + exit(-1); +} + +static FILE * +opentemplate(const char *dir) +{ + char filename[PATH_MAX]; + FILE *fd; + + /* find the template using the eeprom version */ + snprintf(filename, sizeof(filename), "%s/eeprom-%d.%d", + dir, eeprom.ee_version >> 12, eeprom.ee_version & 0xfff); + fd = fopen(filename, "r"); + if (fd == NULL && errno == ENOENT) { + /* retry with just the major version */ + snprintf(filename, sizeof(filename), "%s/eeprom-%d", + dir, eeprom.ee_version >> 12); + fd = fopen(filename, "r"); + if (fd != NULL) /* XXX verbose */ + warnx("Using template file %s", filename); + } + return fd; +} + +int +main(int argc, char *argv[]) +{ + FILE *fd = NULL; + const char *ifname; + int c; + + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) + err(1, "socket"); + ifname = getenv("ATH"); + if (!ifname) + ifname = ATH_DEFAULT; + + progname = argv[0]; + while ((c = getopt(argc, argv, "i:t:")) != -1) + switch (c) { + case 'i': + ifname = optarg; + break; + case 't': + fd = fopen(optarg, "r"); + if (fd == NULL) + err(-1, "Cannot open %s", optarg); + break; + default: + usage(); + /*NOTREACHED*/ + } + argc -= optind; + argv += optind; + + strncpy(atd.ad_name, ifname, sizeof (atd.ad_name)); + + if (argc != 0) { + for (; argc > 0; argc--, argv++) { + uint16_t off, val, oval; + char line[256]; + char *cp; + + cp = strchr(argv[0], '='); + if (cp != NULL) + *cp = '\0'; + off = (uint16_t) strtoul(argv[0], NULL, 0); + if (off == 0 && errno == EINVAL) + errx(1, "%s: invalid eeprom offset %s", + progname, argv[0]); + if (cp == NULL) { + printf("%04x: %04x\n", off, eeread(off)); + } else { + val = (uint16_t) strtoul(cp+1, NULL, 0); + if (val == 0 && errno == EINVAL) + errx(1, "%s: invalid eeprom value %s", + progname, cp+1); + oval = eeread(off); + printf("Write %04x: %04x = %04x? ", + off, oval, val); + fflush(stdout); + if (fgets(line, sizeof(line), stdin) != NULL && + line[0] == 'y') + eewrite(off, val); + } + } + } else { + atd.ad_id = HAL_DIAG_EEPROM; + atd.ad_out_data = (caddr_t) &eep; + atd.ad_out_size = sizeof(eep); + if (ioctl(s, SIOCGATHDIAG, &atd) < 0) + err(1, atd.ad_name); + if (fd == NULL) { + fd = opentemplate(DIR_TEMPLATE); + if (fd == NULL) + fd = opentemplate("."); + if (fd == NULL) + errx(-1, "Cannot locate template file for " + "v%d.%d EEPROM", eeprom.ee_version >> 12, + eeprom.ee_version & 0xfff); + } + parseTemplate(fd, stdout); + fclose(fd); + } + return 0; +} + +static u_int16_t +eeread(u_int16_t off) +{ + u_int16_t eedata; + + atd.ad_id = HAL_DIAG_EEREAD | ATH_DIAG_IN | ATH_DIAG_DYN; + atd.ad_in_size = sizeof(off); + atd.ad_in_data = (caddr_t) &off; + atd.ad_out_size = sizeof(eedata); + atd.ad_out_data = (caddr_t) &eedata; + if (ioctl(s, SIOCGATHDIAG, &atd) < 0) + err(1, atd.ad_name); + return eedata; +} + +static void +eewrite(uint16_t off, uint16_t value) +{ + HAL_DIAG_EEVAL eeval; + + eeval.ee_off = off; + eeval.ee_data = value; + + atd.ad_id = HAL_DIAG_EEWRITE | ATH_DIAG_IN; + atd.ad_in_size = sizeof(eeval); + atd.ad_in_data = (caddr_t) &eeval; + atd.ad_out_size = 0; + atd.ad_out_data = NULL; + if (ioctl(s, SIOCGATHDIAG, &atd) < 0) + err(1, atd.ad_name); +} + +#define MAXID 128 +int lineno; +int bol; +int curmode = -1; +int curchan; +int curpdgain; /* raw pdgain index */ +int curlpdgain; /* logical pdgain index */ +int curpcdac; +int curctl; +int numChannels; +const RAW_DATA_STRUCT_2413 *pRaw; +const TRGT_POWER_INFO *pPowerInfo; +const DATA_PER_CHANNEL *pDataPerChannel; +const EEPROM_POWER_EXPN_5112 *pExpnPower; +int singleXpd; + +static int +token(FILE *fd, char id[], int maxid, const char *what) +{ + int c, i; + + i = 0; + for (;;) { + c = getc(fd); + if (c == EOF) + return EOF; + if (!isalnum(c) && c != '_') { + ungetc(c, fd); + break; + } + if (i == maxid-1) { + warnx("line %d, %s too long", lineno, what); + break; + } + id[i++] = c; + } + id[i] = '\0'; + if (i != 0) + bol = 0; + return i; +} + +static int +skipto(FILE *fd, const char *what) +{ + char id[MAXID]; + int c; + + for (;;) { + c = getc(fd); + if (c == EOF) + goto bad; + if (c == '.' && bol) { /* .directive */ + if (token(fd, id, MAXID, ".directive") == EOF) + goto bad; + if (strcasecmp(id, what) == 0) + break; + continue; + } + if (c == '\\') { /* escape next character */ + c = getc(fd); + if (c == EOF) + goto bad; + } + bol = (c == '\n'); + if (bol) + lineno++; + } + return 0; +bad: + warnx("EOF with no matching .%s", what); + return EOF; +} + +static int +skipws(FILE *fd) +{ + int c, i; + + i = 0; + while ((c = getc(fd)) != EOF && isblank(c)) + i++; + if (c != EOF) + ungetc(c, fd); + if (i != 0) + bol = 0; + return 0; +} + +static void +setmode(int mode) +{ + EEPROM_POWER_EXPN_5112 *exp; + + curmode = mode; + curchan = -1; + curctl = -1; + curpdgain = -1; + curlpdgain = -1; + curpcdac = -1; + switch (curmode) { + case headerInfo11A: + pPowerInfo = eeprom.ee_trgtPwr_11a; + pDataPerChannel = eeprom.ee_dataPerChannel11a; + break; + case headerInfo11B: + pPowerInfo = eeprom.ee_trgtPwr_11b; + pDataPerChannel = eeprom.ee_dataPerChannel11b; + break; + case headerInfo11G: + pPowerInfo = eeprom.ee_trgtPwr_11g; + pDataPerChannel = eeprom.ee_dataPerChannel11g; + break; + } + if (IS_VERS(<, AR_EEPROM_VER4_0)) /* nothing to do */ + return; + if (IS_VERS(<, AR_EEPROM_VER5_0)) { + exp = &eeprom.ee_modePowerArray5112[curmode]; + /* fetch indirect data*/ + atd.ad_id = HAL_DIAG_EEPROM_EXP_11A+curmode; + atd.ad_out_size = roundup( + sizeof(u_int16_t) * exp->numChannels, sizeof(u_int32_t)) + + sizeof(EXPN_DATA_PER_CHANNEL_5112) * exp->numChannels; + atd.ad_out_data = (caddr_t) malloc(atd.ad_out_size); + if (ioctl(s, SIOCGATHDIAG, &atd) < 0) + err(1, atd.ad_name); + exp->pChannels = (void *) atd.ad_out_data; + exp->pDataPerChannel = (void *)((char *)atd.ad_out_data + + roundup(sizeof(u_int16_t) * exp->numChannels, sizeof(u_int32_t))); + pExpnPower = exp; + numChannels = pExpnPower->numChannels; + if (exp->xpdMask != 0x9) { + for (singleXpd = 0; singleXpd < NUM_XPD_PER_CHANNEL; singleXpd++) + if (exp->xpdMask == (1<<singleXpd)) + break; + } else + singleXpd = 0; + } else if (IS_VERS(<, AR_EEPROM_VER14_2)) { + pRaw = &eeprom.ee_rawDataset2413[curmode]; + numChannels = pRaw->numChannels; + } +} + +int +nextctl(int start) +{ + int i; + + for (i = start; i < eeprom.ee_numCtls && eeprom.ee_ctl[i]; i++) { + switch (eeprom.ee_ctl[i] & 3) { + case 0: case 3: + if (curmode != headerInfo11A) + continue; + break; + case 1: + if (curmode != headerInfo11B) + continue; + break; + case 2: + if (curmode != headerInfo11G) + continue; + break; + } + return i; + } + return -1; +} + +static void +printAntennaControl(FILE *fd, int ant) +{ + fprintf(fd, "0x%02X", eeprom.ee_antennaControl[ant][curmode]); +} + +static void +printEdge(FILE *fd, int edge) +{ + const RD_EDGES_POWER *pRdEdgePwrInfo = + &eeprom.ee_rdEdgesPower[curctl*NUM_EDGES]; + + if (pRdEdgePwrInfo[edge].rdEdge == 0) + fprintf(fd, " -- "); + else + fprintf(fd, "%04d", pRdEdgePwrInfo[edge].rdEdge); +} + +static void +printEdgePower(FILE *fd, int edge) +{ + const RD_EDGES_POWER *pRdEdgePwrInfo = + &eeprom.ee_rdEdgesPower[curctl*NUM_EDGES]; + + if (pRdEdgePwrInfo[edge].rdEdge == 0) + fprintf(fd, " -- "); + else + fprintf(fd, "%2d.%d", + pRdEdgePwrInfo[edge].twice_rdEdgePower / 2, + (pRdEdgePwrInfo[edge].twice_rdEdgePower % 2) * 5); +} + +static void +printEdgeFlag(FILE *fd, int edge) +{ + const RD_EDGES_POWER *pRdEdgePwrInfo = + &eeprom.ee_rdEdgesPower[curctl*NUM_EDGES]; + + if (pRdEdgePwrInfo[edge].rdEdge == 0) + fprintf(fd, "--"); + else + fprintf(fd, " %1d", pRdEdgePwrInfo[edge].flag); +} + +static int16_t +getMaxPowerV5(const RAW_DATA_PER_CHANNEL_2413 *data) +{ + uint32_t i; + uint16_t numVpd; + + for (i = 0; i < MAX_NUM_PDGAINS_PER_CHANNEL; i++) { + numVpd = data->pDataPerPDGain[i].numVpd; + if (numVpd > 0) + return data->pDataPerPDGain[i].pwr_t4[numVpd-1]; + } + return 0; +} + +static void +printQuarterDbmPower(FILE *fd, int16_t power25dBm) +{ + fprintf(fd, "%2d.%02d", power25dBm / 4, (power25dBm % 4) * 25); +} + +static void +printHalfDbmPower(FILE *fd, int16_t power5dBm) +{ + fprintf(fd, "%2d.%d", power5dBm / 2, (power5dBm % 2) * 5); +} + +static void +printVpd(FILE *fd, int vpd) +{ + fprintf(fd, "[%3d]", vpd); +} + +static void +printPcdacValue(FILE *fd, int v) +{ + fprintf(fd, "%2d.%02d", v / EEP_SCALE, v % EEP_SCALE); +} + +static void +undef(const char *what) +{ + warnx("%s undefined for version %d.%d format EEPROM", what, + eeprom.ee_version >> 12, eeprom.ee_version & 0xfff); +} + +static int +pdgain(int lpdgain) +{ + uint32_t mask; + int i, l = lpdgain; + + if (IS_VERS(<, AR_EEPROM_VER5_0)) + mask = pExpnPower->xpdMask; + else + mask = pRaw->xpd_mask; + for (i = 0; mask != 0; mask >>= 1, i++) + if ((mask & 1) && l-- == 0) + return i; + warnx("can't find logical pdgain %d", lpdgain); + return -1; +} + +#define COUNTRY_ERD_FLAG 0x8000 +#define WORLDWIDE_ROAMING_FLAG 0x4000 + +void +eevar(FILE *fd, const char *var) +{ +#define streq(a,b) (strcasecmp(a,b) == 0) +#define strneq(a,b,n) (strncasecmp(a,b,n) == 0) + if (streq(var, "mode")) { + fprintf(fd, "%s", + curmode == headerInfo11A ? "11a" : + curmode == headerInfo11B ? "11b" : + curmode == headerInfo11G ? "11g" : "???"); + } else if (streq(var, "version")) { + fprintf(fd, "%04x", eeprom.ee_version); + } else if (streq(var, "V_major")) { + fprintf(fd, "%2d", eeprom.ee_version >> 12); + } else if (streq(var, "V_minor")) { + fprintf(fd, "%2d", eeprom.ee_version & 0xfff); + } else if (streq(var, "earStart")) { + fprintf(fd, "%03x", eeprom.ee_earStart); + } else if (streq(var, "tpStart")) { + fprintf(fd, "%03x", eeprom.ee_targetPowersStart); + } else if (streq(var, "eepMap")) { + fprintf(fd, "%3d", eeprom.ee_eepMap); + } else if (streq(var, "exist32KHzCrystal")) { + fprintf(fd, "%3d", eeprom.ee_exist32kHzCrystal); + } else if (streq(var, "eepMap2PowerCalStart")) { + fprintf(fd , "%3d", eeprom.ee_eepMap2PowerCalStart); + } else if (streq(var, "Amode")) { + fprintf(fd , "%1d", eeprom.ee_Amode); + } else if (streq(var, "Bmode")) { + fprintf(fd , "%1d", eeprom.ee_Bmode); + } else if (streq(var, "Gmode")) { + fprintf(fd , "%1d", eeprom.ee_Gmode); + } else if (streq(var, "regdomain")) { + if ((eeprom.ee_regdomain & COUNTRY_ERD_FLAG) == 0) + fprintf(fd, "%03X ", eeprom.ee_regdomain >> 15); + else + fprintf(fd, "%-3dC", eeprom.ee_regdomain & 0xfff); + } else if (streq(var, "turbo2Disable")) { + fprintf(fd, "%1d", eeprom.ee_turbo2Disable); + } else if (streq(var, "turbo5Disable")) { + fprintf(fd, "%1d", eeprom.ee_turbo5Disable); + } else if (streq(var, "rfKill")) { + fprintf(fd, "%1d", eeprom.ee_rfKill); + } else if (streq(var, "disableXr5")) { + fprintf(fd, "%1d", eeprom.ee_disableXr5); + } else if (streq(var, "disableXr2")) { + fprintf(fd, "%1d", eeprom.ee_disableXr2); + } else if (streq(var, "turbo2WMaxPower5")) { + fprintf(fd, "%2d", eeprom.ee_turbo2WMaxPower5); + } else if (streq(var, "cckOfdmDelta")) { + fprintf(fd, "%2d", eeprom.ee_cckOfdmPwrDelta); + } else if (streq(var, "gainI")) { + fprintf(fd, "%2d", eeprom.ee_gainI[curmode]); + } else if (streq(var, "WWR")) { + fprintf(fd, "%1x", + (eeprom.ee_regdomain & WORLDWIDE_ROAMING_FLAG) != 0); + } else if (streq(var, "falseDetectBackoff")) { + fprintf(fd, "0x%02x", eeprom.ee_falseDetectBackoff[curmode]); + } else if (streq(var, "deviceType")) { + fprintf(fd, "%1x", eeprom.ee_deviceType); + } else if (streq(var, "switchSettling")) { + if (IS_VERS(<, AR_EEPROM_VER14_2)) + fprintf(fd, "0x%02x", eeprom.ee_switchSettling[curmode]); + else + fprintf(fd, "%3d", eepromN.modalHeader[curmode].switchSettling); + } else if (streq(var, "adcDesiredSize")) { + if (IS_VERS(<, AR_EEPROM_VER14_2)) + fprintf(fd, "%2d", eeprom.ee_adcDesiredSize[curmode]); + else + fprintf(fd, "%3d", eepromN.modalHeader[curmode].adcDesiredSize); + } else if (streq(var, "xlnaGain")) { + fprintf(fd, "0x%02x", eeprom.ee_xlnaGain[curmode]); + } else if (streq(var, "txEndToXLNAOn")) { + fprintf(fd, "0x%02x", eeprom.ee_txEndToXLNAOn[curmode]); + } else if (streq(var, "thresh62")) { + if (IS_VERS(<, AR_EEPROM_VER14_2)) + fprintf(fd, "0x%02x", eeprom.ee_thresh62[curmode]); + else + fprintf(fd, "%3d", eepromN.modalHeader[curmode].thresh62); + } else if (streq(var, "txEndToRxOn")) { + fprintf(fd, "%3d", eepromN.modalHeader[curmode].txEndToRxOn); + } else if (streq(var, "txEndToXPAOff")) { + if (IS_VERS(<, AR_EEPROM_VER14_2)) + fprintf(fd, "0x%02x", eeprom.ee_txEndToXPAOff[curmode]); + else + fprintf(fd, "%3d", eepromN.modalHeader[curmode].txEndToXpaOff); + } else if (streq(var, "txFrameToXPAOn")) { + if (IS_VERS(<, AR_EEPROM_VER14_2)) + fprintf(fd, "0x%02x", eeprom.ee_txFrameToXPAOn[curmode]); + else + fprintf(fd, "%3d", eepromN.modalHeader[curmode].txEndToRxOn); + } else if (streq(var, "pgaDesiredSize")) { + if (IS_VERS(<, AR_EEPROM_VER14_2)) + fprintf(fd, "%2d", eeprom.ee_pgaDesiredSize[curmode]); + else + fprintf(fd, "%3d", eepromN.modalHeader[curmode].pgaDesiredSize); + } else if (streq(var, "noiseFloorThresh")) { + fprintf(fd, "%3d", eeprom.ee_noiseFloorThresh[curmode]); + } else if (strneq(var, "noiseFloorThreshCh", 18)) { + fprintf(fd, "%3d", eepromN.modalHeader[curmode].noiseFloorThreshCh[atoi(var+18)]); + } else if (strneq(var, "xlnaGainCh", 10)) { + fprintf(fd, "%3d", eepromN.modalHeader[curmode].xlnaGainCh[atoi(var+10)]); + } else if (streq(var, "xgain")) { + fprintf(fd, "0x%02x", eeprom.ee_xgain[curmode]); + } else if (streq(var, "xpd")) { + if (IS_VERS(<, AR_EEPROM_VER14_2)) + fprintf(fd, "%1d", eeprom.ee_xpd[curmode]); + else + fprintf(fd, "%3d", eepromN.modalHeader[curmode].xpd); + } else if (streq(var, "txrxAtten")) { + fprintf(fd, "0x%02x", eeprom.ee_txrxAtten[curmode]); + } else if (streq(var, "capField")) { + fprintf(fd, "0x%04X", eeprom.ee_capField); + } else if (streq(var, "txrxAttenTurbo")) { + fprintf(fd, "0x%02x", + eeprom.ee_txrxAtten[curmode != headerInfo11A]); + } else if (streq(var, "switchSettlingTurbo")) { + fprintf(fd, "0x%02X", + eeprom.ee_switchSettlingTurbo[curmode != headerInfo11A]); + } else if (streq(var, "adcDesiredSizeTurbo")) { + fprintf(fd, "%2d", + eeprom.ee_adcDesiredSizeTurbo[curmode != headerInfo11A]); + } else if (streq(var, "pgaDesiredSizeTurbo")) { + fprintf(fd, "%2d", + eeprom.ee_pgaDesiredSizeTurbo[curmode != headerInfo11A]); + } else if (streq(var, "rxtxMarginTurbo")) { + fprintf(fd, "0x%02x", + eeprom.ee_rxtxMarginTurbo[curmode != headerInfo11A]); + } else if (strneq(var, "antennaControl", 14)) { + printAntennaControl(fd, atoi(var+14)); + } else if (strneq(var, "antCtrlChain", 12)) { + fprintf(fd, "0x%08X", + eepromN.modalHeader[curmode].antCtrlChain[atoi(var+12)]); + } else if (strneq(var, "antGainCh", 9)) { + fprintf(fd, "%3d", + eepromN.modalHeader[curmode].antennaGainCh[atoi(var+9)]); + } else if (strneq(var, "txRxAttenCh", 11)) { + fprintf(fd, "%3d", + eepromN.modalHeader[curmode].txRxAttenCh[atoi(var+11)]); + } else if (strneq(var, "rxTxMarginCh", 12)) { + fprintf(fd, "%3d", + eepromN.modalHeader[curmode].rxTxMarginCh[atoi(var+12)]); + } else if (streq(var, "xpdGain")) { + fprintf(fd, "%3d", eepromN.modalHeader[curmode].xpdGain); + } else if (strneq(var, "iqCalICh", 8)) { + fprintf(fd, "%3d", + eepromN.modalHeader[curmode].iqCalICh[atoi(var+8)]); + } else if (strneq(var, "iqCalQCh", 8)) { + fprintf(fd, "%3d", + eepromN.modalHeader[curmode].iqCalQCh[atoi(var+8)]); + } else if (streq(var, "pdGainOverlap")) { + printHalfDbmPower(fd, eepromN.modalHeader[curmode].pdGainOverlap); + } else if (streq(var, "ob1")) { + fprintf(fd, "%1d", eeprom.ee_ob1); + } else if (streq(var, "ob2")) { + fprintf(fd, "%1d", eeprom.ee_ob2); + } else if (streq(var, "ob3")) { + fprintf(fd, "%1d", eeprom.ee_ob3); + } else if (streq(var, "ob4")) { + fprintf(fd, "%1d", eeprom.ee_ob4); + } else if (streq(var, "db1")) { + fprintf(fd, "%1d", eeprom.ee_db1); + } else if (streq(var, "db2")) { + fprintf(fd, "%1d", eeprom.ee_db2); + } else if (streq(var, "db3")) { + fprintf(fd, "%1d", eeprom.ee_db3); + } else if (streq(var, "db4")) { + fprintf(fd, "%1d", eeprom.ee_db4); + } else if (streq(var, "obFor24")) { + fprintf(fd, "%1d", eeprom.ee_obFor24); + } else if (streq(var, "ob2GHz0")) { + fprintf(fd, "%1d", eeprom.ee_ob2GHz[0]); + } else if (streq(var, "dbFor24")) { + fprintf(fd, "%1d", eeprom.ee_dbFor24); + } else if (streq(var, "db2GHz0")) { + fprintf(fd, "%1d", eeprom.ee_db2GHz[0]); + } else if (streq(var, "obFor24g")) { + fprintf(fd, "%1d", eeprom.ee_obFor24g); + } else if (streq(var, "ob2GHz1")) { + fprintf(fd, "%1d", eeprom.ee_ob2GHz[1]); + } else if (streq(var, "dbFor24g")) { + fprintf(fd, "%1d", eeprom.ee_dbFor24g); + } else if (streq(var, "db2GHz1")) { + fprintf(fd, "%1d", eeprom.ee_db2GHz[1]); + } else if (streq(var, "ob")) { + fprintf(fd, "%3d", eepromN.modalHeader[curmode].ob); + } else if (streq(var, "db")) { + fprintf(fd, "%3d", eepromN.modalHeader[curmode].db); + } else if (streq(var, "xpaBiasLvl")) { + fprintf(fd, "%3d", eepromN.modalHeader[curmode].xpaBiasLvl); + } else if (streq(var, "pwrDecreaseFor2Chain")) { + printHalfDbmPower(fd, eepromN.modalHeader[curmode].pwrDecreaseFor2Chain); + } else if (streq(var, "pwrDecreaseFor3Chain")) { + printHalfDbmPower(fd, eepromN.modalHeader[curmode].pwrDecreaseFor3Chain); + } else if (streq(var, "txFrameToDataStart")) { + fprintf(fd, "%3d", eepromN.modalHeader[curmode].txFrameToDataStart); + } else if (streq(var, "txFrameToPaOn")) { + fprintf(fd, "%3d", eepromN.modalHeader[curmode].txFrameToPaOn); + } else if (streq(var, "ht40PowerIncForPdadc")) { + fprintf(fd, "%3d", eepromN.modalHeader[curmode].ht40PowerIncForPdadc); + } else if (streq(var, "checksum")) { + fprintf(fd, "0x%04X", eepromN.baseEepHeader.checksum); + } else if (streq(var, "length")) { + fprintf(fd, "0x%04X", eepromN.baseEepHeader.length); + } else if (streq(var, "regDmn0")) { + fprintf(fd, "0x%04X", eepromN.baseEepHeader.regDmn[0]); + } else if (streq(var, "regDmn1")) { + fprintf(fd, "0x%04X", eepromN.baseEepHeader.regDmn[1]); + } else if (streq(var, "txMask")) { + fprintf(fd, "0x%04X", eepromN.baseEepHeader.txMask); + } else if (streq(var, "rxMask")) { + fprintf(fd, "0x%04X", eepromN.baseEepHeader.rxMask); + } else if (streq(var, "rfSilent")) { + fprintf(fd, "0x%04X", eepromN.baseEepHeader.rfSilent); + } else if (streq(var, "btOptions")) { + fprintf(fd, "0x%04X", eepromN.baseEepHeader.blueToothOptions); + } else if (streq(var, "deviceCap")) { + fprintf(fd, "0x%04X", eepromN.baseEepHeader.deviceCap); + } else if (strneq(var, "macaddr", 7)) { + fprintf(fd, "%02X", + eepromN.baseEepHeader.macAddr[atoi(var+7)]); + } else if (streq(var, "opCapFlags")) { + fprintf(fd, "0x%02X", eepromN.baseEepHeader.opCapFlags); + } else if (streq(var, "eepMisc")) { + fprintf(fd, "0x%02X", eepromN.baseEepHeader.eepMisc); + } else if (strneq(var, "binBuildNumber", 14)) { + fprintf(fd, "%3d", + (eepromN.baseEepHeader.binBuildNumber >> (8*atoi(var+14))) + & 0xff); + } else if (strneq(var, "custData", 8)) { + fprintf(fd, "%2.2X", eepromN.custData[atoi(var+8)]); + } else if (streq(var, "xpd_mask")) { + if (IS_VERS(<, AR_EEPROM_VER5_0)) + fprintf(fd, "0x%02x", pExpnPower->xpdMask); + else + fprintf(fd, "0x%02x", pRaw->xpd_mask); + } else if (streq(var, "numChannels")) { + if (IS_VERS(<, AR_EEPROM_VER5_0)) + fprintf(fd, "%2d", pExpnPower->numChannels); + else + fprintf(fd, "%2d", pRaw->numChannels); + } else if (streq(var, "freq")) { + if (IS_VERS(<, AR_EEPROM_VER5_0)) + fprintf(fd, "%4d", pExpnPower->pChannels[curchan]); + else + fprintf(fd, "%4d", pRaw->pChannels[curchan]); + } else if (streq(var, "maxpow")) { + int16_t maxPower_t4; + if (IS_VERS(<, AR_EEPROM_VER5_0)) { + maxPower_t4 = pExpnPower->pDataPerChannel[curchan].maxPower_t4; + } else { + maxPower_t4 = pRaw->pDataPerChannel[curchan].maxPower_t4; + if (maxPower_t4 == 0) + maxPower_t4 = getMaxPowerV5(&pRaw->pDataPerChannel[curchan]); + } + printQuarterDbmPower(fd, maxPower_t4); + } else if (streq(var, "pd_gain")) { + fprintf(fd, "%4d", pRaw->pDataPerChannel[curchan]. + pDataPerPDGain[curpdgain].pd_gain); + } else if (strneq(var, "maxpwr", 6)) { + int vpd = atoi(var+6); + if (vpd < pRaw->pDataPerChannel[curchan].pDataPerPDGain[curpdgain].numVpd) + printQuarterDbmPower(fd, pRaw->pDataPerChannel[curchan]. + pDataPerPDGain[curpdgain].pwr_t4[vpd]); + else + fprintf(fd, " "); + } else if (strneq(var, "pwr_t4_", 7)) { + printQuarterDbmPower(fd, pExpnPower->pDataPerChannel[curchan]. + pDataPerXPD[singleXpd].pwr_t4[atoi(var+7)]); + } else if (strneq(var, "Vpd", 3)) { + int vpd = atoi(var+3); + if (vpd < pRaw->pDataPerChannel[curchan].pDataPerPDGain[curpdgain].numVpd) + printVpd(fd, pRaw->pDataPerChannel[curchan]. + pDataPerPDGain[curpdgain].Vpd[vpd]); + else + fprintf(fd, " "); + } else if (streq(var, "CTL")) { + fprintf(fd, "0x%2x", eeprom.ee_ctl[curctl] & 0xff); + } else if (streq(var, "ctlType")) { + static const char *ctlType[16] = { + "11a base", "11b", "11g", "11a TURBO", "108g", + "2GHT20", "5GHT20", "2GHT40", "5GHT40", + "0x9", "0xa", "0xb", "0xc", "0xd", "0xe", "0xf", + }; + fprintf(fd, "%8s", ctlType[eeprom.ee_ctl[curctl] & CTL_MODE_M]); + } else if (streq(var, "ctlRD")) { + static const char *ctlRD[8] = { + "0x00", " FCC", "0x20", "ETSI", + " MKK", "0x50", "0x60", "0x70" + }; + fprintf(fd, "%s", ctlRD[(eeprom.ee_ctl[curctl] >> 4) & 7]); + } else if (strneq(var, "rdEdgePower", 11)) { + printEdgePower(fd, atoi(var+11)); + } else if (strneq(var, "rdEdgeFlag", 10)) { + printEdgeFlag(fd, atoi(var+10)); + } else if (strneq(var, "rdEdge", 6)) { + printEdge(fd, atoi(var+6)); + } else if (strneq(var, "testChannel", 11)) { + fprintf(fd, "%4d", pPowerInfo[atoi(var+11)].testChannel); + } else if (strneq(var, "pwr6_24_", 8)) { + printHalfDbmPower(fd, pPowerInfo[atoi(var+8)].twicePwr6_24); + } else if (strneq(var, "pwr36_", 6)) { + printHalfDbmPower(fd, pPowerInfo[atoi(var+6)].twicePwr36); + } else if (strneq(var, "pwr48_", 6)) { + printHalfDbmPower(fd, pPowerInfo[atoi(var+6)].twicePwr48); + } else if (strneq(var, "pwr54_", 6)) { + printHalfDbmPower(fd, pPowerInfo[atoi(var+6)].twicePwr54); + } else if (strneq(var, "channelValue", 12)) { + fprintf(fd, "%4d", pDataPerChannel[atoi(var+12)].channelValue); + } else if (strneq(var, "pcdacMin", 8)) { + fprintf(fd, "%02d", pDataPerChannel[atoi(var+8)].pcdacMin); + } else if (strneq(var, "pcdacMax", 8)) { + fprintf(fd, "%02d", pDataPerChannel[atoi(var+8)].pcdacMax); + } else if (strneq(var, "pcdac", 5)) { + if (IS_VERS(<, AR_EEPROM_VER4_0)) { + fprintf(fd, "%02d", pDataPerChannel[atoi(var+5)]. + PcdacValues[curpcdac]); + } else if (IS_VERS(<, AR_EEPROM_VER5_0)) { + fprintf(fd, "%02d", + pExpnPower->pDataPerChannel[curchan]. + pDataPerXPD[singleXpd].pcdac[atoi(var+5)]); + } else + undef("pcdac"); + } else if (strneq(var, "pwrValue", 8)) { + printPcdacValue(fd, + pDataPerChannel[atoi(var+8)].PwrValues[curpcdac]); + } else if (streq(var, "singleXpd")) { + fprintf(fd, "%2d", singleXpd); + } else + warnx("line %u, unknown EEPROM variable \"%s\"", lineno, var); +#undef strneq +#undef streq +} + +static void +ifmode(FILE *ftemplate, const char *mode) +{ + if (strcasecmp(mode, "11a") == 0) { + if (IS_VERS(<, AR_EEPROM_VER14_2)) { + if (eeprom.ee_Amode) + setmode(headerInfo11A); + else + skipto(ftemplate, "endmode"); + return; + } + if (IS_VERS(>=, AR_EEPROM_VER14_2)) { + if (eepromN.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) + setmode(headerInfo11A); + else + skipto(ftemplate, "endmode"); + return; + } + } else if (strcasecmp(mode, "11g") == 0) { + if (IS_VERS(<, AR_EEPROM_VER14_2)) { + if (eeprom.ee_Gmode) + setmode(headerInfo11G); + else + skipto(ftemplate, "endmode"); + return; + } + if (IS_VERS(>=, AR_EEPROM_VER14_2)) { + if (eepromN.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G) + setmode(headerInfo11B); /* NB: 2.4GHz */ + else + skipto(ftemplate, "endmode"); + return; + } + } else if (strcasecmp(mode, "11b") == 0) { + if (IS_VERS(<, AR_EEPROM_VER14_2)) { + if (eeprom.ee_Bmode) + setmode(headerInfo11B); + else + skipto(ftemplate, "endmode"); + return; + } + } + warnx("line %d, unknown/unexpected mode \"%s\" ignored", + lineno, mode); + skipto(ftemplate, "endmode"); +} + +static void +parseTemplate(FILE *ftemplate, FILE *fd) +{ + int c, i; + char id[MAXID]; + long forchan, forpdgain, forctl, forpcdac; + + lineno = 1; + bol = 1; + while ((c = getc(ftemplate)) != EOF) { + if (c == '#') { /* comment */ + skiptoeol: + while ((c = getc(ftemplate)) != EOF && c != '\n') + ; + if (c == EOF) + return; + lineno++; + bol = 1; + continue; + } + if (c == '.' && bol) { /* .directive */ + if (token(ftemplate, id, MAXID, ".directive") == EOF) + return; + /* process directive */ + if (strcasecmp(id, "ifmode") == 0) { + skipws(ftemplate); + if (token(ftemplate, id, MAXID, "id") == EOF) + return; + ifmode(ftemplate, id); + } else if (strcasecmp(id, "endmode") == 0) { + /* XXX free malloc'd indirect data */ + curmode = -1; /* NB: undefined */ + } else if (strcasecmp(id, "forchan") == 0) { + forchan = ftell(ftemplate) - sizeof("forchan"); + if (curchan == -1) + curchan = 0; + } else if (strcasecmp(id, "endforchan") == 0) { + if (++curchan < numChannels) + fseek(ftemplate, forchan, SEEK_SET); + else + curchan = -1; + } else if (strcasecmp(id, "ifpdgain") == 0) { + skipws(ftemplate); + if (token(ftemplate, id, MAXID, "pdgain") == EOF) + return; + curlpdgain = strtoul(id, NULL, 0); + if (curlpdgain >= pRaw->pDataPerChannel[curchan].numPdGains) { + skipto(ftemplate, "endpdgain"); + curlpdgain = -1; + } else + curpdgain = pdgain(curlpdgain); + } else if (strcasecmp(id, "endpdgain") == 0) { + curlpdgain = curpdgain = -1; + } else if (strcasecmp(id, "forpdgain") == 0) { + forpdgain = ftell(ftemplate) - sizeof("forpdgain"); + if (curlpdgain == -1) { + skipws(ftemplate); + if (token(ftemplate, id, MAXID, "pdgain") == EOF) + return; + curlpdgain = strtoul(id, NULL, 0); + if (curlpdgain >= pRaw->pDataPerChannel[curchan].numPdGains) { + skipto(ftemplate, "endforpdgain"); + curlpdgain = -1; + } else + curpdgain = pdgain(curlpdgain); + } + } else if (strcasecmp(id, "endforpdgain") == 0) { + if (++curpdgain < pRaw->pDataPerChannel[curchan].numPdGains) + fseek(ftemplate, forpdgain, SEEK_SET); + else + curpdgain = -1; + } else if (strcasecmp(id, "forpcdac") == 0) { + forpcdac = ftell(ftemplate) - sizeof("forpcdac"); + if (curpcdac == -1) + curpcdac = 0; + } else if (strcasecmp(id, "endforpcdac") == 0) { + if (++curpcdac < pDataPerChannel[0].numPcdacValues) + fseek(ftemplate, forpcdac, SEEK_SET); + else + curpcdac = -1; + } else if (strcasecmp(id, "forctl") == 0) { + forctl = ftell(ftemplate) - sizeof("forchan"); + if (curctl == -1) + curctl = nextctl(0); + } else if (strcasecmp(id, "endforctl") == 0) { + curctl = nextctl(curctl+1); + if (curctl != -1) + fseek(ftemplate, forctl, SEEK_SET); + } else { + warnx("line %d, unknown directive %s ignored", + lineno, id); + } + goto skiptoeol; + } + if (c == '$') { /* $variable reference */ + if (token(ftemplate, id, MAXID, "$var") == EOF) + return; + /* XXX not valid if variable depends on curmode */ + eevar(fd, id); + continue; + } + if (c == '\\') { /* escape next character */ + c = getc(ftemplate); + if (c == EOF) + return; + } + fputc(c, fd); + bol = (c == '\n'); + if (bol) + lineno++; + } +} diff --git a/tools/tools/ath/athprom/eeprom-14 b/tools/tools/ath/athprom/eeprom-14 new file mode 100644 index 000000000000..ef2b1c69dd03 --- /dev/null +++ b/tools/tools/ath/athprom/eeprom-14 @@ -0,0 +1,120 @@ +# $FreeBSD$ +# +# v14 format EEPROM template (AR5416 and later 11n parts) +# + |===================== Header Information ====================| + | Major Version $V_major | Minor Version $V_minor | + |-------------------------------------------------------------| + | Checksum $checksum | Length $length | + | RegDomain 1 $regDmn0 | RegDomain 2 $regDmn1 | + | TX Mask $txMask | RX Mask $rxMask | + | rfSilent $rfSilent | btOptions $btOptions | + | deviceCap $deviceCap | | + | MacAddress: $macaddr0:$macaddr1:$macaddr2:$macaddr3:$macaddr4:$macaddr5 | + | OpFlags: [$opCapFlags] 11A 1, 11G 1 | + | eepMisc: [$eepMisc] endian 0 | + |-------------------------------------------------------------| + | Customer Data in hex | + |= $custData0 $custData1 $custData2 $custData3 $custData4 $custData5 $custData6 $custData7 $custData8 $custData9 $custData10 $custData11 $custData12 $custData13 $custData14 $custData15 =| + |= $custData16 $custData17 $custData18 $custData19 $custData20 $custData21 $custData22 $custData23 $custData24 $custData25 $custData26 $custData27 $custData28 $custData29 $custData30 $custData31 =| + |= $custData32 $custData33 $custData34 $custData35 $custData36 $custData37 $custData38 $custData39 $custData40 $custData41 $custData42 $custData43 $custData44 $custData45 $custData46 $custData47 =| + |= $custData48 $custData49 $custData50 $custData51 $custData52 $custData53 $custData54 $custData55 $custData56 $custData57 $custData58 $custData59 $custData60 $custData61 $custData62 $custData63 =| + |=============================================================| + +.ifmode 11a + |=========== 5GHz Modal Header ===========| + | Ant Chain 0 $antCtrlChain0 | + | Ant Chain 1 $antCtrlChain1 | + | Ant Chain 2 $antCtrlChain2 | + | Ant Chain common 0x00001120 | + | Antenna Gain Chain 0 $antGainCh0 | + | Antenna Gain Chain 1 $antGainCh1 | + | Antenna Gain Chain 2 $antGainCh2 | + | Switch Settling $switchSettling | + | TxRxAttenuation Ch 0 $txRxAttenCh0 | + | TxRxAttenuation Ch 1 $txRxAttenCh1 | + | TxRxAttenuation Ch 2 $txRxAttenCh2 | + | RxTxMargin Chain 0 $rxTxMarginCh0 | + | RxTxMargin Chain 1 $rxTxMarginCh1 | + | RxTxMargin Chain 2 $rxTxMarginCh2 | + | adc desired size $adcDesiredSize | + | pga desired size $pgaDesiredSize | + | xlna gain Chain 0 $xlnaGainCh0 | + | xlna gain Chain 1 $xlnaGainCh1 | + | xlna gain Chain 2 $xlnaGainCh2 | + | tx end to xpa off $txEndToXPAOff | + | tx end to rx on $txEndToRxOn | + | tx frame to xpa on $txFrameToXPAOn | + | thresh62 $thresh62 | + | noise floor thres 0 $noiseFloorThreshCh0 | + | noise floor thres 1 $noiseFloorThreshCh1 | + | noise floor thres 2 $noiseFloorThreshCh2 | + | Xpd Gain Mask $xpdGain | + | Xpd extern $xpd | + | IQ Cal I, Q Chain 0 $iqCalICh0, $iqCalQCh0 | + | IQ Cal I, Q Chain 1 $iqCalICh1, $iqCalQCh1 | + | IQ Cal I, Q Chain 2 $iqCalICh2, $iqCalQCh2 | + | pdGain Overlap $pdGainOverlap dB | + | Analog Output Bias (ob) $ob | + | Analog Driver Bias (db) $db | + | Xpa bias level $xpaBiasLvl | + | pwr dec 2 chain $pwrDecreaseFor2Chain dB | + | pwr dec 3 chain $pwrDecreaseFor3Chain dB | + | txFrameToDataStart $txFrameToDataStart | + | txFrameToPaOn $txFrameToPaOn | + | ht40PowerIncForPdadc $ht40PowerIncForPdadc | + |=========================================| + +============================Target Power Info=============================== +| rate | $testChannel0 | $testChannel1 | $testChannel2 | $testChannel3 | +|==============|==============|==============|==============|==============| +| 6-24 | $pwr6_24_0 | $pwr6_24_1 | $pwr6_24_2 | $pwr6_24_3 | +| 36 | $pwr36_0 | $pwr36_1 | $pwr36_2 | $pwr36_3 | +| 48 | $pwr48_0 | $pwr48_1 | $pwr48_2 | $pwr48_3 | +| 54 | $pwr54_0 | $pwr54_1 | $pwr54_2 | $pwr54_3 | +|==============|==============|==============|==============|==============| +| rate | $testChannel4 | $testChannel5 | $testChannel6 | $testChannel7 | +|==============|==============|==============|==============|==============| +| 6-24 | $pwr6_24_4 | $pwr6_24_5 | $pwr6_24_6 | $pwr6_24_7 | +| 36 | $pwr36_4 | $pwr36_5 | $pwr36_6 | $pwr36_7 | +| 48 | $pwr48_4 | $pwr48_5 | $pwr48_6 | $pwr48_7 | +| 54 | $pwr54_4 | $pwr54_5 | $pwr54_6 | $pwr54_7 | +|==============|==============|==============|==============|==============| + +=======================Test Group Band Edge Power======================== +.forctl +| | +| CTL: $CTL [ $ctlRD $ctlType mode ] | +|=======|=======|=======|=======|=======|=======|=======|=======|=======| +| edge | $rdEdge0 | $rdEdge1 | $rdEdge2 | $rdEdge3 | $rdEdge4 | $rdEdge5 | $rdEdge6 | $rdEdge7 | +|=======|=======|=======|=======|=======|=======|=======|=======|=======| +| power | $rdEdgePower0 | $rdEdgePower1 | $rdEdgePower2 | $rdEdgePower3 | $rdEdgePower4 | $rdEdgePower5 | $rdEdgePower6 | $rdEdgePower7 | +|=======|=======|=======|=======|=======|=======|=======|=======|=======| +| flag | $rdEdgeFlag0 | $rdEdgeFlag1 | $rdEdgeFlag2 | $rdEdgeFlag3 | $rdEdgeFlag4 | $rdEdgeFlag5 | $rdEdgeFlag6 | $rdEdgeFlag7 | +========================================================================= +.endforctl +.endmode + +.ifmode 11g +=============Target Power Info================ +| rate | $testChannel0 | $testChannel1 | +|==============|==============|==============| +| 1 | $pwr6_24_0 | $pwr6_24_1 | +| 2 | $pwr36_0 | $pwr36_1 | +| 5.5 | $pwr48_0 | $pwr48_1 | +| 11 | $pwr54_0 | $pwr54_1 | +|==============|==============|==============| + +=======================Test Group Band Edge Power======================== +.forctl +| | +| CTL: $CTL [ $ctlRD $ctlType mode ] | +|=======|=======|=======|=======|=======|=======|=======|=======|=======| +| edge | $rdEdge0 | $rdEdge1 | $rdEdge2 | $rdEdge3 | $rdEdge4 | $rdEdge5 | $rdEdge6 | $rdEdge7 | +|=======|=======|=======|=======|=======|=======|=======|=======|=======| +| power | $rdEdgePower0 | $rdEdgePower1 | $rdEdgePower2 | $rdEdgePower3 | $rdEdgePower4 | $rdEdgePower5 | $rdEdgePower6 | $rdEdgePower7 | +|=======|=======|=======|=======|=======|=======|=======|=======|=======| +| flag | $rdEdgeFlag0 | $rdEdgeFlag1 | $rdEdgeFlag2 | $rdEdgeFlag3 | $rdEdgeFlag4 | $rdEdgeFlag5 | $rdEdgeFlag6 | $rdEdgeFlag7 | +========================================================================= +.endforctl +.endmode diff --git a/tools/tools/ath/athprom/eeprom-3 b/tools/tools/ath/athprom/eeprom-3 new file mode 100644 index 000000000000..73c7033705d6 --- /dev/null +++ b/tools/tools/ath/athprom/eeprom-3 @@ -0,0 +1,165 @@ +# $FreeBSD$ +# +# v3 format EEPROM template +# +.ifmode 11a + =================Header Information for mode 11a=============== + | Major Version $V_major | Minor Version $V_minor | + |-------------------------------------------------------------| + | A Mode $Amode | B Mode $Bmode | G Mode $Gmode | + | RegDomain $regdomain | Turbo2 Disable $turbo2Disable | Turbo5 Disable $turbo5Disable | + | RF Silent $rfKill | XR5 Disable $disableXr5 | XR2 Disable $disableXr2 | + | Turbo 2W Maximum dBm $turbo2WMaxPower5 | cckOfdmDelta(10x) $cckOfdmDelta | GainI $gainI | + |-------------------------------------------------------------| + | device type $deviceType | Switch Settling Time $switchSettling | + | ADC Desired size $adcDesiredSize | XLNA Gain $xlnaGain | + | tx end to XLNA on $txEndToXLNAOn | Threashold 62 $thresh62 | + | tx end to XPA off $txEndToXPAOff | tx end to XPA on $txFrameToXPAOn | + | PGA Desired size $pgaDesiredSize | Noise Threshold $noiseFloorThresh | + | XPD Gain $xgain | XPD $xpd | + | txrx Attenuation $txrxAtten | Capabilities $capField | + | Antenna control 0 $antennaControl0 | Antenna control 1 $antennaControl1 | + | Antenna control 2 $antennaControl2 | Antenna control 3 $antennaControl3 | + | Antenna control 4 $antennaControl4 | Antenna control 5 $antennaControl5 | + | Antenna control 6 $antennaControl6 | Antenna control 7 $antennaControl7 | + | Antenna control 8 $antennaControl8 | Antenna control 9 $antennaControl9 | + | Antenna control 10 $antennaControl10 | | + |-------------------------------------------------------------| + | OB_1 $ob1 | OB_2 $ob2 | OB_3 $ob3 | OB_4 $ob4 | + | DB_1 $db1 | DB_2 $db2 | DB_3 $db3 | DB_4 $db4 | + =============================================================== + + =========================Calibration Information============================ + | $channelValue0 | $channelValue1 | $channelValue2 | $channelValue3 | $channelValue4 | + |==============|==============|==============|==============|==============| + |pcdac pwr(dBm)|pcdac pwr(dBm)|pcdac pwr(dBm)|pcdac pwr(dBm)|pcdac pwr(dBm)| +.forpcdac + | $pcdac0 $pwrValue0 | $pcdac1 $pwrValue1 | $pcdac2 $pwrValue2 | $pcdac3 $pwrValue3 | $pcdac4 $pwrValue4 | +.endforpcdac + | | | | | | + | pcdac min $pcdacMin0 | pcdac min $pcdacMin1 | pcdac min $pcdacMin2 | pcdac min $pcdacMin3 | pcdac min $pcdacMin4 | + | pcdac max $pcdacMax0 | pcdac max $pcdacMax1 | pcdac max $pcdacMax2 | pcdac max $pcdacMax3 | pcdac max $pcdacMax4 | + |==============|==============|==============|==============|==============| + | $channelValue5 | $channelValue6 | $channelValue7 | $channelValue8 | $channelValue9 | + |==============|==============|==============|==============|==============| + |pcdac pwr(dBm)|pcdac pwr(dBm)|pcdac pwr(dBm)|pcdac pwr(dBm)|pcdac pwr(dBm)| +.forpcdac + | $pcdac5 $pwrValue5 | $pcdac6 $pwrValue6 | $pcdac7 $pwrValue7 | $pcdac8 $pwrValue8 | $pcdac9 $pwrValue9 | +.endforpcdac + | | | | | | + | pcdac min $pcdacMin5 | pcdac min $pcdacMin6 | pcdac min $pcdacMin7 | pcdac min $pcdacMin8 | pcdac min $pcdacMin9 | + | pcdac max $pcdacMax5 | pcdac max $pcdacMax6 | pcdac max $pcdacMax7 | pcdac max $pcdacMax8 | pcdac max $pcdacMax9 | + |==============|==============|==============|==============|==============| + + ============================Target Power Info=============================== + | rate | $testChannel0 | $testChannel1 | $testChannel2 | $testChannel3 | + |==============|==============|==============|==============|==============| + | 6-24 | $pwr6_24_0 | $pwr6_24_1 | $pwr6_24_2 | $pwr6_24_3 | + | 36 | $pwr36_0 | $pwr36_1 | $pwr36_2 | $pwr36_3 | + | 48 | $pwr48_0 | $pwr48_1 | $pwr48_2 | $pwr48_3 | + | 54 | $pwr54_0 | $pwr54_1 | $pwr54_2 | $pwr54_3 | + |==============|==============|==============|==============|==============| + | rate | $testChannel4 | $testChannel5 | $testChannel6 | $testChannel7 | + |==============|==============|==============|==============|==============| + | 6-24 | $pwr6_24_4 | $pwr6_24_5 | $pwr6_24_6 | $pwr6_24_7 | + | 36 | $pwr36_4 | $pwr36_5 | $pwr36_6 | $pwr36_7 | + | 48 | $pwr48_4 | $pwr48_5 | $pwr48_6 | $pwr48_7 | + | 54 | $pwr54_4 | $pwr54_5 | $pwr54_6 | $pwr54_7 | + |==============|==============|==============|==============|==============| +.endmode + +.ifmode 11b + =================Header Information for mode 11b=============== + | Major Version $V_major | Minor Version $V_minor | + |-------------------------------------------------------------| + | A Mode $Amode | B Mode $Bmode | G Mode $Gmode | + | RegDomain $regdomain | Turbo2 Disable $turbo2Disable | Turbo5 Disable $turbo5Disable | + | RF Silent $rfKill | XR5 Disable $disableXr5 | XR2 Disable $disableXr2 | + | Turbo 2W Maximum dBm $turbo2WMaxPower5 | cckOfdmDelta(10x) $cckOfdmDelta | GainI $gainI | + |-------------------------------------------------------------| + | device type $deviceType | Switch Settling Time $switchSettling | + | ADC Desired size $adcDesiredSize | XLNA Gain $xlnaGain | + | tx end to XLNA on $txEndToXLNAOn | Threashold 62 $thresh62 | + | tx end to XPA off $txEndToXPAOff | tx end to XPA on $txFrameToXPAOn | + | PGA Desired size $pgaDesiredSize | Noise Threshold $noiseFloorThresh | + | XPD Gain $xgain | XPD $xpd | + | txrx Attenuation $txrxAtten | Capabilities $capField | + | Antenna control 0 $antennaControl0 | Antenna control 1 $antennaControl1 | + | Antenna control 2 $antennaControl2 | Antenna control 3 $antennaControl3 | + | Antenna control 4 $antennaControl4 | Antenna control 5 $antennaControl5 | + | Antenna control 6 $antennaControl6 | Antenna control 7 $antennaControl7 | + | Antenna control 8 $antennaControl8 | Antenna control 9 $antennaControl9 | + | Antenna control 10 $antennaControl10 | | + |-------------------------------------------------------------| + | OB_1 $obFor24 | B_OB $ob2GHz0 | DB_1 $dbFor24 | B_DB $db2GHz0 | + =============================================================== + + ==========Calibration Information============= + | $channelValue0 | $channelValue1 | $channelValue2 | + |==============|==============|==============| + |pcdac pwr(dBm)|pcdac pwr(dBm)|pcdac pwr(dBm)| +.forpcdac + | $pcdac0 $pwrValue0 | $pcdac1 $pwrValue1 | $pcdac2 $pwrValue2 | +.endforpcdac + | | | | + | pcdac min $pcdacMin0 | pcdac min $pcdacMin1 | pcdac min $pcdacMin2 | + | pcdac max $pcdacMax0 | pcdac max $pcdacMax1 | pcdac max $pcdacMax2 | + |==============|==============|==============| + + =============Target Power Info================ + | rate | $testChannel0 | $testChannel1 | + |==============|==============|==============| + | 1 | $pwr6_24_0 | $pwr6_24_1 | + | 2 | $pwr36_0 | $pwr36_1 | + | 5.5 | $pwr48_0 | $pwr48_1 | + | 11 | $pwr54_0 | $pwr54_1 | + |==============|==============|==============| +.endmode + +.ifmode 11g + =================Header Information for mode 11g=============== + | Major Version $V_major | Minor Version $V_minor | + |-------------------------------------------------------------| + | A Mode $Amode | B Mode $Bmode | G Mode $Gmode | + | RegDomain $regdomain | Turbo2 Disable $turbo2Disable | Turbo5 Disable $turbo5Disable | + | RF Silent $rfKill | XR5 Disable $disableXr5 | XR2 Disable $disableXr2 | + | Turbo 2W Maximum dBm $turbo2WMaxPower5 | cckOfdmDelta(10x) $cckOfdmDelta | GainI $gainI | + |-------------------------------------------------------------| + | device type $deviceType | Switch Settling Time $switchSettling | + | ADC Desired size $adcDesiredSize | XLNA Gain $xlnaGain | + | tx end to XLNA on $txEndToXLNAOn | Threashold 62 $thresh62 | + | tx end to XPA off $txEndToXPAOff | tx end to XPA on $txFrameToXPAOn | + | PGA Desired size $pgaDesiredSize | Noise Threshold $noiseFloorThresh | + | XPD Gain $xgain | XPD $xpd | + | txrx Attenuation $txrxAtten | Capabilities $capField | + | Antenna control 0 $antennaControl0 | Antenna control 1 $antennaControl1 | + | Antenna control 2 $antennaControl2 | Antenna control 3 $antennaControl3 | + | Antenna control 4 $antennaControl4 | Antenna control 5 $antennaControl5 | + | Antenna control 6 $antennaControl6 | Antenna control 7 $antennaControl7 | + | Antenna control 8 $antennaControl8 | Antenna control 9 $antennaControl9 | + | Antenna control 10 $antennaControl10 | | + |-------------------------------------------------------------| + | OB_1 $obFor24g | B_OB $ob2GHz1 | DB_1 $dbFor24g | B_DB $db2GHz1 | + =============================================================== + + ==========Calibration Information============= + | $channelValue0 | $channelValue1 | $channelValue2 | + |==============|==============|==============| + |pcdac pwr(dBm)|pcdac pwr(dBm)|pcdac pwr(dBm)| +.forpcdac + | $pcdac0 $pwrValue0 | $pcdac1 $pwrValue1 | $pcdac2 $pwrValue2 | +.endforpcdac + | | | | + | pcdac min $pcdacMin0 | pcdac min $pcdacMin1 | pcdac min $pcdacMin2 | + | pcdac max $pcdacMax0 | pcdac max $pcdacMax1 | pcdac max $pcdacMax2 | + |==============|==============|==============| + + =============Target Power Info================ + | rate | $testChannel0 | $testChannel1 | + |==============|==============|==============| + | 1 | $pwr6_24_0 | $pwr6_24_1 | + | 2 | $pwr36_0 | $pwr36_1 | + | 5.5 | $pwr48_0 | $pwr48_1 | + | 11 | $pwr54_0 | $pwr54_1 | + |==============|==============|==============| +.endmode diff --git a/tools/tools/ath/athprom/eeprom-4 b/tools/tools/ath/athprom/eeprom-4 new file mode 100644 index 000000000000..0d4708bebc63 --- /dev/null +++ b/tools/tools/ath/athprom/eeprom-4 @@ -0,0 +1,206 @@ +# $FreeBSD$ +# +# v4 format EEPROM template +# +.ifmode 11a + =================Header Information for mode $mode=============== + | Major Version $V_major | Minor Version $V_minor | + | EAR Start $earStart | Target Power Start $tpStart | + | EEP MAP $eepMap | Enable 32 khz $exist32KHzCrystal | + |-------------------------------------------------------------| + | A Mode $Amode | B Mode $Bmode | G Mode $Gmode | + | RegDomain $regdomain | Turbo2 Disable $turbo2Disable | Turbo5 Disable $turbo5Disable | + | RF Silent $rfKill | XR5 Disable $disableXr5 | XR2 Disable $disableXr2 | + | Turbo 2W Maximum dBm $turbo2WMaxPower5 | cckOfdmDelta(10x) $cckOfdmDelta | GainI $gainI | + |-------------------------------------------------------------| + | worldwide roaming $WWR | False detect backoff $falseDetectBackoff | + | device type $deviceType | Switch Settling Time $switchSettling | + | ADC Desired size $adcDesiredSize | XLNA Gain $xlnaGain | + | tx end to XLNA on $txEndToXLNAOn | Threashold 62 $thresh62 | + | tx end to XPA off $txEndToXPAOff | tx end to XPA on $txFrameToXPAOn | + | PGA Desired size $pgaDesiredSize | Noise Threshold $noiseFloorThresh | + | XPD Gain $xgain | XPD $xpd | + | txrx Attenuation $txrxAtten | Capabilities $capField | + | Antenna control 0 $antennaControl0 | Antenna control 1 $antennaControl1 | + | Antenna control 2 $antennaControl2 | Antenna control 3 $antennaControl3 | + | Antenna control 4 $antennaControl4 | Antenna control 5 $antennaControl5 | + | Antenna control 6 $antennaControl6 | Antenna control 7 $antennaControl7 | + | Antenna control 8 $antennaControl8 | Antenna control 9 $antennaControl9 | + | Antenna control 10 $antennaControl10 | | + |-------------------------------------------------------------| + | OB_1 $ob1 | OB_2 $ob2 | OB_3 $ob3 | OB_4 $ob4 | + | DB_1 $db1 | DB_2 $db2 | DB_3 $db3 | DB_4 $db4 | + =============================================================== + + =========5112 Power Calibration Information========== + | XPD_Gain_mask $xpd_mask | Number of channels $numChannels | + | XPD_GAIN $singleXpd | | + |======|========|========|========|========|========| + | freq | pwr1 | pwr2 | pwr3 | pwr4 | maxPow | + | | [pcd] | [pcd] | [pcd] | [pcd] | | + |======|========|========|========|========|========| +.forchan + | $freq | $pwr_t4_0 | $pwr_t4_1 | $pwr_t4_2 | $pwr_t4_3 | $maxpow | + | | [$pcdac0] | [$pcdac1] | [$pcdac2] | [$pcdac3] | | + |======|========|========|========|========|========| +.endforchan + + ============================Target Power Info=============================== + | rate | $testChannel0 | $testChannel1 | $testChannel2 | $testChannel3 | + |==============|==============|==============|==============|==============| + | 6-24 | $pwr6_24_0 | $pwr6_24_1 | $pwr6_24_2 | $pwr6_24_3 | + | 36 | $pwr36_0 | $pwr36_1 | $pwr36_2 | $pwr36_3 | + | 48 | $pwr48_0 | $pwr48_1 | $pwr48_2 | $pwr48_3 | + | 54 | $pwr54_0 | $pwr54_1 | $pwr54_2 | $pwr54_3 | + |==============|==============|==============|==============|==============| + | rate | $testChannel4 | $testChannel5 | $testChannel6 | $testChannel7 | + |==============|==============|==============|==============|==============| + | 6-24 | $pwr6_24_4 | $pwr6_24_5 | $pwr6_24_6 | $pwr6_24_7 | + | 36 | $pwr36_4 | $pwr36_5 | $pwr36_6 | $pwr36_7 | + | 48 | $pwr48_4 | $pwr48_5 | $pwr48_6 | $pwr48_7 | + | 54 | $pwr54_4 | $pwr54_5 | $pwr54_6 | $pwr54_7 | + |==============|==============|==============|==============|==============| + + =======================Test Group Band Edge Power======================== +.forctl + | | + | CTL: $CTL [ $ctlRD $ctlType mode ] | + |=======|=======|=======|=======|=======|=======|=======|=======|=======| + | edge | $rdEdge0 | $rdEdge1 | $rdEdge2 | $rdEdge3 | $rdEdge4 | $rdEdge5 | $rdEdge6 | $rdEdge7 | + |=======|=======|=======|=======|=======|=======|=======|=======|=======| + | power | $rdEdgePower0 | $rdEdgePower1 | $rdEdgePower2 | $rdEdgePower3 | $rdEdgePower4 | $rdEdgePower5 | $rdEdgePower6 | $rdEdgePower7 | + |=======|=======|=======|=======|=======|=======|=======|=======|=======| + | flag | $rdEdgeFlag0 | $rdEdgeFlag1 | $rdEdgeFlag2 | $rdEdgeFlag3 | $rdEdgeFlag4 | $rdEdgeFlag5 | $rdEdgeFlag6 | $rdEdgeFlag7 | + ========================================================================= +.endforctl +.endmode + +.ifmode 11b + =================Header Information for mode $mode=============== + | Major Version $V_major | Minor Version $V_minor | + | EAR Start $earStart | Target Power Start $tpStart | + | EEP MAP $eepMap | Enable 32 khz $exist32KHzCrystal | + |-------------------------------------------------------------| + | A Mode $Amode | B Mode $Bmode | G Mode $Gmode | + | RegDomain $regdomain | Turbo2 Disable $turbo2Disable | Turbo5 Disable $turbo5Disable | + | RF Silent $rfKill | XR5 Disable $disableXr5 | XR2 Disable $disableXr2 | + | Turbo 2W Maximum dBm $turbo2WMaxPower5 | cckOfdmDelta(10x) $cckOfdmDelta | GainI $gainI | + |-------------------------------------------------------------| + | worldwide roaming $WWR | False detect backoff $falseDetectBackoff | + | device type $deviceType | Switch Settling Time $switchSettling | + | ADC Desired size $adcDesiredSize | XLNA Gain $xlnaGain | + | tx end to XLNA on $txEndToXLNAOn | Threashold 62 $thresh62 | + | tx end to XPA off $txEndToXPAOff | tx end to XPA on $txFrameToXPAOn | + | PGA Desired size $pgaDesiredSize | Noise Threshold $noiseFloorThresh | + | XPD Gain $xgain | XPD $xpd | + | txrx Attenuation $txrxAtten | Capabilities $capField | + | Antenna control 0 $antennaControl0 | Antenna control 1 $antennaControl1 | + | Antenna control 2 $antennaControl2 | Antenna control 3 $antennaControl3 | + | Antenna control 4 $antennaControl4 | Antenna control 5 $antennaControl5 | + | Antenna control 6 $antennaControl6 | Antenna control 7 $antennaControl7 | + | Antenna control 8 $antennaControl8 | Antenna control 9 $antennaControl9 | + | Antenna control 10 $antennaControl10 | | + |-------------------------------------------------------------| + | OB_1 $obFor24 | B_OB $ob2GHz0 | DB_1 $dbFor24 | B_DB $db2GHz0 | + =============================================================== + + =========5112 Power Calibration Information========== + | XPD_Gain_mask $xpd_mask | Number of channels $numChannels | + | XPD_GAIN $singleXpd | | + |======|========|========|========|========|========| + | freq | pwr1 | pwr2 | pwr3 | pwr4 | maxPow | + | | [pcd] | [pcd] | [pcd] | [pcd] | | + |======|========|========|========|========|========| +.forchan + | $freq | $pwr_t4_0 | $pwr_t4_1 | $pwr_t4_2 | $pwr_t4_3 | $maxpow | + | | [$pcdac0] | [$pcdac1] | [$pcdac2] | [$pcdac3] | | + |======|========|========|========|========|========| +.endforchan + + =============Target Power Info================ + | rate | $testChannel0 | $testChannel1 | + |==============|==============|==============| + | 1 | $pwr6_24_0 | $pwr6_24_1 | + | 2 | $pwr36_0 | $pwr36_1 | + | 5.5 | $pwr48_0 | $pwr48_1 | + | 11 | $pwr54_0 | $pwr54_1 | + |==============|==============|==============| + + =======================Test Group Band Edge Power======================== +.forctl + | | + | CTL: $CTL [ $ctlRD $ctlType mode ] | + |=======|=======|=======|=======|=======|=======|=======|=======|=======| + | edge | $rdEdge0 | $rdEdge1 | $rdEdge2 | $rdEdge3 | $rdEdge4 | $rdEdge5 | $rdEdge6 | $rdEdge7 | + |=======|=======|=======|=======|=======|=======|=======|=======|=======| + | power | $rdEdgePower0 | $rdEdgePower1 | $rdEdgePower2 | $rdEdgePower3 | $rdEdgePower4 | $rdEdgePower5 | $rdEdgePower6 | $rdEdgePower7 | + |=======|=======|=======|=======|=======|=======|=======|=======|=======| + | flag | $rdEdgeFlag0 | $rdEdgeFlag1 | $rdEdgeFlag2 | $rdEdgeFlag3 | $rdEdgeFlag4 | $rdEdgeFlag5 | $rdEdgeFlag6 | $rdEdgeFlag7 | + ========================================================================= +.endforctl +.endmode + +.ifmode 11g + =================Header Information for mode $mode=============== + | Major Version $V_major | Minor Version $V_minor | + | EAR Start $earStart | Target Power Start $tpStart | + | EEP MAP $eepMap | Enable 32 khz $exist32KHzCrystal | + |-------------------------------------------------------------| + | A Mode $Amode | B Mode $Bmode | G Mode $Gmode | + | RegDomain $regdomain | Turbo2 Disable $turbo2Disable | Turbo5 Disable $turbo5Disable | + | RF Silent $rfKill | XR5 Disable $disableXr5 | XR2 Disable $disableXr2 | + | Turbo 2W Maximum dBm $turbo2WMaxPower5 | cckOfdmDelta(10x) $cckOfdmDelta | GainI $gainI | + |-------------------------------------------------------------| + | worldwide roaming $WWR | False detect backoff $falseDetectBackoff | + | device type $deviceType | Switch Settling Time $switchSettling | + | ADC Desired size $adcDesiredSize | XLNA Gain $xlnaGain | + | tx end to XLNA on $txEndToXLNAOn | Threashold 62 $thresh62 | + | tx end to XPA off $txEndToXPAOff | tx end to XPA on $txFrameToXPAOn | + | PGA Desired size $pgaDesiredSize | Noise Threshold $noiseFloorThresh | + | XPD Gain $xgain | XPD $xpd | + | txrx Attenuation $txrxAtten | Capabilities $capField | + | Antenna control 0 $antennaControl0 | Antenna control 1 $antennaControl1 | + | Antenna control 2 $antennaControl2 | Antenna control 3 $antennaControl3 | + | Antenna control 4 $antennaControl4 | Antenna control 5 $antennaControl5 | + | Antenna control 6 $antennaControl6 | Antenna control 7 $antennaControl7 | + | Antenna control 8 $antennaControl8 | Antenna control 9 $antennaControl9 | + | Antenna control 10 $antennaControl10 | | + |-------------------------------------------------------------| + | OB_1 $obFor24g | B_OB $ob2GHz1 | DB_1 $dbFor24g | B_DB $db2GHz1 | + =============================================================== + + =========5112 Power Calibration Information========== + | XPD_Gain_mask $xpd_mask | Number of channels $numChannels | + | XPD_GAIN $singleXpd | | + |======|========|========|========|========|========| + | freq | pwr1 | pwr2 | pwr3 | pwr4 | maxPow | + | | [pcd] | [pcd] | [pcd] | [pcd] | | + |======|========|========|========|========|========| +.forchan + | $freq | $pwr_t4_0 | $pwr_t4_1 | $pwr_t4_2 | $pwr_t4_3 | $maxpow | + | | [$pcdac0] | [$pcdac1] | [$pcdac2] | [$pcdac3] | | + |======|========|========|========|========|========| +.endforchan + + =============Target Power Info================ + | rate | $testChannel0 | $testChannel1 | + |==============|==============|==============| + | 6-24 | $pwr6_24_0 | $pwr6_24_1 | + | 35 | $pwr36_0 | $pwr36_1 | + | 48 | $pwr48_0 | $pwr48_1 | + | 54 | $pwr54_0 | $pwr54_1 | + |==============|==============|==============| + + =======================Test Group Band Edge Power======================== +.forctl + | | + | CTL: $CTL [ $ctlRD $ctlType mode ] | + |=======|=======|=======|=======|=======|=======|=======|=======|=======| + | edge | $rdEdge0 | $rdEdge1 | $rdEdge2 | $rdEdge3 | $rdEdge4 | $rdEdge5 | $rdEdge6 | $rdEdge7 | + |=======|=======|=======|=======|=======|=======|=======|=======|=======| + | power | $rdEdgePower0 | $rdEdgePower1 | $rdEdgePower2 | $rdEdgePower3 | $rdEdgePower4 | $rdEdgePower5 | $rdEdgePower6 | $rdEdgePower7 | + |=======|=======|=======|=======|=======|=======|=======|=======|=======| + | flag | $rdEdgeFlag0 | $rdEdgeFlag1 | $rdEdgeFlag2 | $rdEdgeFlag3 | $rdEdgeFlag4 | $rdEdgeFlag5 | $rdEdgeFlag6 | $rdEdgeFlag7 | + ========================================================================= +.endforctl +.endmode diff --git a/tools/tools/ath/athprom/eeprom-5 b/tools/tools/ath/athprom/eeprom-5 new file mode 100644 index 000000000000..b48a42ad3e91 --- /dev/null +++ b/tools/tools/ath/athprom/eeprom-5 @@ -0,0 +1,245 @@ +# $FreeBSD$ +# +# v5 format EEPROM template +# +.ifmode 11a + =================Header Information for mode 11a=============== + | Major Version $V_major | Minor Version $V_minor | + | EAR Start $earStart | Target Power Start $tpStart | + | EEP MAP $eepMap | Enable 32 khz $exist32KHzCrystal | + | EEP Map2PowerCalStart $eepMap2PowerCalStart | | + |-------------------------------------------------------------| + | A Mode $Amode | B Mode $Bmode | G Mode $Gmode | + | RegDomain $regdomain | Turbo2 Disable $turbo2Disable | Turbo5 Disable $turbo5Disable | + | RF Silent $rfKill | XR5 Disable $disableXr5 | XR2 Disable $disableXr2 | + | Turbo 2W Maximum dBm $turbo2WMaxPower5 | cckOfdmDelta(10x) $cckOfdmDelta | GainI $gainI | + |-------------------------------------------------------------| + | worldwide roaming $WWR | False detect backoff $falseDetectBackoff | + | device type $deviceType | Switch Settling Time $switchSettling | + | ADC Desired size $adcDesiredSize | XLNA Gain $xlnaGain | + | tx end to XLNA on $txEndToXLNAOn | Threashold 62 $thresh62 | + | tx end to XPA off $txEndToXPAOff | tx end to XPA on $txFrameToXPAOn | + | PGA Desired size $pgaDesiredSize | Noise Threshold $noiseFloorThresh | + | XPD Gain $xgain | XPD $xpd | + | txrx Attenuation $txrxAtten | Capabilities $capField | + | Turbo txrx Attenuat $txrxAttenTurbo | Turbo Switch Settling $switchSettlingTurbo | + | Turbo ADC Desired Size $adcDesiredSizeTurbo | Turbo PGA Desired Size $pgaDesiredSizeTurbo | + | Turbo rxtx Margin $rxtxMarginTurbo | | + | Antenna control 0 $antennaControl0 | Antenna control 1 $antennaControl1 | + | Antenna control 2 $antennaControl2 | Antenna control 3 $antennaControl3 | + | Antenna control 4 $antennaControl4 | Antenna control 5 $antennaControl5 | + | Antenna control 6 $antennaControl6 | Antenna control 7 $antennaControl7 | + | Antenna control 8 $antennaControl8 | Antenna control 9 $antennaControl9 | + | Antenna control 10 $antennaControl10 | | + |-------------------------------------------------------------| + | OB_1 $ob1 | OB_2 $ob2 | OB_3 $ob3 | OB_4 $ob4 | + | DB_1 $db1 | DB_2 $db2 | DB_3 $db3 | DB_4 $db4 | + =============================================================== + +=========2413 Power Calibration Information=================== +| XPD_Gain_mask $xpd_mask | Number of channels $numChannels | | +|========|======|========|========|========|========|========| +| freq | pd | pwr1 | pwr2 | pwr3 | pwr4 | pwr5 | +| maxpow | gain | [Vpd] | [Vpd] | [Vpd] | [Vpd] | [Vpd] | +|========|======|========|========|========|========|========| +.forchan +.ifpdgain 0 +| $freq | $pd_gain | $maxpwr0 | $maxpwr1 | $maxpwr2 | $maxpwr3 | $maxpwr4 | +| | | $Vpd0 | $Vpd1 | $Vpd2 | $Vpd3 | $Vpd4 | +.endpdgain +.ifpdgain 1 +| $maxpow | $pd_gain | $maxpwr0 | $maxpwr1 | $maxpwr2 | $maxpwr3 | $maxpwr4 | +| | | $Vpd0 | $Vpd1 | $Vpd2 | $Vpd3 | $Vpd4 | +.endpdgain +.forpdgain 2 +| $maxpow | $pd_gain | $maxpwr0 | $maxpwr1 | $maxpwr2 | $maxpwr3 | $maxpwr4 | +| | | $Vpd0 | $Vpd1 | $Vpd2 | $Vpd3 | $Vpd4 | +.endforpdgain +|========|======|========|========|========|========|========| +.endforchan + +============================Target Power Info=============================== +| rate | $testChannel0 | $testChannel1 | $testChannel2 | $testChannel3 | +|==============|==============|==============|==============|==============| +| 6-24 | $pwr6_24_0 | $pwr6_24_1 | $pwr6_24_2 | $pwr6_24_3 | +| 36 | $pwr36_0 | $pwr36_1 | $pwr36_2 | $pwr36_3 | +| 48 | $pwr48_0 | $pwr48_1 | $pwr48_2 | $pwr48_3 | +| 54 | $pwr54_0 | $pwr54_1 | $pwr54_2 | $pwr54_3 | +|==============|==============|==============|==============|==============| +| rate | $testChannel4 | $testChannel5 | $testChannel6 | $testChannel7 | +|==============|==============|==============|==============|==============| +| 6-24 | $pwr6_24_4 | $pwr6_24_5 | $pwr6_24_6 | $pwr6_24_7 | +| 36 | $pwr36_4 | $pwr36_5 | $pwr36_6 | $pwr36_7 | +| 48 | $pwr48_4 | $pwr48_5 | $pwr48_6 | $pwr48_7 | +| 54 | $pwr54_4 | $pwr54_5 | $pwr54_6 | $pwr54_7 | +|==============|==============|==============|==============|==============| + +=======================Test Group Band Edge Power======================== +.forctl +| | +| CTL: $CTL [ $ctlRD $ctlType mode ] | +|=======|=======|=======|=======|=======|=======|=======|=======|=======| +| edge | $rdEdge0 | $rdEdge1 | $rdEdge2 | $rdEdge3 | $rdEdge4 | $rdEdge5 | $rdEdge6 | $rdEdge7 | +|=======|=======|=======|=======|=======|=======|=======|=======|=======| +| power | $rdEdgePower0 | $rdEdgePower1 | $rdEdgePower2 | $rdEdgePower3 | $rdEdgePower4 | $rdEdgePower5 | $rdEdgePower6 | $rdEdgePower7 | +|=======|=======|=======|=======|=======|=======|=======|=======|=======| +| flag | $rdEdgeFlag0 | $rdEdgeFlag1 | $rdEdgeFlag2 | $rdEdgeFlag3 | $rdEdgeFlag4 | $rdEdgeFlag5 | $rdEdgeFlag6 | $rdEdgeFlag7 | +========================================================================= +.endforctl +.endmode + +.ifmode 11b + =================Header Information for mode 11b=============== + | Major Version $V_major | Minor Version $V_minor | + | EAR Start $earStart | Target Power Start $tpStart | + | EEP MAP $eepMap | Enable 32 khz $exist32KHzCrystal | + | EEP Map2PowerCalStart $eepMap2PowerCalStart | | + |-------------------------------------------------------------| + | A Mode $Amode | B Mode $Bmode | G Mode $Gmode | + | RegDomain $regdomain | Turbo2 Disable $turbo2Disable | Turbo5 Disable $turbo5Disable | + | RF Silent $rfKill | XR5 Disable $disableXr5 | XR2 Disable $disableXr2 | + | Turbo 2W Maximum dBm $turbo2WMaxPower5 | cckOfdmDelta(10x) $cckOfdmDelta | GainI $gainI | + |-------------------------------------------------------------| + | worldwide roaming $WWR | False detect backoff $falseDetectBackoff | + | device type $deviceType | Switch Settling Time $switchSettling | + | ADC Desired size $adcDesiredSize | XLNA Gain $xlnaGain | + | tx end to XLNA on $txEndToXLNAOn | Threashold 62 $thresh62 | + | tx end to XPA off $txEndToXPAOff | tx end to XPA on $txFrameToXPAOn | + | PGA Desired size $pgaDesiredSize | Noise Threshold $noiseFloorThresh | + | XPD Gain $xgain | XPD $xpd | + | txrx Attenuation $txrxAtten | Capabilities $capField | + | Turbo txrx Attenuat $txrxAttenTurbo | Turbo Switch Settling $switchSettlingTurbo | + | Turbo ADC Desired Size $adcDesiredSizeTurbo | Turbo PGA Desired Size $pgaDesiredSizeTurbo | + | Turbo rxtx Margin $rxtxMarginTurbo | | + | Antenna control 0 $antennaControl0 | Antenna control 1 $antennaControl1 | + | Antenna control 2 $antennaControl2 | Antenna control 3 $antennaControl3 | + | Antenna control 4 $antennaControl4 | Antenna control 5 $antennaControl5 | + | Antenna control 6 $antennaControl6 | Antenna control 7 $antennaControl7 | + | Antenna control 8 $antennaControl8 | Antenna control 9 $antennaControl9 | + | Antenna control 10 $antennaControl10 | | + |-------------------------------------------------------------| + | OB_1 $obFor24 | B_OB $ob2GHz0 | DB_1 $dbFor24 | B_DB $db2GHz0 | + =============================================================== + +=========2413 Power Calibration Information=================== +| XPD_Gain_mask $xpd_mask | Number of channels $numChannels | | +|========|======|========|========|========|========|========| +| freq | pd | pwr1 | pwr2 | pwr3 | pwr4 | pwr5 | +| maxpow | gain | [Vpd] | [Vpd] | [Vpd] | [Vpd] | [Vpd] | +|========|======|========|========|========|========|========| +.forchan +.ifpdgain 0 +| $freq | $pd_gain | $maxpwr0 | $maxpwr1 | $maxpwr2 | $maxpwr3 | $maxpwr4 | +| | | $Vpd0 | $Vpd1 | $Vpd2 | $Vpd3 | $Vpd4 | +.endpdgain +.ifpdgain 1 +| $maxpow | $pd_gain | $maxpwr0 | $maxpwr1 | $maxpwr2 | $maxpwr3 | $maxpwr4 | +| | | $Vpd0 | $Vpd1 | $Vpd2 | $Vpd3 | $Vpd4 | +.endpdgain +.forpdgain 2 +| $maxpow | $pd_gain | $maxpwr0 | $maxpwr1 | $maxpwr2 | $maxpwr3 | $maxpwr4 | +| | | $Vpd0 | $Vpd1 | $Vpd2 | $Vpd3 | $Vpd4 | +.endforpdgain +|========|======|========|========|========|========|========| +.endforchan + +=============Target Power Info================ +| rate | $testChannel0 | $testChannel1 | +|==============|==============|==============| +| 1 | $pwr6_24_0 | $pwr6_24_1 | +| 2 | $pwr36_0 | $pwr36_1 | +| 5.5 | $pwr48_0 | $pwr48_1 | +| 11 | $pwr54_0 | $pwr54_1 | +|==============|==============|==============| + +=======================Test Group Band Edge Power======================== +.forctl +| | +| CTL: $CTL [ $ctlRD $ctlType mode ] | +|=======|=======|=======|=======|=======|=======|=======|=======|=======| +| edge | $rdEdge0 | $rdEdge1 | $rdEdge2 | $rdEdge3 | $rdEdge4 | $rdEdge5 | $rdEdge6 | $rdEdge7 | +|=======|=======|=======|=======|=======|=======|=======|=======|=======| +| power | $rdEdgePower0 | $rdEdgePower1 | $rdEdgePower2 | $rdEdgePower3 | $rdEdgePower4 | $rdEdgePower5 | $rdEdgePower6 | $rdEdgePower7 | +|=======|=======|=======|=======|=======|=======|=======|=======|=======| +| flag | $rdEdgeFlag0 | $rdEdgeFlag1 | $rdEdgeFlag2 | $rdEdgeFlag3 | $rdEdgeFlag4 | $rdEdgeFlag5 | $rdEdgeFlag6 | $rdEdgeFlag7 | +========================================================================= +.endforctl +.endmode + +.ifmode 11g + =================Header Information for mode 11g=============== + | Major Version $V_major | Minor Version $V_minor | + | EAR Start $earStart | Target Power Start $tpStart | + | EEP MAP $eepMap | Enable 32 khz $exist32KHzCrystal | + | EEP Map2PowerCalStart $eepMap2PowerCalStart | | + |-------------------------------------------------------------| + | A Mode $Amode | B Mode $Bmode | G Mode $Gmode | + | RegDomain $regdomain | Turbo2 Disable $turbo2Disable | Turbo5 Disable $turbo5Disable | + | RF Silent $rfKill | XR5 Disable $disableXr5 | XR2 Disable $disableXr2 | + | Turbo 2W Maximum dBm $turbo2WMaxPower5 | cckOfdmDelta(10x) $cckOfdmDelta | GainI $gainI | + |-------------------------------------------------------------| + | worldwide roaming $WWR | False detect backoff $falseDetectBackoff | + | device type $deviceType | Switch Settling Time $switchSettling | + | ADC Desired size $adcDesiredSize | XLNA Gain $xlnaGain | + | tx end to XLNA on $txEndToXLNAOn | Threashold 62 $thresh62 | + | tx end to XPA off $txEndToXPAOff | tx end to XPA on $txFrameToXPAOn | + | PGA Desired size $pgaDesiredSize | Noise Threshold $noiseFloorThresh | + | XPD Gain $xgain | XPD $xpd | + | txrx Attenuation $txrxAtten | Capabilities $capField | + | Turbo txrx Attenuat $txrxAttenTurbo | Turbo Switch Settling $switchSettlingTurbo | + | Turbo ADC Desired Size $adcDesiredSizeTurbo | Turbo PGA Desired Size $pgaDesiredSizeTurbo | + | Turbo rxtx Margin $rxtxMarginTurbo | | + | Antenna control 0 $antennaControl0 | Antenna control 1 $antennaControl1 | + | Antenna control 2 $antennaControl2 | Antenna control 3 $antennaControl3 | + | Antenna control 4 $antennaControl4 | Antenna control 5 $antennaControl5 | + | Antenna control 6 $antennaControl6 | Antenna control 7 $antennaControl7 | + | Antenna control 8 $antennaControl8 | Antenna control 9 $antennaControl9 | + | Antenna control 10 $antennaControl10 | | + |-------------------------------------------------------------| + | OB_1 $obFor24g | B_OB $ob2GHz1 | DB_1 $dbFor24g | B_DB $db2GHz1 | + =============================================================== + +=========2413 Power Calibration Information=================== +| XPD_Gain_mask $xpd_mask | Number of channels $numChannels | | +|========|======|========|========|========|========|========| +| freq | pd | pwr1 | pwr2 | pwr3 | pwr4 | pwr5 | +| maxpow | gain | [Vpd] | [Vpd] | [Vpd] | [Vpd] | [Vpd] | +|========|======|========|========|========|========|========| +.forchan +.ifpdgain 0 +| $freq | $pd_gain | $maxpwr0 | $maxpwr1 | $maxpwr2 | $maxpwr3 | $maxpwr4 | +| | | $Vpd0 | $Vpd1 | $Vpd2 | $Vpd3 | $Vpd4 | +.endpdgain +.ifpdgain 1 +| $maxpow | $pd_gain | $maxpwr0 | $maxpwr1 | $maxpwr2 | $maxpwr3 | $maxpwr4 | +| | | $Vpd0 | $Vpd1 | $Vpd2 | $Vpd3 | $Vpd4 | +.endpdgain +.forpdgain 2 +| $maxpow | $pd_gain | $maxpwr0 | $maxpwr1 | $maxpwr2 | $maxpwr3 | $maxpwr4 | +| | | $Vpd0 | $Vpd1 | $Vpd2 | $Vpd3 | $Vpd4 | +.endforpdgain +|========|======|========|========|========|========|========| +.endforchan + +=============Target Power Info================ +| rate | $testChannel0 | $testChannel1 | +|==============|==============|==============| +| 6-24 | $pwr6_24_0 | $pwr6_24_1 | +| 36 | $pwr36_0 | $pwr36_1 | +| 48 | $pwr48_0 | $pwr48_1 | +| 54 | $pwr54_0 | $pwr54_1 | +|==============|==============|==============| + +=======================Test Group Band Edge Power======================== +.forctl +| | +| CTL: $CTL [ $ctlRD $ctlType mode ] | +|=======|=======|=======|=======|=======|=======|=======|=======|=======| +| edge | $rdEdge0 | $rdEdge1 | $rdEdge2 | $rdEdge3 | $rdEdge4 | $rdEdge5 | $rdEdge6 | $rdEdge7 | +|=======|=======|=======|=======|=======|=======|=======|=======|=======| +| power | $rdEdgePower0 | $rdEdgePower1 | $rdEdgePower2 | $rdEdgePower3 | $rdEdgePower4 | $rdEdgePower5 | $rdEdgePower6 | $rdEdgePower7 | +|=======|=======|=======|=======|=======|=======|=======|=======|=======| +| flag | $rdEdgeFlag0 | $rdEdgeFlag1 | $rdEdgeFlag2 | $rdEdgeFlag3 | $rdEdgeFlag4 | $rdEdgeFlag5 | $rdEdgeFlag6 | $rdEdgeFlag7 | +========================================================================= +.endforctl +.endmode diff --git a/tools/tools/ath/athradar/Makefile b/tools/tools/ath/athradar/Makefile new file mode 100644 index 000000000000..23d3012f2344 --- /dev/null +++ b/tools/tools/ath/athradar/Makefile @@ -0,0 +1,16 @@ +# $FreeBSD$ + +PROG= athradar + +.include <../Makefile.inc> + +SRCS= athradar.c +SRCS+= opt_ah.h +CLEANFILES+= opt_ah.h + +opt_ah.h: + echo "#define AH_DEBUG 1" > opt_ah.h + echo "#define AH_DEBUG_COUNTRY 1" >> opt_ah.h + echo "#define AH_SUPPORT_AR5416 1" >> opt_ah.h + +.include <bsd.prog.mk> diff --git a/tools/tools/ath/athradar/athradar.c b/tools/tools/ath/athradar/athradar.c new file mode 100644 index 000000000000..f40e1bd09be5 --- /dev/null +++ b/tools/tools/ath/athradar/athradar.c @@ -0,0 +1,311 @@ +/* + * 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 <getopt.h> +#include <errno.h> +#include <err.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <unistd.h> + +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 <interface>] <cmd> (<arg>)\n", progname); + printf("\t%s: [-h]\n", progname); + printf("\n"); + printf("Valid commands:\n"); + printf("\tget:\t\tGet current radar parameters\n"); + printf("\tset <param> <value>:\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); +} diff --git a/tools/tools/ath/athrd/Makefile b/tools/tools/ath/athrd/Makefile new file mode 100644 index 000000000000..352d712e621a --- /dev/null +++ b/tools/tools/ath/athrd/Makefile @@ -0,0 +1,21 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../../../sys/dev/ath/ath_hal + +PROG= athrd + +SRCS= athrd.c ah_regdomain.c opt_ah.h + +CLEANFILES+= opt_ah.h + +CFLAGS+= -fno-inline + +.include <../Makefile.inc> + +MAN= athrd.1 + +opt_ah.h: + echo "#define AH_DEBUG 1" > opt_ah.h + echo "#define AH_DEBUG_COUNTRY 1" >> opt_ah.h + +.include <bsd.prog.mk> diff --git a/tools/tools/ath/athrd/athrd.1 b/tools/tools/ath/athrd/athrd.1 new file mode 100644 index 000000000000..59c86f98c56d --- /dev/null +++ b/tools/tools/ath/athrd/athrd.1 @@ -0,0 +1,172 @@ +.\"- +.\" 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$ +.\"/ +.Dd January 27, 2009 +.Dt ATHRD 1 +.Os +.Sh NAME +.Nm athrd +.Nd list channels and transmit power for a country/regulatory domain +.Sh SYNOPSIS +.Nm +.Op Fl aedlpcfr4ABGT +.Op Fl m Ar mode +.Bk +.Op Ar country +.Ek +.Sh DESCRIPTION +.Nm +displays the list of frequencies and the associated maximum transmit +power permitted within a regulatory domain and/or country. +.Pp +If no command line options are given, a default country (\c +.Ql US ) +is used. +Country and regulatory names are case insensitive. +.Pp +The following options are available: +.Bl -tag -width indent +.It Fl a +By default +.Nm +will display B channels only if they are not also marked as available for +use as G channels and similary for A and T channels. +With this option +.Nm +will list all channels. +.It Fl e +Calculate channels not assuming extended channel mode. +.It Fl d +Enabling debugging in the HAL code that calculates the available channels +and transmit power values. +.It Fl l +Provide a list of all known country and regulatory domain names. +.It Fl m Ar mode +Calculate channels and transmit power for operation in +.Ql mode ; +one of +.Ql station , +.Ql ibss , +.Ql monitor , +and +.Ql ap +(or the first two letters). +.It Fl p +Mark passive scan channels with lower case letters and active +scan channels with upper case letters. +.It Fl r +Mark channels that require DFS with a +.Ql * . +.It Fl 4 +Mark channels that have a 4ms packet limit with a +.Ql 4 . +.It Fl c +Display IEEE channel numbers instead of frequencies. +.It Fl f +Display frequencies (default). +.It Fl A +Display only 11A channels. +.It Fl B +Display only 11B channels. +.It Fl G +Display only 11G channels. +.It Fl T +Display only Turbo channels. +.El +.Sh EXAMPLES +The following demonstrates how to list the permissible frequencies +and maximum transport power per channel for use in Spain: +.Pp +.nf +tubby% athrd es +\& +SPAIN (ES, 0x2d4, 724) NULL1_WORLD (0x3, 3) +2412G 14.0 2417G 14.0 2422G 14.0 2427G 17.0 2432G 14.0 2437G 17.0 +2442G 14.0 2447G 17.0 2452G 17.0 2457G 14.0 2462G 17.0 +.fi +.Pp +Each frequency has a suffix that is one of: +.Ql G , +.Ql B , +.Ql A , +or +.Ql T +according to whether the channel is usable with 802.11g, 802.11b, +802.11a, or Atheros Turbo mode. +All channels listed as +.Ql G +are also usable in +.Ql B . +Likewise, all channels listed as +.Ql A +are usable in +.Ql T . +Channels listed as +.Ql B +or +.Ql T +are only usable in those modes. +(Note that when the +.Fl p +option is specified passive scan channels are marked with a lower case +.Ql g , +.Ql b , +.Ql a , +or +.Ql t .) +The transmit power is given in units of dbM. +.Sh DIAGNOSTICS +Various diagnostics about unknown regulatory domains and/or country +codes may be encountered. +Use the +.Fl l +option for a list of valid names. +.Sh SEE ALSO +.Xr ath 4 , +.Xr ath_hal 4 +.Sh STANDARDS +Lots belong here. +.Sh NOTES +.Nm +use the HAL to calculate the set of channels. +The transmit power calculations are done by emulating +how the HAL works. +Because +.Nm +does not +read the actual EEPROM contents from a device this emulation may lag +behind current practice. +.Sh BUGS +The HAL reset logic should be used to calculate the transmit power +for each channel instead of using a separate copy of the code. +The data presented by +.Nm +are the expected values; for compliance testing one must measure the actual +operation of the driver and the HAL. diff --git a/tools/tools/ath/athrd/athrd.c b/tools/tools/ath/athrd/athrd.c new file mode 100644 index 000000000000..c4fc40c63714 --- /dev/null +++ b/tools/tools/ath/athrd/athrd.c @@ -0,0 +1,1673 @@ +/*- + * 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$ + */ +#include "opt_ah.h" + +#include "ah.h" + +#include <net80211/_ieee80211.h> +#include <net80211/ieee80211_regdomain.h> + +#include "ah_internal.h" +#include "ah_eeprom_v3.h" /* XXX */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <unistd.h> +#include <ctype.h> + +int ath_hal_debug = 0; +HAL_CTRY_CODE cc = CTRY_DEFAULT; +HAL_REG_DOMAIN rd = 169; /* FCC */ +HAL_BOOL Amode = 1; +HAL_BOOL Bmode = 1; +HAL_BOOL Gmode = 1; +HAL_BOOL HT20mode = 1; +HAL_BOOL HT40mode = 1; +HAL_BOOL turbo5Disable = AH_FALSE; +HAL_BOOL turbo2Disable = AH_FALSE; + +u_int16_t _numCtls = 8; +u_int16_t _ctl[32] = + { 0x10, 0x13, 0x40, 0x30, 0x11, 0x31, 0x12, 0x32 }; +RD_EDGES_POWER _rdEdgesPower[NUM_EDGES*NUM_CTLS] = { + { 5180, 28, 0 }, /* 0x10 */ + { 5240, 60, 0 }, + { 5260, 36, 0 }, + { 5320, 27, 0 }, + { 5745, 36, 0 }, + { 5765, 36, 0 }, + { 5805, 36, 0 }, + { 5825, 36, 0 }, + + { 5210, 28, 0 }, /* 0x13 */ + { 5250, 28, 0 }, + { 5290, 30, 0 }, + { 5760, 36, 0 }, + { 5800, 36, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + + { 5170, 60, 0 }, /* 0x40 */ + { 5230, 60, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + + { 5180, 33, 0 }, /* 0x30 */ + { 5320, 33, 0 }, + { 5500, 34, 0 }, + { 5700, 34, 0 }, + { 5745, 35, 0 }, + { 5765, 35, 0 }, + { 5785, 35, 0 }, + { 5825, 35, 0 }, + + { 2412, 36, 0 }, /* 0x11 */ + { 2417, 36, 0 }, + { 2422, 36, 0 }, + { 2432, 36, 0 }, + { 2442, 36, 0 }, + { 2457, 36, 0 }, + { 2467, 36, 0 }, + { 2472, 36, 0 }, + + { 2412, 36, 0 }, /* 0x31 */ + { 2417, 36, 0 }, + { 2422, 36, 0 }, + { 2432, 36, 0 }, + { 2442, 36, 0 }, + { 2457, 36, 0 }, + { 2467, 36, 0 }, + { 2472, 36, 0 }, + + { 2412, 36, 0 }, /* 0x12 */ + { 2417, 36, 0 }, + { 2422, 36, 0 }, + { 2432, 36, 0 }, + { 2442, 36, 0 }, + { 2457, 36, 0 }, + { 2467, 36, 0 }, + { 2472, 36, 0 }, + + { 2412, 28, 0 }, /* 0x32 */ + { 2417, 28, 0 }, + { 2422, 28, 0 }, + { 2432, 28, 0 }, + { 2442, 28, 0 }, + { 2457, 28, 0 }, + { 2467, 28, 0 }, + { 2472, 28, 0 }, +}; + +u_int16_t turbo2WMaxPower5 = 32; +u_int16_t turbo2WMaxPower2; +int8_t antennaGainMax[2] = { 0, 0 }; /* XXX */ +int eeversion = AR_EEPROM_VER3_1; +TRGT_POWER_ALL_MODES tpow = { + 8, { + { 22, 24, 28, 32, 5180 }, + { 22, 24, 28, 32, 5200 }, + { 22, 24, 28, 32, 5320 }, + { 26, 30, 34, 34, 5500 }, + { 26, 30, 34, 34, 5700 }, + { 20, 30, 34, 36, 5745 }, + { 20, 30, 34, 36, 5825 }, + { 20, 30, 34, 36, 5850 }, + }, + 2, { + { 23, 27, 31, 34, 2412 }, + { 23, 27, 31, 34, 2447 }, + }, + 2, { + { 36, 36, 36, 36, 2412 }, + { 36, 36, 36, 36, 2484 }, + } +}; +#define numTargetPwr_11a tpow.numTargetPwr_11a +#define trgtPwr_11a tpow.trgtPwr_11a +#define numTargetPwr_11g tpow.numTargetPwr_11g +#define trgtPwr_11g tpow.trgtPwr_11g +#define numTargetPwr_11b tpow.numTargetPwr_11b +#define trgtPwr_11b tpow.trgtPwr_11b + +static HAL_BOOL +getChannelEdges(struct ath_hal *ah, u_int16_t flags, u_int16_t *low, u_int16_t *high) +{ + struct ath_hal_private *ahp = AH_PRIVATE(ah); + HAL_CAPABILITIES *pCap = &ahp->ah_caps; + + if (flags & IEEE80211_CHAN_5GHZ) { + *low = pCap->halLow5GhzChan; + *high = pCap->halHigh5GhzChan; + return AH_TRUE; + } + if (flags & IEEE80211_CHAN_2GHZ) { + *low = pCap->halLow2GhzChan; + *high = pCap->halHigh2GhzChan; + return AH_TRUE; + } + return AH_FALSE; +} + +static u_int +getWirelessModes(struct ath_hal *ah) +{ + u_int mode = 0; + + if (Amode) { + mode = HAL_MODE_11A; + if (!turbo5Disable) + mode |= HAL_MODE_TURBO; + } + if (Bmode) + mode |= HAL_MODE_11B; + if (Gmode) { + mode |= HAL_MODE_11G; + if (!turbo2Disable) + mode |= HAL_MODE_108G; + } + if (HT20mode) + mode |= HAL_MODE_11NG_HT20|HAL_MODE_11NA_HT20; + if (HT40mode) + mode |= HAL_MODE_11NG_HT40PLUS|HAL_MODE_11NA_HT40PLUS + | HAL_MODE_11NG_HT40MINUS|HAL_MODE_11NA_HT40MINUS + ; + return mode; +} + +/* Enumerated Regulatory Domain Information 8 bit values indicate that + * the regdomain is really a pair of unitary regdomains. 12 bit values + * are the real unitary regdomains and are the only ones which have the + * frequency bitmasks and flags set. + */ + +enum EnumRd { + /* + * The following regulatory domain definitions are + * found in the EEPROM. Each regulatory domain + * can operate in either a 5GHz or 2.4GHz wireless mode or + * both 5GHz and 2.4GHz wireless modes. + * In general, the value holds no special + * meaning and is used to decode into either specific + * 2.4GHz or 5GHz wireless mode for that particular + * regulatory domain. + */ + NO_ENUMRD = 0x00, + NULL1_WORLD = 0x03, /* For 11b-only countries (no 11a allowed) */ + NULL1_ETSIB = 0x07, /* Israel */ + NULL1_ETSIC = 0x08, + FCC1_FCCA = 0x10, /* USA */ + FCC1_WORLD = 0x11, /* Hong Kong */ + FCC4_FCCA = 0x12, /* USA - Public Safety */ + + FCC2_FCCA = 0x20, /* Canada */ + FCC2_WORLD = 0x21, /* Australia & HK */ + FCC2_ETSIC = 0x22, + FRANCE_RES = 0x31, /* Legacy France for OEM */ + FCC3_FCCA = 0x3A, /* USA & Canada w/5470 band, 11h, DFS enabled */ + FCC3_WORLD = 0x3B, /* USA & Canada w/5470 band, 11h, DFS enabled */ + + ETSI1_WORLD = 0x37, + ETSI3_ETSIA = 0x32, /* France (optional) */ + ETSI2_WORLD = 0x35, /* Hungary & others */ + ETSI3_WORLD = 0x36, /* France & others */ + ETSI4_WORLD = 0x30, + ETSI4_ETSIC = 0x38, + ETSI5_WORLD = 0x39, + ETSI6_WORLD = 0x34, /* Bulgaria */ + ETSI_RESERVED = 0x33, /* Reserved (Do not used) */ + + MKK1_MKKA = 0x40, /* Japan (JP1) */ + MKK1_MKKB = 0x41, /* Japan (JP0) */ + APL4_WORLD = 0x42, /* Singapore */ + MKK2_MKKA = 0x43, /* Japan with 4.9G channels */ + APL_RESERVED = 0x44, /* Reserved (Do not used) */ + APL2_WORLD = 0x45, /* Korea */ + APL2_APLC = 0x46, + APL3_WORLD = 0x47, + MKK1_FCCA = 0x48, /* Japan (JP1-1) */ + APL2_APLD = 0x49, /* Korea with 2.3G channels */ + MKK1_MKKA1 = 0x4A, /* Japan (JE1) */ + MKK1_MKKA2 = 0x4B, /* Japan (JE2) */ + MKK1_MKKC = 0x4C, /* Japan (MKK1_MKKA,except Ch14) */ + + APL3_FCCA = 0x50, + APL1_WORLD = 0x52, /* Latin America */ + APL1_FCCA = 0x53, + APL1_APLA = 0x54, + APL1_ETSIC = 0x55, + APL2_ETSIC = 0x56, /* Venezuela */ + APL5_WORLD = 0x58, /* Chile */ + APL6_WORLD = 0x5B, /* Singapore */ + APL7_FCCA = 0x5C, /* Taiwan 5.47 Band */ + APL8_WORLD = 0x5D, /* Malaysia 5GHz */ + APL9_WORLD = 0x5E, /* Korea 5GHz */ + + /* + * World mode SKUs + */ + WOR0_WORLD = 0x60, /* World0 (WO0 SKU) */ + WOR1_WORLD = 0x61, /* World1 (WO1 SKU) */ + WOR2_WORLD = 0x62, /* World2 (WO2 SKU) */ + WOR3_WORLD = 0x63, /* World3 (WO3 SKU) */ + WOR4_WORLD = 0x64, /* World4 (WO4 SKU) */ + WOR5_ETSIC = 0x65, /* World5 (WO5 SKU) */ + + WOR01_WORLD = 0x66, /* World0-1 (WW0-1 SKU) */ + WOR02_WORLD = 0x67, /* World0-2 (WW0-2 SKU) */ + EU1_WORLD = 0x68, /* Same as World0-2 (WW0-2 SKU), except active scan ch1-13. No ch14 */ + + WOR9_WORLD = 0x69, /* World9 (WO9 SKU) */ + WORA_WORLD = 0x6A, /* WorldA (WOA SKU) */ + + MKK3_MKKB = 0x80, /* Japan UNI-1 even + MKKB */ + MKK3_MKKA2 = 0x81, /* Japan UNI-1 even + MKKA2 */ + MKK3_MKKC = 0x82, /* Japan UNI-1 even + MKKC */ + + MKK4_MKKB = 0x83, /* Japan UNI-1 even + UNI-2 + MKKB */ + MKK4_MKKA2 = 0x84, /* Japan UNI-1 even + UNI-2 + MKKA2 */ + MKK4_MKKC = 0x85, /* Japan UNI-1 even + UNI-2 + MKKC */ + + MKK5_MKKB = 0x86, /* Japan UNI-1 even + UNI-2 + mid-band + MKKB */ + MKK5_MKKA2 = 0x87, /* Japan UNI-1 even + UNI-2 + mid-band + MKKA2 */ + MKK5_MKKC = 0x88, /* Japan UNI-1 even + UNI-2 + mid-band + MKKC */ + + MKK6_MKKB = 0x89, /* Japan UNI-1 even + UNI-1 odd MKKB */ + MKK6_MKKA2 = 0x8A, /* Japan UNI-1 even + UNI-1 odd + MKKA2 */ + MKK6_MKKC = 0x8B, /* Japan UNI-1 even + UNI-1 odd + MKKC */ + + MKK7_MKKB = 0x8C, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKB */ + MKK7_MKKA2 = 0x8D, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKA2 */ + MKK7_MKKC = 0x8E, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKC */ + + MKK8_MKKB = 0x8F, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKB */ + MKK8_MKKA2 = 0x90, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKA2 */ + MKK8_MKKC = 0x91, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKC */ + + /* Following definitions are used only by s/w to map old + * Japan SKUs. + */ + MKK3_MKKA = 0xF0, /* Japan UNI-1 even + MKKA */ + MKK3_MKKA1 = 0xF1, /* Japan UNI-1 even + MKKA1 */ + MKK3_FCCA = 0xF2, /* Japan UNI-1 even + FCCA */ + MKK4_MKKA = 0xF3, /* Japan UNI-1 even + UNI-2 + MKKA */ + MKK4_MKKA1 = 0xF4, /* Japan UNI-1 even + UNI-2 + MKKA1 */ + MKK4_FCCA = 0xF5, /* Japan UNI-1 even + UNI-2 + FCCA */ + MKK9_MKKA = 0xF6, /* Japan UNI-1 even + 4.9GHz */ + MKK10_MKKA = 0xF7, /* Japan UNI-1 even + UNI-2 + 4.9GHz */ + + /* + * Regulator domains ending in a number (e.g. APL1, + * MK1, ETSI4, etc) apply to 5GHz channel and power + * information. Regulator domains ending in a letter + * (e.g. APLA, FCCA, etc) apply to 2.4GHz channel and + * power information. + */ + APL1 = 0x0150, /* LAT & Asia */ + APL2 = 0x0250, /* LAT & Asia */ + APL3 = 0x0350, /* Taiwan */ + APL4 = 0x0450, /* Jordan */ + APL5 = 0x0550, /* Chile */ + APL6 = 0x0650, /* Singapore */ + APL8 = 0x0850, /* Malaysia */ + APL9 = 0x0950, /* Korea (South) ROC 3 */ + + ETSI1 = 0x0130, /* Europe & others */ + ETSI2 = 0x0230, /* Europe & others */ + ETSI3 = 0x0330, /* Europe & others */ + ETSI4 = 0x0430, /* Europe & others */ + ETSI5 = 0x0530, /* Europe & others */ + ETSI6 = 0x0630, /* Europe & others */ + ETSIA = 0x0A30, /* France */ + ETSIB = 0x0B30, /* Israel */ + ETSIC = 0x0C30, /* Latin America */ + + FCC1 = 0x0110, /* US & others */ + FCC2 = 0x0120, /* Canada, Australia & New Zealand */ + FCC3 = 0x0160, /* US w/new middle band & DFS */ + FCC4 = 0x0165, /* US Public Safety */ + FCCA = 0x0A10, + + APLD = 0x0D50, /* South Korea */ + + MKK1 = 0x0140, /* Japan (UNI-1 odd)*/ + MKK2 = 0x0240, /* Japan (4.9 GHz + UNI-1 odd) */ + MKK3 = 0x0340, /* Japan (UNI-1 even) */ + MKK4 = 0x0440, /* Japan (UNI-1 even + UNI-2) */ + MKK5 = 0x0540, /* Japan (UNI-1 even + UNI-2 + mid-band) */ + MKK6 = 0x0640, /* Japan (UNI-1 odd + UNI-1 even) */ + MKK7 = 0x0740, /* Japan (UNI-1 odd + UNI-1 even + UNI-2 */ + MKK8 = 0x0840, /* Japan (UNI-1 odd + UNI-1 even + UNI-2 + mid-band) */ + MKK9 = 0x0940, /* Japan (UNI-1 even + 4.9 GHZ) */ + MKK10 = 0x0B40, /* Japan (UNI-1 even + UNI-2 + 4.9 GHZ) */ + MKKA = 0x0A40, /* Japan */ + MKKC = 0x0A50, + + NULL1 = 0x0198, + WORLD = 0x0199, + DEBUG_REG_DMN = 0x01ff, +}; +#define DEF_REGDMN FCC1_FCCA + +static struct { + const char *name; + HAL_REG_DOMAIN rd; +} domains[] = { +#define D(_x) { #_x, _x } + D(NO_ENUMRD), + D(NULL1_WORLD), /* For 11b-only countries (no 11a allowed) */ + D(NULL1_ETSIB), /* Israel */ + D(NULL1_ETSIC), + D(FCC1_FCCA), /* USA */ + D(FCC1_WORLD), /* Hong Kong */ + D(FCC4_FCCA), /* USA - Public Safety */ + + D(FCC2_FCCA), /* Canada */ + D(FCC2_WORLD), /* Australia & HK */ + D(FCC2_ETSIC), + D(FRANCE_RES), /* Legacy France for OEM */ + D(FCC3_FCCA), + D(FCC3_WORLD), + + D(ETSI1_WORLD), + D(ETSI3_ETSIA), /* France (optional) */ + D(ETSI2_WORLD), /* Hungary & others */ + D(ETSI3_WORLD), /* France & others */ + D(ETSI4_WORLD), + D(ETSI4_ETSIC), + D(ETSI5_WORLD), + D(ETSI6_WORLD), /* Bulgaria */ + D(ETSI_RESERVED), /* Reserved (Do not used) */ + + D(MKK1_MKKA), /* Japan (JP1) */ + D(MKK1_MKKB), /* Japan (JP0) */ + D(APL4_WORLD), /* Singapore */ + D(MKK2_MKKA), /* Japan with 4.9G channels */ + D(APL_RESERVED), /* Reserved (Do not used) */ + D(APL2_WORLD), /* Korea */ + D(APL2_APLC), + D(APL3_WORLD), + D(MKK1_FCCA), /* Japan (JP1-1) */ + D(APL2_APLD), /* Korea with 2.3G channels */ + D(MKK1_MKKA1), /* Japan (JE1) */ + D(MKK1_MKKA2), /* Japan (JE2) */ + D(MKK1_MKKC), + + D(APL3_FCCA), + D(APL1_WORLD), /* Latin America */ + D(APL1_FCCA), + D(APL1_APLA), + D(APL1_ETSIC), + D(APL2_ETSIC), /* Venezuela */ + D(APL5_WORLD), /* Chile */ + D(APL6_WORLD), /* Singapore */ + D(APL7_FCCA), /* Taiwan 5.47 Band */ + D(APL8_WORLD), /* Malaysia 5GHz */ + D(APL9_WORLD), /* Korea 5GHz */ + + D(WOR0_WORLD), /* World0 (WO0 SKU) */ + D(WOR1_WORLD), /* World1 (WO1 SKU) */ + D(WOR2_WORLD), /* World2 (WO2 SKU) */ + D(WOR3_WORLD), /* World3 (WO3 SKU) */ + D(WOR4_WORLD), /* World4 (WO4 SKU) */ + D(WOR5_ETSIC), /* World5 (WO5 SKU) */ + + D(WOR01_WORLD), /* World0-1 (WW0-1 SKU) */ + D(WOR02_WORLD), /* World0-2 (WW0-2 SKU) */ + D(EU1_WORLD), + + D(WOR9_WORLD), /* World9 (WO9 SKU) */ + D(WORA_WORLD), /* WorldA (WOA SKU) */ + + D(MKK3_MKKB), /* Japan UNI-1 even + MKKB */ + D(MKK3_MKKA2), /* Japan UNI-1 even + MKKA2 */ + D(MKK3_MKKC), /* Japan UNI-1 even + MKKC */ + + D(MKK4_MKKB), /* Japan UNI-1 even + UNI-2 + MKKB */ + D(MKK4_MKKA2), /* Japan UNI-1 even + UNI-2 + MKKA2 */ + D(MKK4_MKKC), /* Japan UNI-1 even + UNI-2 + MKKC */ + + D(MKK5_MKKB), /* Japan UNI-1 even + UNI-2 + mid-band + MKKB */ + D(MKK5_MKKA2), /* Japan UNI-1 even + UNI-2 + mid-band + MKKA2 */ + D(MKK5_MKKC), /* Japan UNI-1 even + UNI-2 + mid-band + MKKC */ + + D(MKK6_MKKB), /* Japan UNI-1 even + UNI-1 odd MKKB */ + D(MKK6_MKKA2), /* Japan UNI-1 even + UNI-1 odd + MKKA2 */ + D(MKK6_MKKC), /* Japan UNI-1 even + UNI-1 odd + MKKC */ + + D(MKK7_MKKB), /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKB */ + D(MKK7_MKKA2), /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKA2 */ + D(MKK7_MKKC), /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKC */ + + D(MKK8_MKKB), /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKB */ + D(MKK8_MKKA2), /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKA2 */ + D(MKK8_MKKC), /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKC */ + + D(MKK3_MKKA), /* Japan UNI-1 even + MKKA */ + D(MKK3_MKKA1), /* Japan UNI-1 even + MKKA1 */ + D(MKK3_FCCA), /* Japan UNI-1 even + FCCA */ + D(MKK4_MKKA), /* Japan UNI-1 even + UNI-2 + MKKA */ + D(MKK4_MKKA1), /* Japan UNI-1 even + UNI-2 + MKKA1 */ + D(MKK4_FCCA), /* Japan UNI-1 even + UNI-2 + FCCA */ + D(MKK9_MKKA), /* Japan UNI-1 even + 4.9GHz */ + D(MKK10_MKKA), /* Japan UNI-1 even + UNI-2 + 4.9GHz */ + + D(APL1), /* LAT & Asia */ + D(APL2), /* LAT & Asia */ + D(APL3), /* Taiwan */ + D(APL4), /* Jordan */ + D(APL5), /* Chile */ + D(APL6), /* Singapore */ + D(APL8), /* Malaysia */ + D(APL9), /* Korea (South) ROC 3 */ + + D(ETSI1), /* Europe & others */ + D(ETSI2), /* Europe & others */ + D(ETSI3), /* Europe & others */ + D(ETSI4), /* Europe & others */ + D(ETSI5), /* Europe & others */ + D(ETSI6), /* Europe & others */ + D(ETSIA), /* France */ + D(ETSIB), /* Israel */ + D(ETSIC), /* Latin America */ + + D(FCC1), /* US & others */ + D(FCC2), + D(FCC3), /* US w/new middle band & DFS */ + D(FCC4), /* US Public Safety */ + D(FCCA), + + D(APLD), /* South Korea */ + + D(MKK1), /* Japan (UNI-1 odd)*/ + D(MKK2), /* Japan (4.9 GHz + UNI-1 odd) */ + D(MKK3), /* Japan (UNI-1 even) */ + D(MKK4), /* Japan (UNI-1 even + UNI-2) */ + D(MKK5), /* Japan (UNI-1 even + UNI-2 + mid-band) */ + D(MKK6), /* Japan (UNI-1 odd + UNI-1 even) */ + D(MKK7), /* Japan (UNI-1 odd + UNI-1 even + UNI-2 */ + D(MKK8), /* Japan (UNI-1 odd + UNI-1 even + UNI-2 + mid-band) */ + D(MKK9), /* Japan (UNI-1 even + 4.9 GHZ) */ + D(MKK10), /* Japan (UNI-1 even + UNI-2 + 4.9 GHZ) */ + D(MKKA), /* Japan */ + D(MKKC), + + D(NULL1), + D(WORLD), + D(DEBUG_REG_DMN), +#undef D +}; + +static HAL_BOOL +rdlookup(const char *name, HAL_REG_DOMAIN *rd) +{ +#define N(a) (sizeof(a)/sizeof(a[0])) + int i; + + for (i = 0; i < N(domains); i++) + if (strcasecmp(domains[i].name, name) == 0) { + *rd = domains[i].rd; + return AH_TRUE; + } + return AH_FALSE; +#undef N +} + +static const char * +getrdname(HAL_REG_DOMAIN rd) +{ +#define N(a) (sizeof(a)/sizeof(a[0])) + int i; + + for (i = 0; i < N(domains); i++) + if (domains[i].rd == rd) + return domains[i].name; + return NULL; +#undef N +} + +static void +rdlist() +{ +#define N(a) (sizeof(a)/sizeof(a[0])) + int i; + + printf("\nRegulatory domains:\n\n"); + for (i = 0; i < N(domains); i++) + printf("%-15s%s", domains[i].name, + ((i+1)%5) == 0 ? "\n" : ""); + printf("\n"); +#undef N +} + +typedef struct { + HAL_CTRY_CODE countryCode; + HAL_REG_DOMAIN regDmnEnum; + const char* isoName; + const char* name; +} COUNTRY_CODE_TO_ENUM_RD; + +/* + * Country Code Table to Enumerated RD + */ +static COUNTRY_CODE_TO_ENUM_RD allCountries[] = { + {CTRY_DEBUG, NO_ENUMRD, "DB", "DEBUG" }, + {CTRY_DEFAULT, DEF_REGDMN, "NA", "NO_COUNTRY_SET" }, + {CTRY_ALBANIA, NULL1_WORLD, "AL", "ALBANIA" }, + {CTRY_ALGERIA, NULL1_WORLD, "DZ", "ALGERIA" }, + {CTRY_ARGENTINA, APL3_WORLD, "AR", "ARGENTINA" }, + {CTRY_ARMENIA, ETSI4_WORLD, "AM", "ARMENIA" }, + {CTRY_AUSTRALIA, FCC2_WORLD, "AU", "AUSTRALIA" }, + {CTRY_AUSTRIA, ETSI1_WORLD, "AT", "AUSTRIA" }, + {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ", "AZERBAIJAN" }, + {CTRY_BAHRAIN, APL6_WORLD, "BH", "BAHRAIN" }, + {CTRY_BELARUS, NULL1_WORLD, "BY", "BELARUS" }, + {CTRY_BELGIUM, ETSI1_WORLD, "BE", "BELGIUM" }, + {CTRY_BELIZE, APL1_ETSIC, "BZ", "BELIZE" }, + {CTRY_BOLIVIA, APL1_ETSIC, "BO", "BOLVIA" }, + {CTRY_BRAZIL, FCC3_WORLD, "BR", "BRAZIL" }, + {CTRY_BRUNEI_DARUSSALAM,APL1_WORLD,"BN", "BRUNEI DARUSSALAM" }, + {CTRY_BULGARIA, ETSI6_WORLD, "BG", "BULGARIA" }, + {CTRY_CANADA, FCC2_FCCA, "CA", "CANADA" }, + {CTRY_CHILE, APL6_WORLD, "CL", "CHILE" }, + {CTRY_CHINA, APL1_WORLD, "CN", "CHINA" }, + {CTRY_COLOMBIA, FCC1_FCCA, "CO", "COLOMBIA" }, + {CTRY_COSTA_RICA, NULL1_WORLD, "CR", "COSTA RICA" }, + {CTRY_CROATIA, ETSI3_WORLD, "HR", "CROATIA" }, + {CTRY_CYPRUS, ETSI1_WORLD, "CY", "CYPRUS" }, + {CTRY_CZECH, ETSI3_WORLD, "CZ", "CZECH REPUBLIC" }, + {CTRY_DENMARK, ETSI1_WORLD, "DK", "DENMARK" }, + {CTRY_DOMINICAN_REPUBLIC,FCC1_FCCA,"DO", "DOMINICAN REPUBLIC" }, + {CTRY_ECUADOR, NULL1_WORLD, "EC", "ECUADOR" }, + {CTRY_EGYPT, ETSI3_WORLD, "EG", "EGYPT" }, + {CTRY_EL_SALVADOR, NULL1_WORLD, "SV", "EL SALVADOR" }, + {CTRY_ESTONIA, ETSI1_WORLD, "EE", "ESTONIA" }, + {CTRY_FINLAND, ETSI1_WORLD, "FI", "FINLAND" }, + {CTRY_FRANCE, ETSI3_WORLD, "FR", "FRANCE" }, + {CTRY_FRANCE2, ETSI3_WORLD, "F2", "FRANCE_RES" }, + {CTRY_GEORGIA, ETSI4_WORLD, "GE", "GEORGIA" }, + {CTRY_GERMANY, ETSI1_WORLD, "DE", "GERMANY" }, + {CTRY_GREECE, ETSI1_WORLD, "GR", "GREECE" }, + {CTRY_GUATEMALA, FCC1_FCCA, "GT", "GUATEMALA" }, + {CTRY_HONDURAS, NULL1_WORLD, "HN", "HONDURAS" }, + {CTRY_HONG_KONG, FCC2_WORLD, "HK", "HONG KONG" }, + {CTRY_HUNGARY, ETSI1_WORLD, "HU", "HUNGARY" }, + {CTRY_ICELAND, ETSI1_WORLD, "IS", "ICELAND" }, + {CTRY_INDIA, APL6_WORLD, "IN", "INDIA" }, + {CTRY_INDONESIA, APL1_WORLD, "ID", "INDONESIA" }, + {CTRY_IRAN, APL1_WORLD, "IR", "IRAN" }, + {CTRY_IRELAND, ETSI1_WORLD, "IE", "IRELAND" }, + {CTRY_ISRAEL, NULL1_WORLD, "IL", "ISRAEL" }, + {CTRY_ITALY, ETSI1_WORLD, "IT", "ITALY" }, + {CTRY_JAPAN, MKK1_MKKA, "JP", "JAPAN" }, + {CTRY_JAPAN1, MKK1_MKKB, "JP", "JAPAN1" }, + {CTRY_JAPAN2, MKK1_FCCA, "JP", "JAPAN2" }, + {CTRY_JAPAN3, MKK2_MKKA, "JP", "JAPAN3" }, + {CTRY_JAPAN4, MKK1_MKKA1, "JP", "JAPAN4" }, + {CTRY_JAPAN5, MKK1_MKKA2, "JP", "JAPAN5" }, + {CTRY_JAPAN6, MKK1_MKKC, "JP", "JAPAN6" }, + + {CTRY_JAPAN7, MKK3_MKKB, "JP", "JAPAN7" }, + {CTRY_JAPAN8, MKK3_MKKA2, "JP", "JAPAN8" }, + {CTRY_JAPAN9, MKK3_MKKC, "JP", "JAPAN9" }, + + {CTRY_JAPAN10, MKK4_MKKB, "JP", "JAPAN10" }, + {CTRY_JAPAN11, MKK4_MKKA2, "JP", "JAPAN11" }, + {CTRY_JAPAN12, MKK4_MKKC, "JP", "JAPAN12" }, + + {CTRY_JAPAN13, MKK5_MKKB, "JP", "JAPAN13" }, + {CTRY_JAPAN14, MKK5_MKKA2, "JP", "JAPAN14" }, + {CTRY_JAPAN15, MKK5_MKKC, "JP", "JAPAN15" }, + + {CTRY_JAPAN16, MKK6_MKKB, "JP", "JAPAN16" }, + {CTRY_JAPAN17, MKK6_MKKA2, "JP", "JAPAN17" }, + {CTRY_JAPAN18, MKK6_MKKC, "JP", "JAPAN18" }, + + {CTRY_JAPAN19, MKK7_MKKB, "JP", "JAPAN19" }, + {CTRY_JAPAN20, MKK7_MKKA2, "JP", "JAPAN20" }, + {CTRY_JAPAN21, MKK7_MKKC, "JP", "JAPAN21" }, + + {CTRY_JAPAN22, MKK8_MKKB, "JP", "JAPAN22" }, + {CTRY_JAPAN23, MKK8_MKKA2, "JP", "JAPAN23" }, + {CTRY_JAPAN24, MKK8_MKKC, "JP", "JAPAN24" }, + + {CTRY_JORDAN, APL4_WORLD, "JO", "JORDAN" }, + {CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ", "KAZAKHSTAN" }, + {CTRY_KOREA_NORTH, APL2_WORLD, "KP", "NORTH KOREA" }, + {CTRY_KOREA_ROC, APL2_WORLD, "KR", "KOREA REPUBLIC" }, + {CTRY_KOREA_ROC2, APL2_WORLD, "K2", "KOREA REPUBLIC2" }, + {CTRY_KOREA_ROC3, APL9_WORLD, "K3", "KOREA REPUBLIC3" }, + {CTRY_KUWAIT, NULL1_WORLD, "KW", "KUWAIT" }, + {CTRY_LATVIA, ETSI1_WORLD, "LV", "LATVIA" }, + {CTRY_LEBANON, NULL1_WORLD, "LB", "LEBANON" }, + {CTRY_LIECHTENSTEIN,ETSI1_WORLD, "LI", "LIECHTENSTEIN" }, + {CTRY_LITHUANIA, ETSI1_WORLD, "LT", "LITHUANIA" }, + {CTRY_LUXEMBOURG, ETSI1_WORLD, "LU", "LUXEMBOURG" }, + {CTRY_MACAU, FCC2_WORLD, "MO", "MACAU" }, + {CTRY_MACEDONIA, NULL1_WORLD, "MK", "MACEDONIA" }, + {CTRY_MALAYSIA, APL8_WORLD, "MY", "MALAYSIA" }, + {CTRY_MALTA, ETSI1_WORLD, "MT", "MALTA" }, + {CTRY_MEXICO, FCC1_FCCA, "MX", "MEXICO" }, + {CTRY_MONACO, ETSI4_WORLD, "MC", "MONACO" }, + {CTRY_MOROCCO, NULL1_WORLD, "MA", "MOROCCO" }, + {CTRY_NETHERLANDS, ETSI1_WORLD, "NL", "NETHERLANDS" }, + {CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ", "NEW ZEALAND" }, + {CTRY_NORWAY, ETSI1_WORLD, "NO", "NORWAY" }, + {CTRY_OMAN, APL6_WORLD, "OM", "OMAN" }, + {CTRY_PAKISTAN, NULL1_WORLD, "PK", "PAKISTAN" }, + {CTRY_PANAMA, FCC1_FCCA, "PA", "PANAMA" }, + {CTRY_PERU, APL1_WORLD, "PE", "PERU" }, + {CTRY_PHILIPPINES, APL1_WORLD, "PH", "PHILIPPINES" }, + {CTRY_POLAND, ETSI1_WORLD, "PL", "POLAND" }, + {CTRY_PORTUGAL, ETSI1_WORLD, "PT", "PORTUGAL" }, + {CTRY_PUERTO_RICO, FCC1_FCCA, "PR", "PUERTO RICO" }, + {CTRY_QATAR, NULL1_WORLD, "QA", "QATAR" }, + {CTRY_ROMANIA, NULL1_WORLD, "RO", "ROMANIA" }, + {CTRY_RUSSIA, NULL1_WORLD, "RU", "RUSSIA" }, + {CTRY_SAUDI_ARABIA,NULL1_WORLD, "SA", "SAUDI ARABIA" }, + {CTRY_SINGAPORE, APL6_WORLD, "SG", "SINGAPORE" }, + {CTRY_SLOVAKIA, ETSI1_WORLD, "SK", "SLOVAK REPUBLIC" }, + {CTRY_SLOVENIA, ETSI1_WORLD, "SI", "SLOVENIA" }, + {CTRY_SOUTH_AFRICA,FCC3_WORLD, "ZA", "SOUTH AFRICA" }, + {CTRY_SPAIN, ETSI1_WORLD, "ES", "SPAIN" }, + {CTRY_SWEDEN, ETSI1_WORLD, "SE", "SWEDEN" }, + {CTRY_SWITZERLAND, ETSI1_WORLD, "CH", "SWITZERLAND" }, + {CTRY_SYRIA, NULL1_WORLD, "SY", "SYRIA" }, + {CTRY_TAIWAN, APL3_FCCA, "TW", "TAIWAN" }, + {CTRY_THAILAND, NULL1_WORLD, "TH", "THAILAND" }, + {CTRY_TRINIDAD_Y_TOBAGO,ETSI4_WORLD,"TT", "TRINIDAD & TOBAGO" }, + {CTRY_TUNISIA, ETSI3_WORLD, "TN", "TUNISIA" }, + {CTRY_TURKEY, ETSI3_WORLD, "TR", "TURKEY" }, + {CTRY_UKRAINE, NULL1_WORLD, "UA", "UKRAINE" }, + {CTRY_UAE, NULL1_WORLD, "AE", "UNITED ARAB EMIRATES" }, + {CTRY_UNITED_KINGDOM, ETSI1_WORLD,"GB", "UNITED KINGDOM" }, + {CTRY_UNITED_STATES, FCC1_FCCA, "US", "UNITED STATES" }, + {CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS", "UNITED STATES (PUBLIC SAFETY)" }, + {CTRY_URUGUAY, APL2_WORLD, "UY", "URUGUAY" }, + {CTRY_UZBEKISTAN, FCC3_FCCA, "UZ", "UZBEKISTAN" }, + {CTRY_VENEZUELA, APL2_ETSIC, "VE", "VENEZUELA" }, + {CTRY_VIET_NAM, NULL1_WORLD, "VN", "VIET NAM" }, + {CTRY_YEMEN, NULL1_WORLD, "YE", "YEMEN" }, + {CTRY_ZIMBABWE, NULL1_WORLD, "ZW", "ZIMBABWE" } +}; + +static HAL_BOOL +cclookup(const char *name, HAL_REG_DOMAIN *rd, HAL_CTRY_CODE *cc) +{ +#define N(a) (sizeof(a)/sizeof(a[0])) + int i; + + for (i = 0; i < N(allCountries); i++) + if (strcasecmp(allCountries[i].isoName, name) == 0 || + strcasecmp(allCountries[i].name, name) == 0) { + *rd = allCountries[i].regDmnEnum; + *cc = allCountries[i].countryCode; + return AH_TRUE; + } + return AH_FALSE; +#undef N +} + +static const char * +getccname(HAL_CTRY_CODE cc) +{ +#define N(a) (sizeof(a)/sizeof(a[0])) + int i; + + for (i = 0; i < N(allCountries); i++) + if (allCountries[i].countryCode == cc) + return allCountries[i].name; + return NULL; +#undef N +} + +static const char * +getccisoname(HAL_CTRY_CODE cc) +{ +#define N(a) (sizeof(a)/sizeof(a[0])) + int i; + + for (i = 0; i < N(allCountries); i++) + if (allCountries[i].countryCode == cc) + return allCountries[i].isoName; + return NULL; +#undef N +} + +static void +cclist() +{ +#define N(a) (sizeof(a)/sizeof(a[0])) + int i; + + printf("\nCountry codes:\n"); + for (i = 0; i < N(allCountries); i++) + printf("%2s %-15.15s%s", + allCountries[i].isoName, + allCountries[i].name, + ((i+1)%4) == 0 ? "\n" : " "); + printf("\n"); +#undef N +} + +static HAL_BOOL +setRateTable(struct ath_hal *ah, const struct ieee80211_channel *chan, + int16_t tpcScaleReduction, int16_t powerLimit, + int16_t *pMinPower, int16_t *pMaxPower); + +static void +calctxpower(struct ath_hal *ah, + int nchan, const struct ieee80211_channel *chans, + int16_t tpcScaleReduction, int16_t powerLimit, int16_t *txpow) +{ + int16_t minpow; + int i; + + for (i = 0; i < nchan; i++) + if (!setRateTable(ah, &chans[i], + tpcScaleReduction, powerLimit, &minpow, &txpow[i])) { + printf("unable to set rate table\n"); + exit(-1); + } +} + +int n = 1; +const char *sep = ""; +int dopassive = 0; +int showchannels = 0; +int isdfs = 0; +int is4ms = 0; + +static int +anychan(const struct ieee80211_channel *chans, int nc, int flag) +{ + int i; + + for (i = 0; i < nc; i++) + if ((chans[i].ic_flags & flag) != 0) + return 1; + return 0; +} + +static __inline int +mapgsm(u_int freq, u_int flags) +{ + freq *= 10; + if (flags & IEEE80211_CHAN_QUARTER) + freq += 5; + else if (flags & IEEE80211_CHAN_HALF) + freq += 10; + else + freq += 20; + return (freq - 24220) / 5; +} + +static __inline int +mappsb(u_int freq, u_int flags) +{ + return ((freq * 10) + (((freq % 5) == 2) ? 5 : 0) - 49400) / 5; +} + +/* + * Convert GHz frequency to IEEE channel number. + */ +int +ath_hal_mhz2ieee(struct ath_hal *ah, u_int freq, u_int flags) +{ + if (flags & IEEE80211_CHAN_2GHZ) { /* 2GHz band */ + if (freq == 2484) + return 14; + if (freq < 2484) + return ((int)freq - 2407) / 5; + else + return 15 + ((freq - 2512) / 20); + } else if (flags & IEEE80211_CHAN_5GHZ) {/* 5Ghz band */ + if (IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) + return mappsb(freq, flags); + else if ((flags & IEEE80211_CHAN_A) && (freq <= 5000)) + return (freq - 4000) / 5; + else + return (freq - 5000) / 5; + } else { /* either, guess */ + if (freq == 2484) + return 14; + if (freq < 2484) + return ((int)freq - 2407) / 5; + if (freq < 5000) { + if (IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) + return mappsb(freq, flags); + else if (freq > 4900) + return (freq - 4000) / 5; + else + return 15 + ((freq - 2512) / 20); + } + return (freq - 5000) / 5; + } +} + +#define IEEE80211_IS_CHAN_4MS(_c) \ + (((_c)->ic_flags & IEEE80211_CHAN_4MSXMIT) != 0) + +static void +dumpchannels(struct ath_hal *ah, int nc, + const struct ieee80211_channel *chans, int16_t *txpow) +{ + int i; + + for (i = 0; i < nc; i++) { + const struct ieee80211_channel *c = &chans[i]; + int type; + + if (showchannels) + printf("%s%3d", sep, + ath_hal_mhz2ieee(ah, c->ic_freq, c->ic_flags)); + else + printf("%s%u", sep, c->ic_freq); + if (IEEE80211_IS_CHAN_HALF(c)) + type = 'H'; + else if (IEEE80211_IS_CHAN_QUARTER(c)) + type = 'Q'; + else if (IEEE80211_IS_CHAN_TURBO(c)) + type = 'T'; + else if (IEEE80211_IS_CHAN_HT(c)) + type = 'N'; + else if (IEEE80211_IS_CHAN_A(c)) + type = 'A'; + else if (IEEE80211_IS_CHAN_108G(c)) + type = 'T'; + else if (IEEE80211_IS_CHAN_G(c)) + type = 'G'; + else + type = 'B'; + if (dopassive && IEEE80211_IS_CHAN_PASSIVE(c)) + type = tolower(type); + if (isdfs && is4ms) + printf("%c%c%c %d.%d", type, + IEEE80211_IS_CHAN_DFS(c) ? '*' : ' ', + IEEE80211_IS_CHAN_4MS(c) ? '4' : ' ', + txpow[i]/2, (txpow[i]%2)*5); + else if (isdfs) + printf("%c%c %d.%d", type, + IEEE80211_IS_CHAN_DFS(c) ? '*' : ' ', + txpow[i]/2, (txpow[i]%2)*5); + else if (is4ms) + printf("%c%c %d.%d", type, + IEEE80211_IS_CHAN_4MS(c) ? '4' : ' ', + txpow[i]/2, (txpow[i]%2)*5); + else + printf("%c %d.%d", type, txpow[i]/2, (txpow[i]%2)*5); + if ((n++ % (showchannels ? 7 : 6)) == 0) + sep = "\n"; + else + sep = " "; + } +} + +static void +intersect(struct ieee80211_channel *dst, int16_t *dtxpow, int *nd, + const struct ieee80211_channel *src, int16_t *stxpow, int ns) +{ + int i = 0, j, k, l; + while (i < *nd) { + for (j = 0; j < ns && dst[i].ic_freq != src[j].ic_freq; j++) + ; + if (j < ns && dtxpow[i] == stxpow[j]) { + for (k = i+1, l = i; k < *nd; k++, l++) + dst[l] = dst[k]; + (*nd)--; + } else + i++; + } +} + +static void +usage(const char *progname) +{ + printf("usage: %s [-acdefoilpr4ABGT] [-m opmode] [cc | rd]\n", progname); + exit(-1); +} + +static HAL_BOOL +getChipPowerLimits(struct ath_hal *ah, struct ieee80211_channel *chan) +{ +} + +static HAL_BOOL +eepromRead(struct ath_hal *ah, u_int off, u_int16_t *data) +{ + /* emulate enough stuff to handle japan channel shift */ + switch (off) { + case AR_EEPROM_VERSION: + *data = eeversion; + return AH_TRUE; + case AR_EEPROM_REG_CAPABILITIES_OFFSET: + *data = AR_EEPROM_EEREGCAP_EN_KK_NEW_11A; + return AH_TRUE; + case AR_EEPROM_REG_CAPABILITIES_OFFSET_PRE4_0: + *data = AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0; + return AH_TRUE; + } + return AH_FALSE; +} + +HAL_STATUS +getCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, + uint32_t capability, uint32_t *result) +{ + const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps; + + switch (type) { + case HAL_CAP_REG_DMN: /* regulatory domain */ + *result = AH_PRIVATE(ah)->ah_currentRD; + return HAL_OK; + default: + return HAL_EINVAL; + } +} + +#define HAL_MODE_HT20 \ + (HAL_MODE_11NG_HT20 | HAL_MODE_11NA_HT20) +#define HAL_MODE_HT40 \ + (HAL_MODE_11NG_HT40PLUS | HAL_MODE_11NG_HT40MINUS | \ + HAL_MODE_11NA_HT40PLUS | HAL_MODE_11NA_HT40MINUS) +#define HAL_MODE_HT (HAL_MODE_HT20 | HAL_MODE_HT40) + +int +main(int argc, char *argv[]) +{ + static const u_int16_t tpcScaleReductionTable[5] = + { 0, 3, 6, 9, MAX_RATE_POWER }; + struct ath_hal_private ahp; + struct ieee80211_channel achans[IEEE80211_CHAN_MAX]; + int16_t atxpow[IEEE80211_CHAN_MAX]; + struct ieee80211_channel bchans[IEEE80211_CHAN_MAX]; + int16_t btxpow[IEEE80211_CHAN_MAX]; + struct ieee80211_channel gchans[IEEE80211_CHAN_MAX]; + int16_t gtxpow[IEEE80211_CHAN_MAX]; + struct ieee80211_channel tchans[IEEE80211_CHAN_MAX]; + int16_t ttxpow[IEEE80211_CHAN_MAX]; + struct ieee80211_channel tgchans[IEEE80211_CHAN_MAX]; + int16_t tgtxpow[IEEE80211_CHAN_MAX]; + struct ieee80211_channel nchans[IEEE80211_CHAN_MAX]; + int16_t ntxpow[IEEE80211_CHAN_MAX]; + int i, na, nb, ng, nt, ntg, nn; + HAL_BOOL showall = AH_FALSE; + HAL_BOOL extendedChanMode = AH_TRUE; + int modes = 0; + int16_t tpcReduction, powerLimit; + int showdfs = 0; + int show4ms = 0; + + memset(&ahp, 0, sizeof(ahp)); + ahp.ah_getChannelEdges = getChannelEdges; + ahp.ah_getWirelessModes = getWirelessModes; + ahp.ah_eepromRead = eepromRead; + ahp.ah_getChipPowerLimits = getChipPowerLimits; + ahp.ah_caps.halWirelessModes = HAL_MODE_ALL; + ahp.ah_caps.halLow5GhzChan = 4920; + ahp.ah_caps.halHigh5GhzChan = 6100; + ahp.ah_caps.halLow2GhzChan = 2312; + ahp.ah_caps.halHigh2GhzChan = 2732; + ahp.ah_caps.halChanHalfRate = AH_TRUE; + ahp.ah_caps.halChanQuarterRate = AH_TRUE; + ahp.h.ah_getCapability = getCapability; + ahp.ah_opmode = HAL_M_STA; + + tpcReduction = tpcScaleReductionTable[0]; + powerLimit = MAX_RATE_POWER; + + while ((i = getopt(argc, argv, "acdeflm:pr4ABGhHNT")) != -1) + switch (i) { + case 'a': + showall = AH_TRUE; + break; + case 'c': + showchannels = AH_TRUE; + break; + case 'd': + ath_hal_debug = HAL_DEBUG_ANY; + break; + case 'e': + extendedChanMode = AH_FALSE; + break; + case 'f': + showchannels = AH_FALSE; + break; + case 'l': + cclist(); + rdlist(); + exit(0); + case 'm': + if (strncasecmp(optarg, "sta", 2) == 0) + ahp.ah_opmode = HAL_M_STA; + else if (strncasecmp(optarg, "ibss", 2) == 0) + ahp.ah_opmode = HAL_M_IBSS; + else if (strncasecmp(optarg, "adhoc", 2) == 0) + ahp.ah_opmode = HAL_M_IBSS; + else if (strncasecmp(optarg, "ap", 2) == 0) + ahp.ah_opmode = HAL_M_HOSTAP; + else if (strncasecmp(optarg, "hostap", 2) == 0) + ahp.ah_opmode = HAL_M_HOSTAP; + else if (strncasecmp(optarg, "monitor", 2) == 0) + ahp.ah_opmode = HAL_M_MONITOR; + else + usage(argv[0]); + break; + case 'p': + dopassive = 1; + break; + case 'A': + modes |= HAL_MODE_11A; + break; + case 'B': + modes |= HAL_MODE_11B; + break; + case 'G': + modes |= HAL_MODE_11G; + break; + case 'h': + modes |= HAL_MODE_HT20; + break; + case 'H': + modes |= HAL_MODE_HT40; + break; + case 'N': + modes |= HAL_MODE_HT; + break; + case 'T': + modes |= HAL_MODE_TURBO | HAL_MODE_108G; + break; + case 'r': + showdfs = 1; + break; + case '4': + show4ms = 1; + break; + default: + usage(argv[0]); + } + switch (argc - optind) { + case 0: + if (!cclookup("US", &rd, &cc)) { + printf("%s: unknown country code\n", "US"); + exit(-1); + } + break; + case 1: /* cc/regdomain */ + if (!cclookup(argv[optind], &rd, &cc)) { + if (!rdlookup(argv[optind], &rd)) { + const char* rdname; + + rd = strtoul(argv[optind], NULL, 0); + rdname = getrdname(rd); + if (rdname == NULL) { + printf("%s: unknown country/regulatory " + "domain code\n", argv[optind]); + exit(-1); + } + } + cc = CTRY_DEFAULT; + } + break; + default: /* regdomain cc */ + if (!rdlookup(argv[optind], &rd)) { + const char* rdname; + + rd = strtoul(argv[optind], NULL, 0); + rdname = getrdname(rd); + if (rdname == NULL) { + printf("%s: unknown country/regulatory " + "domain code\n", argv[optind]); + exit(-1); + } + } + if (!cclookup(argv[optind+1], &rd, &cc)) + cc = strtoul(argv[optind+1], NULL, 0); + break; + } + if (cc != CTRY_DEFAULT) + printf("\n%s (%s, 0x%x, %u) %s (0x%x, %u)\n", + getccname(cc), getccisoname(cc), cc, cc, + getrdname(rd), rd, rd); + else + printf("\n%s (0x%x, %u)\n", + getrdname(rd), rd, rd); + + if (modes == 0) { + /* NB: no HAL_MODE_HT */ + modes = HAL_MODE_11A | HAL_MODE_11B | + HAL_MODE_11G | HAL_MODE_TURBO | HAL_MODE_108G; + } + na = nb = ng = nt = ntg = nn = 0; + if (modes & HAL_MODE_11G) { + ahp.ah_currentRD = rd; + if (ath_hal_getchannels(&ahp.h, gchans, IEEE80211_CHAN_MAX, &ng, + HAL_MODE_11G, cc, rd, extendedChanMode) == HAL_OK) { + calctxpower(&ahp.h, ng, gchans, tpcReduction, powerLimit, gtxpow); + if (showdfs) + isdfs |= anychan(gchans, ng, IEEE80211_CHAN_DFS); + if (show4ms) + is4ms |= anychan(gchans, ng, IEEE80211_CHAN_4MSXMIT); + } + } + if (modes & HAL_MODE_11B) { + ahp.ah_currentRD = rd; + if (ath_hal_getchannels(&ahp.h, bchans, IEEE80211_CHAN_MAX, &nb, + HAL_MODE_11B, cc, rd, extendedChanMode) == HAL_OK) { + calctxpower(&ahp.h, nb, bchans, tpcReduction, powerLimit, btxpow); + if (showdfs) + isdfs |= anychan(bchans, nb, IEEE80211_CHAN_DFS); + if (show4ms) + is4ms |= anychan(bchans, nb, IEEE80211_CHAN_4MSXMIT); + } + } + if (modes & HAL_MODE_11A) { + ahp.ah_currentRD = rd; + if (ath_hal_getchannels(&ahp.h, achans, IEEE80211_CHAN_MAX, &na, + HAL_MODE_11A, cc, rd, extendedChanMode) == HAL_OK) { + calctxpower(&ahp.h, na, achans, tpcReduction, powerLimit, atxpow); + if (showdfs) + isdfs |= anychan(achans, na, IEEE80211_CHAN_DFS); + if (show4ms) + is4ms |= anychan(achans, na, IEEE80211_CHAN_4MSXMIT); + } + } + if (modes & HAL_MODE_TURBO) { + ahp.ah_currentRD = rd; + if (ath_hal_getchannels(&ahp.h, tchans, IEEE80211_CHAN_MAX, &nt, + HAL_MODE_TURBO, cc, rd, extendedChanMode) == HAL_OK) { + calctxpower(&ahp.h, nt, tchans, tpcReduction, powerLimit, ttxpow); + if (showdfs) + isdfs |= anychan(tchans, nt, IEEE80211_CHAN_DFS); + if (show4ms) + is4ms |= anychan(tchans, nt, IEEE80211_CHAN_4MSXMIT); + } + } + if (modes & HAL_MODE_108G) { + ahp.ah_currentRD = rd; + if (ath_hal_getchannels(&ahp.h, tgchans, IEEE80211_CHAN_MAX, &ntg, + HAL_MODE_108G, cc, rd, extendedChanMode) == HAL_OK) { + calctxpower(&ahp.h, ntg, tgchans, tpcReduction, powerLimit, tgtxpow); + if (showdfs) + isdfs |= anychan(tgchans, ntg, IEEE80211_CHAN_DFS); + if (show4ms) + is4ms |= anychan(tgchans, ntg, IEEE80211_CHAN_4MSXMIT); + } + } + if (modes & HAL_MODE_HT) { + ahp.ah_currentRD = rd; + if (ath_hal_getchannels(&ahp.h, nchans, IEEE80211_CHAN_MAX, &nn, + modes & HAL_MODE_HT, cc, rd, extendedChanMode) == HAL_OK) { + calctxpower(&ahp.h, nn, nchans, tpcReduction, powerLimit, ntxpow); + if (showdfs) + isdfs |= anychan(nchans, nn, IEEE80211_CHAN_DFS); + if (show4ms) + is4ms |= anychan(nchans, nn, IEEE80211_CHAN_4MSXMIT); + } + } + + if (!showall) { +#define CHECKMODES(_modes, _m) ((_modes & (_m)) == (_m)) + if (CHECKMODES(modes, HAL_MODE_11B|HAL_MODE_11G)) { + /* b ^= g */ + intersect(bchans, btxpow, &nb, gchans, gtxpow, ng); + } + if (CHECKMODES(modes, HAL_MODE_11A|HAL_MODE_TURBO)) { + /* t ^= a */ + intersect(tchans, ttxpow, &nt, achans, atxpow, na); + } + if (CHECKMODES(modes, HAL_MODE_11G|HAL_MODE_108G)) { + /* tg ^= g */ + intersect(tgchans, tgtxpow, &ntg, gchans, gtxpow, ng); + } + if (CHECKMODES(modes, HAL_MODE_11G|HAL_MODE_HT)) { + /* g ^= n */ + intersect(gchans, gtxpow, &ng, nchans, ntxpow, nn); + } + if (CHECKMODES(modes, HAL_MODE_11A|HAL_MODE_HT)) { + /* a ^= n */ + intersect(achans, atxpow, &na, nchans, ntxpow, nn); + } +#undef CHECKMODES + } + + if (modes & HAL_MODE_11G) + dumpchannels(&ahp.h, ng, gchans, gtxpow); + if (modes & HAL_MODE_11B) + dumpchannels(&ahp.h, nb, bchans, btxpow); + if (modes & HAL_MODE_11A) + dumpchannels(&ahp.h, na, achans, atxpow); + if (modes & HAL_MODE_108G) + dumpchannels(&ahp.h, ntg, tgchans, tgtxpow); + if (modes & HAL_MODE_TURBO) + dumpchannels(&ahp.h, nt, tchans, ttxpow); + if (modes & HAL_MODE_HT) + dumpchannels(&ahp.h, nn, nchans, ntxpow); + printf("\n"); + return (0); +} + +/* + * Search a list for a specified value v that is within + * EEP_DELTA of the search values. Return the closest + * values in the list above and below the desired value. + * EEP_DELTA is a factional value; everything is scaled + * so only integer arithmetic is used. + * + * NB: the input list is assumed to be sorted in ascending order + */ +static void +ar5212GetLowerUpperValues(u_int16_t v, u_int16_t *lp, u_int16_t listSize, + u_int16_t *vlo, u_int16_t *vhi) +{ + u_int32_t target = v * EEP_SCALE; + u_int16_t *ep = lp+listSize; + + /* + * Check first and last elements for out-of-bounds conditions. + */ + if (target < (u_int32_t)(lp[0] * EEP_SCALE - EEP_DELTA)) { + *vlo = *vhi = lp[0]; + return; + } + if (target > (u_int32_t)(ep[-1] * EEP_SCALE + EEP_DELTA)) { + *vlo = *vhi = ep[-1]; + return; + } + + /* look for value being near or between 2 values in list */ + for (; lp < ep; lp++) { + /* + * If value is close to the current value of the list + * then target is not between values, it is one of the values + */ + if (abs(lp[0] * EEP_SCALE - target) < EEP_DELTA) { + *vlo = *vhi = lp[0]; + return; + } + /* + * Look for value being between current value and next value + * if so return these 2 values + */ + if (target < (u_int32_t)(lp[1] * EEP_SCALE - EEP_DELTA)) { + *vlo = lp[0]; + *vhi = lp[1]; + return; + } + } +} + +/* + * Find the maximum conformance test limit for the given channel and CTL info + */ +static u_int16_t +ar5212GetMaxEdgePower(u_int16_t channel, RD_EDGES_POWER *pRdEdgesPower) +{ + /* temp array for holding edge channels */ + u_int16_t tempChannelList[NUM_EDGES]; + u_int16_t clo, chi, twiceMaxEdgePower; + int i, numEdges; + + /* Get the edge power */ + for (i = 0; i < NUM_EDGES; i++) { + if (pRdEdgesPower[i].rdEdge == 0) + break; + tempChannelList[i] = pRdEdgesPower[i].rdEdge; + } + numEdges = i; + + ar5212GetLowerUpperValues(channel, tempChannelList, + numEdges, &clo, &chi); + /* Get the index for the lower channel */ + for (i = 0; i < numEdges && clo != tempChannelList[i]; i++) + ; + /* Is lower channel ever outside the rdEdge? */ + HALASSERT(i != numEdges); + + if ((clo == chi && clo == channel) || (pRdEdgesPower[i].flag)) { + /* + * If there's an exact channel match or an inband flag set + * on the lower channel use the given rdEdgePower + */ + twiceMaxEdgePower = pRdEdgesPower[i].twice_rdEdgePower; + HALASSERT(twiceMaxEdgePower > 0); + } else + twiceMaxEdgePower = MAX_RATE_POWER; + return twiceMaxEdgePower; +} + +/* + * Returns interpolated or the scaled up interpolated value + */ +static u_int16_t +interpolate(u_int16_t target, u_int16_t srcLeft, u_int16_t srcRight, + u_int16_t targetLeft, u_int16_t targetRight) +{ + u_int16_t rv; + int16_t lRatio; + + /* to get an accurate ratio, always scale, if want to scale, then don't scale back down */ + if ((targetLeft * targetRight) == 0) + return 0; + + if (srcRight != srcLeft) { + /* + * Note the ratio always need to be scaled, + * since it will be a fraction. + */ + lRatio = (target - srcLeft) * EEP_SCALE / (srcRight - srcLeft); + if (lRatio < 0) { + /* Return as Left target if value would be negative */ + rv = targetLeft; + } else if (lRatio > EEP_SCALE) { + /* Return as Right target if Ratio is greater than 100% (SCALE) */ + rv = targetRight; + } else { + rv = (lRatio * targetRight + (EEP_SCALE - lRatio) * + targetLeft) / EEP_SCALE; + } + } else { + rv = targetLeft; + } + return rv; +} + +/* + * Return the four rates of target power for the given target power table + * channel, and number of channels + */ +static void +ar5212GetTargetPowers(struct ath_hal *ah, const struct ieee80211_channel *chan, + TRGT_POWER_INFO *powInfo, + u_int16_t numChannels, TRGT_POWER_INFO *pNewPower) +{ + /* temp array for holding target power channels */ + u_int16_t tempChannelList[NUM_TEST_FREQUENCIES]; + u_int16_t clo, chi, ixlo, ixhi; + int i; + + /* Copy the target powers into the temp channel list */ + for (i = 0; i < numChannels; i++) + tempChannelList[i] = powInfo[i].testChannel; + + ar5212GetLowerUpperValues(chan->ic_freq, tempChannelList, + numChannels, &clo, &chi); + + /* Get the indices for the channel */ + ixlo = ixhi = 0; + for (i = 0; i < numChannels; i++) { + if (clo == tempChannelList[i]) { + ixlo = i; + } + if (chi == tempChannelList[i]) { + ixhi = i; + break; + } + } + + /* + * Get the lower and upper channels, target powers, + * and interpolate between them. + */ + pNewPower->twicePwr6_24 = interpolate(chan->ic_freq, clo, chi, + powInfo[ixlo].twicePwr6_24, powInfo[ixhi].twicePwr6_24); + pNewPower->twicePwr36 = interpolate(chan->ic_freq, clo, chi, + powInfo[ixlo].twicePwr36, powInfo[ixhi].twicePwr36); + pNewPower->twicePwr48 = interpolate(chan->ic_freq, clo, chi, + powInfo[ixlo].twicePwr48, powInfo[ixhi].twicePwr48); + pNewPower->twicePwr54 = interpolate(chan->ic_freq, clo, chi, + powInfo[ixlo].twicePwr54, powInfo[ixhi].twicePwr54); +} + +static RD_EDGES_POWER* +findEdgePower(struct ath_hal *ah, u_int ctl) +{ + int i; + + for (i = 0; i < _numCtls; i++) + if (_ctl[i] == ctl) + return &_rdEdgesPower[i * NUM_EDGES]; + return AH_NULL; +} + +/* + * Sets the transmit power in the baseband for the given + * operating channel and mode. + */ +static HAL_BOOL +setRateTable(struct ath_hal *ah, const struct ieee80211_channel *chan, + int16_t tpcScaleReduction, int16_t powerLimit, + int16_t *pMinPower, int16_t *pMaxPower) +{ + u_int16_t ratesArray[16]; + u_int16_t *rpow = ratesArray; + u_int16_t twiceMaxRDPower, twiceMaxEdgePower, twiceMaxEdgePowerCck; + int8_t twiceAntennaGain, twiceAntennaReduction; + TRGT_POWER_INFO targetPowerOfdm, targetPowerCck; + RD_EDGES_POWER *rep; + int16_t scaledPower; + u_int8_t cfgCtl; + + twiceMaxRDPower = chan->ic_maxregpower * 2; + *pMaxPower = -MAX_RATE_POWER; + *pMinPower = MAX_RATE_POWER; + + /* Get conformance test limit maximum for this channel */ + cfgCtl = ath_hal_getctl(ah, chan); + rep = findEdgePower(ah, cfgCtl); + if (rep != AH_NULL) + twiceMaxEdgePower = ar5212GetMaxEdgePower(chan->ic_freq, rep); + else + twiceMaxEdgePower = MAX_RATE_POWER; + + if (IEEE80211_IS_CHAN_G(chan)) { + /* Check for a CCK CTL for 11G CCK powers */ + cfgCtl = (cfgCtl & 0xFC) | 0x01; + rep = findEdgePower(ah, cfgCtl); + if (rep != AH_NULL) + twiceMaxEdgePowerCck = ar5212GetMaxEdgePower(chan->ic_freq, rep); + else + twiceMaxEdgePowerCck = MAX_RATE_POWER; + } else { + /* Set the 11B cck edge power to the one found before */ + twiceMaxEdgePowerCck = twiceMaxEdgePower; + } + + /* Get Antenna Gain reduction */ + if (IEEE80211_IS_CHAN_5GHZ(chan)) { + twiceAntennaGain = antennaGainMax[0]; + } else { + twiceAntennaGain = antennaGainMax[1]; + } + twiceAntennaReduction = + ath_hal_getantennareduction(ah, chan, twiceAntennaGain); + + if (IEEE80211_IS_CHAN_OFDM(chan)) { + /* Get final OFDM target powers */ + if (IEEE80211_IS_CHAN_G(chan)) { + /* TODO - add Turbo 2.4 to this mode check */ + ar5212GetTargetPowers(ah, chan, trgtPwr_11g, + numTargetPwr_11g, &targetPowerOfdm); + } else { + ar5212GetTargetPowers(ah, chan, trgtPwr_11a, + numTargetPwr_11a, &targetPowerOfdm); + } + + /* Get Maximum OFDM power */ + /* Minimum of target and edge powers */ + scaledPower = AH_MIN(twiceMaxEdgePower, + twiceMaxRDPower - twiceAntennaReduction); + + /* + * If turbo is set, reduce power to keep power + * consumption under 2 Watts. Note that we always do + * this unless specially configured. Then we limit + * power only for non-AP operation. + */ + if (IEEE80211_IS_CHAN_TURBO(chan) +#ifdef AH_ENABLE_AP_SUPPORT + && AH_PRIVATE(ah)->ah_opmode != HAL_M_HOSTAP +#endif + ) { + /* + * If turbo is set, reduce power to keep power + * consumption under 2 Watts + */ + if (eeversion >= AR_EEPROM_VER3_1) + scaledPower = AH_MIN(scaledPower, + turbo2WMaxPower5); + /* + * EEPROM version 4.0 added an additional + * constraint on 2.4GHz channels. + */ + if (eeversion >= AR_EEPROM_VER4_0 && + IEEE80211_IS_CHAN_2GHZ(chan)) + scaledPower = AH_MIN(scaledPower, + turbo2WMaxPower2); + } + /* Reduce power by max regulatory domain allowed restrictions */ + scaledPower -= (tpcScaleReduction * 2); + scaledPower = (scaledPower < 0) ? 0 : scaledPower; + scaledPower = AH_MIN(scaledPower, powerLimit); + + scaledPower = AH_MIN(scaledPower, targetPowerOfdm.twicePwr6_24); + + /* Set OFDM rates 9, 12, 18, 24, 36, 48, 54, XR */ + rpow[0] = rpow[1] = rpow[2] = rpow[3] = rpow[4] = scaledPower; + rpow[5] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr36); + rpow[6] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr48); + rpow[7] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr54); + +#ifdef notyet + if (eeversion >= AR_EEPROM_VER4_0) { + /* Setup XR target power from EEPROM */ + rpow[15] = AH_MIN(scaledPower, IS_CHAN_2GHZ(chan) ? + xrTargetPower2 : xrTargetPower5); + } else { + /* XR uses 6mb power */ + rpow[15] = rpow[0]; + } +#else + rpow[15] = rpow[0]; +#endif + + *pMinPower = rpow[7]; + *pMaxPower = rpow[0]; + +#if 0 + ahp->ah_ofdmTxPower = rpow[0]; +#endif + + HALDEBUG(ah, HAL_DEBUG_ANY, + "%s: MaxRD: %d TurboMax: %d MaxCTL: %d " + "TPC_Reduction %d\n", __func__, + twiceMaxRDPower, turbo2WMaxPower5, + twiceMaxEdgePower, tpcScaleReduction * 2); + } + + if (IEEE80211_IS_CHAN_CCK(chan)) { + /* Get final CCK target powers */ + ar5212GetTargetPowers(ah, chan, trgtPwr_11b, + numTargetPwr_11b, &targetPowerCck); + + /* Reduce power by max regulatory domain allowed restrictions */ + scaledPower = AH_MIN(twiceMaxEdgePowerCck, + twiceMaxRDPower - twiceAntennaReduction); + + scaledPower -= (tpcScaleReduction * 2); + scaledPower = (scaledPower < 0) ? 0 : scaledPower; + scaledPower = AH_MIN(scaledPower, powerLimit); + + rpow[8] = (scaledPower < 1) ? 1 : scaledPower; + + /* Set CCK rates 2L, 2S, 5.5L, 5.5S, 11L, 11S */ + rpow[8] = AH_MIN(scaledPower, targetPowerCck.twicePwr6_24); + rpow[9] = AH_MIN(scaledPower, targetPowerCck.twicePwr36); + rpow[10] = rpow[9]; + rpow[11] = AH_MIN(scaledPower, targetPowerCck.twicePwr48); + rpow[12] = rpow[11]; + rpow[13] = AH_MIN(scaledPower, targetPowerCck.twicePwr54); + rpow[14] = rpow[13]; + + /* Set min/max power based off OFDM values or initialization */ + if (rpow[13] < *pMinPower) + *pMinPower = rpow[13]; + if (rpow[9] > *pMaxPower) + *pMaxPower = rpow[9]; + + } +#if 0 + ahp->ah_tx6PowerInHalfDbm = *pMaxPower; +#endif + return AH_TRUE; +} + +void* +ath_hal_malloc(size_t size) +{ + return calloc(1, size); +} + +void +ath_hal_free(void* p) +{ + return free(p); +} + +void +ath_hal_vprintf(struct ath_hal *ah, const char* fmt, va_list ap) +{ + vprintf(fmt, ap); +} + +void +ath_hal_printf(struct ath_hal *ah, const char* fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + ath_hal_vprintf(ah, fmt, ap); + va_end(ap); +} + +void +DO_HALDEBUG(struct ath_hal *ah, u_int mask, const char* fmt, ...) +{ + __va_list ap; + va_start(ap, fmt); + ath_hal_vprintf(ah, fmt, ap); + va_end(ap); +} diff --git a/tools/tools/ath/athrd/run.sh b/tools/tools/ath/athrd/run.sh new file mode 100755 index 000000000000..3e1e01a27be4 --- /dev/null +++ b/tools/tools/ath/athrd/run.sh @@ -0,0 +1,17 @@ +# $FreeBSD$ + +COUNTRIES=${@:-" + DB NA AL DZ AR AM AU AT AZ BH BY BE BZ BO BR BN BG + CA CL CN CO CR HR CY CZ DK DO EC EG SV EE FI FR GE + DE GR GT HN HK HU IS IN ID IR IE IL IT JP J1 J2 J3 + J4 J5 JO KZ KP KR K2 KW LV LB LI LT LU MO MK MY MX + MC MA NL NZ NO OM PK PA PE PH PL PT PR QA RO RU SA + SG SK SI ZA ES SE CH SY TW TH TT TN TR UA AE GB US + UY UZ VE VN YE ZW WOR0_WORLD WOR1_WORLD WOR2_WORLD WOR3_WORLD + WOR4_WORLD, WOR5_ETSIC EU1_WORLD WOR01_WORLD WOR02_WORLD +"} + +for i in $COUNTRIES +do + ./athrd -o $i +done diff --git a/tools/tools/ath/athregs/Makefile b/tools/tools/ath/athregs/Makefile new file mode 100644 index 000000000000..6b61b32ceb51 --- /dev/null +++ b/tools/tools/ath/athregs/Makefile @@ -0,0 +1,23 @@ +# $FreeBSD$ + +PROG= athregs + +.PATH.c: ${.CURDIR}/../common + +SRCS= dumpregs.c +SRCS+= dumpregs_5210.c +SRCS+= dumpregs_5211.c +SRCS+= dumpregs_5212.c +SRCS+= dumpregs_5416.c +SRCS+= opt_ah.h + +CLEANFILES+= opt_ah.h + +opt_ah.h: + echo "#define AH_DEBUG 1" > opt_ah.h + echo "#define AH_DEBUG_COUNTRY 1" >> opt_ah.h + echo "#define AH_SUPPORT_AR5416 1" >> opt_ah.h + +.include <../Makefile.inc> + +.include <bsd.prog.mk> diff --git a/tools/tools/ath/athregs/dumpregs.c b/tools/tools/ath/athregs/dumpregs.c new file mode 100644 index 000000000000..50e8a1e03978 --- /dev/null +++ b/tools/tools/ath/athregs/dumpregs.c @@ -0,0 +1,721 @@ +/*- + * Copyright (c) 2002-2008 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$ + */ +#include "diag.h" + +#include "ah.h" +#include "ah_internal.h" +/* XXX cheat, 5212 has a superset of the key table defs */ +#include "ar5212/ar5212reg.h" + +#include "dumpregs.h" + +#include <getopt.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <err.h> + +typedef struct { + HAL_REVS revs; + u_int32_t regdata[0xffff / sizeof(u_int32_t)]; +#define MAXREGS 5*1024 + struct dumpreg *regs[MAXREGS]; + u_int nregs; + u_int show_names : 1, + show_addrs : 1; +} dumpregs_t; +static dumpregs_t state; + +#undef OS_REG_READ +#define OS_REG_READ(ah, off) state.regdata[(off) >> 2] + +static int ath_hal_anyregs(int what); +static int ath_hal_setupregs(struct ath_diag *atd, int what); +static u_int ath_hal_setupdiagregs(const HAL_REGRANGE regs[], u_int nr); +static void ath_hal_dumpregs(FILE *fd, int what); +static void ath_hal_dumprange(FILE *fd, u_int a, u_int b); +static void ath_hal_dumpkeycache(FILE *fd, int nkeys); +static void ath_hal_dumpint(FILE *fd, int what); +static void ath_hal_dumpqcu(FILE *fd, int what); +static void ath_hal_dumpdcu(FILE *fd, int what); +static void ath_hal_dumpbb(FILE *fd, int what); + +static void +usage(void) +{ + fprintf(stderr, "usage: athregs [-i interface] [-abdkmqxz]\n"); + fprintf(stderr, "-a display all registers\n"); + fprintf(stderr, "-b display baseband registers\n"); + fprintf(stderr, "-d display DCU registers\n"); + fprintf(stderr, "-k display key cache registers\n"); + fprintf(stderr, "-m display \"MAC\" registers (default)\n"); + fprintf(stderr, "-q display QCU registers\n"); + fprintf(stderr, "-x display XR registers\n"); + fprintf(stderr, "-z display interrupt registers\n"); + fprintf(stderr, "\n"); + fprintf(stderr, "-A display register address\n"); + fprintf(stderr, "-N suppress display of register name\n"); + exit(-1); +} + +int +main(int argc, char *argv[]) +{ + struct ath_diag atd; + const char *ifname; + u_int32_t *data; + u_int32_t *dp, *ep; + int what, c, s, i; + + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) + err(1, "socket"); + ifname = getenv("ATH"); + if (!ifname) + ifname = ATH_DEFAULT; + + what = 0; + state.show_addrs = 0; + state.show_names = 1; + while ((c = getopt(argc, argv, "i:aAbdkmNqxz")) != -1) + switch (c) { + case 'a': + what |= DUMP_ALL; + break; + case 'A': + state.show_addrs = 1; + break; + case 'b': + what |= DUMP_BASEBAND; + break; + case 'd': + what |= DUMP_DCU; + break; + case 'k': + what |= DUMP_KEYCACHE; + break; + case 'i': + ifname = optarg; + break; + case 'm': + what |= DUMP_BASIC; + break; + case 'N': + state.show_names = 0; + break; + case 'q': + what |= DUMP_QCU; + break; + case 'x': + what |= DUMP_XR; + break; + case 'z': + what |= DUMP_INTERRUPT; + break; + default: + usage(); + /*NOTREACHED*/ + } + strncpy(atd.ad_name, ifname, sizeof (atd.ad_name)); + + argc -= optind; + argv += optind; + if (what == 0) + what = DUMP_BASIC; + + atd.ad_id = HAL_DIAG_REVS; + atd.ad_out_data = (caddr_t) &state.revs; + atd.ad_out_size = sizeof(state.revs); + if (ioctl(s, SIOCGATHDIAG, &atd) < 0) + err(1, atd.ad_name); + + if (ath_hal_setupregs(&atd, what) == 0) + errx(-1, "no registers are known for this part " + "(devid 0x%x mac %d.%d phy %d)", state.revs.ah_devid, + state.revs.ah_macVersion, state.revs.ah_macRev, + state.revs.ah_phyRev); + + atd.ad_out_size = ath_hal_setupdiagregs((HAL_REGRANGE *) atd.ad_in_data, + atd.ad_in_size / sizeof(HAL_REGRANGE)); + atd.ad_out_data = (caddr_t) malloc(atd.ad_out_size); + if (atd.ad_out_data == NULL) { + fprintf(stderr, "Cannot malloc output buffer, size %u\n", + atd.ad_out_size); + exit(-1); + } + atd.ad_id = HAL_DIAG_REGS | ATH_DIAG_IN | ATH_DIAG_DYN; + if (ioctl(s, SIOCGATHDIAG, &atd) < 0) + err(1, atd.ad_name); + + /* + * Expand register data into global space that can be + * indexed directly by register offset. + */ + dp = (u_int32_t *)atd.ad_out_data; + ep = (u_int32_t *)(atd.ad_out_data + atd.ad_out_size); + while (dp < ep) { + u_int r = dp[0] >> 16; /* start of range */ + u_int e = dp[0] & 0xffff; /* end of range */ + dp++; + /* convert offsets to indices */ + r >>= 2; e >>= 2; + do { + if (dp >= ep) { + fprintf(stderr, "Warning, botched return data;" + "register at offset 0x%x not present\n", + r << 2); + break; + } + state.regdata[r++] = *dp++; + } while (r <= e); + } + + if (what & DUMP_BASIC) + ath_hal_dumpregs(stdout, DUMP_BASIC); + if ((what & DUMP_INTERRUPT) && ath_hal_anyregs(DUMP_INTERRUPT)) { + if (what & DUMP_BASIC) + putchar('\n'); + if (state.show_addrs) + ath_hal_dumpregs(stdout, DUMP_INTERRUPT); + else + ath_hal_dumpint(stdout, what); + } + if ((what & DUMP_QCU) && ath_hal_anyregs(DUMP_QCU)) { + if (what & (DUMP_BASIC|DUMP_INTERRUPT)) + putchar('\n'); + if (state.show_addrs) + ath_hal_dumpregs(stdout, DUMP_QCU); + else + ath_hal_dumpqcu(stdout, what); + } + if ((what & DUMP_DCU) && ath_hal_anyregs(DUMP_DCU)) { + if (what & (DUMP_BASIC|DUMP_INTERRUPT|DUMP_QCU)) + putchar('\n'); + if (state.show_addrs) + ath_hal_dumpregs(stdout, DUMP_DCU); + else + ath_hal_dumpdcu(stdout, what); + } + if (what & DUMP_KEYCACHE) { + if (state.show_addrs) { + if (what & (DUMP_BASIC|DUMP_INTERRUPT|DUMP_QCU|DUMP_DCU)) + putchar('\n'); + ath_hal_dumpregs(stdout, DUMP_KEYCACHE); + } else + ath_hal_dumpkeycache(stdout, 128); + } + if (what & DUMP_BASEBAND) { + if (what &~ DUMP_BASEBAND) + fprintf(stdout, "\n"); + ath_hal_dumpbb(stdout, what); + } + return 0; +} + +static int +regcompar(const void *a, const void *b) +{ + const struct dumpreg *ra = *(const struct dumpreg **)a; + const struct dumpreg *rb = *(const struct dumpreg **)b; + return ra->addr - rb->addr; +} + +void +register_regs(struct dumpreg *chipregs, u_int nchipregs, + int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max) +{ + const int existing_regs = state.nregs; + int i, j; + + for (i = 0; i < nchipregs; i++) { + struct dumpreg *nr = &chipregs[i]; + if (nr->srevMin == 0) + nr->srevMin = def_srev_min; + if (nr->srevMax == 0) + nr->srevMax = def_srev_max; + if (nr->phyMin == 0) + nr->phyMin = def_phy_min; + if (nr->phyMax == 0) + nr->phyMax = def_phy_max; + for (j = 0; j < existing_regs; j++) { + struct dumpreg *r = state.regs[j]; + /* + * Check if we can just expand the mac+phy + * coverage for the existing entry. + */ + if (nr->addr == r->addr && + (nr->name == r->name || + nr->name != NULL && r->name != NULL && + strcmp(nr->name, r->name) == 0)) { + if (nr->srevMin < r->srevMin && + (r->srevMin <= nr->srevMax && + nr->srevMax+1 <= r->srevMax)) { + r->srevMin = nr->srevMin; + goto skip; + } + if (nr->srevMax > r->srevMax && + (r->srevMin <= nr->srevMin && + nr->srevMin <= r->srevMax)) { + r->srevMax = nr->srevMax; + goto skip; + } + } + if (r->addr > nr->addr) + break; + } + /* + * New item, add to the end, it'll be sorted below. + */ + if (state.nregs == MAXREGS) + errx(-1, "too many registers; bump MAXREGS"); + state.regs[state.nregs++] = nr; + skip: + ; + } + qsort(state.regs, state.nregs, sizeof(struct dumpreg *), regcompar); +} + +void +register_keycache(u_int nslots, + int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max) +{ +#define SET(r, a) do { \ + r->addr = a; r->type = DUMP_KEYCACHE; r++; \ +} while(0) + struct dumpreg *keyregs, *r; + int i; + + keyregs = (struct dumpreg *) calloc(nslots, 8*sizeof(struct dumpreg)); + if (keyregs == NULL) + errx(-1, "no space to %d keycache slots\n", nslots); + r = keyregs; + for (i = 0; i < nslots; i++) { + SET(r, AR_KEYTABLE_KEY0(i)); + SET(r, AR_KEYTABLE_KEY1(i)); + SET(r, AR_KEYTABLE_KEY2(i)); + SET(r, AR_KEYTABLE_KEY3(i)); + SET(r, AR_KEYTABLE_KEY4(i)); + SET(r, AR_KEYTABLE_TYPE(i)); + SET(r, AR_KEYTABLE_MAC0(i)); + SET(r, AR_KEYTABLE_MAC1(i)); + } + register_regs(keyregs, 8*nslots, + def_srev_min, def_srev_max, def_phy_min, def_phy_max); +#undef SET +} + +void +register_range(u_int brange, u_int erange, int type, + int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max) +{ + struct dumpreg *bbregs, *r; + int i, nregs; + + nregs = (erange - brange) / sizeof(uint32_t); + bbregs = (struct dumpreg *) calloc(nregs, sizeof(struct dumpreg)); + if (bbregs == NULL) + errx(-1, "no space for %d register slots (type %d)\n", + nregs, type); + r = bbregs; + for (i = 0; i < nregs; i++) { + r->addr = brange + (i<<2); + r->type = type; + r++; + } + register_regs(bbregs, nregs, + def_srev_min, def_srev_max, def_phy_min, def_phy_max); +} + +static __inline int +match(const struct dumpreg *dr, const HAL_REVS *revs) +{ + if (!MAC_MATCH(dr, revs->ah_macVersion, revs->ah_macRev)) + return 0; + if ((dr->type & DUMP_BASEBAND) && !PHY_MATCH(dr, revs->ah_phyRev)) + return 0; + return 1; +} + +static int +ath_hal_anyregs(int what) +{ + const HAL_REVS *revs = &state.revs; + int i; + + for (i = 0; i < state.nregs; i++) { + const struct dumpreg *dr = state.regs[i]; + if ((what & dr->type) && match(dr, revs)) + return 1; + } + return 0; +} + +static int +ath_hal_setupregs(struct ath_diag *atd, int what) +{ + const HAL_REVS *revs = &state.revs; + HAL_REGRANGE r; + size_t space = 0; + u_int8_t *cp; + int i, brun, erun; + + brun = erun = -1; + for (i = 0; i < state.nregs; i++) { + const struct dumpreg *dr = state.regs[i]; + if ((what & dr->type) && match(dr, revs)) { + if (erun + 4 != dr->addr) { + if (brun != -1) + space += sizeof(HAL_REGRANGE); + brun = erun = dr->addr; + } else + erun = dr->addr; + } + } + space += sizeof(HAL_REGRANGE); + + atd->ad_in_data = (caddr_t) malloc(space); + if (atd->ad_in_data == NULL) { + fprintf(stderr, "Cannot malloc memory for registers!\n"); + exit(-1); + } + atd->ad_in_size = space; + cp = (u_int8_t *) atd->ad_in_data; + brun = erun = -1; + for (i = 0; i < state.nregs; i++) { + const struct dumpreg *dr = state.regs[i]; + if ((what & dr->type) && match(dr, revs)) { + if (erun + 4 != dr->addr) { + if (brun != -1) { + r.start = brun, r.end = erun; + memcpy(cp, &r, sizeof(r)); + cp += sizeof(r); + } + brun = erun = dr->addr; + } else + erun = dr->addr; + } + } + if (brun != -1) { + r.start = brun, r.end = erun; + memcpy(cp, &r, sizeof(r)); + cp += sizeof(r); + } + return space / sizeof(uint32_t); +} + +static void +ath_hal_dumpregs(FILE *fd, int what) +{ + const HAL_REVS *revs = &state.revs; + const char *sep = ""; + int i, count, itemsperline; + + count = 0; + itemsperline = 4; + if (state.show_names && state.show_addrs) + itemsperline--; + for (i = 0; i < state.nregs; i++) { + const struct dumpreg *dr = state.regs[i]; + if ((what & dr->type) && match(dr, revs)) { + if (state.show_names && dr->name != NULL) { + fprintf(fd, "%s%-8s", sep, dr->name); + if (state.show_addrs) + fprintf(fd, " [%04x]", dr->addr); + } else + fprintf(fd, "%s%04x", sep, dr->addr); + fprintf(fd, " %08x", OS_REG_READ(ah, dr->addr)); + sep = " "; + if ((++count % itemsperline) == 0) + sep = "\n"; + } + } + if (count) + fprintf(fd, "\n"); +} + +static void +ath_hal_dumprange(FILE *fd, u_int a, u_int b) +{ + u_int r; + + for (r = a; r+16 <= b; r += 5*4) + fprintf(fd, + "%04x %08x %04x %08x %04x %08x %04x %08x %04x %08x\n" + , r, OS_REG_READ(ah, r) + , r+4, OS_REG_READ(ah, r+4) + , r+8, OS_REG_READ(ah, r+8) + , r+12, OS_REG_READ(ah, r+12) + , r+16, OS_REG_READ(ah, r+16) + ); + switch (b-r) { + case 16: + fprintf(fd + , "%04x %08x %04x %08x %04x %08x %04x %08x\n" + , r, OS_REG_READ(ah, r) + , r+4, OS_REG_READ(ah, r+4) + , r+8, OS_REG_READ(ah, r+8) + , r+12, OS_REG_READ(ah, r+12) + ); + break; + case 12: + fprintf(fd, "%04x %08x %04x %08x %04x %08x\n" + , r, OS_REG_READ(ah, r) + , r+4, OS_REG_READ(ah, r+4) + , r+8, OS_REG_READ(ah, r+8) + ); + break; + case 8: + fprintf(fd, "%04x %08x %04x %08x\n" + , r, OS_REG_READ(ah, r) + , r+4, OS_REG_READ(ah, r+4) + ); + break; + case 4: + fprintf(fd, "%04x %08x\n" + , r, OS_REG_READ(ah, r) + ); + break; + } +} + +static void +ath_hal_dumpint(FILE *fd, int what) +{ + int i; + + /* Interrupt registers */ + fprintf(fd, "IMR: %08x S0 %08x S1 %08x S2 %08x S3 %08x S4 %08x\n" + , OS_REG_READ(ah, AR_IMR) + , OS_REG_READ(ah, AR_IMR_S0) + , OS_REG_READ(ah, AR_IMR_S1) + , OS_REG_READ(ah, AR_IMR_S2) + , OS_REG_READ(ah, AR_IMR_S3) + , OS_REG_READ(ah, AR_IMR_S4) + ); + fprintf(fd, "ISR: %08x S0 %08x S1 %08x S2 %08x S3 %08x S4 %08x\n" + , OS_REG_READ(ah, AR_ISR) + , OS_REG_READ(ah, AR_ISR_S0) + , OS_REG_READ(ah, AR_ISR_S1) + , OS_REG_READ(ah, AR_ISR_S2) + , OS_REG_READ(ah, AR_ISR_S3) + , OS_REG_READ(ah, AR_ISR_S4) + ); +} + +static void +ath_hal_dumpqcu(FILE *fd, int what) +{ + int i; + + /* QCU registers */ + fprintf(fd, "%-8s %08x %-8s %08x %-8s %08x\n" + , "Q_TXE", OS_REG_READ(ah, AR_Q_TXE) + , "Q_TXD", OS_REG_READ(ah, AR_Q_TXD) + , "Q_RDYTIMSHD", OS_REG_READ(ah, AR_Q_RDYTIMESHDN) + ); + fprintf(fd, "Q_ONESHOTARM_SC %08x Q_ONESHOTARM_CC %08x\n" + , OS_REG_READ(ah, AR_Q_ONESHOTARM_SC) + , OS_REG_READ(ah, AR_Q_ONESHOTARM_CC) + ); + for (i = 0; i < 10; i++) + fprintf(fd, "Q[%u] TXDP %08x CBR %08x RDYT %08x MISC %08x STS %08x\n" + , i + , OS_REG_READ(ah, AR_QTXDP(i)) + , OS_REG_READ(ah, AR_QCBRCFG(i)) + , OS_REG_READ(ah, AR_QRDYTIMECFG(i)) + , OS_REG_READ(ah, AR_QMISC(i)) + , OS_REG_READ(ah, AR_QSTS(i)) + ); +} + +static void +ath_hal_dumpdcu(FILE *fd, int what) +{ + int i; + + /* DCU registers */ + for (i = 0; i < 10; i++) + fprintf(fd, "D[%u] MASK %08x IFS %08x RTRY %08x CHNT %08x MISC %06x\n" + , i + , OS_REG_READ(ah, AR_DQCUMASK(i)) + , OS_REG_READ(ah, AR_DLCL_IFS(i)) + , OS_REG_READ(ah, AR_DRETRY_LIMIT(i)) + , OS_REG_READ(ah, AR_DCHNTIME(i)) + , OS_REG_READ(ah, AR_DMISC(i)) + ); +} + +static void +ath_hal_dumpbb(FILE *fd, int what) +{ + const HAL_REVS *revs = &state.revs; + int i, brun, erun; + + brun = erun = 0; + for (i = 0; i < state.nregs; i++) { + const struct dumpreg *dr = state.regs[i]; + if (!match(dr, revs)) + continue; + if (dr->type & DUMP_BASEBAND) { + if (brun == 0) { + brun = erun = dr->addr; + } else if (dr->addr == erun + sizeof(uint32_t)) { + erun = dr->addr; + } else { + ath_hal_dumprange(fd, brun, erun); + brun = erun = dr->addr; + } + } else { + if (brun != 0) + ath_hal_dumprange(fd, brun, erun); + brun = erun = 0; + } + } + if (brun != 0) + ath_hal_dumprange(fd, brun, erun); +} + +static u_int +ath_hal_setupdiagregs(const HAL_REGRANGE regs[], u_int nr) +{ + u_int space; + int i; + + space = 0; + for (i = 0; i < nr; i++) { + u_int n = 2 * sizeof(u_int32_t); /* reg range + first */ + if (regs[i].end) { + if (regs[i].end < regs[i].start) { + fprintf(stderr, "%s: bad register range, " + "end 0x%x < start 0x%x\n", + __func__, regs[i].end, regs[i].end); + exit(-1); + } + n += regs[i].end - regs[i].start; + } + space += n; + } + return space; +} + +/* + * Format an Ethernet MAC for printing. + */ +static const char* +ether_sprintf(const u_int8_t *mac) +{ + static char etherbuf[18]; + snprintf(etherbuf, sizeof(etherbuf), "%02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return etherbuf; +} + +#ifndef isclr +#define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY)) +#define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) +#define isset(a,i) ((a)[(i)/NBBY] & (1<<((i)%NBBY))) +#define isclr(a,i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) +#endif + +static void +ath_hal_dumpkeycache(FILE *fd, int nkeys) +{ + static const char *keytypenames[] = { + "WEP-40", /* AR_KEYTABLE_TYPE_40 */ + "WEP-104", /* AR_KEYTABLE_TYPE_104 */ + "#2", + "WEP-128", /* AR_KEYTABLE_TYPE_128 */ + "TKIP", /* AR_KEYTABLE_TYPE_TKIP */ + "AES-OCB", /* AR_KEYTABLE_TYPE_AES */ + "AES-CCM", /* AR_KEYTABLE_TYPE_CCM */ + "CLR", /* AR_KEYTABLE_TYPE_CLR */ + }; + int micEnabled = SREV(state.revs.ah_macVersion, state.revs.ah_macRev) < SREV(4,8) ? 0 : + OS_REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_CRPT_MIC_ENABLE; + u_int8_t mac[IEEE80211_ADDR_LEN]; + u_int8_t ismic[128/NBBY]; + int entry; + int first = 1; + + memset(ismic, 0, sizeof(ismic)); + for (entry = 0; entry < nkeys; entry++) { + u_int32_t macLo, macHi, type; + u_int32_t key0, key1, key2, key3, key4; + + macHi = OS_REG_READ(ah, AR_KEYTABLE_MAC1(entry)); + if ((macHi & AR_KEYTABLE_VALID) == 0 && isclr(ismic, entry)) + continue; + macLo = OS_REG_READ(ah, AR_KEYTABLE_MAC0(entry)); + macHi <<= 1; + if (macLo & (1<<31)) + macHi |= 1; + macLo <<= 1; + mac[4] = macHi & 0xff; + mac[5] = macHi >> 8; + mac[0] = macLo & 0xff; + mac[1] = macLo >> 8; + mac[2] = macLo >> 16; + mac[3] = macLo >> 24; + type = OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry)); + if ((type & 7) == AR_KEYTABLE_TYPE_TKIP && micEnabled) + setbit(ismic, entry+64); + key0 = OS_REG_READ(ah, AR_KEYTABLE_KEY0(entry)); + key1 = OS_REG_READ(ah, AR_KEYTABLE_KEY1(entry)); + key2 = OS_REG_READ(ah, AR_KEYTABLE_KEY2(entry)); + key3 = OS_REG_READ(ah, AR_KEYTABLE_KEY3(entry)); + key4 = OS_REG_READ(ah, AR_KEYTABLE_KEY4(entry)); + if (first) { + fprintf(fd, "\n"); + first = 0; + } + fprintf(fd, "KEY[%03u] MAC %s %-7s %02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x\n" + , entry + , ether_sprintf(mac) + , isset(ismic, entry) ? "MIC" : keytypenames[type & 7] + , (key0 >> 0) & 0xff + , (key0 >> 8) & 0xff + , (key0 >> 16) & 0xff + , (key0 >> 24) & 0xff + , (key1 >> 0) & 0xff + , (key1 >> 8) & 0xff + , (key2 >> 0) & 0xff + , (key2 >> 8) & 0xff + , (key2 >> 16) & 0xff + , (key2 >> 24) & 0xff + , (key3 >> 0) & 0xff + , (key3 >> 8) & 0xff + , (key4 >> 0) & 0xff + , (key4 >> 8) & 0xff + , (key4 >> 16) & 0xff + , (key4 >> 24) & 0xff + ); + } +} diff --git a/tools/tools/ath/athstats/Makefile b/tools/tools/ath/athstats/Makefile new file mode 100644 index 000000000000..b1b976619f8a --- /dev/null +++ b/tools/tools/ath/athstats/Makefile @@ -0,0 +1,26 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../../../sys/dev/ath/ath_hal + +PROG= athstats + +SRCS= main.c statfoo.c athstats.c opt_ah.h ah_osdep.h + +CLEANFILES+= opt_ah.h + +.include <../Makefile.inc> + +CFLAGS+=-DATH_SUPPORT_ANI +CFLAGS+=-DATH_SUPPORT_TDMA + +opt_ah.h: + echo "#define AH_DEBUG 1" > opt_ah.h + echo "#define AH_DEBUG_COUNTRY 1" >> opt_ah.h + echo "#define AH_SUPPORT_AR5416 1" >> opt_ah.h + +ah_osdep.h: + echo 'typedef void *HAL_SOFTC;' >ah_osdep.h + echo 'typedef int HAL_BUS_TAG;' >>ah_osdep.h + echo 'typedef void *HAL_BUS_HANDLE;' >>ah_osdep.h + +.include <bsd.prog.mk> diff --git a/tools/tools/ath/athstats/athstats.c b/tools/tools/ath/athstats/athstats.c new file mode 100644 index 000000000000..c36dfa030b66 --- /dev/null +++ b/tools/tools/ath/athstats/athstats.c @@ -0,0 +1,1109 @@ +/*- + * 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$ + */ + +#include "opt_ah.h" + +/* + * ath statistics class. + */ +#include <sys/types.h> +#include <sys/file.h> +#include <sys/sockio.h> +#include <sys/socket.h> +#include <net/if.h> +#include <net/if_media.h> +#include <net/if_var.h> + +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <string.h> +#include <unistd.h> +#include <err.h> + +#include "ah.h" +#include "ah_desc.h" +#include "net80211/ieee80211_ioctl.h" +#include "net80211/ieee80211_radiotap.h" +#include "if_athioctl.h" + +#include "athstats.h" + +#ifdef ATH_SUPPORT_ANI +#define HAL_EP_RND(x,mul) \ + ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) +#define HAL_RSSI(x) HAL_EP_RND(x, HAL_RSSI_EP_MULTIPLIER) +#endif + +#define NOTPRESENT { 0, "", "" } + +#define AFTER(prev) ((prev)+1) + +static const struct fmt athstats[] = { +#define S_INPUT 0 + { 8, "input", "input", "data frames received" }, +#define S_OUTPUT AFTER(S_INPUT) + { 8, "output", "output", "data frames transmit" }, +#define S_TX_ALTRATE AFTER(S_OUTPUT) + { 7, "altrate", "altrate", "tx frames with an alternate rate" }, +#define S_TX_SHORTRETRY AFTER(S_TX_ALTRATE) + { 7, "short", "short", "short on-chip tx retries" }, +#define S_TX_LONGRETRY AFTER(S_TX_SHORTRETRY) + { 7, "long", "long", "long on-chip tx retries" }, +#define S_TX_XRETRIES AFTER(S_TX_LONGRETRY) + { 6, "xretry", "xretry", "tx failed 'cuz too many retries" }, +#define S_MIB AFTER(S_TX_XRETRIES) + { 5, "mib", "mib", "mib overflow interrupts" }, +#ifndef __linux__ +#define S_TX_LINEAR AFTER(S_MIB) + { 5, "txlinear", "txlinear", "tx linearized to cluster" }, +#define S_BSTUCK AFTER(S_TX_LINEAR) + { 5, "bstuck", "bstuck", "stuck beacon conditions" }, +#define S_INTRCOAL AFTER(S_BSTUCK) + { 5, "intrcoal", "intrcoal", "interrupts coalesced" }, +#define S_RATE AFTER(S_INTRCOAL) +#else +#define S_RATE AFTER(S_MIB) +#endif + { 5, "rate", "rate", "current transmit rate" }, +#define S_WATCHDOG AFTER(S_RATE) + { 5, "wdog", "wdog", "watchdog timeouts" }, +#define S_FATAL AFTER(S_WATCHDOG) + { 5, "fatal", "fatal", "hardware error interrupts" }, +#define S_BMISS AFTER(S_FATAL) + { 5, "bmiss", "bmiss", "beacon miss interrupts" }, +#define S_RXORN AFTER(S_BMISS) + { 5, "rxorn", "rxorn", "recv overrun interrupts" }, +#define S_RXEOL AFTER(S_RXORN) + { 5, "rxeol", "rxeol", "recv eol interrupts" }, +#define S_TXURN AFTER(S_RXEOL) + { 5, "txurn", "txurn", "txmit underrun interrupts" }, +#define S_TX_MGMT AFTER(S_TXURN) + { 5, "txmgt", "txmgt", "tx management frames" }, +#define S_TX_DISCARD AFTER(S_TX_MGMT) + { 5, "txdisc", "txdisc", "tx frames discarded prior to association" }, +#define S_TX_INVALID AFTER(S_TX_DISCARD) + { 5, "txinv", "txinv", "tx invalid (19)" }, +#define S_TX_QSTOP AFTER(S_TX_INVALID) + { 5, "qstop", "qstop", "tx stopped 'cuz no xmit buffer" }, +#define S_TX_ENCAP AFTER(S_TX_QSTOP) + { 5, "txencode", "txencode", "tx encapsulation failed" }, +#define S_TX_NONODE AFTER(S_TX_ENCAP) + { 5, "txnonode", "txnonode", "tx failed 'cuz no node" }, +#define S_TX_NOBUF AFTER(S_TX_NONODE) + { 5, "txnobuf", "txnobuf", "tx failed 'cuz dma buffer allocation failed" }, +#define S_TX_NOFRAG AFTER(S_TX_NOBUF) + { 5, "txnofrag", "txnofrag", "tx failed 'cuz frag buffer allocation(s) failed" }, +#define S_TX_NOMBUF AFTER(S_TX_NOFRAG) + { 5, "txnombuf", "txnombuf", "tx failed 'cuz mbuf allocation failed" }, +#ifndef __linux__ +#define S_TX_NOMCL AFTER(S_TX_NOMBUF) + { 5, "txnomcl", "txnomcl", "tx failed 'cuz cluster allocation failed" }, +#define S_TX_FIFOERR AFTER(S_TX_NOMCL) +#else +#define S_TX_FIFOERR AFTER(S_TX_NOMBUF) +#endif + { 5, "efifo", "efifo", "tx failed 'cuz FIFO underrun" }, +#define S_TX_FILTERED AFTER(S_TX_FIFOERR) + { 5, "efilt", "efilt", "tx failed 'cuz destination filtered" }, +#define S_TX_BADRATE AFTER(S_TX_FILTERED) + { 5, "txbadrate", "txbadrate", "tx failed 'cuz bogus xmit rate" }, +#define S_TX_NOACK AFTER(S_TX_BADRATE) + { 5, "noack", "noack", "tx frames with no ack marked" }, +#define S_TX_RTS AFTER(S_TX_NOACK) + { 5, "rts", "rts", "tx frames with rts enabled" }, +#define S_TX_CTS AFTER(S_TX_RTS) + { 5, "cts", "cts", "tx frames with cts enabled" }, +#define S_TX_SHORTPRE AFTER(S_TX_CTS) + { 5, "shpre", "shpre", "tx frames with short preamble" }, +#define S_TX_PROTECT AFTER(S_TX_SHORTPRE) + { 5, "protect", "protect", "tx frames with 11g protection" }, +#define S_RX_ORN AFTER(S_TX_PROTECT) + { 5, "rxorn", "rxorn", "rx failed 'cuz of desc overrun" }, +#define S_RX_CRC_ERR AFTER(S_RX_ORN) + { 6, "crcerr", "crcerr", "rx failed 'cuz of bad CRC" }, +#define S_RX_FIFO_ERR AFTER(S_RX_CRC_ERR) + { 5, "rxfifo", "rxfifo", "rx failed 'cuz of FIFO overrun" }, +#define S_RX_CRYPTO_ERR AFTER(S_RX_FIFO_ERR) + { 5, "crypt", "crypt", "rx failed 'cuz decryption" }, +#define S_RX_MIC_ERR AFTER(S_RX_CRYPTO_ERR) + { 4, "mic", "mic", "rx failed 'cuz MIC failure" }, +#define S_RX_TOOSHORT AFTER(S_RX_MIC_ERR) + { 5, "rxshort", "rxshort", "rx failed 'cuz frame too short" }, +#define S_RX_NOMBUF AFTER(S_RX_TOOSHORT) + { 5, "rxnombuf", "rxnombuf", "rx setup failed 'cuz no mbuf" }, +#define S_RX_MGT AFTER(S_RX_NOMBUF) + { 5, "rxmgt", "rxmgt", "rx management frames" }, +#define S_RX_CTL AFTER(S_RX_MGT) + { 5, "rxctl", "rxctl", "rx control frames" }, +#define S_RX_PHY_ERR AFTER(S_RX_CTL) + { 7, "phyerr", "phyerr", "rx failed 'cuz of PHY err" }, +#define S_RX_PHY_UNDERRUN AFTER(S_RX_PHY_ERR) + { 4, "phyund", "TUnd", "transmit underrun" }, +#define S_RX_PHY_TIMING AFTER(S_RX_PHY_UNDERRUN) + { 4, "phytim", "Tim", "timing error" }, +#define S_RX_PHY_PARITY AFTER(S_RX_PHY_TIMING) + { 4, "phypar", "IPar", "illegal parity" }, +#define S_RX_PHY_RATE AFTER(S_RX_PHY_PARITY) + { 4, "phyrate", "IRate", "illegal rate" }, +#define S_RX_PHY_LENGTH AFTER(S_RX_PHY_RATE) + { 4, "phylen", "ILen", "illegal length" }, +#define S_RX_PHY_RADAR AFTER(S_RX_PHY_LENGTH) + { 4, "phyradar", "Radar", "radar detect" }, +#define S_RX_PHY_SERVICE AFTER(S_RX_PHY_RADAR) + { 4, "physervice", "Service", "illegal service" }, +#define S_RX_PHY_TOR AFTER(S_RX_PHY_SERVICE) + { 4, "phytor", "TOR", "transmit override receive" }, +#define S_RX_PHY_OFDM_TIMING AFTER(S_RX_PHY_TOR) + { 6, "ofdmtim", "ofdmtim", "OFDM timing" }, +#define S_RX_PHY_OFDM_SIGNAL_PARITY AFTER(S_RX_PHY_OFDM_TIMING) + { 6, "ofdmsig", "ofdmsig", "OFDM illegal parity" }, +#define S_RX_PHY_OFDM_RATE_ILLEGAL AFTER(S_RX_PHY_OFDM_SIGNAL_PARITY) + { 6, "ofdmrate", "ofdmrate", "OFDM illegal rate" }, +#define S_RX_PHY_OFDM_POWER_DROP AFTER(S_RX_PHY_OFDM_RATE_ILLEGAL) + { 6, "ofdmpow", "ofdmpow", "OFDM power drop" }, +#define S_RX_PHY_OFDM_SERVICE AFTER(S_RX_PHY_OFDM_POWER_DROP) + { 6, "ofdmservice", "ofdmservice", "OFDM illegal service" }, +#define S_RX_PHY_OFDM_RESTART AFTER(S_RX_PHY_OFDM_SERVICE) + { 6, "ofdmrestart", "ofdmrestart", "OFDM restart" }, +#define S_RX_PHY_CCK_TIMING AFTER(S_RX_PHY_OFDM_RESTART) + { 6, "ccktim", "ccktim", "CCK timing" }, +#define S_RX_PHY_CCK_HEADER_CRC AFTER(S_RX_PHY_CCK_TIMING) + { 6, "cckhead", "cckhead", "CCK header crc" }, +#define S_RX_PHY_CCK_RATE_ILLEGAL AFTER(S_RX_PHY_CCK_HEADER_CRC) + { 6, "cckrate", "cckrate", "CCK illegal rate" }, +#define S_RX_PHY_CCK_SERVICE AFTER(S_RX_PHY_CCK_RATE_ILLEGAL) + { 6, "cckservice", "cckservice", "CCK illegal service" }, +#define S_RX_PHY_CCK_RESTART AFTER(S_RX_PHY_CCK_SERVICE) + { 6, "cckrestar", "cckrestar", "CCK restart" }, +#define S_BE_NOMBUF AFTER(S_RX_PHY_CCK_RESTART) + { 4, "benombuf", "benombuf", "beacon setup failed 'cuz no mbuf" }, +#define S_BE_XMIT AFTER(S_BE_NOMBUF) + { 7, "bexmit", "bexmit", "beacons transmitted" }, +#define S_PER_CAL AFTER(S_BE_XMIT) + { 4, "pcal", "pcal", "periodic calibrations" }, +#define S_PER_CALFAIL AFTER(S_PER_CAL) + { 4, "pcalf", "pcalf", "periodic calibration failures" }, +#define S_PER_RFGAIN AFTER(S_PER_CALFAIL) + { 4, "prfga", "prfga", "rfgain value change" }, +#if ATH_SUPPORT_TDMA +#define S_TDMA_UPDATE AFTER(S_PER_RFGAIN) + { 5, "tdmau", "tdmau", "TDMA slot timing updates" }, +#define S_TDMA_TIMERS AFTER(S_TDMA_UPDATE) + { 5, "tdmab", "tdmab", "TDMA slot update set beacon timers" }, +#define S_TDMA_TSF AFTER(S_TDMA_TIMERS) + { 5, "tdmat", "tdmat", "TDMA slot update set TSF" }, +#define S_TDMA_TSFADJ AFTER(S_TDMA_TSF) + { 8, "tdmadj", "tdmadj", "TDMA slot adjust (usecs, smoothed)" }, +#define S_TDMA_ACK AFTER(S_TDMA_TSFADJ) + { 5, "tdmack", "tdmack", "TDMA tx failed 'cuz ACK required" }, +#define S_RATE_CALLS AFTER(S_TDMA_ACK) +#else +#define S_RATE_CALLS AFTER(S_PER_RFGAIN) +#endif + { 5, "ratec", "ratec", "rate control checks" }, +#define S_RATE_RAISE AFTER(S_RATE_CALLS) + { 5, "rate+", "rate+", "rate control raised xmit rate" }, +#define S_RATE_DROP AFTER(S_RATE_RAISE) + { 5, "rate-", "rate-", "rate control dropped xmit rate" }, +#define S_TX_RSSI AFTER(S_RATE_DROP) + { 4, "arssi", "arssi", "rssi of last ack" }, +#define S_RX_RSSI AFTER(S_TX_RSSI) + { 4, "rssi", "rssi", "avg recv rssi" }, +#define S_RX_NOISE AFTER(S_RX_RSSI) + { 5, "noise", "noise", "rx noise floor" }, +#define S_BMISS_PHANTOM AFTER(S_RX_NOISE) + { 5, "bmissphantom", "bmissphantom", "phantom beacon misses" }, +#define S_TX_RAW AFTER(S_BMISS_PHANTOM) + { 5, "txraw", "txraw", "tx frames through raw api" }, +#define S_TX_RAW_FAIL AFTER(S_TX_RAW) + { 5, "txrawfail", "txrawfail", "raw tx failed 'cuz interface/hw down" }, +#define S_RX_TOOBIG AFTER(S_TX_RAW_FAIL) + { 5, "rx2big", "rx2big", "rx failed 'cuz frame too large" }, +#define S_RX_AGG AFTER(S_RX_TOOBIG) + { 5, "rxagg", "rxagg", "A-MPDU sub-frames received" }, +#define S_RX_HALFGI AFTER(S_RX_AGG) + { 5, "rxhalfgi", "rxhgi", "Half-GI frames received" }, +#define S_RX_2040 AFTER(S_RX_HALFGI) + { 6, "rx2040", "rx2040", "40MHz frames received" }, +#define S_RX_PRE_CRC_ERR AFTER(S_RX_2040) + { 11, "rxprecrcerr", "rxprecrcerr", "CRC errors for non-last A-MPDU subframes" }, +#define S_RX_POST_CRC_ERR AFTER(S_RX_PRE_CRC_ERR) + { 12, "rxpostcrcerr", "rxpostcrcerr", "CRC errors for last subframe in an A-MPDU" }, +#define S_RX_DECRYPT_BUSY_ERR AFTER(S_RX_POST_CRC_ERR) + { 10, "rxdescbusy", "rxdescbusy", "Decryption engine busy" }, +#define S_RX_HI_CHAIN AFTER(S_RX_DECRYPT_BUSY_ERR) + { 4, "rxhi", "rxhi", "Frames received with RX chain in high power mode" }, +#define S_TX_HTPROTECT AFTER(S_RX_HI_CHAIN) + { 7, "txhtprot", "txhtprot", "Frames transmitted with HT Protection" }, +#define S_RX_QEND AFTER(S_TX_HTPROTECT) + { 7, "rxquend", "rxquend", "Hit end of RX descriptor queue" }, +#define S_TX_TIMEOUT AFTER(S_RX_QEND) + { 4, "txtimeout", "TXTX", "TX Timeout" }, +#define S_TX_CSTIMEOUT AFTER(S_TX_TIMEOUT) + { 4, "csttimeout", "CSTX", "Carrier Sense Timeout" }, +#define S_TX_XTXOP_ERR AFTER(S_TX_CSTIMEOUT) + { 5, "xtxoperr", "TXOPX", "TXOP exceed" }, +#define S_TX_TIMEREXPIRED_ERR AFTER(S_TX_XTXOP_ERR) + { 7, "texperr", "texperr", "TX Timer expired" }, +#define S_TX_DESCCFG_ERR AFTER(S_TX_TIMEREXPIRED_ERR) + { 10, "desccfgerr", "desccfgerr", "TX descriptor error" }, +#define S_TX_SWRETRIES AFTER(S_TX_DESCCFG_ERR) + { 9, "txswretry", "txswretry", "Number of frames retransmitted in software" }, +#define S_TX_SWRETRIES_MAX AFTER(S_TX_SWRETRIES) + { 7, "txswmax", "txswmax", "Number of frames exceeding software retry" }, +#define S_TX_DATA_UNDERRUN AFTER(S_TX_SWRETRIES_MAX) + { 5, "txdataunderrun", "TXDAU", "A-MPDU TX FIFO data underrun" }, +#define S_TX_DELIM_UNDERRUN AFTER(S_TX_DATA_UNDERRUN) + { 5, "txdelimunderrun", "TXDEU", "A-MPDU TX Delimiter underrun" }, +#define S_TX_AGGR_OK AFTER(S_TX_DELIM_UNDERRUN) + { 5, "txaggrok", "TXAOK", "A-MPDU sub-frame TX attempt success" }, +#define S_TX_AGGR_FAIL AFTER(S_TX_AGGR_OK) + { 4, "txaggrfail", "TXAF", "A-MPDU sub-frame TX attempt failures" }, +#define S_TX_AGGR_FAILALL AFTER(S_TX_AGGR_FAIL) + { 7, "txaggrfailall", "TXAFALL", "A-MPDU TX frame failures" }, +#ifndef __linux__ +#define S_CABQ_XMIT AFTER(S_TX_AGGR_FAILALL) + { 5, "cabxmit", "cabxmit", "cabq frames transmitted" }, +#define S_CABQ_BUSY AFTER(S_CABQ_XMIT) + { 5, "cabqbusy", "cabqbusy", "cabq xmit overflowed beacon interval" }, +#define S_TX_NODATA AFTER(S_CABQ_BUSY) + { 5, "txnodata", "txnodata", "tx discarded empty frame" }, +#define S_TX_BUSDMA AFTER(S_TX_NODATA) + { 5, "txbusdma", "txbusdma", "tx failed for dma resrcs" }, +#define S_RX_BUSDMA AFTER(S_TX_BUSDMA) + { 5, "rxbusdma", "rxbusdma", "rx setup failed for dma resrcs" }, +#define S_FF_TXOK AFTER(S_RX_BUSDMA) +#else +#define S_FF_TXOK AFTER(S_TX_AGGR_FAILALL) +#endif + { 5, "fftxok", "fftxok", "fast frames xmit successfully" }, +#define S_FF_TXERR AFTER(S_FF_TXOK) + { 5, "fftxerr", "fftxerr", "fast frames not xmit due to error" }, +#define S_FF_RX AFTER(S_FF_TXERR) + { 5, "ffrx", "ffrx", "fast frames received" }, +#define S_FF_FLUSH AFTER(S_FF_RX) + { 5, "ffflush", "ffflush", "fast frames flushed from staging q" }, +#define S_TX_QFULL AFTER(S_FF_FLUSH) + { 5, "txqfull", "txqfull", "tx discarded 'cuz queue is full" }, +#define S_ANT_DEFSWITCH AFTER(S_TX_QFULL) + { 5, "defsw", "defsw", "switched default/rx antenna" }, +#define S_ANT_TXSWITCH AFTER(S_ANT_DEFSWITCH) + { 5, "txsw", "txsw", "tx used alternate antenna" }, +#ifdef ATH_SUPPORT_ANI +#define S_ANI_NOISE AFTER(S_ANT_TXSWITCH) + { 2, "ni", "NI", "noise immunity level" }, +#define S_ANI_SPUR AFTER(S_ANI_NOISE) + { 2, "si", "SI", "spur immunity level" }, +#define S_ANI_STEP AFTER(S_ANI_SPUR) + { 2, "step", "ST", "first step level" }, +#define S_ANI_OFDM AFTER(S_ANI_STEP) + { 4, "owsd", "OWSD", "OFDM weak signal detect" }, +#define S_ANI_CCK AFTER(S_ANI_OFDM) + { 4, "cwst", "CWST", "CCK weak signal threshold" }, +#define S_ANI_MAXSPUR AFTER(S_ANI_CCK) + { 3, "maxsi","MSI", "max spur immunity level" }, +#define S_ANI_LISTEN AFTER(S_ANI_MAXSPUR) + { 6, "listen","LISTEN", "listen time" }, +#define S_ANI_NIUP AFTER(S_ANI_LISTEN) + { 4, "ni+", "NI-", "ANI increased noise immunity" }, +#define S_ANI_NIDOWN AFTER(S_ANI_NIUP) + { 4, "ni-", "NI-", "ANI decrease noise immunity" }, +#define S_ANI_SIUP AFTER(S_ANI_NIDOWN) + { 4, "si+", "SI+", "ANI increased spur immunity" }, +#define S_ANI_SIDOWN AFTER(S_ANI_SIUP) + { 4, "si-", "SI-", "ANI decrease spur immunity" }, +#define S_ANI_OFDMON AFTER(S_ANI_SIDOWN) + { 5, "ofdm+","OFDM+", "ANI enabled OFDM weak signal detect" }, +#define S_ANI_OFDMOFF AFTER(S_ANI_OFDMON) + { 5, "ofdm-","OFDM-", "ANI disabled OFDM weak signal detect" }, +#define S_ANI_CCKHI AFTER(S_ANI_OFDMOFF) + { 5, "cck+", "CCK+", "ANI enabled CCK weak signal threshold" }, +#define S_ANI_CCKLO AFTER(S_ANI_CCKHI) + { 5, "cck-", "CCK-", "ANI disabled CCK weak signal threshold" }, +#define S_ANI_STEPUP AFTER(S_ANI_CCKLO) + { 5, "step+","STEP+", "ANI increased first step level" }, +#define S_ANI_STEPDOWN AFTER(S_ANI_STEPUP) + { 5, "step-","STEP-", "ANI decreased first step level" }, +#define S_ANI_OFDMERRS AFTER(S_ANI_STEPDOWN) + { 8, "ofdm", "OFDM", "cumulative OFDM phy error count" }, +#define S_ANI_CCKERRS AFTER(S_ANI_OFDMERRS) + { 8, "cck", "CCK", "cumulative CCK phy error count" }, +#define S_ANI_RESET AFTER(S_ANI_CCKERRS) + { 5, "reset","RESET", "ANI parameters zero'd for non-STA operation" }, +#define S_ANI_LZERO AFTER(S_ANI_RESET) + { 5, "lzero","LZERO", "ANI forced listen time to zero" }, +#define S_ANI_LNEG AFTER(S_ANI_LZERO) + { 5, "lneg", "LNEG", "ANI calculated listen time < 0" }, +#define S_MIB_ACKBAD AFTER(S_ANI_LNEG) + { 5, "ackbad","ACKBAD", "missing ACK's" }, +#define S_MIB_RTSBAD AFTER(S_MIB_ACKBAD) + { 5, "rtsbad","RTSBAD", "RTS without CTS" }, +#define S_MIB_RTSGOOD AFTER(S_MIB_RTSBAD) + { 5, "rtsgood","RTSGOOD", "successful RTS" }, +#define S_MIB_FCSBAD AFTER(S_MIB_RTSGOOD) + { 5, "fcsbad","FCSBAD", "bad FCS" }, +#define S_MIB_BEACONS AFTER(S_MIB_FCSBAD) + { 5, "beacons","beacons", "beacons received" }, +#define S_NODE_AVGBRSSI AFTER(S_MIB_BEACONS) + { 3, "avgbrssi","BSI", "average rssi (beacons only)" }, +#define S_NODE_AVGRSSI AFTER(S_NODE_AVGBRSSI) + { 3, "avgrssi","DSI", "average rssi (all rx'd frames)" }, +#define S_NODE_AVGARSSI AFTER(S_NODE_AVGRSSI) + { 3, "avgtxrssi","TSI", "average rssi (ACKs only)" }, +#define S_ANT_TX0 AFTER(S_NODE_AVGARSSI) +#else +#define S_ANT_TX0 AFTER(S_ANT_TXSWITCH) +#endif /* ATH_SUPPORT_ANI */ + { 8, "tx0", "ant0(tx)", "frames tx on antenna 0" }, +#define S_ANT_TX1 AFTER(S_ANT_TX0) + { 8, "tx1", "ant1(tx)", "frames tx on antenna 1" }, +#define S_ANT_TX2 AFTER(S_ANT_TX1) + { 8, "tx2", "ant2(tx)", "frames tx on antenna 2" }, +#define S_ANT_TX3 AFTER(S_ANT_TX2) + { 8, "tx3", "ant3(tx)", "frames tx on antenna 3" }, +#define S_ANT_TX4 AFTER(S_ANT_TX3) + { 8, "tx4", "ant4(tx)", "frames tx on antenna 4" }, +#define S_ANT_TX5 AFTER(S_ANT_TX4) + { 8, "tx5", "ant5(tx)", "frames tx on antenna 5" }, +#define S_ANT_TX6 AFTER(S_ANT_TX5) + { 8, "tx6", "ant6(tx)", "frames tx on antenna 6" }, +#define S_ANT_TX7 AFTER(S_ANT_TX6) + { 8, "tx7", "ant7(tx)", "frames tx on antenna 7" }, +#define S_ANT_RX0 AFTER(S_ANT_TX7) + { 8, "rx0", "ant0(rx)", "frames rx on antenna 0" }, +#define S_ANT_RX1 AFTER(S_ANT_RX0) + { 8, "rx1", "ant1(rx)", "frames rx on antenna 1" }, +#define S_ANT_RX2 AFTER(S_ANT_RX1) + { 8, "rx2", "ant2(rx)", "frames rx on antenna 2" }, +#define S_ANT_RX3 AFTER(S_ANT_RX2) + { 8, "rx3", "ant3(rx)", "frames rx on antenna 3" }, +#define S_ANT_RX4 AFTER(S_ANT_RX3) + { 8, "rx4", "ant4(rx)", "frames rx on antenna 4" }, +#define S_ANT_RX5 AFTER(S_ANT_RX4) + { 8, "rx5", "ant5(rx)", "frames rx on antenna 5" }, +#define S_ANT_RX6 AFTER(S_ANT_RX5) + { 8, "rx6", "ant6(rx)", "frames rx on antenna 6" }, +#define S_ANT_RX7 AFTER(S_ANT_RX6) + { 8, "rx7", "ant7(rx)", "frames rx on antenna 7" }, +#define S_TX_SIGNAL AFTER(S_ANT_RX7) + { 4, "asignal", "asig", "signal of last ack (dBm)" }, +#define S_RX_SIGNAL AFTER(S_TX_SIGNAL) + { 4, "signal", "sig", "avg recv signal (dBm)" }, + +}; +#define S_PHY_MIN S_RX_PHY_UNDERRUN +#define S_PHY_MAX S_RX_PHY_CCK_RESTART +#define S_LAST S_ANT_TX0 +#define S_MAX S_ANT_RX7+1 + +/* + * XXX fold this into the external HAL definitions! -adrian + */ +struct _athstats { + struct ath_stats ath; +#ifdef ATH_SUPPORT_ANI + struct { + uint32_t ast_ani_niup; /* increased noise immunity */ + uint32_t ast_ani_nidown; /* decreased noise immunity */ + uint32_t ast_ani_spurup; /* increased spur immunity */ + uint32_t ast_ani_spurdown; /* descreased spur immunity */ + uint32_t ast_ani_ofdmon; /* OFDM weak signal detect on */ + uint32_t ast_ani_ofdmoff; /* OFDM weak signal detect off*/ + uint32_t ast_ani_cckhigh; /* CCK weak signal thr high */ + uint32_t ast_ani_ccklow; /* CCK weak signal thr low */ + uint32_t ast_ani_stepup; /* increased first step level */ + uint32_t ast_ani_stepdown; /* decreased first step level */ + uint32_t ast_ani_ofdmerrs; /* cumulative ofdm phy err cnt*/ + uint32_t ast_ani_cckerrs; /* cumulative cck phy err cnt */ + uint32_t ast_ani_reset; /* params zero'd for non-STA */ + uint32_t ast_ani_lzero; /* listen time forced to zero */ + uint32_t ast_ani_lneg; /* listen time calculated < 0 */ + HAL_MIB_STATS ast_mibstats; /* MIB counter stats */ + HAL_NODE_STATS ast_nodestats; /* latest rssi stats */ + } ani_stats; + struct { + uint8_t noiseImmunityLevel; + uint8_t spurImmunityLevel; + uint8_t firstepLevel; + uint8_t ofdmWeakSigDetectOff; + uint8_t cckWeakSigThreshold; + uint32_t listenTime; + } ani_state; +#endif +}; + +struct athstatfoo_p { + struct athstatfoo base; + int s; + int optstats; +#define ATHSTATS_ANI 0x0001 + struct ifreq ifr; + struct ath_diag atd; + struct _athstats cur; + struct _athstats total; +}; + +static void +ath_setifname(struct athstatfoo *wf0, const char *ifname) +{ + struct athstatfoo_p *wf = (struct athstatfoo_p *) wf0; + + strncpy(wf->ifr.ifr_name, ifname, sizeof (wf->ifr.ifr_name)); +#ifdef ATH_SUPPORT_ANI + strncpy(wf->atd.ad_name, ifname, sizeof (wf->atd.ad_name)); + wf->optstats |= ATHSTATS_ANI; +#endif +} + +static void +ath_zerostats(struct athstatfoo *wf0) +{ + struct athstatfoo_p *wf = (struct athstatfoo_p *) wf0; + + if (ioctl(wf->s, SIOCZATHSTATS, &wf->ifr) < 0) + err(-1, wf->ifr.ifr_name); +} + +static void +ath_collect(struct athstatfoo_p *wf, struct _athstats *stats) +{ + wf->ifr.ifr_data = (caddr_t) &stats->ath; + if (ioctl(wf->s, SIOCGATHSTATS, &wf->ifr) < 0) + err(1, wf->ifr.ifr_name); +#ifdef ATH_SUPPORT_ANI + if (wf->optstats & ATHSTATS_ANI) { + wf->atd.ad_id = 5; + wf->atd.ad_out_data = (caddr_t) &stats->ani_state; + wf->atd.ad_out_size = sizeof(stats->ani_state); + if (ioctl(wf->s, SIOCGATHDIAG, &wf->atd) < 0) { + warn(wf->atd.ad_name); + wf->optstats &= ~ATHSTATS_ANI; + } + wf->atd.ad_id = 8; + wf->atd.ad_out_data = (caddr_t) &stats->ani_stats; + wf->atd.ad_out_size = sizeof(stats->ani_stats); + if (ioctl(wf->s, SIOCGATHDIAG, &wf->atd) < 0) + warn(wf->atd.ad_name); + } +#endif /* ATH_SUPPORT_ANI */ +} + +static void +ath_collect_cur(struct statfoo *sf) +{ + struct athstatfoo_p *wf = (struct athstatfoo_p *) sf; + + ath_collect(wf, &wf->cur); +} + +static void +ath_collect_tot(struct statfoo *sf) +{ + struct athstatfoo_p *wf = (struct athstatfoo_p *) sf; + + ath_collect(wf, &wf->total); +} + +static void +ath_update_tot(struct statfoo *sf) +{ + struct athstatfoo_p *wf = (struct athstatfoo_p *) sf; + + wf->total = wf->cur; +} + +static void +snprintrate(char b[], size_t bs, int rate) +{ + if (rate & IEEE80211_RATE_MCS) + snprintf(b, bs, "MCS%u", rate &~ IEEE80211_RATE_MCS); + else if (rate & 1) + snprintf(b, bs, "%u.5M", rate / 2); + else + snprintf(b, bs, "%uM", rate / 2); +} + +static int +ath_get_curstat(struct statfoo *sf, int s, char b[], size_t bs) +{ + struct athstatfoo_p *wf = (struct athstatfoo_p *) sf; +#define STAT(x) \ + snprintf(b, bs, "%u", wf->cur.ath.ast_##x - wf->total.ath.ast_##x); return 1 +#define PHY(x) \ + snprintf(b, bs, "%u", wf->cur.ath.ast_rx_phy[x] - wf->total.ath.ast_rx_phy[x]); return 1 +#define ANI(x) \ + snprintf(b, bs, "%u", wf->cur.ani_state.x); return 1 +#define ANISTAT(x) \ + snprintf(b, bs, "%u", wf->cur.ani_stats.ast_ani_##x - wf->total.ani_stats.ast_ani_##x); return 1 +#define MIBSTAT(x) \ + snprintf(b, bs, "%u", wf->cur.ani_stats.ast_mibstats.x - wf->total.ani_stats.ast_mibstats.x); return 1 +#define TXANT(x) \ + snprintf(b, bs, "%u", wf->cur.ath.ast_ant_tx[x] - wf->total.ath.ast_ant_tx[x]); return 1 +#define RXANT(x) \ + snprintf(b, bs, "%u", wf->cur.ath.ast_ant_rx[x] - wf->total.ath.ast_ant_rx[x]); return 1 + + switch (s) { + case S_INPUT: + snprintf(b, bs, "%lu", + (wf->cur.ath.ast_rx_packets - wf->total.ath.ast_rx_packets) - + (wf->cur.ath.ast_rx_mgt - wf->total.ath.ast_rx_mgt)); + return 1; + case S_OUTPUT: + snprintf(b, bs, "%lu", + wf->cur.ath.ast_tx_packets - wf->total.ath.ast_tx_packets); + return 1; + case S_RATE: + snprintrate(b, bs, wf->cur.ath.ast_tx_rate); + return 1; + case S_WATCHDOG: STAT(watchdog); + case S_FATAL: STAT(hardware); + case S_BMISS: STAT(bmiss); + case S_BMISS_PHANTOM: STAT(bmiss_phantom); +#ifdef S_BSTUCK + case S_BSTUCK: STAT(bstuck); +#endif + case S_RXORN: STAT(rxorn); + case S_RXEOL: STAT(rxeol); + case S_TXURN: STAT(txurn); + case S_MIB: STAT(mib); +#ifdef S_INTRCOAL + case S_INTRCOAL: STAT(intrcoal); +#endif + case S_TX_MGMT: STAT(tx_mgmt); + case S_TX_DISCARD: STAT(tx_discard); + case S_TX_QSTOP: STAT(tx_qstop); + case S_TX_ENCAP: STAT(tx_encap); + case S_TX_NONODE: STAT(tx_nonode); + case S_TX_NOBUF: STAT(tx_nobuf); + case S_TX_NOFRAG: STAT(tx_nofrag); + case S_TX_NOMBUF: STAT(tx_nombuf); +#ifdef S_TX_NOMCL + case S_TX_NOMCL: STAT(tx_nomcl); + case S_TX_LINEAR: STAT(tx_linear); + case S_TX_NODATA: STAT(tx_nodata); + case S_TX_BUSDMA: STAT(tx_busdma); +#endif + case S_TX_XRETRIES: STAT(tx_xretries); + case S_TX_FIFOERR: STAT(tx_fifoerr); + case S_TX_FILTERED: STAT(tx_filtered); + case S_TX_SHORTRETRY: STAT(tx_shortretry); + case S_TX_LONGRETRY: STAT(tx_longretry); + case S_TX_BADRATE: STAT(tx_badrate); + case S_TX_NOACK: STAT(tx_noack); + case S_TX_RTS: STAT(tx_rts); + case S_TX_CTS: STAT(tx_cts); + case S_TX_SHORTPRE: STAT(tx_shortpre); + case S_TX_ALTRATE: STAT(tx_altrate); + case S_TX_PROTECT: STAT(tx_protect); + case S_TX_RAW: STAT(tx_raw); + case S_TX_RAW_FAIL: STAT(tx_raw_fail); + case S_RX_NOMBUF: STAT(rx_nombuf); +#ifdef S_RX_BUSDMA + case S_RX_BUSDMA: STAT(rx_busdma); +#endif + case S_RX_ORN: STAT(rx_orn); + case S_RX_CRC_ERR: STAT(rx_crcerr); + case S_RX_FIFO_ERR: STAT(rx_fifoerr); + case S_RX_CRYPTO_ERR: STAT(rx_badcrypt); + case S_RX_MIC_ERR: STAT(rx_badmic); + case S_RX_PHY_ERR: STAT(rx_phyerr); + case S_RX_PHY_UNDERRUN: PHY(HAL_PHYERR_UNDERRUN); + case S_RX_PHY_TIMING: PHY(HAL_PHYERR_TIMING); + case S_RX_PHY_PARITY: PHY(HAL_PHYERR_PARITY); + case S_RX_PHY_RATE: PHY(HAL_PHYERR_RATE); + case S_RX_PHY_LENGTH: PHY(HAL_PHYERR_LENGTH); + case S_RX_PHY_RADAR: PHY(HAL_PHYERR_RADAR); + case S_RX_PHY_SERVICE: PHY(HAL_PHYERR_SERVICE); + case S_RX_PHY_TOR: PHY(HAL_PHYERR_TOR); + case S_RX_PHY_OFDM_TIMING: PHY(HAL_PHYERR_OFDM_TIMING); + case S_RX_PHY_OFDM_SIGNAL_PARITY: PHY(HAL_PHYERR_OFDM_SIGNAL_PARITY); + case S_RX_PHY_OFDM_RATE_ILLEGAL: PHY(HAL_PHYERR_OFDM_RATE_ILLEGAL); + case S_RX_PHY_OFDM_POWER_DROP: PHY(HAL_PHYERR_OFDM_POWER_DROP); + case S_RX_PHY_OFDM_SERVICE: PHY(HAL_PHYERR_OFDM_SERVICE); + case S_RX_PHY_OFDM_RESTART: PHY(HAL_PHYERR_OFDM_RESTART); + case S_RX_PHY_CCK_TIMING: PHY(HAL_PHYERR_CCK_TIMING); + case S_RX_PHY_CCK_HEADER_CRC: PHY(HAL_PHYERR_CCK_HEADER_CRC); + case S_RX_PHY_CCK_RATE_ILLEGAL: PHY(HAL_PHYERR_CCK_RATE_ILLEGAL); + case S_RX_PHY_CCK_SERVICE: PHY(HAL_PHYERR_CCK_SERVICE); + case S_RX_PHY_CCK_RESTART: PHY(HAL_PHYERR_CCK_RESTART); + case S_RX_TOOSHORT: STAT(rx_tooshort); + case S_RX_TOOBIG: STAT(rx_toobig); + case S_RX_MGT: STAT(rx_mgt); + case S_RX_CTL: STAT(rx_ctl); + case S_TX_RSSI: + snprintf(b, bs, "%d", wf->cur.ath.ast_tx_rssi); + return 1; + case S_RX_RSSI: + snprintf(b, bs, "%d", wf->cur.ath.ast_rx_rssi); + return 1; + case S_BE_XMIT: STAT(be_xmit); + case S_BE_NOMBUF: STAT(be_nombuf); + case S_PER_CAL: STAT(per_cal); + case S_PER_CALFAIL: STAT(per_calfail); + case S_PER_RFGAIN: STAT(per_rfgain); +#ifdef S_TDMA_UPDATE + case S_TDMA_UPDATE: STAT(tdma_update); + case S_TDMA_TIMERS: STAT(tdma_timers); + case S_TDMA_TSF: STAT(tdma_tsf); + case S_TDMA_TSFADJ: + snprintf(b, bs, "-%d/+%d", + wf->cur.ath.ast_tdma_tsfadjm, wf->cur.ath.ast_tdma_tsfadjp); + return 1; + case S_TDMA_ACK: STAT(tdma_ack); +#endif + case S_RATE_CALLS: STAT(rate_calls); + case S_RATE_RAISE: STAT(rate_raise); + case S_RATE_DROP: STAT(rate_drop); + case S_ANT_DEFSWITCH: STAT(ant_defswitch); + case S_ANT_TXSWITCH: STAT(ant_txswitch); +#ifdef S_ANI_NOISE + case S_ANI_NOISE: ANI(noiseImmunityLevel); + case S_ANI_SPUR: ANI(spurImmunityLevel); + case S_ANI_STEP: ANI(firstepLevel); + case S_ANI_OFDM: ANI(ofdmWeakSigDetectOff); + case S_ANI_CCK: ANI(cckWeakSigThreshold); + case S_ANI_LISTEN: ANI(listenTime); + case S_ANI_NIUP: ANISTAT(niup); + case S_ANI_NIDOWN: ANISTAT(nidown); + case S_ANI_SIUP: ANISTAT(spurup); + case S_ANI_SIDOWN: ANISTAT(spurdown); + case S_ANI_OFDMON: ANISTAT(ofdmon); + case S_ANI_OFDMOFF: ANISTAT(ofdmoff); + case S_ANI_CCKHI: ANISTAT(cckhigh); + case S_ANI_CCKLO: ANISTAT(ccklow); + case S_ANI_STEPUP: ANISTAT(stepup); + case S_ANI_STEPDOWN: ANISTAT(stepdown); + case S_ANI_OFDMERRS: ANISTAT(ofdmerrs); + case S_ANI_CCKERRS: ANISTAT(cckerrs); + case S_ANI_RESET: ANISTAT(reset); + case S_ANI_LZERO: ANISTAT(lzero); + case S_ANI_LNEG: ANISTAT(lneg); + case S_MIB_ACKBAD: MIBSTAT(ackrcv_bad); + case S_MIB_RTSBAD: MIBSTAT(rts_bad); + case S_MIB_RTSGOOD: MIBSTAT(rts_good); + case S_MIB_FCSBAD: MIBSTAT(fcs_bad); + case S_MIB_BEACONS: MIBSTAT(beacons); + case S_NODE_AVGBRSSI: + snprintf(b, bs, "%u", + HAL_RSSI(wf->cur.ani_stats.ast_nodestats.ns_avgbrssi)); + return 1; + case S_NODE_AVGRSSI: + snprintf(b, bs, "%u", + HAL_RSSI(wf->cur.ani_stats.ast_nodestats.ns_avgrssi)); + return 1; + case S_NODE_AVGARSSI: + snprintf(b, bs, "%u", + HAL_RSSI(wf->cur.ani_stats.ast_nodestats.ns_avgtxrssi)); + return 1; +#endif + case S_ANT_TX0: TXANT(0); + case S_ANT_TX1: TXANT(1); + case S_ANT_TX2: TXANT(2); + case S_ANT_TX3: TXANT(3); + case S_ANT_TX4: TXANT(4); + case S_ANT_TX5: TXANT(5); + case S_ANT_TX6: TXANT(6); + case S_ANT_TX7: TXANT(7); + case S_ANT_RX0: RXANT(0); + case S_ANT_RX1: RXANT(1); + case S_ANT_RX2: RXANT(2); + case S_ANT_RX3: RXANT(3); + case S_ANT_RX4: RXANT(4); + case S_ANT_RX5: RXANT(5); + case S_ANT_RX6: RXANT(6); + case S_ANT_RX7: RXANT(7); +#ifdef S_CABQ_XMIT + case S_CABQ_XMIT: STAT(cabq_xmit); + case S_CABQ_BUSY: STAT(cabq_busy); +#endif + case S_FF_TXOK: STAT(ff_txok); + case S_FF_TXERR: STAT(ff_txerr); + case S_FF_RX: STAT(ff_rx); + case S_FF_FLUSH: STAT(ff_flush); + case S_TX_QFULL: STAT(tx_qfull); + case S_RX_NOISE: + snprintf(b, bs, "%d", wf->cur.ath.ast_rx_noise); + return 1; + case S_TX_SIGNAL: + snprintf(b, bs, "%d", + wf->cur.ath.ast_tx_rssi + wf->cur.ath.ast_rx_noise); + return 1; + case S_RX_SIGNAL: + snprintf(b, bs, "%d", + wf->cur.ath.ast_rx_rssi + wf->cur.ath.ast_rx_noise); + return 1; + case S_RX_AGG: STAT(rx_agg); + case S_RX_HALFGI: STAT(rx_halfgi); + case S_RX_2040: STAT(rx_2040); + case S_RX_PRE_CRC_ERR: STAT(rx_pre_crc_err); + case S_RX_POST_CRC_ERR: STAT(rx_post_crc_err); + case S_RX_DECRYPT_BUSY_ERR: STAT(rx_decrypt_busy_err); + case S_RX_HI_CHAIN: STAT(rx_hi_rx_chain); + case S_TX_HTPROTECT: STAT(tx_htprotect); + case S_RX_QEND: STAT(rx_hitqueueend); + case S_TX_TIMEOUT: STAT(tx_timeout); + case S_TX_CSTIMEOUT: STAT(tx_cst); + case S_TX_XTXOP_ERR: STAT(tx_xtxop); + case S_TX_TIMEREXPIRED_ERR: STAT(tx_timerexpired); + case S_TX_DESCCFG_ERR: STAT(tx_desccfgerr); + case S_TX_SWRETRIES: STAT(tx_swretries); + case S_TX_SWRETRIES_MAX: STAT(tx_swretrymax); + case S_TX_DATA_UNDERRUN: STAT(tx_data_underrun); + case S_TX_DELIM_UNDERRUN: STAT(tx_delim_underrun); + case S_TX_AGGR_OK: STAT(tx_aggr_ok); + case S_TX_AGGR_FAIL: STAT(tx_aggr_fail); + case S_TX_AGGR_FAILALL: STAT(tx_aggr_failall); + } + b[0] = '\0'; + return 0; +#undef RXANT +#undef TXANT +#undef ANI +#undef ANISTAT +#undef MIBSTAT +#undef PHY +#undef STAT +} + +static int +ath_get_totstat(struct statfoo *sf, int s, char b[], size_t bs) +{ + struct athstatfoo_p *wf = (struct athstatfoo_p *) sf; +#define STAT(x) \ + snprintf(b, bs, "%u", wf->total.ath.ast_##x); return 1 +#define PHY(x) \ + snprintf(b, bs, "%u", wf->total.ath.ast_rx_phy[x]); return 1 +#define ANI(x) \ + snprintf(b, bs, "%u", wf->total.ani_state.x); return 1 +#define ANISTAT(x) \ + snprintf(b, bs, "%u", wf->total.ani_stats.ast_ani_##x); return 1 +#define MIBSTAT(x) \ + snprintf(b, bs, "%u", wf->total.ani_stats.ast_mibstats.x); return 1 +#define TXANT(x) \ + snprintf(b, bs, "%u", wf->total.ath.ast_ant_tx[x]); return 1 +#define RXANT(x) \ + snprintf(b, bs, "%u", wf->total.ath.ast_ant_rx[x]); return 1 + + switch (s) { + case S_INPUT: + snprintf(b, bs, "%lu", + wf->total.ath.ast_rx_packets - wf->total.ath.ast_rx_mgt); + return 1; + case S_OUTPUT: + snprintf(b, bs, "%lu", wf->total.ath.ast_tx_packets); + return 1; + case S_RATE: + snprintrate(b, bs, wf->total.ath.ast_tx_rate); + return 1; + case S_WATCHDOG: STAT(watchdog); + case S_FATAL: STAT(hardware); + case S_BMISS: STAT(bmiss); + case S_BMISS_PHANTOM: STAT(bmiss_phantom); +#ifdef S_BSTUCK + case S_BSTUCK: STAT(bstuck); +#endif + case S_RXORN: STAT(rxorn); + case S_RXEOL: STAT(rxeol); + case S_TXURN: STAT(txurn); + case S_MIB: STAT(mib); +#ifdef S_INTRCOAL + case S_INTRCOAL: STAT(intrcoal); +#endif + case S_TX_MGMT: STAT(tx_mgmt); + case S_TX_DISCARD: STAT(tx_discard); + case S_TX_QSTOP: STAT(tx_qstop); + case S_TX_ENCAP: STAT(tx_encap); + case S_TX_NONODE: STAT(tx_nonode); + case S_TX_NOBUF: STAT(tx_nobuf); + case S_TX_NOFRAG: STAT(tx_nofrag); + case S_TX_NOMBUF: STAT(tx_nombuf); +#ifdef S_TX_NOMCL + case S_TX_NOMCL: STAT(tx_nomcl); + case S_TX_LINEAR: STAT(tx_linear); + case S_TX_NODATA: STAT(tx_nodata); + case S_TX_BUSDMA: STAT(tx_busdma); +#endif + case S_TX_XRETRIES: STAT(tx_xretries); + case S_TX_FIFOERR: STAT(tx_fifoerr); + case S_TX_FILTERED: STAT(tx_filtered); + case S_TX_SHORTRETRY: STAT(tx_shortretry); + case S_TX_LONGRETRY: STAT(tx_longretry); + case S_TX_BADRATE: STAT(tx_badrate); + case S_TX_NOACK: STAT(tx_noack); + case S_TX_RTS: STAT(tx_rts); + case S_TX_CTS: STAT(tx_cts); + case S_TX_SHORTPRE: STAT(tx_shortpre); + case S_TX_ALTRATE: STAT(tx_altrate); + case S_TX_PROTECT: STAT(tx_protect); + case S_TX_RAW: STAT(tx_raw); + case S_TX_RAW_FAIL: STAT(tx_raw_fail); + case S_RX_NOMBUF: STAT(rx_nombuf); +#ifdef S_RX_BUSDMA + case S_RX_BUSDMA: STAT(rx_busdma); +#endif + case S_RX_ORN: STAT(rx_orn); + case S_RX_CRC_ERR: STAT(rx_crcerr); + case S_RX_FIFO_ERR: STAT(rx_fifoerr); + case S_RX_CRYPTO_ERR: STAT(rx_badcrypt); + case S_RX_MIC_ERR: STAT(rx_badmic); + case S_RX_PHY_ERR: STAT(rx_phyerr); + case S_RX_PHY_UNDERRUN: PHY(HAL_PHYERR_UNDERRUN); + case S_RX_PHY_TIMING: PHY(HAL_PHYERR_TIMING); + case S_RX_PHY_PARITY: PHY(HAL_PHYERR_PARITY); + case S_RX_PHY_RATE: PHY(HAL_PHYERR_RATE); + case S_RX_PHY_LENGTH: PHY(HAL_PHYERR_LENGTH); + case S_RX_PHY_RADAR: PHY(HAL_PHYERR_RADAR); + case S_RX_PHY_SERVICE: PHY(HAL_PHYERR_SERVICE); + case S_RX_PHY_TOR: PHY(HAL_PHYERR_TOR); + case S_RX_PHY_OFDM_TIMING: PHY(HAL_PHYERR_OFDM_TIMING); + case S_RX_PHY_OFDM_SIGNAL_PARITY: PHY(HAL_PHYERR_OFDM_SIGNAL_PARITY); + case S_RX_PHY_OFDM_RATE_ILLEGAL: PHY(HAL_PHYERR_OFDM_RATE_ILLEGAL); + case S_RX_PHY_OFDM_POWER_DROP: PHY(HAL_PHYERR_OFDM_POWER_DROP); + case S_RX_PHY_OFDM_SERVICE: PHY(HAL_PHYERR_OFDM_SERVICE); + case S_RX_PHY_OFDM_RESTART: PHY(HAL_PHYERR_OFDM_RESTART); + case S_RX_PHY_CCK_TIMING: PHY(HAL_PHYERR_CCK_TIMING); + case S_RX_PHY_CCK_HEADER_CRC: PHY(HAL_PHYERR_CCK_HEADER_CRC); + case S_RX_PHY_CCK_RATE_ILLEGAL: PHY(HAL_PHYERR_CCK_RATE_ILLEGAL); + case S_RX_PHY_CCK_SERVICE: PHY(HAL_PHYERR_CCK_SERVICE); + case S_RX_PHY_CCK_RESTART: PHY(HAL_PHYERR_CCK_RESTART); + case S_RX_TOOSHORT: STAT(rx_tooshort); + case S_RX_TOOBIG: STAT(rx_toobig); + case S_RX_MGT: STAT(rx_mgt); + case S_RX_CTL: STAT(rx_ctl); + case S_TX_RSSI: + snprintf(b, bs, "%d", wf->total.ath.ast_tx_rssi); + return 1; + case S_RX_RSSI: + snprintf(b, bs, "%d", wf->total.ath.ast_rx_rssi); + return 1; + case S_BE_XMIT: STAT(be_xmit); + case S_BE_NOMBUF: STAT(be_nombuf); + case S_PER_CAL: STAT(per_cal); + case S_PER_CALFAIL: STAT(per_calfail); + case S_PER_RFGAIN: STAT(per_rfgain); +#ifdef S_TDMA_UPDATE + case S_TDMA_UPDATE: STAT(tdma_update); + case S_TDMA_TIMERS: STAT(tdma_timers); + case S_TDMA_TSF: STAT(tdma_tsf); + case S_TDMA_TSFADJ: + snprintf(b, bs, "-%d/+%d", + wf->total.ath.ast_tdma_tsfadjm, + wf->total.ath.ast_tdma_tsfadjp); + return 1; + case S_TDMA_ACK: STAT(tdma_ack); +#endif + case S_RATE_CALLS: STAT(rate_calls); + case S_RATE_RAISE: STAT(rate_raise); + case S_RATE_DROP: STAT(rate_drop); + case S_ANT_DEFSWITCH: STAT(ant_defswitch); + case S_ANT_TXSWITCH: STAT(ant_txswitch); +#ifdef S_ANI_NOISE + case S_ANI_NOISE: ANI(noiseImmunityLevel); + case S_ANI_SPUR: ANI(spurImmunityLevel); + case S_ANI_STEP: ANI(firstepLevel); + case S_ANI_OFDM: ANI(ofdmWeakSigDetectOff); + case S_ANI_CCK: ANI(cckWeakSigThreshold); + case S_ANI_LISTEN: ANI(listenTime); + case S_ANI_NIUP: ANISTAT(niup); + case S_ANI_NIDOWN: ANISTAT(nidown); + case S_ANI_SIUP: ANISTAT(spurup); + case S_ANI_SIDOWN: ANISTAT(spurdown); + case S_ANI_OFDMON: ANISTAT(ofdmon); + case S_ANI_OFDMOFF: ANISTAT(ofdmoff); + case S_ANI_CCKHI: ANISTAT(cckhigh); + case S_ANI_CCKLO: ANISTAT(ccklow); + case S_ANI_STEPUP: ANISTAT(stepup); + case S_ANI_STEPDOWN: ANISTAT(stepdown); + case S_ANI_OFDMERRS: ANISTAT(ofdmerrs); + case S_ANI_CCKERRS: ANISTAT(cckerrs); + case S_ANI_RESET: ANISTAT(reset); + case S_ANI_LZERO: ANISTAT(lzero); + case S_ANI_LNEG: ANISTAT(lneg); + case S_MIB_ACKBAD: MIBSTAT(ackrcv_bad); + case S_MIB_RTSBAD: MIBSTAT(rts_bad); + case S_MIB_RTSGOOD: MIBSTAT(rts_good); + case S_MIB_FCSBAD: MIBSTAT(fcs_bad); + case S_MIB_BEACONS: MIBSTAT(beacons); + case S_NODE_AVGBRSSI: + snprintf(b, bs, "%u", + HAL_RSSI(wf->total.ani_stats.ast_nodestats.ns_avgbrssi)); + return 1; + case S_NODE_AVGRSSI: + snprintf(b, bs, "%u", + HAL_RSSI(wf->total.ani_stats.ast_nodestats.ns_avgrssi)); + return 1; + case S_NODE_AVGARSSI: + snprintf(b, bs, "%u", + HAL_RSSI(wf->total.ani_stats.ast_nodestats.ns_avgtxrssi)); + return 1; +#endif + case S_ANT_TX0: TXANT(0); + case S_ANT_TX1: TXANT(1); + case S_ANT_TX2: TXANT(2); + case S_ANT_TX3: TXANT(3); + case S_ANT_TX4: TXANT(4); + case S_ANT_TX5: TXANT(5); + case S_ANT_TX6: TXANT(6); + case S_ANT_TX7: TXANT(7); + case S_ANT_RX0: RXANT(0); + case S_ANT_RX1: RXANT(1); + case S_ANT_RX2: RXANT(2); + case S_ANT_RX3: RXANT(3); + case S_ANT_RX4: RXANT(4); + case S_ANT_RX5: RXANT(5); + case S_ANT_RX6: RXANT(6); + case S_ANT_RX7: RXANT(7); +#ifdef S_CABQ_XMIT + case S_CABQ_XMIT: STAT(cabq_xmit); + case S_CABQ_BUSY: STAT(cabq_busy); +#endif + case S_FF_TXOK: STAT(ff_txok); + case S_FF_TXERR: STAT(ff_txerr); + case S_FF_RX: STAT(ff_rx); + case S_FF_FLUSH: STAT(ff_flush); + case S_TX_QFULL: STAT(tx_qfull); + case S_RX_NOISE: + snprintf(b, bs, "%d", wf->total.ath.ast_rx_noise); + return 1; + case S_TX_SIGNAL: + snprintf(b, bs, "%d", + wf->total.ath.ast_tx_rssi + wf->total.ath.ast_rx_noise); + return 1; + case S_RX_SIGNAL: + snprintf(b, bs, "%d", + wf->total.ath.ast_rx_rssi + wf->total.ath.ast_rx_noise); + return 1; + case S_RX_AGG: STAT(rx_agg); + case S_RX_HALFGI: STAT(rx_halfgi); + case S_RX_2040: STAT(rx_2040); + case S_RX_PRE_CRC_ERR: STAT(rx_pre_crc_err); + case S_RX_POST_CRC_ERR: STAT(rx_post_crc_err); + case S_RX_DECRYPT_BUSY_ERR: STAT(rx_decrypt_busy_err); + case S_RX_HI_CHAIN: STAT(rx_hi_rx_chain); + case S_TX_HTPROTECT: STAT(tx_htprotect); + case S_RX_QEND: STAT(rx_hitqueueend); + case S_TX_TIMEOUT: STAT(tx_timeout); + case S_TX_CSTIMEOUT: STAT(tx_cst); + case S_TX_XTXOP_ERR: STAT(tx_xtxop); + case S_TX_TIMEREXPIRED_ERR: STAT(tx_timerexpired); + case S_TX_DESCCFG_ERR: STAT(tx_desccfgerr); + case S_TX_SWRETRIES: STAT(tx_swretries); + case S_TX_SWRETRIES_MAX: STAT(tx_swretrymax); + case S_TX_DATA_UNDERRUN: STAT(tx_data_underrun); + case S_TX_DELIM_UNDERRUN: STAT(tx_delim_underrun); + case S_TX_AGGR_OK: STAT(tx_aggr_ok); + case S_TX_AGGR_FAIL: STAT(tx_aggr_fail); + case S_TX_AGGR_FAILALL: STAT(tx_aggr_failall); + } + b[0] = '\0'; + return 0; +#undef RXANT +#undef TXANT +#undef ANI +#undef ANISTAT +#undef MIBSTAT +#undef PHY +#undef STAT +} + +static void +ath_print_verbose(struct statfoo *sf, FILE *fd) +{ + struct athstatfoo_p *wf = (struct athstatfoo_p *) sf; +#define isphyerr(i) (S_PHY_MIN <= i && i <= S_PHY_MAX) + const struct fmt *f; + char s[32]; + const char *indent; + int i, width; + + width = 0; + for (i = 0; i < S_LAST; i++) { + f = &sf->stats[i]; + if (!isphyerr(i) && f->width > width) + width = f->width; + } + for (i = 0; i < S_LAST; i++) { + if (ath_get_totstat(sf, i, s, sizeof(s)) && strcmp(s, "0")) { + if (isphyerr(i)) + indent = " "; + else + indent = ""; + fprintf(fd, "%s%-*s %s\n", indent, width, s, athstats[i].desc); + } + } + fprintf(fd, "Antenna profile:\n"); + for (i = 0; i < 8; i++) + if (wf->total.ath.ast_ant_rx[i] || wf->total.ath.ast_ant_tx[i]) + fprintf(fd, "[%u] tx %8u rx %8u\n", i, + wf->total.ath.ast_ant_tx[i], + wf->total.ath.ast_ant_rx[i]); +#undef isphyerr +} + +STATFOO_DEFINE_BOUNCE(athstatfoo) + +struct athstatfoo * +athstats_new(const char *ifname, const char *fmtstring) +{ +#define N(a) (sizeof(a) / sizeof(a[0])) + struct athstatfoo_p *wf; + + wf = calloc(1, sizeof(struct athstatfoo_p)); + if (wf != NULL) { + statfoo_init(&wf->base.base, "athstats", athstats, N(athstats)); + /* override base methods */ + wf->base.base.collect_cur = ath_collect_cur; + wf->base.base.collect_tot = ath_collect_tot; + wf->base.base.get_curstat = ath_get_curstat; + wf->base.base.get_totstat = ath_get_totstat; + wf->base.base.update_tot = ath_update_tot; + wf->base.base.print_verbose = ath_print_verbose; + + /* setup bounce functions for public methods */ + STATFOO_BOUNCE(wf, athstatfoo); + + /* setup our public methods */ + wf->base.setifname = ath_setifname; +#if 0 + wf->base.setstamac = wlan_setstamac; +#endif + wf->base.zerostats = ath_zerostats; + wf->s = socket(AF_INET, SOCK_DGRAM, 0); + if (wf->s < 0) + err(1, "socket"); + + ath_setifname(&wf->base, ifname); + wf->base.setfmt(&wf->base, fmtstring); + } + return &wf->base; +#undef N +} diff --git a/tools/tools/ath/athstats/athstats.h b/tools/tools/ath/athstats/athstats.h new file mode 100644 index 000000000000..cfd44ca7fb1b --- /dev/null +++ b/tools/tools/ath/athstats/athstats.h @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 2002-2007 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$ + */ + +#ifndef _ATHSTATS_H_ +#define _ATHSTATS_H_ + +#include "statfoo.h" + +/* + * ath statistics class. + */ +struct athstatfoo { + struct statfoo base; + + STATFOO_DECL_METHODS(struct athstatfoo *); + + /* set the network interface name for collection */ + void (*setifname)(struct athstatfoo *, const char *ifname); + /* set the mac address of the associated station/ap */ + void (*setstamac)(struct athstatfoo *, const uint8_t mac[]); + /* zero in-kernel statistics */ + void (*zerostats)(struct athstatfoo *); +}; + +struct athstatfoo *athstats_new(const char *ifname, const char *fmtstring); +#endif /* _ATHSTATS_H_ */ diff --git a/tools/tools/ath/athstats/main.c b/tools/tools/ath/athstats/main.c new file mode 100644 index 000000000000..489c0bd796f6 --- /dev/null +++ b/tools/tools/ath/athstats/main.c @@ -0,0 +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 <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <unistd.h> +#include <string.h> +#include <err.h> + +#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) +{ +#define N(a) (sizeof(a)/sizeof(a[0])) + int i; + for (i = 0; i < N(tags); i++) + if (strcasecmp(tags[i].tag, tag) == 0) + return tags[i].fmt; + return tag; +#undef N +} + +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"; + 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; +} diff --git a/tools/tools/ath/athstats/statfoo.c b/tools/tools/ath/athstats/statfoo.c new file mode 100644 index 000000000000..eb39e25bbab8 --- /dev/null +++ b/tools/tools/ath/athstats/statfoo.c @@ -0,0 +1,206 @@ +/*- + * Copyright (c) 2002-2007 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$ + */ + +#include <stdio.h> +#include <string.h> + +#include "statfoo.h" + +static void +statfoo_setfmt(struct statfoo *sf, const char *fmt0) +{ +#define N(a) (sizeof(a)/sizeof(a[0])) + char fmt[4096]; + char *fp, *tok; + int i, j; + + j = 0; + strlcpy(fmt, fmt0, sizeof(fmt)); + for (fp = fmt; (tok = strsep(&fp, ", ")) != NULL;) { + for (i = 0; i < sf->nstats; i++) + if (strcasecmp(tok, sf->stats[i].name) == 0) + break; + if (i >= sf->nstats) { + fprintf(stderr, "%s: unknown statistic name \"%s\" " + "skipped\n", sf->name, tok); + continue; + } + if (j+3 > sizeof(sf->fmts)) { + fprintf(stderr, "%s: not enough room for all stats; " + "stopped at %s\n", sf->name, tok); + break; + } + if (j != 0) + sf->fmts[j++] = ' '; + sf->fmts[j++] = FMTS_IS_STAT; + sf->fmts[j++] = i & 0xff; + sf->fmts[j++] = (i >> 8) & 0xff; + } + sf->fmts[j] = '\0'; +#undef N +} + +static void +statfoo_collect(struct statfoo *sf) +{ + fprintf(stderr, "%s: don't know how to collect data\n", sf->name); +} + +static void +statfoo_update_tot(struct statfoo *sf) +{ + fprintf(stderr, "%s: don't know how to update total data\n", sf->name); +} + +static int +statfoo_get(struct statfoo *sf, int s, char b[], size_t bs) +{ + fprintf(stderr, "%s: don't know how to get stat #%u\n", sf->name, s); + return 0; +} + +static void +statfoo_print_header(struct statfoo *sf, FILE *fd) +{ + const unsigned char *cp; + int i; + const struct fmt *f; + + for (cp = sf->fmts; *cp != '\0'; cp++) { + if (*cp == FMTS_IS_STAT) { + i = *(++cp); + i |= ((int) *(++cp)) << 8; + f = &sf->stats[i]; + fprintf(fd, "%*s", f->width, f->label); + } else + putc(*cp, fd); + } + putc('\n', fd); +} + +static void +statfoo_print_current(struct statfoo *sf, FILE *fd) +{ + char buf[32]; + const unsigned char *cp; + int i; + const struct fmt *f; + + for (cp = sf->fmts; *cp != '\0'; cp++) { + if (*cp == FMTS_IS_STAT) { + i = *(++cp); + i |= ((int) *(++cp)) << 8; + f = &sf->stats[i]; + if (sf->get_curstat(sf, i, buf, sizeof(buf))) + fprintf(fd, "%*s", f->width, buf); + } else + putc(*cp, fd); + } + putc('\n', fd); +} + +static void +statfoo_print_total(struct statfoo *sf, FILE *fd) +{ + char buf[32]; + const unsigned char *cp; + const struct fmt *f; + int i; + + for (cp = sf->fmts; *cp != '\0'; cp++) { + if (*cp == FMTS_IS_STAT) { + i = *(++cp); + i |= ((int) *(++cp)) << 8; + f = &sf->stats[i]; + if (sf->get_totstat(sf, i, buf, sizeof(buf))) + fprintf(fd, "%*s", f->width, buf); + } else + putc(*cp, fd); + } + putc('\n', fd); +} + +static void +statfoo_print_verbose(struct statfoo *sf, FILE *fd) +{ + const struct fmt *f; + char s[32]; + int i, width; + + width = 0; + for (i = 0; i < sf->nstats; i++) { + f = &sf->stats[i]; + if (f->width > width) + width = f->width; + } + for (i = 0; i < sf->nstats; i++) { + f = &sf->stats[i]; + if (sf->get_totstat(sf, i, s, sizeof(s)) && strcmp(s, "0")) + fprintf(fd, "%-*s %s\n", width, s, f->desc); + } +} + +static void +statfoo_print_fields(struct statfoo *sf, FILE *fd) +{ + int i, w, width; + + width = 0; + for (i = 0; i < sf->nstats; i++) { + w = strlen(sf->stats[i].name); + if (w > width) + width = w; + } + for (i = 0; i < sf->nstats; i++) { + const struct fmt *f = &sf->stats[i]; + if (f->width != 0) + fprintf(fd, "%-*s %s\n", width, f->name, f->desc); + } +} + +void +statfoo_init(struct statfoo *sf, const char *name, const struct fmt *stats, int nstats) +{ + sf->name = name; + sf->stats = stats; + sf->nstats = nstats; + sf->setfmt = statfoo_setfmt; + sf->collect_cur = statfoo_collect; + sf->collect_tot = statfoo_collect; + sf->update_tot = statfoo_update_tot; + sf->get_curstat = statfoo_get; + sf->get_totstat = statfoo_get; + sf->print_header = statfoo_print_header; + sf->print_current = statfoo_print_current; + sf->print_total = statfoo_print_total; + sf->print_verbose = statfoo_print_verbose; + sf->print_fields = statfoo_print_fields; +} diff --git a/tools/tools/ath/athstats/statfoo.h b/tools/tools/ath/athstats/statfoo.h new file mode 100644 index 000000000000..849a271913cc --- /dev/null +++ b/tools/tools/ath/athstats/statfoo.h @@ -0,0 +1,128 @@ +/*- + * Copyright (c) 2002-2007 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$ + */ + +#ifndef _STATFOO_H_ +#define _STATFOO_H_ +/* + * Base class for managing+displaying periodically collected statistics. + */ + +/* + * Statistic definition/description. The are defined + * for stats that correspond 1-1 w/ a collected stat + * and for stats that are calculated indirectly. + */ +struct fmt { + int width; /* printed field width */ + const char* name; /* stat field name referenced by user */ + const char* label; /* printed header label */ + const char* desc; /* verbose description */ +}; + +#define STATFOO_DECL_METHODS(_p) \ + /* set the format of the statistics to display */ \ + void (*setfmt)(_p, const char *); \ + /* collect+store ``current statistics'' */ \ + void (*collect_cur)(_p); \ + /* collect+store ``total statistics'' */ \ + void (*collect_tot)(_p); \ + /* update ``total statistics'' if necessary from current */ \ + void (*update_tot)(_p); \ + /* format a statistic from the current stats */ \ + int (*get_curstat)(_p, int, char [], size_t); \ + /* format a statistic from the total stats */ \ + int (*get_totstat)(_p, int, char [], size_t); \ + /* print field headers terminated by a \n */ \ + void (*print_header)(_p, FILE *); \ + /* print current statistics terminated by a \n */ \ + void (*print_current)(_p, FILE *); \ + /* print total statistics terminated by a \n */ \ + void (*print_total)(_p, FILE *); \ + /* print total statistics in a verbose (1 stat/line) format */ \ + void (*print_verbose)(_p, FILE *); \ + /* print available statistics */ \ + void (*print_fields)(_p, FILE *) + +/* + * Statistics base class. This class is not usable; only + * classes derived from it are useful. + */ +struct statfoo { + const char *name; /* statistics name, e.g. wlanstats */ + const struct fmt *stats; /* statistics in class */ + int nstats; /* number of stats */ +#define FMTS_IS_STAT 0x80 /* the following two bytes are the stat id */ + unsigned char fmts[4096]; /* private: compiled stats to display */ + + STATFOO_DECL_METHODS(struct statfoo *); +}; + +void statfoo_init(struct statfoo *, const char *name, + const struct fmt *stats, int nstats); + +#define STATFOO_DEFINE_BOUNCE(_t) \ +static void _t##_setfmt(struct _t *wf, const char *fmt0) \ + { wf->base.setfmt(&wf->base, fmt0); } \ +static void _t##_collect_cur(struct _t *wf) \ + { wf->base.collect_cur(&wf->base); } \ +static void _t##_collect_tot(struct _t *wf) \ + { wf->base.collect_tot(&wf->base); } \ +static void _t##_update_tot(struct _t *wf) \ + { wf->base.update_tot(&wf->base); } \ +static int _t##_get_curstat(struct _t *wf, int s, char b[], size_t bs) \ + { return wf->base.get_curstat(&wf->base, s, b, bs); } \ +static int _t##_get_totstat(struct _t *wf, int s, char b[], size_t bs) \ + { return wf->base.get_totstat(&wf->base, s, b, bs); } \ +static void _t##_print_header(struct _t *wf, FILE *fd) \ + { wf->base.print_header(&wf->base, fd); } \ +static void _t##_print_current(struct _t *wf, FILE *fd) \ + { wf->base.print_current(&wf->base, fd); } \ +static void _t##_print_total(struct _t *wf, FILE *fd) \ + { wf->base.print_total(&wf->base, fd); } \ +static void _t##_print_verbose(struct _t *wf, FILE *fd) \ + { wf->base.print_verbose(&wf->base, fd); } \ +static void _t##_print_fields(struct _t *wf, FILE *fd) \ + { wf->base.print_fields(&wf->base, fd); } + +#define STATFOO_BOUNCE(_p, _t) do { \ + _p->base.setfmt = _t##_setfmt; \ + _p->base.collect_cur = _t##_collect_cur; \ + _p->base.collect_tot = _t##_collect_tot; \ + _p->base.update_tot = _t##_update_tot; \ + _p->base.get_curstat = _t##_get_curstat; \ + _p->base.get_totstat = _t##_get_totstat; \ + _p->base.print_header = _t##_print_header; \ + _p->base.print_current = _t##_print_current; \ + _p->base.print_total = _t##_print_total; \ + _p->base.print_verbose = _t##_print_verbose; \ + _p->base.print_fields = _t##_print_fields; \ +} while (0) +#endif /* _STATFOO_H_ */ diff --git a/tools/tools/ath/common/ah_osdep.h b/tools/tools/ath/common/ah_osdep.h new file mode 100644 index 000000000000..047811159a42 --- /dev/null +++ b/tools/tools/ath/common/ah_osdep.h @@ -0,0 +1,75 @@ +/*- + * Copyright (c) 2002-2008 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$ + */ +#ifndef _ATH_AH_OSDEP_H_ +#define _ATH_AH_OSDEP_H_ +/* + * Atheros Hardware Access Layer (HAL) OS Dependent Definitions. + */ +#include <sys/param.h> + +/* + * Bus i/o type definitions. + */ +typedef void *HAL_SOFTC; +typedef int HAL_BUS_TAG; +typedef void *HAL_BUS_HANDLE; + +#define OS_DELAY(_n) DELAY(_n) +#define OS_INLINE __inline +#define OS_MEMZERO(_a, _size) bzero((_a), (_size)) +#define OS_MEMCPY(_dst, _src, _size) bcopy((_src), (_dst), (_size)) +#define OS_MACEQU(_a, _b) \ + (bcmp((_a), (_b), IEEE80211_ADDR_LEN) == 0) + +struct ath_hal; +extern u_int32_t OS_GETUPTIME(struct ath_hal *); +extern void OS_REG_WRITE(struct ath_hal *, u_int32_t, u_int32_t); +extern u_int32_t OS_REG_READ(struct ath_hal *, u_int32_t); +extern void OS_MARK(struct ath_hal *, u_int id, u_int32_t value); +#define OS_GETUPTIME(_ah) 0 +#define OS_REG_WRITE(_ah, _reg, _val) +#define OS_REG_READ(_ah, _reg) 0 +#define OS_MARK(_ah, _id, _v) +#define __packed __attribute__((__packed__)) + +/* + * Linux/BSD gcc compatibility shims. + */ +#ifndef __printflike +#define __printflike(_a,_b) \ + __attribute__ ((__format__ (__printf__, _a, _b))) +#endif +#include <stdarg.h> +#ifndef __va_list +#define __va_list va_list +#endif +#define OS_INLINE __inline +#endif /* _ATH_AH_OSDEP_H_ */ diff --git a/tools/tools/ath/common/diag.h b/tools/tools/ath/common/diag.h new file mode 100644 index 000000000000..8c0c1a7f1c4b --- /dev/null +++ b/tools/tools/ath/common/diag.h @@ -0,0 +1,61 @@ +#ifndef _DIAG_ +#define _DIAG_ +/*- + * Copyright (c) 2002-2008 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$ + */ +#include <sys/types.h> +#include <sys/file.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <net/if.h> +#include <stdio.h> + +#include <net80211/ieee80211_radiotap.h> +#include "if_athioctl.h" + +struct statshandler { + u_long interval; + void *total; + void *cur; + + void (*getstats)(struct statshandler *, void *); + void (*update)(struct statshandler *); + + void (*printbanner)(struct statshandler *, FILE *); + void (*reportdelta)(struct statshandler *, FILE *); + void (*reporttotal)(struct statshandler *, FILE *); + void (*reportverbose)(struct statshandler *, FILE *); +}; + +extern void reportstats(FILE *fd, struct statshandler *sh); +extern void runstats(FILE *fd, struct statshandler *sh); +extern void reportcol(FILE *fd, u_int32_t v, const char *def_fmt, + u_int32_t max, const char *alt_fmt); +#endif /* _DIAG_ */ diff --git a/tools/tools/ath/common/dumpregs.h b/tools/tools/ath/common/dumpregs.h new file mode 100644 index 000000000000..88689cf766a3 --- /dev/null +++ b/tools/tools/ath/common/dumpregs.h @@ -0,0 +1,98 @@ +#ifndef _DUMPREGS_ +#define _DUMPREGS_ +/*- + * Copyright (c) 2002-2008 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$ + */ + +#define __constructor __attribute__((constructor)) + +struct dumpreg { + uint32_t addr; + const char *name; + const char *bits; + int type; + u_int srevMin, srevMax; + u_int phyMin, phyMax; +}; +#define SREV(v,r) (((v) << 16) | (r)) +#define MAC_MATCH(dr, mv, mr) \ + ((dr)->srevMin <= SREV(mv,mr) && SREV(mv,mr) < (dr)->srevMax) + +#define PHY_MATCH(dr, pr) \ + ((dr)->phyMin <= (pr) && (pr) < (dr)->phyMax) +#define PHYANY 0,0xffff + +enum { + DUMP_BASIC = 0x0001, /* basic/default registers */ + DUMP_KEYCACHE = 0x0002, /* key cache */ + DUMP_BASEBAND = 0x0004, /* baseband */ + DUMP_INTERRUPT = 0x0008, /* interrupt state */ + DUMP_XR = 0x0010, /* XR state */ + DUMP_QCU = 0x0020, /* QCU state */ + DUMP_DCU = 0x0040, /* DCU state */ + + DUMP_PUBLIC = 0x0061, /* public = BASIC+QCU+DCU */ + DUMP_ALL = 0xffff +}; + +#define _DEFREG(_addr, _name, _type) \ + { .addr = _addr, .name = _name, .type = _type } +#define _DEFREGx(_addr, _name, _type, _srevmin, _srevmax) \ + { .addr = _addr, .name = _name, .type = _type, \ + .srevMin = _srevmin, .srevMax = _srevmax } +#define _DEFREGfmt(_addr, _name, _type, _fmt) \ + { .addr = _addr, .name = _name, .type = _type, .bits = _fmt } +#define DEFVOID(_addr, _name) _DEFREG(_addr, _name, 0) +#define DEFVOIDx(_addr, _name, _smin, _smax) \ + __DEFREGx(_addr, _name, _smin, _smax, 0) +#define DEFVOIDfmt(_addr, _name, _fmt) \ + _DEFREGfmt(_addr, _name, 0, _fmt) +#define DEFBASIC(_addr, _name) _DEFREG(_addr, _name, DUMP_BASIC) +#define DEFBASICfmt(_addr, _name, _fmt) \ + _DEFREGfmt(_addr, _name, DUMP_BASIC, _fmt) +#define DEFBASICx(_addr, _name, _smin, _smax) \ + _DEFREGx(_addr, _name, DUMP_BASIC, _smin, _smax) +#define DEFBB(_addr, _name) _DEFREG(_addr, _name, DUMP_BASEBAND) +#define DEFINT(_addr, _name) _DEFREG(_addr, _name, DUMP_INTERRUPT) +#define DEFINTfmt(_addr, _name, _fmt) \ + _DEFREGfmt(_addr, _name, DUMP_INTERRUPT, _fmt) +#define DEFQCU(_addr, _name) _DEFREG(_addr, _name, DUMP_QCU) +#define DEFDCU(_addr, _name) _DEFREG(_addr, _name, DUMP_DCU) + +void register_regs(struct dumpreg *_regs, u_int _nregs, + int def_srev_min, int def_srev_max, + int def_phy_min, int def_phy_max); +void register_keycache(u_int nslots, + int def_srev_min, int def_srev_max, + int def_phy_min, int def_phy_max); +void register_range(u_int brange, u_int erange, int what, + int def_srev_min, int def_srev_max, + int def_phy_min, int def_phy_max); +#endif /* _DUMPREGS_ */ diff --git a/tools/tools/ath/common/dumpregs_5210.c b/tools/tools/ath/common/dumpregs_5210.c new file mode 100644 index 000000000000..f7b273b0ca38 --- /dev/null +++ b/tools/tools/ath/common/dumpregs_5210.c @@ -0,0 +1,125 @@ +/*- + * Copyright (c) 2002-2008 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$ + */ +#include "diag.h" + +#include "ah.h" +#include "ah_internal.h" +#include "ar5210/ar5210reg.h" +#include "ar5210/ar5210phy.h" + +#include "dumpregs.h" + +#define N(a) (sizeof(a) / sizeof(a[0])) + +static struct dumpreg ar5210regs[] = { + DEFBASIC(AR_TXDP0, "TXDP0"), + DEFBASIC(AR_TXDP1, "TXDP1"), + DEFBASICfmt(AR_CR, "CR", AR_CR_BITS), + DEFBASIC(AR_RXDP, "RXDP"), + DEFBASICfmt(AR_CFG, "CFG", AR_CFG_BITS), + /* NB: read clears pending interrupts */ + DEFVOIDfmt(AR_ISR, "ISR", AR_ISR_BITS), + DEFBASICfmt(AR_IMR, "IMR", AR_IMR_BITS), + DEFBASICfmt(AR_IER, "IER", AR_IER_BITS), + DEFBASICfmt(AR_BCR, "BCR", AR_BCR_BITS), + DEFBASICfmt(AR_BSR, "BSR", AR_BSR_BITS), + DEFBASICfmt(AR_TXCFG, "TXCFG", AR_TXCFG_BITS), + DEFBASIC(AR_RXCFG, "RXCFG"), + DEFBASIC(AR_MIBC, "MIBC"), + DEFBASIC(AR_TOPS, "TOPS"), + DEFBASIC(AR_RXNOFRM, "RXNOFR"), + DEFBASIC(AR_TXNOFRM, "TXNOFR"), + DEFBASIC(AR_RPGTO, "RPGTO"), + DEFBASIC(AR_RFCNT, "RFCNT"), + DEFBASIC(AR_MISC, "MISC"), + DEFBASICfmt(AR_RC, "RC", AR_RC_BITS), + DEFBASICfmt(AR_SCR, "SCR", AR_SCR_BITS), + DEFBASICfmt(AR_INTPEND, "INTPEND", AR_INTPEND_BITS), + DEFBASIC(AR_SFR, "SFR"), + DEFBASICfmt(AR_PCICFG, "PCICFG", AR_PCICFG_BITS), + DEFBASIC(AR_GPIOCR, "GPIOCR"), + DEFVOID(AR_GPIODO, "GPIODO"), + DEFVOID(AR_GPIODI, "GPIODI"), + DEFBASIC(AR_SREV, "SREV"), + DEFBASIC(AR_STA_ID0, "STA_ID0"), + DEFBASICfmt(AR_STA_ID1, "STA_ID1", AR_STA_ID1_BITS), + DEFBASIC(AR_BSS_ID0, "BSS_ID0"), + DEFBASIC(AR_BSS_ID1, "BSS_ID1"), + DEFBASIC(AR_SLOT_TIME, "SLOTTIME"), + DEFBASIC(AR_TIME_OUT, "TIME_OUT"), + DEFBASIC(AR_RSSI_THR, "RSSI_THR"), + DEFBASIC(AR_RETRY_LMT, "RETRY_LM"), + DEFBASIC(AR_USEC, "USEC"), + DEFBASICfmt(AR_BEACON, "BEACON", AR_BEACON_BITS), + DEFBASIC(AR_CFP_PERIOD, "CFP_PER"), + DEFBASIC(AR_TIMER0, "TIMER0"), + DEFBASIC(AR_TIMER1, "TIMER1"), + DEFBASIC(AR_TIMER2, "TIMER2"), + DEFBASIC(AR_TIMER3, "TIMER3"), + DEFBASIC(AR_IFS0, "IFS0"), + DEFBASIC(AR_IFS1, "IFS1" ), + DEFBASIC(AR_CFP_DUR, "CFP_DUR"), + DEFBASICfmt(AR_RX_FILTER, "RXFILTER", AR_BEACON_BITS), + DEFBASIC(AR_MCAST_FIL0, "MCAST_0"), + DEFBASIC(AR_MCAST_FIL1, "MCAST_1"), + DEFBASIC(AR_TX_MASK0, "TX_MASK0"), + DEFBASIC(AR_TX_MASK1, "TX_MASK1"), + DEFVOID(AR_CLR_TMASK, "CLR_TMASK"), + DEFBASIC(AR_TRIG_LEV, "TRIG_LEV"), + DEFBASICfmt(AR_DIAG_SW, "DIAG_SW", AR_DIAG_SW_BITS), + DEFBASIC(AR_TSF_L32, "TSF_L32"), + DEFBASIC(AR_TSF_U32, "TSF_U32"), + DEFBASIC(AR_LAST_TSTP, "LAST_TST"), + DEFBASIC(AR_RETRY_CNT, "RETRYCNT"), + DEFBASIC(AR_BACKOFF, "BACKOFF"), + DEFBASIC(AR_NAV, "NAV"), + DEFBASIC(AR_RTS_OK, "RTS_OK"), + DEFBASIC(AR_RTS_FAIL, "RTS_FAIL"), + DEFBASIC(AR_ACK_FAIL, "ACK_FAIL"), + DEFBASIC(AR_FCS_FAIL, "FCS_FAIL"), + DEFBASIC(AR_BEACON_CNT, "BEAC_CNT"), + + DEFVOIDfmt(AR_PHY_FRCTL, "PHY_FRCTL", AR_PHY_FRCTL_BITS), + DEFVOIDfmt(AR_PHY_AGC, "PHY_AGC", AR_PHY_AGC_BITS), + DEFVOID(AR_PHY_CHIPID, "PHY_CHIPID"), + DEFVOIDfmt(AR_PHY_ACTIVE, "PHY_ACTIVE", AR_PHY_ACTIVE_BITS), + DEFVOIDfmt(AR_PHY_AGCCTL, "PHY_AGCCTL", AR_PHY_AGCCTL_BITS), +}; + +static __constructor void +ar5210_ctor(void) +{ +#define MAC5210 SREV(1,0), SREV(2,0) + register_regs(ar5210regs, N(ar5210regs), MAC5210, PHYANY); + register_keycache(64, MAC5210, PHYANY); + + register_range(0x9800, 0x9840, DUMP_BASEBAND, MAC5210, PHYANY); +} diff --git a/tools/tools/ath/common/dumpregs_5211.c b/tools/tools/ath/common/dumpregs_5211.c new file mode 100644 index 000000000000..17ecbced2ef1 --- /dev/null +++ b/tools/tools/ath/common/dumpregs_5211.c @@ -0,0 +1,293 @@ +/*- + * Copyright (c) 2002-2008 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$ + */ +#include "diag.h" + +#include "ah.h" +#include "ah_internal.h" +#include "ar5211/ar5211reg.h" +#include "ar5211/ar5211phy.h" + +#include "dumpregs.h" + +#define N(a) (sizeof(a) / sizeof(a[0])) + +static struct dumpreg ar5211regs[] = { + DEFBASICfmt(AR_CR, "CR", AR_CR_BITS), + DEFBASIC(AR_RXDP, "RXDP"), + DEFBASICfmt(AR_CFG, "CFG", AR_CFG_BITS), + DEFBASICfmt(AR_IER, "IER", AR_IER_BITS), + DEFBASIC(AR_RTSD0, "RTSD0"), + DEFBASIC(AR_RTSD1, "RTSD1"), + DEFBASICfmt(AR_TXCFG, "TXCFG", AR_TXCFG_BITS), + DEFBASIC(AR_RXCFG, "RXCFG"), + DEFBASIC(AR5211_JUMBO_LAST, "JLAST"), + DEFBASIC(AR_MIBC, "MIBC"), + DEFBASIC(AR_TOPS, "TOPS"), + DEFBASIC(AR_RXNPTO, "RXNPTO"), + DEFBASIC(AR_TXNPTO, "TXNPTO"), + DEFBASIC(AR_RFGTO, "RFGTO"), + DEFBASIC(AR_RFCNT, "RFCNT"), + DEFBASIC(AR_MACMISC, "MISC"), + DEFVOID(AR5311_QDCLKGATE, "AR5311_QDCLKGATE"), + + DEFINT(AR_ISR, "ISR"), + DEFINT(AR_ISR_S0, "ISR_S0"), + DEFINT(AR_ISR_S1, "ISR_S1"), + DEFINT(AR_ISR_S2, "ISR_S2"), + DEFINT(AR_ISR_S3, "ISR_S3"), + DEFINT(AR_ISR_S4, "ISR_S4"), + DEFINT(AR_IMR, "IMR"), + DEFINT(AR_IMR_S0, "IMR_S0"), + DEFINT(AR_IMR_S1, "IMR_S1"), + DEFINT(AR_IMR_S2, "IMR_S2"), + DEFINT(AR_IMR_S3, "IMR_S3"), + DEFINT(AR_IMR_S4, "IMR_S4"), + /* NB: don't read the RAC so we don't affect operation */ + DEFVOID(AR_ISR_RAC, "ISR_RAC"), + DEFINT(AR_ISR_S0_S, "ISR_S0_S"), + DEFINT(AR_ISR_S1_S, "ISR_S1_S"), + DEFINT(AR_ISR_S2_S, "ISR_S2_S"), + DEFINT(AR_ISR_S3_S, "ISR_S3_S"), + DEFINT(AR_ISR_S4_S, "ISR_S4_S"), + + DEFQCU(AR_Q0_TXDP, "Q0_TXDP"), + DEFQCU(AR_Q1_TXDP, "Q1_TXDP"), + DEFQCU(AR_Q2_TXDP, "Q2_TXDP"), + DEFQCU(AR_Q3_TXDP, "Q3_TXDP"), + DEFQCU(AR_Q4_TXDP, "Q4_TXDP"), + DEFQCU(AR_Q5_TXDP, "Q5_TXDP"), + DEFQCU(AR_Q6_TXDP, "Q6_TXDP"), + DEFQCU(AR_Q7_TXDP, "Q7_TXDP"), + DEFQCU(AR_Q8_TXDP, "Q8_TXDP"), + DEFQCU(AR_Q9_TXDP, "Q9_TXDP"), + + DEFQCU(AR_Q_TXE, "Q_TXE"), + DEFQCU(AR_Q_TXD, "Q_TXD"), + + DEFQCU(AR_Q0_CBRCFG, "Q0_CBR"), + DEFQCU(AR_Q1_CBRCFG, "Q1_CBR"), + DEFQCU(AR_Q2_CBRCFG, "Q2_CBR"), + DEFQCU(AR_Q3_CBRCFG, "Q3_CBR"), + DEFQCU(AR_Q4_CBRCFG, "Q4_CBR"), + DEFQCU(AR_Q5_CBRCFG, "Q5_CBR"), + DEFQCU(AR_Q6_CBRCFG, "Q6_CBR"), + DEFQCU(AR_Q7_CBRCFG, "Q7_CBR"), + DEFQCU(AR_Q8_CBRCFG, "Q8_CBR"), + DEFQCU(AR_Q9_CBRCFG, "Q9_CBR"), + + DEFQCU(AR_Q0_RDYTIMECFG, "Q0_RDYT"), + DEFQCU(AR_Q1_RDYTIMECFG, "Q1_RDYT"), + DEFQCU(AR_Q2_RDYTIMECFG, "Q2_RDYT"), + DEFQCU(AR_Q3_RDYTIMECFG, "Q3_RDYT"), + DEFQCU(AR_Q4_RDYTIMECFG, "Q4_RDYT"), + DEFQCU(AR_Q5_RDYTIMECFG, "Q5_RDYT"), + DEFQCU(AR_Q6_RDYTIMECFG, "Q6_RDYT"), + DEFQCU(AR_Q7_RDYTIMECFG, "Q7_RDYT"), + DEFQCU(AR_Q8_RDYTIMECFG, "Q8_RDYT"), + DEFQCU(AR_Q9_RDYTIMECFG, "Q9_RDYT"), + + DEFQCU(AR_Q_ONESHOTARM_SC, "Q_ONESHOTARM_SC"), + DEFQCU(AR_Q_ONESHOTARM_CC, "Q_ONESHOTARM_CC"), + + DEFQCU(AR_Q0_MISC, "Q0_MISC"), + DEFQCU(AR_Q1_MISC, "Q1_MISC"), + DEFQCU(AR_Q2_MISC, "Q2_MISC"), + DEFQCU(AR_Q3_MISC, "Q3_MISC"), + DEFQCU(AR_Q4_MISC, "Q4_MISC"), + DEFQCU(AR_Q5_MISC, "Q5_MISC"), + DEFQCU(AR_Q6_MISC, "Q6_MISC"), + DEFQCU(AR_Q7_MISC, "Q7_MISC"), + DEFQCU(AR_Q8_MISC, "Q8_MISC"), + DEFQCU(AR_Q9_MISC, "Q9_MISC"), + + DEFQCU(AR_Q0_STS, "Q0_STS"), + DEFQCU(AR_Q1_STS, "Q1_STS"), + DEFQCU(AR_Q2_STS, "Q2_STS"), + DEFQCU(AR_Q3_STS, "Q3_STS"), + DEFQCU(AR_Q4_STS, "Q4_STS"), + DEFQCU(AR_Q5_STS, "Q5_STS"), + DEFQCU(AR_Q6_STS, "Q6_STS"), + DEFQCU(AR_Q7_STS, "Q7_STS"), + DEFQCU(AR_Q8_STS, "Q8_STS"), + DEFQCU(AR_Q9_STS, "Q9_STS"), + + DEFQCU(AR_Q_RDYTIMESHDN, "Q_RDYTIMSHD"), + + DEFQCU(AR_D0_QCUMASK, "D0_MASK"), + DEFQCU(AR_D1_QCUMASK, "D1_MASK"), + DEFQCU(AR_D2_QCUMASK, "D2_MASK"), + DEFQCU(AR_D3_QCUMASK, "D3_MASK"), + DEFQCU(AR_D4_QCUMASK, "D4_MASK"), + DEFQCU(AR_D5_QCUMASK, "D5_MASK"), + DEFQCU(AR_D6_QCUMASK, "D6_MASK"), + DEFQCU(AR_D7_QCUMASK, "D7_MASK"), + DEFQCU(AR_D8_QCUMASK, "D8_MASK"), + DEFQCU(AR_D9_QCUMASK, "D9_MASK"), + + DEFDCU(AR_D0_LCL_IFS, "D0_IFS"), + DEFDCU(AR_D1_LCL_IFS, "D1_IFS"), + DEFDCU(AR_D2_LCL_IFS, "D2_IFS"), + DEFDCU(AR_D3_LCL_IFS, "D3_IFS"), + DEFDCU(AR_D4_LCL_IFS, "D4_IFS"), + DEFDCU(AR_D5_LCL_IFS, "D5_IFS"), + DEFDCU(AR_D6_LCL_IFS, "D6_IFS"), + DEFDCU(AR_D7_LCL_IFS, "D7_IFS"), + DEFDCU(AR_D8_LCL_IFS, "D8_IFS"), + DEFDCU(AR_D9_LCL_IFS, "D9_IFS"), + + DEFDCU(AR_D0_RETRY_LIMIT, "D0_RTRY"), + DEFDCU(AR_D1_RETRY_LIMIT, "D1_RTRY"), + DEFDCU(AR_D2_RETRY_LIMIT, "D2_RTRY"), + DEFDCU(AR_D3_RETRY_LIMIT, "D3_RTRY"), + DEFDCU(AR_D4_RETRY_LIMIT, "D4_RTRY"), + DEFDCU(AR_D5_RETRY_LIMIT, "D5_RTRY"), + DEFDCU(AR_D6_RETRY_LIMIT, "D6_RTRY"), + DEFDCU(AR_D7_RETRY_LIMIT, "D7_RTRY"), + DEFDCU(AR_D8_RETRY_LIMIT, "D8_RTRY"), + DEFDCU(AR_D9_RETRY_LIMIT, "D9_RTRY"), + + DEFDCU(AR_D0_CHNTIME, "D0_CHNT"), + DEFDCU(AR_D1_CHNTIME, "D1_CHNT"), + DEFDCU(AR_D2_CHNTIME, "D2_CHNT"), + DEFDCU(AR_D3_CHNTIME, "D3_CHNT"), + DEFDCU(AR_D4_CHNTIME, "D4_CHNT"), + DEFDCU(AR_D5_CHNTIME, "D5_CHNT"), + DEFDCU(AR_D6_CHNTIME, "D6_CHNT"), + DEFDCU(AR_D7_CHNTIME, "D7_CHNT"), + DEFDCU(AR_D8_CHNTIME, "D8_CHNT"), + DEFDCU(AR_D9_CHNTIME, "D9_CHNT"), + + DEFDCU(AR_D0_MISC, "D0_MISC"), + DEFDCU(AR_D1_MISC, "D1_MISC"), + DEFDCU(AR_D2_MISC, "D2_MISC"), + DEFDCU(AR_D3_MISC, "D3_MISC"), + DEFDCU(AR_D4_MISC, "D4_MISC"), + DEFDCU(AR_D5_MISC, "D5_MISC"), + DEFDCU(AR_D6_MISC, "D6_MISC"), + DEFDCU(AR_D7_MISC, "D7_MISC"), + DEFDCU(AR_D8_MISC, "D8_MISC"), + DEFDCU(AR_D9_MISC, "D9_MISC"), + + DEFDCU(AR_D0_SEQNUM, "D0_SEQ"), + DEFDCU(AR_D1_SEQNUM, "D1_SEQ"), + DEFDCU(AR_D2_SEQNUM, "D2_SEQ"), + DEFDCU(AR_D3_SEQNUM, "D3_SEQ"), + DEFDCU(AR_D4_SEQNUM, "D4_SEQ"), + DEFDCU(AR_D5_SEQNUM, "D5_SEQ"), + DEFDCU(AR_D6_SEQNUM, "D6_SEQ"), + DEFDCU(AR_D7_SEQNUM, "D7_SEQ"), + DEFDCU(AR_D8_SEQNUM, "D8_SEQ"), + DEFDCU(AR_D9_SEQNUM, "D9_SEQ"), + + DEFBASIC(AR_D_GBL_IFS_SIFS, "D_SIFS"), + DEFBASIC(AR_D_GBL_IFS_SLOT, "D_SLOT"), + DEFBASIC(AR_D_GBL_IFS_EIFS, "D_EIFS"), + DEFBASIC(AR_D_GBL_IFS_MISC, "D_MISC"), + DEFBASIC(AR_D_FPCTL, "D_FPCTL"), + DEFBASIC(AR_D_TXPSE, "D_TXPSE"), + DEFVOID(AR_D_TXBLK_CMD, "D_CMD"), +#if 0 + DEFVOID(AR_D_TXBLK_DATA, "D_DATA"), +#endif + DEFVOID(AR_D_TXBLK_CLR, "D_CLR"), + DEFVOID(AR_D_TXBLK_SET, "D_SET"), + DEFBASICfmt(AR_RC, "RC", AR_RC_BITS), + DEFBASICfmt(AR_SCR, "SCR", AR_SCR_BITS), + DEFBASICfmt(AR_INTPEND, "INTPEND", AR_INTPEND_BITS), + DEFBASIC(AR_SFR, "SFR"), + DEFBASICfmt(AR_PCICFG, "PCICFG", AR_PCICFG_BITS), + DEFBASIC(AR_GPIOCR, "GPIOCR"), + DEFBASIC(AR_GPIODO, "GPIODO"), + DEFBASIC(AR_GPIODI, "GPIODI"), + DEFBASIC(AR_SREV, "SREV"), + DEFVOID(AR_EEPROM_ADDR, "EEADDR"), + DEFVOID(AR_EEPROM_DATA, "EEDATA"), + DEFVOID(AR_EEPROM_CMD, "EECMD"), + DEFVOID(AR_EEPROM_STS, "EESTS"), + DEFVOID(AR_EEPROM_CFG, "EECFG"), + DEFBASIC(AR_STA_ID0, "STA_ID0"), + DEFBASICfmt(AR_STA_ID1, "STA_ID1", AR_STA_ID1_BITS), + DEFBASIC(AR_BSS_ID0, "BSS_ID0"), + DEFBASIC(AR_BSS_ID1, "BSS_ID1"), + DEFBASIC(AR_SLOT_TIME, "SLOTTIME"), + DEFBASIC(AR_TIME_OUT, "TIME_OUT"), + DEFBASIC(AR_RSSI_THR, "RSSI_THR"), + DEFBASIC(AR_USEC, "USEC"), + DEFBASICfmt(AR_BEACON, "BEACON", AR_BEACON_BITS), + DEFBASIC(AR_CFP_PERIOD, "CFP_PER"), + DEFBASIC(AR_TIMER0, "TIMER0"), + DEFBASIC(AR_TIMER1, "TIMER1"), + DEFBASIC(AR_TIMER2, "TIMER2"), + DEFBASIC(AR_TIMER3, "TIMER3"), + DEFBASIC(AR_CFP_DUR, "CFP_DUR"), + DEFBASICfmt(AR_RX_FILTER, "RXFILTER", AR_RX_FILTER_BITS), + DEFBASIC(AR_MCAST_FIL0, "MCAST_0"), + DEFBASIC(AR_MCAST_FIL1, "MCAST_1"), + DEFBASICfmt(AR_DIAG_SW, "DIAG_SW", AR_DIAG_SW_BITS), + DEFBASIC(AR_TSF_L32, "TSF_L32"), + DEFBASIC(AR_TSF_U32, "TSF_U32"), + DEFBASIC(AR_TST_ADDAC, "TST_ADAC"), + DEFBASIC(AR_DEF_ANTENNA, "DEF_ANT"), + + DEFBASIC(AR_LAST_TSTP, "LAST_TST"), + DEFBASIC(AR_NAV, "NAV"), + DEFBASIC(AR_RTS_OK, "RTS_OK"), + DEFBASIC(AR_RTS_FAIL, "RTS_FAIL"), + DEFBASIC(AR_ACK_FAIL, "ACK_FAIL"), + DEFBASIC(AR_FCS_FAIL, "FCS_FAIL"), + DEFBASIC(AR_BEACON_CNT, "BEAC_CNT"), + + DEFVOID(AR_PHY_TURBO, "PHY_TURBO"), + DEFVOID(AR_PHY_CHIP_ID, "PHY_CHIP_ID"), + DEFVOID(AR_PHY_ACTIVE, "PHY_ACTIVE"), + DEFVOID(AR_PHY_AGC_CONTROL, "PHY_AGC_CONTROL"), + DEFVOID(AR_PHY_PLL_CTL, "PHY_PLL_CTL"), + DEFVOID(AR_PHY_RX_DELAY, "PHY_RX_DELAY"), + DEFVOID(AR_PHY_TIMING_CTRL4,"PHY_TIMING_CTRL4"), + DEFVOID(AR_PHY_RADAR_0, "PHY_RADAR_0"), + DEFVOID(AR_PHY_IQCAL_RES_PWR_MEAS_I,"PHY_IQCAL_RES_PWR_MEAS_I"), + DEFVOID(AR_PHY_IQCAL_RES_PWR_MEAS_Q,"PHY_IQCAL_RES_PWR_MEAS_Q"), + DEFVOID(AR_PHY_IQCAL_RES_IQ_CORR_MEAS,"PHY_IQCAL_RES_IQ_CORR_MEAS"), + DEFVOID(AR_PHY_CURRENT_RSSI,"PHY_CURRENT_RSSI"), + DEFVOID(AR5211_PHY_MODE, "PHY_MODE"), +}; + +static __constructor void +ar5211_ctor(void) +{ +#define MAC5211 SREV(2,0), SREV(4,5) + register_regs(ar5211regs, N(ar5211regs), MAC5211, PHYANY); + register_keycache(128, MAC5211, PHYANY); + + register_range(0x9800, 0x987c, DUMP_BASEBAND, MAC5211, PHYANY); + register_range(0x9900, 0x995c, DUMP_BASEBAND, MAC5211, PHYANY); + register_range(0x9c00, 0x9c1c, DUMP_BASEBAND, MAC5211, PHYANY); +} diff --git a/tools/tools/ath/common/dumpregs_5212.c b/tools/tools/ath/common/dumpregs_5212.c new file mode 100644 index 000000000000..8d129ecd4e30 --- /dev/null +++ b/tools/tools/ath/common/dumpregs_5212.c @@ -0,0 +1,433 @@ +/*- + * Copyright (c) 2002-2008 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$ + */ +#include "diag.h" + +#include "ah.h" +#include "ah_internal.h" +#include "ar5212/ar5212reg.h" +#include "ar5212/ar5212phy.h" + +#include "dumpregs.h" + +#define N(a) (sizeof(a) / sizeof(a[0])) + +#define MAC5212 SREV(4,5), SREV(16,0) +#define MAC5213 SREV(5,9), SREV(16,0) + +static struct dumpreg ar5212regs[] = { + DEFBASIC(AR_CR, "CR"), + DEFBASIC(AR_RXDP, "RXDP"), + DEFBASICfmt(AR_CFG, "CFG", + "\20\1SWTD\2SWTB\3SWRD\4SWRB\5SWRG\6AP_ADHOC\11PHOK\12EEBS"), + DEFBASIC(AR_IER, "IER"), + DEFBASIC(AR_TXCFG, "TXCFG"), + DEFBASICfmt(AR_RXCFG, "RXCFG", + "\20\6JUMBO_ENA\7JUMBO_WRAP\10SLEEP_DEBUG"), + DEFBASIC(AR_MIBC, "MIBC"), + DEFBASIC(AR_TOPS, "TOPS"), + DEFBASIC(AR_RXNPTO, "RXNPTO"), + DEFBASIC(AR_TXNPTO, "TXNPTO"), + DEFBASIC(AR_RPGTO, "RPGTO"), + DEFBASIC(AR_RPCNT, "RPCNT"), + DEFBASIC(AR_MACMISC, "MACMISC"), + DEFBASIC(AR_SPC_0, "SPC_0"), + DEFBASIC(AR_SPC_1, "SPC_1"), + + DEFINTfmt(AR_ISR, "ISR", + "\20\1RXOK\2RXDESC\3RXERR\4RXNOPKT\5RXEOL\6RXORN\7TXOK\10TXDESC" + "\11TXERR\12TXNOPKT\13TXEOL\14TXURN\15MIB\16SWI\17RXPHY\20RXKCM" + "\21SWBA\22BRSSI\23BMISS\24HIUERR\25BNR\26RXCHIRP\27RXDOPPL\30BCNMISS" + "\31TIM\32GPIO\33QCBROVF\34QCBRURN\35QTRIG"), + DEFINT(AR_ISR_S0, "ISR_S0"), + DEFINT(AR_ISR_S1, "ISR_S1"), + DEFINTfmt(AR_ISR_S2, "ISR_S2", + "\20\21MCABT\22SSERR\23DPERR\24TIM\25CABEND\26DTIMSYNC\27BCNTO" + "\30CABTO\31DTIM"), + DEFINT(AR_ISR_S3, "ISR_S3"), + DEFINT(AR_ISR_S4, "ISR_S4"), + DEFINTfmt(AR_IMR, "IMR", + "\20\1RXOK\2RXDESC\3RXERR\4RXNOPKT\5RXEOL\6RXORN\7TXOK\10TXDESC" + "\11TXERR\12TXNOPKT\13TXEOL\14TXURN\15MIB\16SWI\17RXPHY\20RXKCM" + "\21SWBA\22BRSSI\23BMISS\24HIUERR\25BNR\26RXCHIRP\27RXDOPPL\30BCNMISS" + "\31TIM\32GPIO\33QCBROVF\34QCBRURN\35QTRIG"), + DEFINT(AR_IMR_S0, "IMR_S0"), + DEFINT(AR_IMR_S1, "IMR_S1"), + DEFINTfmt(AR_IMR_S2, "IMR_S2", + "\20\21MCABT\22SSERR\23DPERR\24TIM\25CABEND\26DTIMSYNC\27BCNTO" + "\30CABTO\31DTIM"), + DEFINT(AR_IMR_S3, "IMR_S3"), + DEFINT(AR_IMR_S4, "IMR_S4"), + /* NB: don't read the RAC so we don't affect operation */ + DEFVOID(AR_ISR_RAC, "ISR_RAC"), + DEFINT(AR_ISR_S0_S, "ISR_S0_S"), + DEFINT(AR_ISR_S1_S, "ISR_S1_S"), + DEFINT(AR_ISR_S2_S, "ISR_S2_S"), + DEFINT(AR_ISR_S3_S, "ISR_S3_S"), + DEFINT(AR_ISR_S4_S, "ISR_S4_S"), + + DEFBASIC(AR_DMADBG_0, "DMADBG0"), + DEFBASIC(AR_DMADBG_1, "DMADBG1"), + DEFBASIC(AR_DMADBG_2, "DMADBG2"), + DEFBASIC(AR_DMADBG_3, "DMADBG3"), + DEFBASIC(AR_DMADBG_4, "DMADBG4"), + DEFBASIC(AR_DMADBG_5, "DMADBG5"), + DEFBASIC(AR_DMADBG_6, "DMADBG6"), + DEFBASIC(AR_DMADBG_7, "DMADBG7"), + + DEFBASIC(AR_DCM_A, "DCM_A"), + DEFBASIC(AR_DCM_D, "DCM_D"), + DEFBASIC(AR_DCCFG, "DCCFG"), + DEFBASIC(AR_CCFG, "CCFG"), + DEFBASIC(AR_CCUCFG, "CCUCFG"), + DEFBASIC(AR_CPC_0, "CPC0"), + DEFBASIC(AR_CPC_1, "CPC1"), + DEFBASIC(AR_CPC_2, "CPC2"), + DEFBASIC(AR_CPC_3, "CPC3"), + DEFBASIC(AR_CPCOVF, "CPCOVF"), + + DEFQCU(AR_Q0_TXDP, "Q0_TXDP"), + DEFQCU(AR_Q1_TXDP, "Q1_TXDP"), + DEFQCU(AR_Q2_TXDP, "Q2_TXDP"), + DEFQCU(AR_Q3_TXDP, "Q3_TXDP"), + DEFQCU(AR_Q4_TXDP, "Q4_TXDP"), + DEFQCU(AR_Q5_TXDP, "Q5_TXDP"), + DEFQCU(AR_Q6_TXDP, "Q6_TXDP"), + DEFQCU(AR_Q7_TXDP, "Q7_TXDP"), + DEFQCU(AR_Q8_TXDP, "Q8_TXDP"), + DEFQCU(AR_Q9_TXDP, "Q9_TXDP"), + + DEFQCU(AR_Q_TXE, "Q_TXE"), + DEFQCU(AR_Q_TXD, "Q_TXD"), + + DEFQCU(AR_Q0_CBRCFG, "Q0_CBR"), + DEFQCU(AR_Q1_CBRCFG, "Q1_CBR"), + DEFQCU(AR_Q2_CBRCFG, "Q2_CBR"), + DEFQCU(AR_Q3_CBRCFG, "Q3_CBR"), + DEFQCU(AR_Q4_CBRCFG, "Q4_CBR"), + DEFQCU(AR_Q5_CBRCFG, "Q5_CBR"), + DEFQCU(AR_Q6_CBRCFG, "Q6_CBR"), + DEFQCU(AR_Q7_CBRCFG, "Q7_CBR"), + DEFQCU(AR_Q8_CBRCFG, "Q8_CBR"), + DEFQCU(AR_Q9_CBRCFG, "Q9_CBR"), + + DEFQCU(AR_Q0_RDYTIMECFG, "Q0_RDYT"), + DEFQCU(AR_Q1_RDYTIMECFG, "Q1_RDYT"), + DEFQCU(AR_Q2_RDYTIMECFG, "Q2_RDYT"), + DEFQCU(AR_Q3_RDYTIMECFG, "Q3_RDYT"), + DEFQCU(AR_Q4_RDYTIMECFG, "Q4_RDYT"), + DEFQCU(AR_Q5_RDYTIMECFG, "Q5_RDYT"), + DEFQCU(AR_Q6_RDYTIMECFG, "Q6_RDYT"), + DEFQCU(AR_Q7_RDYTIMECFG, "Q7_RDYT"), + DEFQCU(AR_Q8_RDYTIMECFG, "Q8_RDYT"), + DEFQCU(AR_Q9_RDYTIMECFG, "Q9_RDYT"), + + DEFQCU(AR_Q_ONESHOTARM_SC, "Q_ONESHOTARM_SC"), + DEFQCU(AR_Q_ONESHOTARM_CC, "Q_ONESHOTARM_CC"), + + DEFQCU(AR_Q0_MISC, "Q0_MISC"), + DEFQCU(AR_Q1_MISC, "Q1_MISC"), + DEFQCU(AR_Q2_MISC, "Q2_MISC"), + DEFQCU(AR_Q3_MISC, "Q3_MISC"), + DEFQCU(AR_Q4_MISC, "Q4_MISC"), + DEFQCU(AR_Q5_MISC, "Q5_MISC"), + DEFQCU(AR_Q6_MISC, "Q6_MISC"), + DEFQCU(AR_Q7_MISC, "Q7_MISC"), + DEFQCU(AR_Q8_MISC, "Q8_MISC"), + DEFQCU(AR_Q9_MISC, "Q9_MISC"), + + DEFQCU(AR_Q0_STS, "Q0_STS"), + DEFQCU(AR_Q1_STS, "Q1_STS"), + DEFQCU(AR_Q2_STS, "Q2_STS"), + DEFQCU(AR_Q3_STS, "Q3_STS"), + DEFQCU(AR_Q4_STS, "Q4_STS"), + DEFQCU(AR_Q5_STS, "Q5_STS"), + DEFQCU(AR_Q6_STS, "Q6_STS"), + DEFQCU(AR_Q7_STS, "Q7_STS"), + DEFQCU(AR_Q8_STS, "Q8_STS"), + DEFQCU(AR_Q9_STS, "Q9_STS"), + + DEFQCU(AR_Q_RDYTIMESHDN, "Q_RDYTIMSHD"), + + DEFQCU(AR_Q_CBBS, "Q_CBBS"), + DEFQCU(AR_Q_CBBA, "Q_CBBA"), + DEFQCU(AR_Q_CBC, "Q_CBC"), + + DEFDCU(AR_D0_QCUMASK, "D0_MASK"), + DEFDCU(AR_D1_QCUMASK, "D1_MASK"), + DEFDCU(AR_D2_QCUMASK, "D2_MASK"), + DEFDCU(AR_D3_QCUMASK, "D3_MASK"), + DEFDCU(AR_D4_QCUMASK, "D4_MASK"), + DEFDCU(AR_D5_QCUMASK, "D5_MASK"), + DEFDCU(AR_D6_QCUMASK, "D6_MASK"), + DEFDCU(AR_D7_QCUMASK, "D7_MASK"), + DEFDCU(AR_D8_QCUMASK, "D8_MASK"), + DEFDCU(AR_D9_QCUMASK, "D9_MASK"), + + DEFDCU(AR_D0_LCL_IFS, "D0_IFS"), + DEFDCU(AR_D1_LCL_IFS, "D1_IFS"), + DEFDCU(AR_D2_LCL_IFS, "D2_IFS"), + DEFDCU(AR_D3_LCL_IFS, "D3_IFS"), + DEFDCU(AR_D4_LCL_IFS, "D4_IFS"), + DEFDCU(AR_D5_LCL_IFS, "D5_IFS"), + DEFDCU(AR_D6_LCL_IFS, "D6_IFS"), + DEFDCU(AR_D7_LCL_IFS, "D7_IFS"), + DEFDCU(AR_D8_LCL_IFS, "D8_IFS"), + DEFDCU(AR_D9_LCL_IFS, "D9_IFS"), + + DEFDCU(AR_D0_RETRY_LIMIT, "D0_RTRY"), + DEFDCU(AR_D1_RETRY_LIMIT, "D1_RTRY"), + DEFDCU(AR_D2_RETRY_LIMIT, "D2_RTRY"), + DEFDCU(AR_D3_RETRY_LIMIT, "D3_RTRY"), + DEFDCU(AR_D4_RETRY_LIMIT, "D4_RTRY"), + DEFDCU(AR_D5_RETRY_LIMIT, "D5_RTRY"), + DEFDCU(AR_D6_RETRY_LIMIT, "D6_RTRY"), + DEFDCU(AR_D7_RETRY_LIMIT, "D7_RTRY"), + DEFDCU(AR_D8_RETRY_LIMIT, "D8_RTRY"), + DEFDCU(AR_D9_RETRY_LIMIT, "D9_RTRY"), + + DEFDCU(AR_D0_CHNTIME, "D0_CHNT"), + DEFDCU(AR_D1_CHNTIME, "D1_CHNT"), + DEFDCU(AR_D2_CHNTIME, "D2_CHNT"), + DEFDCU(AR_D3_CHNTIME, "D3_CHNT"), + DEFDCU(AR_D4_CHNTIME, "D4_CHNT"), + DEFDCU(AR_D5_CHNTIME, "D5_CHNT"), + DEFDCU(AR_D6_CHNTIME, "D6_CHNT"), + DEFDCU(AR_D7_CHNTIME, "D7_CHNT"), + DEFDCU(AR_D8_CHNTIME, "D8_CHNT"), + DEFDCU(AR_D9_CHNTIME, "D9_CHNT"), + + DEFDCU(AR_D0_MISC, "D0_MISC"), + DEFDCU(AR_D1_MISC, "D1_MISC"), + DEFDCU(AR_D2_MISC, "D2_MISC"), + DEFDCU(AR_D3_MISC, "D3_MISC"), + DEFDCU(AR_D4_MISC, "D4_MISC"), + DEFDCU(AR_D5_MISC, "D5_MISC"), + DEFDCU(AR_D6_MISC, "D6_MISC"), + DEFDCU(AR_D7_MISC, "D7_MISC"), + DEFDCU(AR_D8_MISC, "D8_MISC"), + DEFDCU(AR_D9_MISC, "D9_MISC"), + + _DEFREG(AR_D_SEQNUM, "D_SEQ", DUMP_BASIC | DUMP_DCU), + DEFBASIC(AR_D_GBL_IFS_SIFS, "D_SIFS"), + DEFBASIC(AR_D_GBL_IFS_SLOT, "D_SLOT"), + DEFBASIC(AR_D_GBL_IFS_EIFS, "D_EIFS"), + DEFBASIC(AR_D_GBL_IFS_MISC, "D_MISC"), + DEFBASIC(AR_D_FPCTL, "D_FPCTL"), + DEFBASIC(AR_D_TXPSE, "D_TXPSE"), + DEFVOID(AR_D_TXBLK_CMD, "D_CMD"), +#if 0 + DEFVOID(AR_D_TXBLK_DATA, "D_DATA"), +#endif + DEFVOID(AR_D_TXBLK_CLR, "D_CLR"), + DEFVOID(AR_D_TXBLK_SET, "D_SET"), + DEFBASIC(AR_RC, "RC"), + DEFBASICfmt(AR_SCR, "SCR", + "\20\22SLDTP\23SLDWP\24SLEPOL\25MIBIE"), + DEFBASIC(AR_INTPEND, "INTPEND"), + DEFBASIC(AR_SFR, "SFR"), + DEFBASIC(AR_PCICFG, "PCICFG"), + DEFBASIC(AR_GPIOCR, "GPIOCR"), + DEFBASIC(AR_GPIODO, "GPIODO"), + DEFBASIC(AR_GPIODI, "GPIODI"), + DEFBASIC(AR_SREV, "SREV"), + + DEFBASICx(AR_PCIE_PMC, "PCIEPMC", SREV(4,8), SREV(13,7)), + DEFBASICx(AR_PCIE_SERDES, "SERDES", SREV(4,8), SREV(13,7)), + DEFBASICx(AR_PCIE_SERDES2, "SERDES2", SREV(4,8), SREV(13,7)), + DEFVOID(AR_EEPROM_ADDR, "EEADDR"), + DEFVOID(AR_EEPROM_DATA, "EEDATA"), + DEFVOID(AR_EEPROM_CMD, "EECMD"), + DEFVOID(AR_EEPROM_STS, "EESTS"), + DEFVOID(AR_EEPROM_CFG, "EECFG"), + DEFBASIC(AR_STA_ID0, "STA_ID0"), + DEFBASICfmt(AR_STA_ID1, "STA_ID1", + "\20\21STA_AP\22ADHOC\23PWR_SAV\24KSRCHDIS\25PCF\26USE_DEFANT" + "\27UPD_DEFANT\30RTS_USE_DEF\31ACKCTS_6MB\32BASE_RATE11B\33USE_DA_SG" + "\34CRPT_MIC_ENABLE\35KSRCH_MODE\36PRE_SEQNUM\37CBCIV_ENDIAN" + "\40MCAST_KSRCH"), + DEFBASIC(AR_BSS_ID0, "BSS_ID0"), + DEFBASIC(AR_BSS_ID1, "BSS_ID1"), + DEFBASIC(AR_SLOT_TIME, "SLOTTIME"), + DEFBASIC(AR_TIME_OUT, "TIME_OUT"), + DEFBASIC(AR_RSSI_THR, "RSSI_THR"), + DEFBASIC(AR_USEC, "USEC"), + DEFBASIC(AR_BEACON, "BEACON"), + DEFBASIC(AR_CFP_PERIOD, "CFP_PER"), + DEFBASIC(AR_TIMER0, "TIMER0"), + DEFBASIC(AR_TIMER1, "TIMER1"), + DEFBASIC(AR_TIMER2, "TIMER2"), + DEFBASIC(AR_TIMER3, "TIMER3"), + DEFBASIC(AR_CFP_DUR, "CFP_DUR"), + DEFBASICfmt(AR_RX_FILTER, "RXFILTER", + "\20\1UCAST\2MCAST\3BCAST\4CONTROL\5BEACON\6PROM\7XR_POLL\10PROBE_REQ"), + DEFBASIC(AR_MCAST_FIL0, "MCAST_0"), + DEFBASIC(AR_MCAST_FIL1, "MCAST_1"), + DEFBASICfmt(AR_DIAG_SW, "DIAG_SW", + "\20\1CACHE_ACK\2ACK_DIS\3CTS_DIS\4ENCRYPT_DIS\5DECRYPT_DIS\6RX_DIS" + "\7CORR_FCS\10CHAN_INFO\11EN_SCRAMSD\22FRAME_NV0\25RX_CLR_HI" + "\26IGNORE_CS\27CHAN_IDLE\30PHEAR_ME"), + DEFBASIC(AR_TSF_L32, "TSF_L32"), + DEFBASIC(AR_TSF_U32, "TSF_U32"), + DEFBASIC(AR_TST_ADDAC, "TST_ADAC"), + DEFBASIC(AR_DEF_ANTENNA, "DEF_ANT"), + DEFBASIC(AR_QOS_MASK, "QOS_MASK"), + DEFBASIC(AR_SEQ_MASK, "SEQ_MASK"), + DEFBASIC(AR_OBSERV_2, "OBSERV2"), + DEFBASIC(AR_OBSERV_1, "OBSERV1"), + + DEFBASIC(AR_LAST_TSTP, "LAST_TST"), + DEFBASIC(AR_NAV, "NAV"), + DEFBASIC(AR_RTS_OK, "RTS_OK"), + DEFBASIC(AR_RTS_FAIL, "RTS_FAIL"), + DEFBASIC(AR_ACK_FAIL, "ACK_FAIL"), + DEFBASIC(AR_FCS_FAIL, "FCS_FAIL"), + DEFBASIC(AR_BEACON_CNT, "BEAC_CNT"), + + DEFBASIC(AR_SLEEP1, "SLEEP1"), + DEFBASIC(AR_SLEEP2, "SLEEP2"), + DEFBASIC(AR_SLEEP3, "SLEEP3"), + DEFBASIC(AR_BSSMSKL, "BSSMSKL"), + DEFBASIC(AR_BSSMSKU, "BSSMSKU"), + DEFBASIC(AR_TPC, "TPC"), + DEFBASIC(AR_TFCNT, "TFCNT"), + DEFBASIC(AR_RFCNT, "RFCNT"), + DEFBASIC(AR_RCCNT, "RCCNT"), + DEFBASIC(AR_CCCNT, "CCCNT"), + DEFBASIC(AR_QUIET1, "QUIET1"), + DEFBASIC(AR_QUIET2, "QUIET2"), + DEFBASIC(AR_TSF_PARM, "TSF_PARM"), + DEFBASIC(AR_NOACK, "NOACK"), + DEFBASIC(AR_PHY_ERR, "PHY_ERR"), + DEFBASIC(AR_QOS_CONTROL, "QOS_CTRL"), + DEFBASIC(AR_QOS_SELECT, "QOS_SEL"), + DEFBASIC(AR_MISC_MODE, "MISCMODE"), + DEFBASIC(AR_FILTOFDM, "FILTOFDM"), + DEFBASIC(AR_FILTCCK, "FILTCCK"), + DEFBASIC(AR_PHYCNT1, "PHYCNT1"), + DEFBASIC(AR_PHYCNTMASK1, "PHYCMSK1"), + DEFBASIC(AR_PHYCNT2, "PHYCNT2"), + DEFBASIC(AR_PHYCNTMASK2, "PHYCMSK2"), + + DEFVOID(AR_PHYCNT1, "PHYCNT1"), + DEFVOID(AR_PHYCNTMASK1, "PHYCNTMASK1"), + DEFVOID(AR_PHYCNT2, "PHYCNT2"), + DEFVOID(AR_PHYCNTMASK2, "PHYCNTMASK2"), + + DEFVOID(AR_PHY_TEST, "PHY_TEST"), + DEFVOID(AR_PHY_TURBO, "PHY_TURBO"), + DEFVOID(AR_PHY_TESTCTRL, "PHY_TESTCTRL"), + DEFVOID(AR_PHY_TIMING3, "PHY_TIMING3"), + DEFVOID(AR_PHY_CHIP_ID, "PHY_CHIP_ID"), + DEFVOIDfmt(AR_PHY_ACTIVE, "PHY_ACTIVE", "\20\1ENA"), + DEFVOID(AR_PHY_TX_CTL, "PHY_TX_CTL"), + DEFVOID(AR_PHY_ADC_CTL, "PHY_ADC_CTL"), + DEFVOID(AR_PHY_BB_XP_PA_CTL,"PHY_BB_XP_PA_CTL"), + DEFVOID(AR_PHY_TSTDAC_CONST,"PHY_TSTDAC_CONST"), + DEFVOID(AR_PHY_SETTLING, "PHY_SETTLING"), + DEFVOID(AR_PHY_RXGAIN, "PHY_RXGAIN"), + DEFVOID(AR_PHY_DESIRED_SZ, "PHY_DESIRED_SZ"), + DEFVOID(AR_PHY_FIND_SIG, "PHY_FIND_SIG"), + DEFVOID(AR_PHY_AGC_CTL1, "PHY_AGC_CTL1"), + DEFVOIDfmt(AR_PHY_AGC_CONTROL, "PHY_AGC_CONTROL", + "\20\1CAL\2NF\16ENA_NF\22NO_UPDATE_NF"), + DEFVOIDfmt(AR_PHY_SFCORR_LOW, "PHY_SFCORR_LOW", + "\20\1USE_SELF_CORR_LOW"), + DEFVOID(AR_PHY_SFCORR, "PHY_SFCORR"), + DEFVOID(AR_PHY_SLEEP_CTR_CONTROL, "PHY_SLEEP_CTR_CONTROL"), + DEFVOID(AR_PHY_SLEEP_CTR_LIMIT, "PHY_SLEEP_CTR_LIMIT"), + DEFVOID(AR_PHY_SLEEP_SCAL, "PHY_SLEEP_SCAL"), + DEFVOID(AR_PHY_BIN_MASK_1, "PHY_BIN_MASK_1"), + DEFVOID(AR_PHY_BIN_MASK_2, "PHY_BIN_MASK_2"), + DEFVOID(AR_PHY_BIN_MASK_3, "PHY_BIN_MASK_3"), + DEFVOID(AR_PHY_MASK_CTL, "PHY_MASK_CTL"), + DEFVOID(AR_PHY_PLL_CTL, "PHY_PLL_CTL"), + DEFVOID(AR_PHY_RX_DELAY, "PHY_RX_DELAY"), + DEFVOID(AR_PHY_TIMING_CTRL4,"PHY_TIMING_CTRL4"), + DEFVOID(AR_PHY_TIMING5, "PHY_TIMING5"), + DEFVOID(AR_PHY_PAPD_PROBE, "PHY_PAPD_PROBE"), + DEFVOID(AR_PHY_POWER_TX_RATE1,"PHY_POWER_TX_RATE1"), + DEFVOID(AR_PHY_POWER_TX_RATE2,"PHY_POWER_TX_RATE2"), + DEFVOID(AR_PHY_POWER_TX_RATE_MAX, "PHY_POWER_TX_RATE_MAX"), + DEFVOID(AR_PHY_FRAME_CTL, "PHY_FRAME_CTL"), + DEFVOID(AR_PHY_TXPWRADJ, "PHY_TXPWRADJ"), + DEFVOID(AR_PHY_RADAR_0, "PHY_RADAR_0"), + DEFVOID(AR_PHY_SIGMA_DELTA, "PHY_SIGMA_DELTA"), + DEFVOID(AR_PHY_RESTART, "PHY_RESTART"), + DEFVOID(AR_PHY_RFBUS_REQ, "PHY_RFBUS_REQ"), + DEFVOID(AR_PHY_TIMING7, "PHY_TIMING7"), + DEFVOID(AR_PHY_TIMING8, "PHY_TIMING8"), + DEFVOID(AR_PHY_BIN_MASK2_1, "PHY_BIN_MASK2_1"), + DEFVOID(AR_PHY_BIN_MASK2_2, "PHY_BIN_MASK2_2"), + DEFVOID(AR_PHY_BIN_MASK2_3, "PHY_BIN_MASK2_3"), + DEFVOID(AR_PHY_BIN_MASK2_4, "PHY_BIN_MASK2_4"), + DEFVOID(AR_PHY_TIMING9, "PHY_TIMING9"), + DEFVOID(AR_PHY_TIMING10, "PHY_TIMING10"), + DEFVOID(AR_PHY_TIMING11, "PHY_TIMING11"), + DEFVOID(AR_PHY_HEAVY_CLIP_ENABLE, "PHY_HEAVY_CLIP_ENABLE"), + DEFVOID(AR_PHY_M_SLEEP, "PHY_M_SLEEP"), + DEFVOID(AR_PHY_REFCLKDLY, "PHY_REFCLKDLY"), + DEFVOID(AR_PHY_REFCLKPD, "PHY_REFCLKPD"), + DEFVOID(AR_PHY_IQCAL_RES_PWR_MEAS_I, "PHY_IQCAL_RES_PWR_MEAS_I"), + DEFVOID(AR_PHY_IQCAL_RES_PWR_MEAS_Q, "PHY_IQCAL_RES_PWR_MEAS_Q"), + DEFVOID(AR_PHY_IQCAL_RES_IQ_CORR_MEAS, "PHY_IQCAL_RES_IQ_CORR_MEAS"), + DEFVOID(AR_PHY_CURRENT_RSSI,"PHY_CURRENT_RSSI"), + DEFVOID(AR_PHY_RFBUS_GNT, "PHY_RFBUS_GNT"), + DEFVOIDfmt(AR_PHY_MODE, "PHY_MODE", + "\20\1CCK\2RF2GHZ\3DYNAMIC\4AR5112\5HALF\6QUARTER"), + DEFVOID(AR_PHY_CCK_TX_CTRL, "PHY_CCK_TX_CTRL"), + DEFVOID(AR_PHY_CCK_DETECT, "PHY_CCK_DETECT"), + DEFVOID(AR_PHY_GAIN_2GHZ, "PHY_GAIN_2GHZ"), + DEFVOID(AR_PHY_CCK_RXCTRL4, "PHY_CCK_RXCTRL4"), + DEFVOID(AR_PHY_DAG_CTRLCCK, "PHY_DAG_CTRLCCK"), + DEFVOID(AR_PHY_DAG_CTRLCCK, "PHY_DAG_CTRLCCK"), + DEFVOID(AR_PHY_POWER_TX_RATE3,"PHY_POWER_TX_RATE3"), + DEFVOID(AR_PHY_POWER_TX_RATE4,"PHY_POWER_TX_RATE4"), + DEFVOID(AR_PHY_FAST_ADC, "PHY_FAST_ADC"), + DEFVOID(AR_PHY_BLUETOOTH, "PHY_BLUETOOTH"), + DEFVOID(AR_PHY_TPCRG1, "PHY_TPCRG1"), + DEFVOID(AR_PHY_TPCRG5, "PHY_TPCRG5"), + + /* XXX { AR_RATE_DURATION(0), AR_RATE_DURATION(0x20) }, */ +}; + +static __constructor void +ar5212_ctor(void) +{ + register_regs(ar5212regs, N(ar5212regs), MAC5212, PHYANY); + register_keycache(128, MAC5212, PHYANY); + + register_range(0x9800, 0x987c, DUMP_BASEBAND, MAC5212, PHYANY); + register_range(0x9900, 0x995c, DUMP_BASEBAND, MAC5212, PHYANY); + register_range(0x9c00, 0x9c1c, DUMP_BASEBAND, MAC5212, PHYANY); + register_range(0xa180, 0xa238, DUMP_BASEBAND, MAC5212, PHYANY); + register_range(0xa258, 0xa26c, DUMP_BASEBAND, + SREV(7,8), SREV(15,15), PHYANY); +} diff --git a/tools/tools/ath/common/dumpregs_5416.c b/tools/tools/ath/common/dumpregs_5416.c new file mode 100644 index 000000000000..d52c9ca0c251 --- /dev/null +++ b/tools/tools/ath/common/dumpregs_5416.c @@ -0,0 +1,423 @@ +/*- + * Copyright (c) 2002-2008 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$ + */ +#include "diag.h" + +#include "ah.h" +#include "ah_internal.h" +#include "ar5416/ar5416reg.h" +#include "ar5416/ar5416phy.h" + +#include "dumpregs.h" + +#define N(a) (sizeof(a) / sizeof(a[0])) + +#define MAC5416 SREV(13,8), SREV(0xff,0xff) /* XXX */ + +static struct dumpreg ar5416regs[] = { + DEFBASIC(AR_CR, "CR"), + DEFBASIC(AR_RXDP, "RXDP"), + DEFBASIC(AR_CFG, "CFG"), + DEFBASIC(AR_MIRT, "MIRT"), + DEFBASIC(AR_TIMT, "TIMT"), + DEFBASIC(AR_CST, "CST"), + DEFBASIC(AR_IER, "IER"), + DEFBASIC(AR_TXCFG, "TXCFG"), + DEFBASICfmt(AR_RXCFG, "RXCFG", + "\20\6JUMBO_ENA\7JUMBO_WRAP\10SLEEP_DEBUG"), + DEFBASIC(AR_MIBC, "MIBC"), + DEFBASIC(AR_TOPS, "TOPS"), + DEFBASIC(AR_RXNPTO, "RXNPTO"), + DEFBASIC(AR_TXNPTO, "TXNPTO"), + DEFBASIC(AR_RPGTO, "RPGTO"), + DEFBASIC(AR_RPCNT, "RPCNT"), + DEFBASIC(AR_MACMISC, "MACMISC"), + DEFBASIC(AR_SPC_0, "SPC_0"), + DEFBASIC(AR_SPC_1, "SPC_1"), + DEFBASIC(AR_GTXTO, "GTXTO"), + DEFBASIC(AR_GTTM, "GTTM"), + + DEFINTfmt(AR_ISR, "ISR", + "\20\1RXOK\2RXDESC\3RXERR\4RXNOPKT\5RXEOL\6RXORN\7TXOK\10TXDESC" + "\11TXERR\12TXNOPKT\13TXEOL\14TXURN\15MIB\16SWI\17RXPHY\20RXKCM" + "\21SWBA\22BRSSI\23BMISS\24HIUERR\25BNR\26RXCHIRP\27RXDOPPL\30BCNMISS" + "\31TIM\32GPIO\33QCBROVF\34QCBRURN\35QTRIG"), + DEFINT(AR_ISR_S0, "ISR_S0"), + DEFINT(AR_ISR_S1, "ISR_S1"), + DEFINTfmt(AR_ISR_S2, "ISR_S2", + "\20\21MCABT\22SSERR\23DPERR\24TIM\25CABEND\26DTIMSYNC\27BCNTO" + "\30CABTO\31DTIM"), + DEFINT(AR_ISR_S3, "ISR_S3"), + DEFINT(AR_ISR_S4, "ISR_S4"), + DEFINT(AR_ISR_S5, "ISR_S5"), + DEFINTfmt(AR_IMR, "IMR", + "\20\1RXOK\2RXDESC\3RXERR\4RXNOPKT\5RXEOL\6RXORN\7TXOK\10TXDESC" + "\11TXERR\12TXNOPKT\13TXEOL\14TXURN\15MIB\16SWI\17RXPHY\20RXKCM" + "\21SWBA\22BRSSI\23BMISS\24HIUERR\25BNR\26RXCHIRP\27RXDOPPL\30BCNMISS" + "\31TIM\32GPIO\33QCBROVF\34QCBRURN\35QTRIG"), + DEFINT(AR_IMR_S0, "IMR_S0"), + DEFINT(AR_IMR_S1, "IMR_S1"), + DEFINTfmt(AR_IMR_S2, "IMR_S2", + "\20\21MCABT\22SSERR\23DPERR\24TIM\25CABEND\26DTIMSYNC\27BCNTO" + "\30CABTO\31DTIM"), + DEFINT(AR_IMR_S3, "IMR_S3"), + DEFINT(AR_IMR_S4, "IMR_S4"), + /* NB: don't read the RAC so we don't affect operation */ + DEFVOID(AR_ISR_RAC, "ISR_RAC"), + DEFINT(AR_ISR_S0_S, "ISR_S0_S"), + DEFINT(AR_ISR_S1_S, "ISR_S1_S"), + DEFINT(AR_ISR_S2_S, "ISR_S2_S"), + DEFINT(AR_ISR_S3_S, "ISR_S3_S"), + DEFINT(AR_ISR_S4_S, "ISR_S4_S"), + DEFINT(AR_ISR_S5_S, "ISR_S5_S"), + + DEFBASIC(AR_DMADBG_0, "DMADBG0"), + DEFBASIC(AR_DMADBG_1, "DMADBG1"), + DEFBASIC(AR_DMADBG_2, "DMADBG2"), + DEFBASIC(AR_DMADBG_3, "DMADBG3"), + DEFBASIC(AR_DMADBG_4, "DMADBG4"), + DEFBASIC(AR_DMADBG_5, "DMADBG5"), + DEFBASIC(AR_DMADBG_6, "DMADBG6"), + DEFBASIC(AR_DMADBG_7, "DMADBG7"), + + DEFBASIC(AR_DCM_A, "DCM_A"), + DEFBASIC(AR_DCM_D, "DCM_D"), + DEFBASIC(AR_DCCFG, "DCCFG"), + DEFBASIC(AR_CCFG, "CCFG"), + DEFBASIC(AR_CCUCFG, "CCUCFG"), + DEFBASIC(AR_CPC_0, "CPC0"), + DEFBASIC(AR_CPC_1, "CPC1"), + DEFBASIC(AR_CPC_2, "CPC2"), + DEFBASIC(AR_CPC_3, "CPC3"), + DEFBASIC(AR_CPCOVF, "CPCOVF"), + + DEFQCU(AR_Q0_TXDP, "Q0_TXDP"), + DEFQCU(AR_Q1_TXDP, "Q1_TXDP"), + DEFQCU(AR_Q2_TXDP, "Q2_TXDP"), + DEFQCU(AR_Q3_TXDP, "Q3_TXDP"), + DEFQCU(AR_Q4_TXDP, "Q4_TXDP"), + DEFQCU(AR_Q5_TXDP, "Q5_TXDP"), + DEFQCU(AR_Q6_TXDP, "Q6_TXDP"), + DEFQCU(AR_Q7_TXDP, "Q7_TXDP"), + DEFQCU(AR_Q8_TXDP, "Q8_TXDP"), + DEFQCU(AR_Q9_TXDP, "Q9_TXDP"), + + DEFQCU(AR_Q_TXE, "Q_TXE"), + DEFQCU(AR_Q_TXD, "Q_TXD"), + + DEFQCU(AR_Q0_CBRCFG, "Q0_CBR"), + DEFQCU(AR_Q1_CBRCFG, "Q1_CBR"), + DEFQCU(AR_Q2_CBRCFG, "Q2_CBR"), + DEFQCU(AR_Q3_CBRCFG, "Q3_CBR"), + DEFQCU(AR_Q4_CBRCFG, "Q4_CBR"), + DEFQCU(AR_Q5_CBRCFG, "Q5_CBR"), + DEFQCU(AR_Q6_CBRCFG, "Q6_CBR"), + DEFQCU(AR_Q7_CBRCFG, "Q7_CBR"), + DEFQCU(AR_Q8_CBRCFG, "Q8_CBR"), + DEFQCU(AR_Q9_CBRCFG, "Q9_CBR"), + + DEFQCU(AR_Q0_RDYTIMECFG, "Q0_RDYT"), + DEFQCU(AR_Q1_RDYTIMECFG, "Q1_RDYT"), + DEFQCU(AR_Q2_RDYTIMECFG, "Q2_RDYT"), + DEFQCU(AR_Q3_RDYTIMECFG, "Q3_RDYT"), + DEFQCU(AR_Q4_RDYTIMECFG, "Q4_RDYT"), + DEFQCU(AR_Q5_RDYTIMECFG, "Q5_RDYT"), + DEFQCU(AR_Q6_RDYTIMECFG, "Q6_RDYT"), + DEFQCU(AR_Q7_RDYTIMECFG, "Q7_RDYT"), + DEFQCU(AR_Q8_RDYTIMECFG, "Q8_RDYT"), + DEFQCU(AR_Q9_RDYTIMECFG, "Q9_RDYT"), + + DEFQCU(AR_Q_ONESHOTARM_SC, "Q_ONESHOTARM_SC"), + DEFQCU(AR_Q_ONESHOTARM_CC, "Q_ONESHOTARM_CC"), + + DEFQCU(AR_Q0_MISC, "Q0_MISC"), + DEFQCU(AR_Q1_MISC, "Q1_MISC"), + DEFQCU(AR_Q2_MISC, "Q2_MISC"), + DEFQCU(AR_Q3_MISC, "Q3_MISC"), + DEFQCU(AR_Q4_MISC, "Q4_MISC"), + DEFQCU(AR_Q5_MISC, "Q5_MISC"), + DEFQCU(AR_Q6_MISC, "Q6_MISC"), + DEFQCU(AR_Q7_MISC, "Q7_MISC"), + DEFQCU(AR_Q8_MISC, "Q8_MISC"), + DEFQCU(AR_Q9_MISC, "Q9_MISC"), + + DEFQCU(AR_Q0_STS, "Q0_STS"), + DEFQCU(AR_Q1_STS, "Q1_STS"), + DEFQCU(AR_Q2_STS, "Q2_STS"), + DEFQCU(AR_Q3_STS, "Q3_STS"), + DEFQCU(AR_Q4_STS, "Q4_STS"), + DEFQCU(AR_Q5_STS, "Q5_STS"), + DEFQCU(AR_Q6_STS, "Q6_STS"), + DEFQCU(AR_Q7_STS, "Q7_STS"), + DEFQCU(AR_Q8_STS, "Q8_STS"), + DEFQCU(AR_Q9_STS, "Q9_STS"), + + DEFQCU(AR_Q_RDYTIMESHDN, "Q_RDYTIMSHD"), + + DEFQCU(AR_Q_CBBS, "Q_CBBS"), + DEFQCU(AR_Q_CBBA, "Q_CBBA"), + DEFQCU(AR_Q_CBC, "Q_CBC"), + + DEFDCU(AR_D0_QCUMASK, "D0_MASK"), + DEFDCU(AR_D1_QCUMASK, "D1_MASK"), + DEFDCU(AR_D2_QCUMASK, "D2_MASK"), + DEFDCU(AR_D3_QCUMASK, "D3_MASK"), + DEFDCU(AR_D4_QCUMASK, "D4_MASK"), + DEFDCU(AR_D5_QCUMASK, "D5_MASK"), + DEFDCU(AR_D6_QCUMASK, "D6_MASK"), + DEFDCU(AR_D7_QCUMASK, "D7_MASK"), + DEFDCU(AR_D8_QCUMASK, "D8_MASK"), + DEFDCU(AR_D9_QCUMASK, "D9_MASK"), + + DEFDCU(AR_D0_LCL_IFS, "D0_IFS"), + DEFDCU(AR_D1_LCL_IFS, "D1_IFS"), + DEFDCU(AR_D2_LCL_IFS, "D2_IFS"), + DEFDCU(AR_D3_LCL_IFS, "D3_IFS"), + DEFDCU(AR_D4_LCL_IFS, "D4_IFS"), + DEFDCU(AR_D5_LCL_IFS, "D5_IFS"), + DEFDCU(AR_D6_LCL_IFS, "D6_IFS"), + DEFDCU(AR_D7_LCL_IFS, "D7_IFS"), + DEFDCU(AR_D8_LCL_IFS, "D8_IFS"), + DEFDCU(AR_D9_LCL_IFS, "D9_IFS"), + + DEFDCU(AR_D0_RETRY_LIMIT, "D0_RTRY"), + DEFDCU(AR_D1_RETRY_LIMIT, "D1_RTRY"), + DEFDCU(AR_D2_RETRY_LIMIT, "D2_RTRY"), + DEFDCU(AR_D3_RETRY_LIMIT, "D3_RTRY"), + DEFDCU(AR_D4_RETRY_LIMIT, "D4_RTRY"), + DEFDCU(AR_D5_RETRY_LIMIT, "D5_RTRY"), + DEFDCU(AR_D6_RETRY_LIMIT, "D6_RTRY"), + DEFDCU(AR_D7_RETRY_LIMIT, "D7_RTRY"), + DEFDCU(AR_D8_RETRY_LIMIT, "D8_RTRY"), + DEFDCU(AR_D9_RETRY_LIMIT, "D9_RTRY"), + + DEFDCU(AR_D0_CHNTIME, "D0_CHNT"), + DEFDCU(AR_D1_CHNTIME, "D1_CHNT"), + DEFDCU(AR_D2_CHNTIME, "D2_CHNT"), + DEFDCU(AR_D3_CHNTIME, "D3_CHNT"), + DEFDCU(AR_D4_CHNTIME, "D4_CHNT"), + DEFDCU(AR_D5_CHNTIME, "D5_CHNT"), + DEFDCU(AR_D6_CHNTIME, "D6_CHNT"), + DEFDCU(AR_D7_CHNTIME, "D7_CHNT"), + DEFDCU(AR_D8_CHNTIME, "D8_CHNT"), + DEFDCU(AR_D9_CHNTIME, "D9_CHNT"), + + DEFDCU(AR_D0_MISC, "D0_MISC"), + DEFDCU(AR_D1_MISC, "D1_MISC"), + DEFDCU(AR_D2_MISC, "D2_MISC"), + DEFDCU(AR_D3_MISC, "D3_MISC"), + DEFDCU(AR_D4_MISC, "D4_MISC"), + DEFDCU(AR_D5_MISC, "D5_MISC"), + DEFDCU(AR_D6_MISC, "D6_MISC"), + DEFDCU(AR_D7_MISC, "D7_MISC"), + DEFDCU(AR_D8_MISC, "D8_MISC"), + DEFDCU(AR_D9_MISC, "D9_MISC"), + + _DEFREG(AR_D_SEQNUM, "D_SEQ", DUMP_BASIC | DUMP_DCU), + DEFBASIC(AR_D_GBL_IFS_SIFS, "D_SIFS"), + DEFBASIC(AR_D_GBL_IFS_SLOT, "D_SLOT"), + DEFBASIC(AR_D_GBL_IFS_EIFS, "D_EIFS"), + DEFBASIC(AR_D_GBL_IFS_MISC, "D_MISC"), + DEFBASIC(AR_D_FPCTL, "D_FPCTL"), + DEFBASIC(AR_D_TXPSE, "D_TXPSE"), + DEFVOID(AR_D_TXBLK_CMD, "D_CMD"), +#if 0 + DEFVOID(AR_D_TXBLK_DATA, "D_DATA"), +#endif + DEFVOID(AR_D_TXBLK_CLR, "D_CLR"), + DEFVOID(AR_D_TXBLK_SET, "D_SET"), + + DEFBASIC(AR_MAC_LED, "MAC_LED"), + DEFBASICfmt(AR_RC, "RC", + "\20\1AHB\2APB\11HOSTIF"), + DEFBASIC(AR_SCR, "SCR"), + DEFBASIC(AR_INTPEND, "INTPEND"), + DEFBASIC(AR_SFR, "SFR"), + DEFBASIC(AR_PCICFG, "PCICFG"), + DEFBASIC(AR_SREV, "SREV"), + + DEFBASIC(AR_AHB_MODE, "AHBMODE"), + DEFBASIC(AR_PCIE_PM_CTRL, "PCIEPMC"), + DEFBASIC(AR5416_PCIE_SERDES,"SERDES"), + DEFBASIC(AR5416_PCIE_SERDES2, "SERDES2"), + + DEFVOID(AR_INTR_SYNC_CAUSE_CLR, "INTR_SYNC_CAUSE_CLR"), + DEFVOID(AR_INTR_SYNC_CAUSE, "INTR_SYNC_CAUSE"), + DEFVOID(AR_INTR_SYNC_ENABLE,"INTR_SYNC_ENABLE"), + DEFBASIC(AR_INTR_ASYNC_MASK,"IASYNCM"), + DEFBASIC(AR_INTR_SYNC_MASK, "ISYNCM"), + DEFVOID(AR_INTR_ASYNC_CAUSE,"INTR_ASYNC_CAUSE"), + DEFVOID(AR_INTR_ASYNC_ENABLE,"INTR_ASYNC_ENABLE"), + + DEFBASICfmt(AR_RTC_RC, "RTC_RC", + "\20\1MAC_WARM\2MAC_COLD"), + DEFBASIC(AR_RTC_PLL_CONTROL,"RTC_PLL"), + DEFVOID(AR_RTC_RESET, "RTC_RESET"), + DEFVOIDfmt(AR_RTC_STATUS, "RTC_STATUS", + "\20\1SHUTDOWN\2ON\3SLEEP\4WAKEUP\5COLDRESET\6PLLCHANGE"), + DEFVOID(AR_RTC_SLEEP_CLK, "RTC_SLEEP_CLK"), + DEFVOIDfmt(AR_RTC_FORCE_WAKE,"RTC_FORCE_WAKE", + "\20\1EN\2WAKE_ON_INT"), + DEFVOID(AR_RTC_INTR_CAUSE, "RTC_INTR_CAUSE"), + DEFVOID(AR_RTC_INTR_MASK, "RTC_INTR_MASK"), + + DEFBASIC(AR_GPIO_IN_OUT, "GPIOIO"), + DEFBASIC(AR_GPIO_OE_OUT, "GPIOOE"), + DEFBASIC(AR_GPIO_INTR_POL, "GPIOPOL"), + DEFBASIC(AR_GPIO_INPUT_EN_VAL, "GPIOIEV"), + DEFBASIC(AR_GPIO_INPUT_MUX1, "GPIMUX1"), + DEFBASIC(AR_GPIO_INPUT_MUX2, "GPIMUX2"), + DEFBASIC(AR_GPIO_OUTPUT_MUX1, "GPOMUX1"), + DEFBASIC(AR_GPIO_OUTPUT_MUX2, "GPOMUX2"), + DEFBASIC(AR_GPIO_OUTPUT_MUX3, "GPOMUX3"), + DEFBASIC(AR_OBS, "OBS"), + DEFVOID(AR_EEPROM_ADDR, "EEADDR"), + DEFVOID(AR_EEPROM_DATA, "EEDATA"), + DEFVOID(AR_EEPROM_CMD, "EECMD"), + DEFVOID(AR_EEPROM_STS, "EESTS"), + DEFVOID(AR_EEPROM_CFG, "EECFG"), + DEFBASIC(AR_STA_ID0, "STA_ID0"), + DEFBASICfmt(AR_STA_ID1, "STA_ID1", + "\20\21AP\22ADHOC\23PWR_SAV\24KSRCHDIS\25PCF\26USE_DEFANT" + "\27UPD_DEFANT\30RTS_USE_DEF\31ACKCTS_6MB\32BASE_RATE_11B" + "\33USE_DA_SG\34CRPT_MIC_ENABLE\35KSRCH_MODE\36PRE_SEQNUM" + "\37CBCIV_ENDIAN\40MCAST_KSRC"), + DEFBASIC(AR_BSS_ID0, "BSS_ID0"), + DEFBASIC(AR_BSS_ID1, "BSS_ID1"), + DEFBASIC(AR_SLOT_TIME, "SLOTTIME"), + DEFBASIC(AR_TIME_OUT, "TIME_OUT"), + DEFBASIC(AR_RSSI_THR, "RSSI_THR"), + DEFBASIC(AR_USEC, "USEC"), + DEFBASIC(AR_BEACON, "BEACON"), + DEFBASIC(AR_CFP_PERIOD, "CFP_PER"), + DEFBASIC(AR_TIMER0, "TIMER0"), + DEFBASIC(AR_TIMER1, "TIMER1"), + DEFBASIC(AR_TIMER2, "TIMER2"), + DEFBASIC(AR_TIMER3, "TIMER3"), + DEFBASIC(AR_CFP_DUR, "CFP_DUR"), + DEFBASIC(AR_RX_FILTER, "RXFILTER"), + DEFBASIC(AR_MCAST_FIL0, "MCAST_0"), + DEFBASIC(AR_MCAST_FIL1, "MCAST_1"), + DEFBASICfmt(AR_DIAG_SW, "DIAG_SW", + "\20\1CACHE_ACK\2ACK_DIS\3CTS_DIS\4ENCRYPT_DIS\5DECRYPT_DIS\6RX_DIS" + "\7CORR_FCS\10CHAN_INFO\11EN_SCRAMSD\22FRAME_NV0\25RX_CLR_HI" + "\26IGNORE_CS\27CHAN_IDLE\30PHEAR_ME"), + DEFBASIC(AR_TSF_L32, "TSF_L32"), + DEFBASIC(AR_TSF_U32, "TSF_U32"), + DEFBASIC(AR_TST_ADDAC, "TST_ADAC"), + DEFBASIC(AR_DEF_ANTENNA, "DEF_ANT"), + DEFBASIC(AR_QOS_MASK, "QOS_MASK"), + DEFBASIC(AR_SEQ_MASK, "SEQ_MASK"), + DEFBASIC(AR_OBSERV_2, "OBSERV2"), + DEFBASIC(AR_OBSERV_1, "OBSERV1"), + + DEFBASIC(AR_LAST_TSTP, "LAST_TST"), + DEFBASIC(AR_NAV, "NAV"), + DEFBASIC(AR_RTS_OK, "RTS_OK"), + DEFBASIC(AR_RTS_FAIL, "RTS_FAIL"), + DEFBASIC(AR_ACK_FAIL, "ACK_FAIL"), + DEFBASIC(AR_FCS_FAIL, "FCS_FAIL"), + DEFBASIC(AR_BEACON_CNT, "BEAC_CNT"), + + DEFBASIC(AR_SLEEP1, "SLEEP1"), + DEFBASIC(AR_SLEEP2, "SLEEP2"), + DEFBASIC(AR_SLEEP3, "SLEEP3"), + DEFBASIC(AR_BSSMSKL, "BSSMSKL"), + DEFBASIC(AR_BSSMSKU, "BSSMSKU"), + DEFBASIC(AR_TPC, "TPC"), + DEFBASIC(AR_TFCNT, "TFCNT"), + DEFBASIC(AR_RFCNT, "RFCNT"), + DEFBASIC(AR_RCCNT, "RCCNT"), + DEFBASIC(AR_CCCNT, "CCCNT"), + DEFBASIC(AR_QUIET1, "QUIET1"), + DEFBASIC(AR_QUIET2, "QUIET2"), + DEFBASIC(AR_TSF_PARM, "TSF_PARM"), + DEFBASIC(AR_NOACK, "NOACK"), + DEFBASIC(AR_PHY_ERR, "PHY_ERR"), + DEFBASIC(AR_QOS_CONTROL, "QOS_CTRL"), + DEFBASIC(AR_QOS_SELECT, "QOS_SEL"), + DEFBASIC(AR_MISC_MODE, "MISCMODE"), + DEFBASIC(AR_FILTOFDM, "FILTOFDM"), + DEFBASIC(AR_FILTCCK, "FILTCCK"), + DEFBASIC(AR_PHYCNT1, "PHYCNT1"), + DEFBASIC(AR_PHYCNTMASK1, "PHYCMSK1"), + DEFBASIC(AR_PHYCNT2, "PHYCNT2"), + DEFBASIC(AR_PHYCNTMASK2, "PHYCMSK2"), + + DEFBASIC(AR_TXOP_X, "TXOPX"), + DEFBASIC(AR_NEXT_TBTT, "NXTTBTT"), + DEFBASIC(AR_NEXT_DBA, "NXTDBA"), + DEFBASIC(AR_NEXT_SWBA, "NXTSWBA"), + DEFBASIC(AR_NEXT_CFP, "NXTCFP"), + DEFBASIC(AR_NEXT_HCF, "NXTHCF"), + DEFBASIC(AR_NEXT_DTIM, "NXTDTIM"), + DEFBASIC(AR_NEXT_QUIET, "NXTQUIET"), + DEFBASIC(AR_NEXT_NDP, "NXTNDP"), + DEFBASIC(AR5416_BEACON_PERIOD, "BCNPER"), + DEFBASIC(AR_DBA_PERIOD, "DBAPER"), + DEFBASIC(AR_SWBA_PERIOD, "SWBAPER"), + DEFBASIC(AR_TIM_PERIOD, "TIMPER"), + DEFBASIC(AR_DTIM_PERIOD, "DTIMPER"), + DEFBASIC(AR_QUIET_PERIOD, "QUIETPER"), + DEFBASIC(AR_NDP_PERIOD, "NDPPER"), + DEFBASIC(AR_TIMER_MODE, "TIMERMOD"), + DEFBASIC(AR_2040_MODE, "2040MODE"), + DEFBASIC(AR_PCU_TXBUF_CTRL, "PCUTXBUF"), + DEFBASIC(AR_SLP32_MODE, "SLP32MOD"), + DEFBASIC(AR_SLP32_WAKE, "SLP32WAK"), + DEFBASIC(AR_SLP32_INC, "SLP32INC"), + DEFBASIC(AR_SLP_CNT, "SLPCNT"), + DEFBASIC(AR_SLP_MIB_CTRL, "SLPMIB"), + DEFBASIC(AR_EXTRCCNT, "EXTRCCNT"), + DEFBASIC(AR_PHY_TURBO, "PHYTURBO"), + + DEFVOID(AR_PHY_ADC_SERIAL_CTL, "PHY_ADC_SERIAL_CTL"), + + /* XXX { AR_RATE_DURATION(0), AR_RATE_DURATION(0x20) }, */ +}; + +static __constructor void +ar5416_ctor(void) +{ + register_regs(ar5416regs, N(ar5416regs), MAC5416, PHYANY); + register_keycache(128, MAC5416, PHYANY); + + register_range(0x9800, 0x987c, DUMP_BASEBAND, MAC5416, PHYANY); + register_range(0x9900, 0x997c, DUMP_BASEBAND, MAC5416, PHYANY); + register_range(0x99a4, 0x99a4, DUMP_BASEBAND, MAC5416, PHYANY); + register_range(0x9c00, 0x9c1c, DUMP_BASEBAND, MAC5416, PHYANY); + register_range(0xa180, 0xa238, DUMP_BASEBAND, MAC5416, PHYANY); + register_range(0xa258, 0xa26c, DUMP_BASEBAND, MAC5416, PHYANY); + register_range(0xa3c8, 0xa3d4, DUMP_BASEBAND, MAC5416, PHYANY); + register_range(0xa864, 0xa864, DUMP_BASEBAND, MAC5416, PHYANY); + register_range(0xa9bc, 0xa9bc, DUMP_BASEBAND, MAC5416, PHYANY); + register_range(0xb864, 0xb864, DUMP_BASEBAND, MAC5416, PHYANY); + register_range(0xb9bc, 0xb9bc, DUMP_BASEBAND, MAC5416, PHYANY); +} diff --git a/tools/tools/backout_commit/backout_commit.rb b/tools/tools/backout_commit/backout_commit.rb new file mode 100644 index 000000000000..264c271b60bf --- /dev/null +++ b/tools/tools/backout_commit/backout_commit.rb @@ -0,0 +1,350 @@ +#!/usr/bin/env ruby -w + +# $FreeBSD$ + +# Please note, that this utility must be kept in sync with +# CVSROOT/log_accum.pl. If someone has a different output from their +# mail client when saving e-mails as text files, feel free to hack it +# in as an option. +# +# If someone would like to hack in the ability to generate diffs based +# off of this script, by all means, be my guest. + +require 'getoptlong' + +$basedir = '/usr' +$backout_script = "backout-#{Time.now.strftime("%Y-%m-%d-%H-%M")}.sh" +$commit_authors = [] +$commit_dates = [] +$commit_file = nil +$commit_message = nil +$cvsbin = nil +$cvs_path = '/usr/bin/cvs' +$cvsrc_ignore = true +$debug = 0 +$echo_path = '/usr/bin/echo' +$echo_warnings = true +$force_script_edit = false +$force_remove = false +$output = $stdout +$quiet_script = false +$shell_path = '/bin/sh' +$shell_args = '--' + +def debug(level, *msgs) + if level <= $debug + if $debug > 1 + $output.puts "DEBUG(#{level}): #{msgs.shift}" + else + $output.puts msgs.shift + end + + for msg in msgs + $output.puts "\t #{msg}" + end + end +end # def debug() + + +def usage(msg, info = nil) + out = (msg.nil? ? $stdout : $stderr) + out.puts "#{File.basename($0)} usage:" << (msg.nil? ? '' : " #{msg}") + out.puts "#{info}" unless info.nil? + out.puts "" + out.puts " -s, --backout-script=<file> Specifies the filename of the script" + out.puts " -D, --basedir=<dir> Specifies the base directory [/usr]" + out.puts " -a, --commit-author=<uid> Forces a commit author" + out.puts " -d, --commit-date=<date> Forces a commit date" + out.puts " -m, --commit-file=<path> Specifies a commit message file" + out.puts " -M, --commit-message=<msg> Specifies a commit message" + out.puts " -c, --cvs-path=<path> Specifies the CVS binary to be used [cvs]" + out.puts " -C, --cvsrc-ignore=<bool> If true, will ignore options in ~/.cvsrc" + out.puts " -e, --echo-path=<path> Specifies the path to echo" + out.puts " -f, --force-remove=<bool> If true, removes new files [false]" + out.puts " -F, --force-edit=<bool> If true, add -C to the shell arguments in" + out.puts " the backout script if the shell is sh," + out.puts " which forces an edit of the script" + out.puts " -O, --output=<stdio> Specifies what fd to direct the output to" + out.puts " -A, --shell-args=<string> Specifies the shell arguments to be used" + out.puts " -S, --shell-path=<path> Specifies the shell to be used [/bin/sh]" + out.puts " -W, --warnings=<bool> Turns on or off warnings [true]" + exit(msg.nil? ? 0 : 1) +end + + +OPTION_LIST = [ + ['--backout-script','-s', GetoptLong::REQUIRED_ARGUMENT], + ['--basedir','-D', GetoptLong::REQUIRED_ARGUMENT], + ['--commit-author','-a', GetoptLong::REQUIRED_ARGUMENT], + ['--commit-date','-d', GetoptLong::REQUIRED_ARGUMENT], + ['--commit-file','-m', GetoptLong::REQUIRED_ARGUMENT], + ['--commit-message','-M', GetoptLong::REQUIRED_ARGUMENT], + ['--cvs-path','-c',GetoptLong::REQUIRED_ARGUMENT], + ['--cvsrc-ignore','-C',GetoptLong::REQUIRED_ARGUMENT], + ['--echo-path','-e',GetoptLong::REQUIRED_ARGUMENT], + ['--force-edit','-F',GetoptLong::REQUIRED_ARGUMENT], + ['--force-remove','-f',GetoptLong::REQUIRED_ARGUMENT], + ['--output', '-O', GetoptLong::REQUIRED_ARGUMENT], + ['--quiet-script','-q',GetoptLong::REQUIRED_ARGUMENT], + ['--shell-args','-A',GetoptLong::REQUIRED_ARGUMENT], + ['--shell-path','-S',GetoptLong::REQUIRED_ARGUMENT], + ['--warnings','-w', GetoptLong::REQUIRED_ARGUMENT], +] + +opt_parser = GetoptLong.new(*OPTION_LIST) +opt_parser.quiet = true + +begin + opt_parser.each do |opt,arg| + case opt + when '--backout-script' + debug(3, "backout script was #{$backout_script.inspect} : is #{arg.inspect}") + $backout_script = arg + when '--basedir' + debug(3, "base directory was #{$basedir.inspect} : is #{arg.inspect}") + $basedir = arg + when '--commit-author' + debug(3, "commit author #{arg.inspect} added to list") + $commit_authors.push(arg.dup) + when '--commit-date' + debug(3, "commit date #{arg.inspect} added to list") + $commit_date.push(arg.dup) + when '--commit-file' + debug(3, "commit file was #{$commit_file.inspect} : is #{arg.inspect}") + $commit_file = arg + when '--commit-message' + debug(3, "commit message was #{$commit_message.inspect} : is #{arg.inspect}") + $commit_message = arg + when '--cvs-path' + debug(3, "cvs path was #{$cvs_path.inspect} : is #{arg.inspect}") + $cvs_path = arg + when '--cvsrc-ignore' + if arg =~ /true|yes/i + $cvsrc_ignore = true + elsif arg =~ /false|no/i + $cvsrc_ignore = false + else + usage("#{opt}: unknown bool format \"#{arg}\"", "Valid options are \"true\", \"false\", \"yes\", or \"no\"") + end + debug(3, "ignoring of ~/.cvsrc is set to #{$cvsrc_ignore.inspect}") + when '--echo-path' + debug(3, "echo path was #{$echo_path.inspect} : is #{arg.inspect}") + $echo_path = arg + when '--force-edit' + if arg =~ /true|yes/i + $force_script_edit = true + elsif arg =~ /false|no/i + $force_script_edit = false + else + usage("#{opt}: unknown bool format \"#{arg}\"", "Valid options are \"true\", \"false\", \"yes\", or \"no\"") + end + debug(3, "force edit of backout script is set to #{$force_script_edit.inspect}") + when '--force-remove' + if arg =~ /true|yes/i + $force_remove = true + elsif arg =~ /false|no/i + $force_remove = false + else + usage("#{opt}: unknown bool format \"#{arg}\"", "Valid options are \"true\", \"false\", \"yes\", or \"no\"") + end + debug(3, "force removal of files is set to #{$force_remove.inspect}") + when '--output' + case arg + when 'stdout' + $output = $stdout + when 'stderr' + $output = $stderr + else + usage("#{opt}: unknown output format","Valid outputs are \"stdout\" and \"stderr\"") + end + debug(3, "output set to #{arg}") + when '--quiet-script' + if arg =~ /true|yes/i + $quiet_script = true + elsif arg =~ /false|no/i + $quiet_script = false + else + usage("#{opt}: unknown bool format \"#{arg}\"", "Valid options are \"true\", \"false\", \"yes\", or \"no\"") + end + debug(3, "quiet script is set to #{$quiet_script.inspect}") + when '--shell-args' + debug(3, "shell args were #{$shell_args.inspect} : is #{arg.inspect}") + $shell_args = arg + when '--shell-path' + debug(3, "shell path was #{$shell_path.inspect} : is #{arg.inspect}") + $shell_path = arg + when '--warnings' + if arg =~ /true|yes/i + $echo_warnings = true + elsif arg =~ /false|no/i + $echo_warnings = false + else + usage("#{opt}: unknown bool format \"#{arg}\"", "Valid options are \"true\", \"false\", \"yes\", or \"no\"") + end + debug(3, "warnings are set to #{$echo_warnings.inspect}") + end + end +rescue GetoptLong::InvalidOption + usage("invalid argument") +rescue GetoptLong::MissingArgument + usage("missing argument") +rescue GetoptLong::NeedlessArgument => msg + usage("passed an extra argument: #{msg}") +end + +debug(3, "Verbosity set to: #{$debug}") + +$cvsbin = $cvs_path +$cvsbin << " -f" if $cvsrc_ignore + +if ARGV.length < 1 + usage("require a commit message to parse") +end + +$output.puts("Backout directory:\t#{$basedir}") +$output.puts("Backout script:\t\t#{$backout_script}") +$output.puts("") + +# Backout script - to be run by hand +File.open($backout_script, "w+") do |f| + removals = [] + updates = [] + files = [] + + f.puts("#!#{$shell_path}#{($force_script_edit && $shell_path == '/bin/sh') ? ' -C' : ''} #{$shell_args}") + f.puts() + f.puts("# Generated at: #{Time.now()}") + f.puts("# Generated by: #{ENV['USER']}\@#{ENV['HOST']}") + f.puts() + f.puts("BASEDIR=#{$basedir}") + f.puts('if [ $BASEDIR != $PWD ]; then') + f.puts(' echo "Please change to $BASEDIR before running this shell script"') + f.puts(' exit 1') + f.puts('fi') + f.puts() + + author_regexp = Regexp.new(/^([^\ ]+)\s+([\d]{4})\/([\d]{2})\/([\d]{2}) ([\d]{2}):([\d]{2}):([\d]{2}) ([A-Z]{3})$/) + file_regexp = Regexp.new(/^ ([\d\.]+)\s+\+([\d]+) \-([\d]+)\s+(.*?)$/) + newdead_regexp = Regexp.new(/^(.*?) \((new|dead)\)$/) + rev_regexp = Regexp.new(/^ Revision Changes Path$/) + + for email_file in ARGV + File.open(email_file) do |e| + $output.print("Scanning through #{email_file}...") + found_files = false + for line in e + line.chomp! + if found_files == false + amd = author_regexp.match(line) + if !amd.nil? + $commit_authors.push(amd[1].dup) + $commit_dates.push(Time.local(*amd[2..7]).dup) + elsif rev_regexp.match(line) + found_files = true + end + else # if found_files + md = file_regexp.match(line) + next if md.nil? + + filename = md[4] + ndmd = newdead_regexp.match(filename) + if !ndmd.nil? + filename = ndmd[1] + if ndmd[2] == 'new' + removals.push(filename) + f.puts("#{$force_remove ? '' : '# '}#{$echo_path} -n \"Removing #{filename}...\"") if !$quiet_script + f.puts("#{$force_remove ? '' : '# '}#{$cvsbin} rm -f #{filename}") + f.puts("#{$force_remove ? '' : '# '}#{$echo_path} \"done.\"") if !$quiet_script + f.puts() + files.push(filename) + next + end + end + f.puts("#{$echo_path} -n \"Updating #{filename} to #{md[1]}...\"") if !$quiet_script + f.puts("#{$cvsbin} up -p -r #{md[1]} #{filename} > #{filename}") + f.puts("#{$echo_path} \"done.\"") if !$quiet_script + f.puts() + files.push(filename) + end # if found_files + end # for line in.. + $output.puts("done.") + end # File.open() + end # for email_file in ARGV... + + if removals.length > 0 && $force_remove == false + f.puts("#{$echo_warnings ? '' : '# '}#{$echo_path} \"You may want to remove the following file#{removals.length > 1 ? 's' : ''}:\"") + for filename in removals + f.puts("#{$echo_warnings ? '' : '# '}#{$echo_path} \"\t#{filename}\"") + end + f.puts() + f.puts("#{$echo_warnings ? '' : '# '}#{$echo_path} \"There is code in #{$backout_script} to remove #{removals.length > 1 ? 'these files' : 'this file'} for you,\"") + f.puts("#{$echo_warnings ? '' : '# '}#{$echo_path} \"just uncomment them or pass the option --force-remove=true to #{$0}.\"") + end + + f.puts() + f.puts("# # # Uncomment the following line to commit the backout.") + f.puts("# # #{$echo_path} -n \"Committing backout...\"") if !$quiet_script + if !$commit_message.nil? + if $commit_message.empty? or $commit_message =~ /^default|no|yes|true|false/i + $commit_message = "Backout of commit by #{$commit_authors.join(', ')} done on #{$commit_dates.join(', ')} because\n[___FILL_IN_THE_BLANK___]\n" + end + + f.puts() + f.puts("# # # EDIT COMMIT MESSAGE HERE") + f.puts("CVSCOMMITMSG=<<DONTUSECVSMSG") + f.puts($commit_message) + f.puts('DONTUSECVSMSG') + f.puts() + elsif !$commit_file.nil? + f.puts("if [ ! -r #{$commit_file} ]; then") + f.puts(" #{$echo_path} \"The commit message file #{$commit_file} is not readable,\"") + f.puts(" #{$echo_path} \"please fix this and re-run the script.\"") + f.puts(" exit 1") + f.puts("fi") + f.puts() + end + + f.print("# # #{$cvsbin} ci") + if !$commit_message.nil? + f.print(" -m \"$CVSCOMMITMSG\"") + elsif !$commit_file.nil? + f.print(" -F \"#{$commit_file}\"") + end + f.puts(" #{files.join(' ')}") + + if !$quiet_script + if $commit_message.nil? and $commit_file.nil? + f.print("# # #{$echo_path} \"Commit complete. Backout should be complete. Please check to verify.\"") + else + f.puts("# # #{$echo_path} \"done.\"") + end + end +end # File.open() + +$output.puts() +$output.puts("Change to #{$basedir} and run this script. Please look through this script and") +$output.puts("make changes as necessary. There are commented out commands available") +$output.puts("in the script.") +$output.puts() +if !$commit_message.nil? + $output.puts("If you scroll to the bottom of #{$backout_script} you should be able to") + $output.puts("find a HERE document with your commit message, if you would like to make") + $output.puts("any further changes to your message.") + $output.puts() +end +if !$commit_file.nil? + begin + stat = File.stat($commit_file) + rescue Errno::ENOENT + $output.puts("The output file specified, \"#{$commit_file}\" DOES NOT EXIST!!! Please be sure to") + $output.puts("create/edit the file \"#{$commit_file}\" before you run this script") + $output.puts() + end +end +$output.puts("Example script usage:") +$output.puts("\tmv #{$backout_script} #{$basedir}") +$output.puts("\tcd #{$basedir}") +$output.puts("\tless #{$backout_script}") +$output.puts("\t#{$shell_path} #{$backout_script}") +$output.puts("\trm -f #{$backout_script}") +$output.puts() diff --git a/tools/tools/build_option_survey/listallopts.sh b/tools/tools/build_option_survey/listallopts.sh new file mode 100644 index 000000000000..77c859aaee48 --- /dev/null +++ b/tools/tools/build_option_survey/listallopts.sh @@ -0,0 +1,22 @@ +#!/bin/sh +# +# $FreeBSD$ +# +# This file is in the public domain + + +set -e + +T=/tmp/_$$ + +cd /usr/src +make showconfig __MAKE_CONF=/dev/null SRCCONF=/dev/null | + sort | + sed ' + s/^MK_// + s/=// + ' | awk ' + $2 == "yes" { printf "WITHOUT_%s\n", $1 } + $2 == "no" { printf "WITH_%s\n", $1 } + ' + diff --git a/tools/tools/build_option_survey/mkhtml.sh b/tools/tools/build_option_survey/mkhtml.sh new file mode 100644 index 000000000000..a6261f918887 --- /dev/null +++ b/tools/tools/build_option_survey/mkhtml.sh @@ -0,0 +1,224 @@ +#!/bin/sh +# This file is in the public domain +# $FreeBSD$ + +set -e + +sh reduce.sh + +OPLIST=`sh listallopts.sh` + +ODIR=/usr/obj/`pwd` +RDIR=${ODIR}/_.result +export ODIR RDIR + +table_td () ( + + awk -v R=$1 -v T=$2 -v M=$4 ' + BEGIN { + t= R "-" T + } + $1 == t { + if ($3 == 0 && $5 == 0 && $7 == 0) { + printf "<TD align=center COLSPAN=5>no effect</TD>" + } else { + if ($3 == 0) { + printf "<TD align=right>+%d</TD>", $3 + } else { + printf "<TD align=right>" + printf "<A HREF=\"%s/%s.mtree.add.txt\">+%d</A>", M, t, $3 + printf "</TD>" + } + if ($5 == 0) { + printf "<TD align=right>-%d</TD>", $5 + } else { + printf "<TD align=right>" + printf "<A HREF=\"%s/%s.mtree.sub.txt\">-%d</A>", M, t, $5 + printf "</TD>" + } + if ($7 == 0) { + printf "<TD align=right>*%d</TD>", $7 + } else { + printf "<TD align=right>" + printf "<A HREF=\"%s/%s.mtree.chg.txt\">*%d</A>", M, t, $7 + printf "</TD>" + } + printf "<TD align=right>%d</TD>", $9 + printf "<TD align=right>%d</TD>", -$11 + } + printf "\n" + d = 1 + } + END { + if (d != 1) { + printf "<TD COLSPAN=5></TD>" + } + } + ' $3/stats + mkdir -p $HDIR/$4 + cp $3/r*.txt $HDIR/$4 || true +) + +HDIR=${ODIR}/HTML +rm -rf ${HDIR} +mkdir -p ${HDIR} +H=${HDIR}/index.html + +echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> +<HTML>' > $H + +echo '<HEAD> +<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> +<TITLE>FreeBSD Build Options Survey</TITLE> +</HEAD> +<BODY bgcolor="#FFFFFF"> +' >> $H + +echo ' +<H2>The table is explained at the bottom</H2> +<HR> +' >> $H + +echo '<TABLE border="1" cellspacing="0">' >> $H + +echo "<TR>" >> $H +echo "<TH ROWSPAN=2>src.conf</TH>" >> $H +echo "<TH ROWSPAN=2>MK_FOO</TH>" >> $H +echo "<TH ROWSPAN=2></TH>" >> $H +echo "<TH COLSPAN=5>BuildWorld</TH>" >> $H +echo "<TH ROWSPAN=2></TH>" >> $H +echo "<TH COLSPAN=5>InstallWorld</TH>" >> $H +echo "<TH ROWSPAN=2></TH>" >> $H +echo "<TH COLSPAN=5>World</TH>" >> $H +echo "</TR>" >> $H + +echo "<TR>" >> $H +for i in bw iw w +do + echo "<TH>A</TH>" >> $H + echo "<TH>D</TH>" >> $H + echo "<TH>C</TH>" >> $H + echo "<TH>KB</TH>" >> $H + echo "<TH>Delta</TH>" >> $H +done +echo "</TR>" >> $H + +majcol ( ) ( + echo "<TD></TD>" >> $H + if [ ! -f $3/$1/done ] ; then + echo "<TD align=center COLSPAN=5>no data yet</TD>" >> $H + elif [ -f $3/$1/_.success ] ; then + table_td $2 $1 $3 $4 >> $H + else + echo "<TD align=center COLSPAN=5>failed</TD>" >> $H + fi +) + + +for o in $OPLIST +do + md=`echo "${o}=foo" | md5` + m=${RDIR}/$md + if [ ! -d $m ] ; then + continue + fi + if [ ! -f $m/stats ] ; then + continue + fi + echo "=== mkhtml ${d}_${o}" + + echo "<TR>" >> $H + echo "<TD><PRE>" >> $H + cat $m/src.conf >> $H + echo "</PRE></TD>" >> $H + echo "<TD><PRE>" >> $H + if [ -f $m/bw/_.sc ] ; then + comm -13 ${RDIR}/Ref/_.sc $m/bw/_.sc >> $H + fi + echo "</PRE></TD>" >> $H + + majcol bw r $m $md + majcol iw r $m $md + majcol w r $m $md + echo "</TR>" >> $H +done +echo "</TABLE>" >> $H +echo ' +<HR> +<H2>How to read this table</H2> +<P> +The table has five major columns. + +<OL> +<LI><P><B>src.conf</B></P> +<P>The name of the option being tested</P> +<P> +All options are tested both in their WITH_FOO and WITHOUT_FOO variants +but if the option has no effect (ie: is the default) it will not appear +in the table +</P> +</LI> + +<LI><P><B>MK_FOO</B></P> +<P>Internal build flags affected by this option </P> +</LI> + +<LI><P><B>Buildworld</B></P> +<P>What happens when the option is given to buildworld but not installworld</P> +<PRE>Ie: + make buildworld WITH_FOO=yes + make installworld +</PRE> +</LI> + +<LI><P><B>Installworld</B></P> +<P>What happens when the option is given to installworld but not buildworld</P> +<PRE>Ie: + make buildworld + make installworld WITH_FOO=yes +</PRE> +</LI> + +<LI><P><B>World</B></P> +<P>What happens when the option is given to both buildworld and installworld</P> +<PRE>Ie: + make buildworld WITH_FOO=yes + make installworld WITH_FOO=yes +</PRE> +</LI> +</OL> + +<P>Inside each of the last three major columns there are five subcolumns</P> +<OL> +<LI><P><B>A</B></P> +<P>Number of added files/directories (relative to the option not be given</P> +<P>If non-zero, the number links to a list of the added files/directories</P> +</LI> +<LI><P><B>D</B></P> +<P>Number of deleted files/directories (relative to the option not be given</P> +<P>If non-zero, the number links to a list of the files not installed files/directories</P> +</LI> +<LI><P><B>C</B></P> +<P>Number of changed files/directories (relative to the option not be given</P> +<P>If non-zero, the number links to a list of the files/directories which are differnet (two lines each)</P> +</LI> +<LI><P><B>KB</B></P> +<P>Size of installed operating system in kilobytes</P> +<LI><P><B>Delta</B></P> +<P>Size change in kilobytes relative to the option not be given</P> +</LI> +</OL> + +<HR>' >> $H +echo ' +<p> + <a href="http://validator.w3.org/check?uri=referer"><img + src="http://www.w3.org/Icons/valid-html401" + alt="Valid HTML 4.01 Transitional" height="31" width="88"></a> +</p> + +' >> $H +echo "</HTML>" >> $H + +echo "rsync phk" +rsync -r $HDIR/. phk@phk:www/misc/build_options diff --git a/tools/tools/build_option_survey/option_survey.sh b/tools/tools/build_option_survey/option_survey.sh new file mode 100644 index 000000000000..3fee3164de0f --- /dev/null +++ b/tools/tools/build_option_survey/option_survey.sh @@ -0,0 +1,198 @@ +#!/bin/sh +# This file is in the public domain +# $FreeBSD$ + +set -ex + +OPLIST=`sh listallopts.sh` + +MDUNIT=47 +export MDUNIT + +ODIR=/usr/obj/`pwd` +FDIR=${ODIR}/files +MNT=${ODIR}/_.mnt +RDIR=${ODIR}/_.result + +export ODIR MNT RDIR FDIR + +bw ( ) ( + cd ../../.. + make showconfig \ + SRCCONF=${ODIR}/src.conf __MAKE_CONF=/dev/null \ + > ${FDIR}/_.sc 2>&1 + a=$? + echo retval $a + if [ $a -ne 0 ] ; then + exit 1 + fi + make -j 4 buildworld \ + SRCCONF=${ODIR}/src.conf __MAKE_CONF=/dev/null \ + > ${FDIR}/_.bw 2>&1 + a=$? + echo retval $a + if [ $a -ne 0 ] ; then + exit 1 + fi + make -j 4 buildkernel \ + KERNCONF=GENERIC \ + SRCCONF=${ODIR}/src.conf __MAKE_CONF=/dev/null \ + > ${FDIR}/_.bk 2>&1 + a=$? + echo retval $a + if [ $a -ne 0 ] ; then + exit 1 + fi + exit 0 +) + +iw ( ) ( + trap "umount ${MNT} || true" 1 2 15 EXIT + newfs -O1 -U -b 4096 -f 512 /dev/md$MDUNIT + mkdir -p ${MNT} + mount /dev/md${MDUNIT} ${MNT} + + cd ../../.. + make installworld \ + SRCCONF=${ODIR}/src.conf __MAKE_CONF=/dev/null \ + DESTDIR=${MNT} \ + > ${FDIR}/_.iw 2>&1 + a=$? + echo retval $a + if [ $a -ne 0 ] ; then + exit 1 + fi + cd etc + make distribution \ + SRCCONF=${ODIR}/src.conf __MAKE_CONF=/dev/null \ + DESTDIR=${MNT} \ + > ${FDIR}/_.etc 2>&1 + a=$? + echo retval $a + if [ $a -ne 0 ] ; then + exit 1 + fi + cd .. + make installkernel \ + KERNCONF=GENERIC \ + DESTDIR=${MNT} \ + SRCCONF=${ODIR}/src.conf __MAKE_CONF=/dev/null \ + > ${FDIR}/_.ik 2>&1 + a=$? + echo retval $a + if [ $a -ne 0 ] ; then + exit 1 + fi + + sync ${MNT} + ( cd ${MNT} && mtree -c ) > ${FDIR}/_.mtree + ( cd ${MNT} && du ) > ${FDIR}/_.du + ( df -i ${MNT} ) > ${FDIR}/_.df + echo success > ${FDIR}/_.success + sync + sleep 1 + sync + sleep 1 + trap "" 1 2 15 EXIT + umount ${MNT} + echo "iw done" +) + + +# Clean and recreate the ODIR + +if true ; then + echo "=== Clean and recreate ${ODIR}" + if rm -rf ${ODIR} ; then + true + else + chflags -R noschg ${ODIR} + rm -rf ${ODIR} + fi + mkdir -p ${ODIR} ${FDIR} ${MNT} + +fi + +trap "umount ${MNT} || true; mdconfig -d -u $MDUNIT" 1 2 15 EXIT + +umount $MNT || true +mdconfig -d -u $MDUNIT || true +dd if=/dev/zero of=${ODIR}/imgfile bs=1m count=250 +mdconfig -a -t vnode -f ${ODIR}/imgfile -u $MDUNIT + +# Build & install the reference world + +if true ; then + echo "=== Build reference world" + echo '' > ${ODIR}/src.conf + MAKEOBJDIRPREFIX=$ODIR/_.ref + export MAKEOBJDIRPREFIX + bw + echo "=== Install reference world" + mkdir -p ${RDIR}/Ref + iw + mv ${FDIR}/_.* ${RDIR}/Ref +fi + +# Parse option list into subdirectories with src.conf files. + +if true ; then + rm -rf ${RDIR}/[0-9a-f]* + for o in $OPLIST + do + echo "${o}=foo" > ${FDIR}/_src.conf + m=`md5 < ${FDIR}/_src.conf` + mkdir -p ${RDIR}/$m + mv ${FDIR}/_src.conf ${RDIR}/$m/src.conf + done +fi + +# Run through each testtarget in turn + +if true ; then + for d in ${RDIR}/[0-9a-z]* + do + if [ ! -d $d ] ; then + continue; + fi + echo '------------------------------------------------' + cat $d/src.conf + echo '------------------------------------------------' + cp $d/src.conf ${ODIR}/src.conf + + if [ ! -f $d/iw/done ] ; then + MAKEOBJDIRPREFIX=$ODIR/_.ref + export MAKEOBJDIRPREFIX + echo "# BW(ref)+IW(ref) `cat $d/src.conf`" + rm -rf $d/iw + mkdir -p $d/iw + iw || true + mv ${FDIR}/_.* $d/iw || true + touch $d/iw/done + fi + if [ ! -f $d/bw/done ] ; then + MAKEOBJDIRPREFIX=$ODIR/_.tst + export MAKEOBJDIRPREFIX + echo "# BW(opt) `cat $d/src.conf`" + rm -rf $d/w $d/bw + mkdir -p $d/w $d/bw + if bw ; then + mv ${FDIR}/_.* $d/bw || true + + echo "# BW(opt)+IW(opt) `cat $d/src.conf`" + iw || true + mv ${FDIR}/_.* $d/w || true + touch $d/w/done + + echo "# BW(opt)+IW(ref) `cat $d/src.conf`" + echo '' > ${ODIR}/src.conf + iw || true + mv ${FDIR}/_.* $d/bw || true + touch $d/bw/done + else + mv ${FDIR}/_.* $d/bw || true + touch $d/bw/done $d/w/done + fi + fi + done +fi diff --git a/tools/tools/build_option_survey/reduce.sh b/tools/tools/build_option_survey/reduce.sh new file mode 100644 index 000000000000..375574987574 --- /dev/null +++ b/tools/tools/build_option_survey/reduce.sh @@ -0,0 +1,77 @@ +#!/bin/sh +# This file is in the public domain +# $FreeBSD$ + +set -e + +OPLIST=`sh listallopts.sh` + +ODIR=/usr/obj/`pwd` +RDIR=${ODIR}/_.result +export ODIR RDIR + + +compa ( ) ( + if [ ! -f $1/_.mtree ] ; then + return + fi + if [ ! -f $2/_.mtree ] ; then + return + fi + + mtree -k uid,gid,mode,nlink,size,link,type,flags \ + -f ${1}/_.mtree -f $2/_.mtree > $2/_.mtree.all.txt || true + grep '^ ' $2/_.mtree.all.txt > $4/$3.mtree.chg.txt || true + grep '^[^ ]' $2/_.mtree.all.txt > $4/$3.mtree.sub.txt || true + grep '^ [^ ]' $2/_.mtree.all.txt > $4/$3.mtree.add.txt || true + a=`wc -l < $4/$3.mtree.add.txt` + s=`wc -l < $4/$3.mtree.sub.txt` + c=`wc -l < $4/$3.mtree.chg.txt` + c=`expr $c / 2 || true` + + br=`awk 'NR == 2 {print $3}' $1/_.df` + bt=`awk 'NR == 2 {print $3}' $2/_.df` + echo $3 A $a S $s C $c B $bt D `expr $br - $bt` +) + +for o in $OPLIST +do + md=`echo "${o}=foo" | md5` + m=${RDIR}/$md + if [ ! -d $m ] ; then + continue + fi + if [ ! -d $m/iw -a ! -d $m/bw -a ! -d $m/w ] ; then + continue + fi + echo "=== reduce ${o}" + + echo + echo ------------------------------------------------------------- + echo $md + cat $m/src.conf + echo ------------------------------------------------------------- + if [ ! -f $m/iw/done ] ; then + echo "IW pending" + elif [ ! -f $m/iw/_.success ] ; then + echo "IW failed" + fi + if [ ! -f $m/bw/done ] ; then + echo "BW pending" + elif [ ! -f $m/bw/_.success ] ; then + echo "BW failed" + fi + if [ ! -f $m/w/done ] ; then + echo "W pending" + elif [ ! -f $m/w/_.success ] ; then + echo "W failed" + fi + ( + for x in iw bw w + do + compa ${RDIR}/Ref/ $m/$x r-$x $m + done + ) > $m/stats + cat $m/stats +done +echo "== reduce done" diff --git a/tools/tools/bus_autoconf/Makefile b/tools/tools/bus_autoconf/Makefile new file mode 100644 index 000000000000..c7104de478ec --- /dev/null +++ b/tools/tools/bus_autoconf/Makefile @@ -0,0 +1,46 @@ +# $FreeBSD$ +# +# Copyright (c) 2011 Hans Petter Selasky. 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. +# 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. +# + +# +# Example on how to use: +# +# make clean all install +# +# ./bus_autoconf.sh /boot/kernel/*.ko | less +# + +PROG= bus_autoconf +MAN= +BINDIR?= /usr/local/bin + +SRCS+= bus_autoconf.c +SRCS+= bus_load_file.c +SRCS+= bus_sections.c +SRCS+= bus_usb.c + +WARNS= 6 + +.include <bsd.prog.mk> diff --git a/tools/tools/bus_autoconf/bus_autoconf.c b/tools/tools/bus_autoconf/bus_autoconf.c new file mode 100644 index 000000000000..bd5d11ef092c --- /dev/null +++ b/tools/tools/bus_autoconf/bus_autoconf.c @@ -0,0 +1,125 @@ +/* $FreeBSD$ */ + +/*- + * Copyright (c) 2011 Hans Petter Selasky. 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. + * 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. + */ + +/* + * Disclaimer: This utility and format is subject to change and not a + * committed interface. + */ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <err.h> +#include <sysexits.h> +#include <unistd.h> + +#include "bus_autoconf.h" +#include "bus_sections.h" +#include "bus_load_file.h" +#include "bus_usb.h" + +static void +usage(void) +{ + fprintf(stderr, + "bus_autoconf - devd config file generator\n" + " -i <structure_type,module.ko>\n" + " -F <format_file>\n" + " -h show usage\n" + ); + exit(EX_USAGE); +} + +int +main(int argc, char **argv) +{ + const char *params = "i:F:h"; + char *fname; + char *section; + char *module; + char *postfix; + uint8_t *ptr; + uint32_t len; + int c; + int any_opt = 0; + + while ((c = getopt(argc, argv, params)) != -1) { + switch (c) { + case 'i': + fname = optarg; + load_file(fname, &ptr, &len); + + module = strchr(fname, ','); + if (module == NULL) { + errx(EX_USAGE, "Invalid input " + "file name '%s'", fname); + } + /* split module and section */ + *module++ = 0; + + /* remove postfix */ + postfix = strchr(module, '.'); + if (postfix) + *postfix = 0; + + /* get section name */ + section = fname; + + /* check section type */ + if (strncmp(section, "usb_", 4) == 0) + usb_import_entries(section, module, ptr, len); + else + errx(EX_USAGE, "Invalid section '%s'", section); + + free(ptr); + + any_opt = 1; + break; + + case 'F': + fname = optarg; + load_file(fname, &ptr, &len); + format_parse_entries(ptr, len); + free(ptr); + + any_opt = 1; + break; + + default: + usage(); + break; + } + } + + if (any_opt == 0) + usage(); + + usb_dump_entries(); + + return (0); +} diff --git a/tools/tools/bus_autoconf/bus_autoconf.h b/tools/tools/bus_autoconf/bus_autoconf.h new file mode 100644 index 000000000000..0a1ca3fb3163 --- /dev/null +++ b/tools/tools/bus_autoconf/bus_autoconf.h @@ -0,0 +1,31 @@ +/* $FreeBSD$ */ + +/*- + * Copyright (c) 2011 Hans Petter Selasky. 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. + * 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. + */ + +#ifndef _BUS_AUTOCONF_H_ +#define _BUS_AUTOCONF_H_ + +#endif /* _BUS_AUTOCONF_H_ */ diff --git a/tools/tools/bus_autoconf/bus_autoconf.sh b/tools/tools/bus_autoconf/bus_autoconf.sh new file mode 100644 index 000000000000..c99df91e18f7 --- /dev/null +++ b/tools/tools/bus_autoconf/bus_autoconf.sh @@ -0,0 +1,78 @@ +#!/bin/sh +# +# $FreeBSD$ +# +# Copyright (c) 2011 Hans Petter Selasky. 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. +# 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. +# + +OS=FreeBSD +DOLLAR=$ +OBJCOPY=objcopy + +cat <<EOF +# +# ${DOLLAR}${OS}${DOLLAR} +# +# This file was automatically generated by "tools/bus_autoconf.sh". +# Please do not edit! +# + +EOF + +rm -f bus_autoconf_format.bin +rm -f bus_autoconf_args.txt +rm -f bus_autoconf.ids + +for F in $* +do + +G=$(basename ${F}) + +# Format information +${OBJCOPY} -j bus_autoconf_format -O binary ${F} bus_autoconf.ids 2> /dev/null +[ -f bus_autoconf.ids ] && cat bus_autoconf.ids >> bus_autoconf_format.bin + +# USB Host mode +${OBJCOPY} -j usb_host_id -O binary ${F} "usb_host_id,${G}" 2> /dev/null +[ -f "usb_host_id,${G}" ] && (echo -n " -i usb_host_id,${G}" >> bus_autoconf_args.txt) + +# USB Device mode +${OBJCOPY} -j usb_device_id -O binary ${F} "usb_device_id,${G}" 2> /dev/null +[ -f "usb_device_id,${G}" ] && (echo -n " -i usb_device_id,${G}" >> bus_autoconf_args.txt) + +# USB Dual mode +${OBJCOPY} -j usb_dual_id -O binary ${F} "usb_dual_id,${G}" 2> /dev/null +[ -f "usb_dual_id,${G}" ] && (echo -n " -i usb_dual_id,${G}" >> bus_autoconf_args.txt) + +done + +# Dump all data +bus_autoconf -F bus_autoconf_format.bin $(cat bus_autoconf_args.txt) + +# Cleanup +rm -f -- \ + $(cat bus_autoconf_args.txt) \ + bus_autoconf_args.txt \ + bus_autoconf_format.bin \ + bus_autoconf.ids diff --git a/tools/tools/bus_autoconf/bus_autoconf_format_example.txt b/tools/tools/bus_autoconf/bus_autoconf_format_example.txt new file mode 100644 index 000000000000..e118f1faebcc --- /dev/null +++ b/tools/tools/bus_autoconf/bus_autoconf_format_example.txt @@ -0,0 +1,111 @@ +/* $FreeBSD$ */ + +#if BYTE_ORDER == BIG_ENDIAN +#define U16_XOR "8" +#define U32_XOR "12" +#define U64_XOR "56" +#define U8_BITFIELD_XOR "7" +#define U16_BITFIELD_XOR "15" +#define U32_BITFIELD_XOR "31" +#define U64_BITFIELD_XOR "63" +#else +#define U16_XOR "0" +#define U32_XOR "0" +#define U64_XOR "0" +#define U8_BITFIELD_XOR "0" +#define U16_BITFIELD_XOR "0" +#define U32_BITFIELD_XOR "0" +#define U64_BITFIELD_XOR "0" +#endif + +#if USB_HAVE_COMPAT_LINUX +#define MFL_SIZE "1" +#else +#define MFL_SIZE "0" +#endif + +static const char __section("bus_autoconf_format") __used usb_id_format[] = { + + /* + * Declare three different sections that use the same format. + * All sizes are in bits. Fields cannot be greater than + * 8 bits in size. Bitfields having a size greater than 1 + * must fit within the byte in which the bitfield is defined. + */ + + "usb_host_id{256,:}" + "usb_device_id{256,:}" + "usb_dual_id{256,:}" + + /* + * Describe all fields in the usb_device_id structure + * which is found in sys/dev/usb/usbdi.h. + */ + +#if BITS_PER_LONG == 32 || BITS_PER_LONG == 64 + "unused{0,8}" + "unused{0,8}" + "unused{0,8}" + "unused{0,8}" +#if BITS_PER_LONG == 64 + "unused{0,8}" + "unused{0,8}" + "unused{0,8}" + "unused{0,8}" +#endif +#else +#error "Please update code." +#endif + + "idVendor[0]{" U16_XOR ",8}" + "idVendor[1]{" U16_XOR ",8}" + "idProduct[0]{" U16_XOR ",8}" + "idProduct[1]{" U16_XOR ",8}" + "bcdDevice_lo[0]{" U16_XOR ",8}" + "bcdDevice_lo[1]{" U16_XOR ",8}" + "bcdDevice_hi[0]{" U16_XOR ",8}" + "bcdDevice_hi[1]{" U16_XOR ",8}" + + "bDeviceClass{0,8}" + "bDeviceSubClass{0,8}" + "bDeviceProtocol{0,8}" + "bInterfaceClass{0,8}" + "bInterfaceSubClass{0,8}" + "bInterfaceProtocol{0,8}" + +/* NOTE: On big endian machines bitfields are bitreversed. */ + + "mf_vendor{" U8_BITFIELD_XOR ",1}" + "mf_product{" U8_BITFIELD_XOR ",1}" + "mf_dev_lo{" U8_BITFIELD_XOR ",1}" + "mf_dev_hi{" U8_BITFIELD_XOR ",1}" + + "mf_dev_class{" U8_BITFIELD_XOR ",1}" + "mf_dev_subclass{" U8_BITFIELD_XOR ",1}" + "mf_dev_protocol{" U8_BITFIELD_XOR ",1}" + "mf_int_class{" U8_BITFIELD_XOR ",1}" + + "mf_int_subclass{" U8_BITFIELD_XOR ",1}" + "mf_int_protocol{" U8_BITFIELD_XOR ",1}" + "unused{" U8_BITFIELD_XOR ",6}" + + "mfl_vendor{" U16_XOR "," MFL_SIZE "}" + "mfl_product{" U16_XOR "," MFL_SIZE "}" + "mfl_dev_lo{" U16_XOR "," MFL_SIZE "}" + "mfl_dev_hi{" U16_XOR "," MFL_SIZE "}" + + "mfl_dev_class{" U16_XOR "," MFL_SIZE "}" + "mfl_dev_subclass{" U16_XOR "," MFL_SIZE "}" + "mfl_dev_protocol{" U16_XOR "," MFL_SIZE "}" + "mfl_int_class{" U16_XOR "," MFL_SIZE "}" + + "mfl_int_subclass{" U16_XOR "," MFL_SIZE "}" + "mfl_int_protocol{" U16_XOR "," MFL_SIZE "}" + "unused{" U16_XOR "," MFL_SIZE "}" + "unused{" U16_XOR "," MFL_SIZE "}" + + "unused{" U16_XOR "," MFL_SIZE "}" + "unused{" U16_XOR "," MFL_SIZE "}" + "unused{" U16_XOR "," MFL_SIZE "}" + "unused{" U16_XOR "," MFL_SIZE "}" +}; diff --git a/tools/tools/bus_autoconf/bus_load_file.c b/tools/tools/bus_autoconf/bus_load_file.c new file mode 100644 index 000000000000..527e5bce49bf --- /dev/null +++ b/tools/tools/bus_autoconf/bus_load_file.c @@ -0,0 +1,76 @@ +/* $FreeBSD$ */ + +/*- + * Copyright (c) 2011 Hans Petter Selasky. 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. + * 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. + */ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <fcntl.h> +#include <err.h> +#include <sysexits.h> +#include <unistd.h> + +#include "bus_load_file.h" + +void +load_file(const char *fname, uint8_t **pptr, uint32_t *plen) +{ + uint8_t *ptr; + uint32_t len; + off_t off; + int f; + + f = open(fname, O_RDONLY); + if (f < 0) + err(EX_NOINPUT, "Cannot open file '%s'", fname); + + off = lseek(f, 0, SEEK_END); + if (off < 0) { + err(EX_NOINPUT, "Cannot seek to " + "end of file '%s'", fname); + } + + if (lseek(f, 0, SEEK_SET) < 0) { + err(EX_NOINPUT, "Cannot seek to " + "beginning of file '%s'", fname); + } + + len = off; + if (len != off) + err(EX_NOINPUT, "File '%s' is too big", fname); + + ptr = malloc(len); + if (ptr == NULL) + errx(EX_SOFTWARE, "Out of memory"); + + if (read(f, ptr, len) != len) + err(EX_NOINPUT, "Cannot read all data"); + + close(f); + + *pptr = ptr; + *plen = len; +} diff --git a/tools/tools/bus_autoconf/bus_load_file.h b/tools/tools/bus_autoconf/bus_load_file.h new file mode 100644 index 000000000000..57e7739c6155 --- /dev/null +++ b/tools/tools/bus_autoconf/bus_load_file.h @@ -0,0 +1,33 @@ +/* $FreeBSD$ */ + +/*- + * Copyright (c) 2011 Hans Petter Selasky. 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. + * 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. + */ + +#ifndef _BUS_LOAD_FILE_H_ +#define _BUS_LOAD_FILE_H_ + +void load_file(const char *, uint8_t **, uint32_t *); + +#endif /* _BUS_LOAD_FILE_H_ */ diff --git a/tools/tools/bus_autoconf/bus_sections.c b/tools/tools/bus_autoconf/bus_sections.c new file mode 100644 index 000000000000..c3260487d1c3 --- /dev/null +++ b/tools/tools/bus_autoconf/bus_sections.c @@ -0,0 +1,223 @@ +/* $FreeBSD$ */ + +/*- + * Copyright (c) 2011 Hans Petter Selasky. 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. + * 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. + */ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <unistd.h> +#include <sysexits.h> +#include <err.h> +#include <string.h> + +#include <sys/queue.h> + +#include "bus_sections.h" + +#define MAX_STRING 64 + +struct format_info; +typedef TAILQ_HEAD(,format_info) format_info_head_t; +typedef TAILQ_ENTRY(format_info) format_info_entry_t; + +static format_info_head_t format_head = TAILQ_HEAD_INITIALIZER(format_head); + +struct format_info { + format_info_entry_t entry; + format_info_head_t fields; + char name[MAX_STRING]; + uint16_t bit_offset; + uint16_t bit_size; +}; + +static struct format_info * +format_info_new(char *pstr, uint16_t bo, uint16_t bs) +{ + struct format_info *pfi; + + pfi = malloc(sizeof(*pfi)); + if (pfi == NULL) + errx(EX_SOFTWARE, "Out of memory."); + + memset(pfi, 0, sizeof(*pfi)); + + TAILQ_INIT(&pfi->fields); + + strlcpy(pfi->name, pstr, sizeof(pfi->name)); + pfi->bit_offset = bo; + pfi->bit_size = bs; + return (pfi); +} + +static const struct format_info * +format_get_section(const char *section) +{ + const struct format_info *psub; + static const struct format_info *psub_last; + static const char *psub_cache; + + if (psub_cache && strcmp(psub_cache, section) == 0) + return (psub_last); + + TAILQ_FOREACH(psub, &format_head, entry) { + if (strcmp(section, psub->name) == 0) { + psub_cache = section; + psub_last = psub; + return (psub); + } + } + warnx("Section '%s' not found", section); + psub_cache = section; + psub_last = psub; + return (NULL); +} + +uint16_t +format_get_section_size(const char *section) +{ + const struct format_info *pfi; + + pfi = format_get_section(section); + if (pfi == NULL) + return (0); + + return ((pfi->bit_offset + 7) / 8); +} + + +uint8_t +format_get_field(const char *section, const char *field, + const uint8_t *ptr, uint16_t size) +{ + const struct format_info *pfi; + const struct format_info *psub; + uint16_t rem; + uint16_t off; + uint16_t sz; + + pfi = format_get_section(section); + if (pfi == NULL) + return (0); + + /* skip until we find the fields */ + while (pfi && TAILQ_FIRST(&pfi->fields) == NULL) + pfi = TAILQ_NEXT(pfi, entry); + + if (pfi == NULL) + return (0); + + TAILQ_FOREACH(psub, &pfi->fields, entry) { + if (strcmp(field, psub->name) == 0) { + + /* range check */ + if (((psub->bit_offset + psub->bit_size) / 8) > size) + return (0); + + /* compute byte offset */ + rem = psub->bit_offset & 7; + off = psub->bit_offset / 8; + sz = psub->bit_size; + + /* extract bit-field */ + return ((ptr[off] >> rem) & ((1 << sz) - 1)); + } + } + warnx("Field '%s' not found in '%s'", field, pfi->name); + return (0); +} + +void +format_parse_entries(const uint8_t *ptr, uint32_t len) +{ + static const char *command_list = "012345678:"; + const char *cmd; + struct format_info *pfi; + struct format_info *pfi_last = NULL; + char linebuf[3][MAX_STRING]; + uint32_t off = 0; + uint16_t bit_offset = 0; + uint8_t state = 0; + uint8_t cmd_index; + int c; + + /* + * The format we are parsing: + * <string>{string,string}<next_string>{...} + */ + while (len--) { + c = *(ptr++); + + /* skip some characters */ + if (c == 0 || c == '\n' || c == '\r' || c == ' ' || c == '\t') + continue; + + /* accumulate non-field delimiters */ + if (strchr("{,}", c) == NULL) { + if (off < (MAX_STRING - 1)) { + linebuf[state][off] = c; + off++; + } + continue; + } + /* parse keyword */ + linebuf[state][off] = 0; + off = 0; + state++; + if (state == 3) { + /* check for command in command list */ + cmd = strchr(command_list, linebuf[2][0]); + if (cmd != NULL) + cmd_index = cmd - command_list; + else + cmd_index = 255; + + /* + * Check for new field, format is: + * + * <field_name>{bit_offset_xor, bit_size} + */ + if (cmd_index < 9 && pfi_last != NULL) { + pfi = format_info_new(linebuf[0], bit_offset ^ + atoi(linebuf[1]), cmd_index); + TAILQ_INSERT_TAIL(&pfi_last->fields, pfi, entry); + bit_offset += cmd_index; + } + /* + * Check for new section, format is: + * + * <section_name>{section_bit_size, :} + */ + if (cmd_index == 9) { + pfi_last = format_info_new(linebuf[0], + atoi(linebuf[1]), cmd_index); + TAILQ_INSERT_TAIL(&format_head, pfi_last, entry); + bit_offset = 0; + } + state = 0; + continue; + } + } +} diff --git a/tools/tools/bus_autoconf/bus_sections.h b/tools/tools/bus_autoconf/bus_sections.h new file mode 100644 index 000000000000..2c4c6fc86f20 --- /dev/null +++ b/tools/tools/bus_autoconf/bus_sections.h @@ -0,0 +1,35 @@ +/* $FreeBSD$ */ + +/*- + * Copyright (c) 2011 Hans Petter Selasky. 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. + * 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. + */ + +#ifndef _BUS_SECTIONS_H_ +#define _BUS_SECTIONS_H_ + +uint16_t format_get_section_size(const char *); +uint8_t format_get_field(const char *, const char *, const uint8_t *, uint16_t); +void format_parse_entries(const uint8_t *, uint32_t); + +#endif /* _BUS_SECTIONS_H_ */ diff --git a/tools/tools/bus_autoconf/bus_usb.c b/tools/tools/bus_autoconf/bus_usb.c new file mode 100644 index 000000000000..f15dd49a98b4 --- /dev/null +++ b/tools/tools/bus_autoconf/bus_usb.c @@ -0,0 +1,386 @@ +/* $FreeBSD$ */ + +/*- + * Copyright (c) 2011 Hans Petter Selasky. 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. + * 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. + */ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <err.h> +#include <sysexits.h> +#include <unistd.h> +#include <sys/queue.h> + +#include "bus_autoconf.h" +#include "bus_sections.h" +#include "bus_usb.h" + +struct usb_blob; +typedef TAILQ_HEAD(,usb_blob) usb_blob_head_t; +typedef TAILQ_ENTRY(usb_blob) usb_blob_entry_t; + +static usb_blob_head_t usb_blob_head = TAILQ_HEAD_INITIALIZER(usb_blob_head); +static uint32_t usb_blob_count; + +struct usb_blob { + usb_blob_entry_t entry; + struct usb_device_id temp; +}; + +/* + * To ensure that the correct USB driver is loaded, the driver having + * the most information about the device must be probed first. Then + * more generic drivers shall be probed. + */ +static int +usb_compare(const void *_a, const void *_b) +{ + const struct usb_device_id *a = _a; + const struct usb_device_id *b = _b; + int retval; + + /* vendor matches first */ + + if (a->match_flag_vendor > b->match_flag_vendor) + return (-1); + if (a->match_flag_vendor < b->match_flag_vendor) + return (1); + + /* product matches first */ + + if (a->match_flag_product > b->match_flag_product) + return (-1); + if (a->match_flag_product < b->match_flag_product) + return (1); + + /* device class matches first */ + + if (a->match_flag_dev_class > b->match_flag_dev_class) + return (-1); + if (a->match_flag_dev_class < b->match_flag_dev_class) + return (1); + + if (a->match_flag_dev_subclass > b->match_flag_dev_subclass) + return (-1); + if (a->match_flag_dev_subclass < b->match_flag_dev_subclass) + return (1); + + /* interface class matches first */ + + if (a->match_flag_int_class > b->match_flag_int_class) + return (-1); + if (a->match_flag_int_class < b->match_flag_int_class) + return (1); + + if (a->match_flag_int_subclass > b->match_flag_int_subclass) + return (-1); + if (a->match_flag_int_subclass < b->match_flag_int_subclass) + return (1); + + if (a->match_flag_int_protocol > b->match_flag_int_protocol) + return (-1); + if (a->match_flag_int_protocol < b->match_flag_int_protocol) + return (1); + + /* then sort according to value */ + + if (a->idVendor > b->idVendor) + return (1); + if (a->idVendor < b->idVendor) + return (-1); + if (a->idProduct > b->idProduct) + return (1); + if (a->idProduct < b->idProduct) + return (-1); + if (a->bDeviceClass > b->bDeviceClass) + return (1); + if (a->bDeviceClass < b->bDeviceClass) + return (-1); + if (a->bDeviceSubClass > b->bDeviceSubClass) + return (1); + if (a->bDeviceSubClass < b->bDeviceSubClass) + return (-1); + if (a->bDeviceProtocol > b->bDeviceProtocol) + return (1); + if (a->bDeviceProtocol < b->bDeviceProtocol) + return (-1); + if (a->bInterfaceClass > b->bInterfaceClass) + return (1); + if (a->bInterfaceClass < b->bInterfaceClass) + return (-1); + if (a->bInterfaceSubClass > b->bInterfaceSubClass) + return (1); + if (a->bInterfaceSubClass < b->bInterfaceSubClass) + return (-1); + if (a->bInterfaceProtocol > b->bInterfaceProtocol) + return (1); + if (a->bInterfaceProtocol < b->bInterfaceProtocol) + return (-1); + + /* in the end sort by module name and mode */ + + retval = strcmp(a->module_name, b->module_name); + if (retval == 0) + retval = strcmp(a->module_mode, b->module_mode); + return (retval); +} + +static void +usb_sort_entries(struct usb_device_id *id, uint32_t nid) +{ + qsort(id, nid, sizeof(*id), &usb_compare); +} + +static void +usb_import_entry(struct usb_device_id *id, const char *type, + const char *module, const uint8_t *ptr, uint16_t size) +{ + const char *mode; + + if (strstr(type, "_host_")) + mode = "host"; + else if (strstr(type, "_device_")) + mode = "device"; + else + mode = "(host|device)"; + + strlcpy(id->module_name, module, sizeof(id->module_name)); + strlcpy(id->module_mode, mode, sizeof(id->module_mode)); + + /* import data from binary object */ + + if (format_get_field(type, "mfl_vendor", ptr, size)) + id->match_flag_vendor = 1; + if (format_get_field(type, "mfl_product", ptr, size)) + id->match_flag_product = 1; + if (format_get_field(type, "mfl_dev_lo", ptr, size)) + id->match_flag_dev_lo = 1; + if (format_get_field(type, "mfl_dev_hi", ptr, size)) + id->match_flag_dev_hi = 1; + if (format_get_field(type, "mfl_dev_class", ptr, size)) + id->match_flag_dev_class = 1; + if (format_get_field(type, "mfl_dev_subclass", ptr, size)) + id->match_flag_dev_subclass = 1; + if (format_get_field(type, "mfl_dev_protocol", ptr, size)) + id->match_flag_dev_protocol = 1; + if (format_get_field(type, "mfl_int_class", ptr, size)) + id->match_flag_int_class = 1; + if (format_get_field(type, "mfl_int_subclass", ptr, size)) + id->match_flag_int_subclass = 1; + if (format_get_field(type, "mfl_int_protocol", ptr, size)) + id->match_flag_int_protocol = 1; + + id->idVendor = format_get_field(type, "idVendor[0]", ptr, size) | + (format_get_field(type, "idVendor[1]", ptr, size) << 8); + id->idProduct = format_get_field(type, "idProduct[0]", ptr, size) | + (format_get_field(type, "idProduct[1]", ptr, size) << 8); + + id->bcdDevice_lo = format_get_field(type, "bcdDevice_lo[0]", ptr, size) | + (format_get_field(type, "bcdDevice_lo[1]", ptr, size) << 8); + + id->bcdDevice_hi = format_get_field(type, "bcdDevice_hi[0]", ptr, size) | + (format_get_field(type, "bcdDevice_hi[1]", ptr, size) << 8); + + id->bDeviceClass = format_get_field(type, "bDeviceClass", ptr, size); + id->bDeviceSubClass = format_get_field(type, "bDeviceSubClass", ptr, size); + id->bDeviceProtocol = format_get_field(type, "bDeviceProtocol", ptr, size); + + id->bInterfaceClass = format_get_field(type, "bInterfaceClass", ptr, size); + id->bInterfaceSubClass = format_get_field(type, "bInterfaceSubClass", ptr, size); + id->bInterfaceProtocol = format_get_field(type, "bInterfaceProtocol", ptr, size); + + if (format_get_field(type, "mf_vendor", ptr, size)) + id->match_flag_vendor = 1; + if (format_get_field(type, "mf_product", ptr, size)) + id->match_flag_product = 1; + if (format_get_field(type, "mf_dev_lo", ptr, size)) + id->match_flag_dev_lo = 1; + if (format_get_field(type, "mf_dev_hi", ptr, size)) + id->match_flag_dev_hi = 1; + if (format_get_field(type, "mf_dev_class", ptr, size)) + id->match_flag_dev_class = 1; + if (format_get_field(type, "mf_dev_subclass", ptr, size)) + id->match_flag_dev_subclass = 1; + if (format_get_field(type, "mf_dev_protocol", ptr, size)) + id->match_flag_dev_protocol = 1; + if (format_get_field(type, "mf_int_class", ptr, size)) + id->match_flag_int_class = 1; + if (format_get_field(type, "mf_int_subclass", ptr, size)) + id->match_flag_int_subclass = 1; + if (format_get_field(type, "mf_int_protocol", ptr, size)) + id->match_flag_int_protocol = 1; + + /* compute some internal fields */ + id->is_iface = id->match_flag_int_class | + id->match_flag_int_protocol | + id->match_flag_int_subclass; + + id->is_dev = id->match_flag_dev_class | + id->match_flag_dev_subclass; + + id->is_vp = id->match_flag_vendor | + id->match_flag_product; + + id->is_any = id->is_vp + id->is_dev + id->is_iface; +} + +static uint32_t +usb_dump(struct usb_device_id *id, uint32_t nid) +{ + uint32_t n = 1; + + if (id->is_any) { + printf("nomatch 32 {\n" + " match \"bus\" \"uhub[0-9]+\";\n" + " match \"mode\" \"%s\";\n", id->module_mode); + } else { + printf("# skipped entry on module %s\n", + id->module_name); + return (n); + } + + if (id->match_flag_vendor) { + printf(" match \"vendor\" \"0x%04x\";\n", + id->idVendor); + } + if (id->match_flag_product) { + uint32_t x; + + if (id->is_any == 1 && id->is_vp == 1) { + /* try to join similar entries */ + while (n < nid) { + if (id[n].is_any != 1 || id[n].is_vp != 1) + break; + if (id[n].idVendor != id[0].idVendor) + break; + if (strcmp(id[n].module_name, id[0].module_name)) + break; + if (strcmp(id[n].module_mode, id[0].module_mode)) + break; + n++; + } + } + if (n == 1) { + printf(" match \"product\" \"0x%04x\";\n", + id->idProduct); + } else { + printf(" match \"product\" \"("); + + for (x = 0; x != n; x++) { + printf("0x%04x%s", id[x].idProduct, + (x == (n - 1)) ? "" : "|"); + } + + printf(")\";\n"); + } + } + if (id->match_flag_dev_class) { + printf(" match \"devclass\" \"0x%02x\";\n", + id->bDeviceClass); + } + if (id->match_flag_dev_subclass) { + printf(" match \"devsubclass\" \"0x%02x\";\n", + id->bDeviceSubClass); + } + if (id->match_flag_int_class) { + printf(" match \"intclass\" \"0x%02x\";\n", + id->bInterfaceClass); + } + if (id->match_flag_int_subclass) { + printf(" match \"intsubclass\" \"0x%02x\";\n", + id->bInterfaceSubClass); + } + if (id->match_flag_int_protocol) { + printf(" match \"intprotocol\" \"0x%02x\";\n", + id->bInterfaceProtocol); + } + printf(" action \"kldload -n %s\";\n" + "};\n\n", id->module_name); + + return (n); +} + +void +usb_import_entries(const char *section, const char *module, + const uint8_t *ptr, uint32_t len) +{ + struct usb_blob *pub; + uint32_t section_size; + uint32_t off; + + section_size = format_get_section_size(section); + if (section_size == 0) { + errx(EX_DATAERR, "Invalid or non-existing " + "section format '%s'", section); + } + if (len % section_size) { + errx(EX_DATAERR, "Length %d is not " + "divisible by %d. Section format '%s'", + len, section_size, section); + } + for (off = 0; off != len; off += section_size) { + pub = malloc(sizeof(*pub)); + if (pub == NULL) + errx(EX_SOFTWARE, "Out of memory"); + + memset(pub, 0, sizeof(*pub)); + + usb_import_entry(&pub->temp, section, + module, ptr + off, section_size); + + TAILQ_INSERT_TAIL(&usb_blob_head, pub, entry); + + usb_blob_count++; + if (usb_blob_count == 0) + errx(EX_SOFTWARE, "Too many entries"); + } +} + +void +usb_dump_entries(void) +{ + struct usb_blob *pub; + struct usb_device_id *id; + uint32_t x; + + id = malloc(usb_blob_count * sizeof(*id)); + if (id == NULL) + errx(EX_SOFTWARE, "Out of memory"); + + /* make linear array of all USB blobs */ + x = 0; + TAILQ_FOREACH(pub, &usb_blob_head, entry) + id[x++] = pub->temp; + + usb_sort_entries(id, usb_blob_count); + + for (x = 0; x != usb_blob_count;) + x += usb_dump(id + x, usb_blob_count - x); + + free(id); + + printf("# %d USB entries processed\n\n", usb_blob_count); +} diff --git a/tools/tools/bus_autoconf/bus_usb.h b/tools/tools/bus_autoconf/bus_usb.h new file mode 100644 index 000000000000..378df9a64c3e --- /dev/null +++ b/tools/tools/bus_autoconf/bus_usb.h @@ -0,0 +1,73 @@ +/* $FreeBSD$ */ + +/*- + * Copyright (c) 2011 Hans Petter Selasky. 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. + * 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. + */ + +#ifndef _BUS_USB_H_ +#define _BUS_USB_H_ + +struct usb_device_id { + + /* Internal fields */ + char module_name[32]; + char module_mode[32]; + uint8_t is_iface; + uint8_t is_vp; + uint8_t is_dev; + uint8_t is_any; + + /* Used for product specific matches; the BCD range is inclusive */ + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice_lo; + uint16_t bcdDevice_hi; + + /* Used for device class matches */ + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + + /* Used for interface class matches */ + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + + /* Select which fields to match against */ + uint8_t match_flag_vendor:1; + uint8_t match_flag_product:1; + uint8_t match_flag_dev_lo:1; + uint8_t match_flag_dev_hi:1; + uint8_t match_flag_dev_class:1; + uint8_t match_flag_dev_subclass:1; + uint8_t match_flag_dev_protocol:1; + uint8_t match_flag_int_class:1; + uint8_t match_flag_int_subclass:1; + uint8_t match_flag_int_protocol:1; +}; + +void usb_import_entries(const char *, const char *, const uint8_t *, uint32_t); +void usb_dump_entries(void); + +#endif /* _BUS_USB_H_ */ diff --git a/tools/tools/cd2dvd/cd2dvd.sh b/tools/tools/cd2dvd/cd2dvd.sh new file mode 100755 index 000000000000..c741344e73bd --- /dev/null +++ b/tools/tools/cd2dvd/cd2dvd.sh @@ -0,0 +1,267 @@ +#!/bin/sh +# +# Copyright (C) 2008 Roman Kurakin rik@freebsd.org. 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. +# 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 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 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. +# +# Merges FreeBSD's several CD installation medias to the single DVD disk. +# +# $FreeBSD$ + +## Helper functions +usage () { + echo "Usage: $0 <dvd_img_name> <cd_img_name <cd_img_name ..>>" +} + +# Copy data from the cd +# $1 os name +# $2 disk image name +# $3 mount dir +# $4 destination dir +copycd () { + # Set some variables + md="" + _os="${1}" + _img="${2}" + _mnt="${3}" + _dst="${4}" + if [ $# -ne "4" ] + then + echo "Error: function ${0} takes exactly four parameters." + exit 1 + fi + if [ "${_os}" != "FreeBSD" -a "${_os}" != "Linux" ] + then + echo "Error: do not know how to handle ${_os} os." + exit 1 + fi + if [ ! -f "${_img}" ] + then + echo "Error: file ${_img} does not exists or not a regula file." + exit 1 + fi + if [ ! -r "${_img}" ] + then + echo "Error: you do not have the read permissions." + exit 1 + fi + if [ ! -d "${_mnt}" ] + then + echo "Error: ${_mnt} is not a directory or does not exists." + fi + if [ ! -d "${_dst}" ] + then + echo "Error: ${_dst} is not a directory or does not exists." + fi + if [ ! -w "${_dst}" ] + then + echo "Error: you do not have write permissions granted for ${_dst} directory." + fi + if [ "${_os}" != "Linux" ] + then + md=`mdconfig -a -t vnode -f ${_img}` || exit 1 + mount_cd9660 /dev/${md} ${_mnt} || exit 1 + else + mount -o loop ${_img} ${_mnt} || exit 1 + fi + if [ ! -f ${_mnt}/cdrom.inf ] + then + echo "Error: Failed to find cdrom.inf for ${_img}." + exit 1 + fi + cdvol=`grep "^CD_VOLUME.*" ${_mnt}/cdrom.inf | sed "s/CD_VOLUME[[:space:]]*=[[:space:]]*//"` + if test -z "${cdvol}" -o ! "${cdvol}" -eq "${cdvol}" 2> /dev/null + then + echo "Error: failed to get volume id for ${_img}." + exit 1 + fi + cdver=`grep "^CD_VERSION.*" ${_mnt}/cdrom.inf | sed "s/CD_VERSION[[:space:]]*=[[:space:]]*//"` + if test -z "${cdver}" + then + echo "Error: failed to get version id for ${_img}." + exit 1 + fi + if [ -z "${VERID}" ] + then + VERID="${cdver}" + _exclude="" + else + if [ "${VERID}" != "${cdver}" ] + then + echo "Error: cd version ids mismatch while processing ${_img}." + exit 1 + fi +# _exclude="--exclude ./cdrom.inf --exclude ./packages/INDEX" + _exclude="! -regex ./cdrom.inf ! -regex ./packages/INDEX" + fi + echo "Merging ${_img}:" +# --quite -u -V + (cd "${_mnt}" && find . ${_exclude} | cpio -p -d -m -V --quiet "${_dst}") || exit 1 +# (cd "${_mnt}" && tar ${_exclude} -cvf - .) | (cd "${_dst}" && tar xvf -) || exit 1 + if [ "${_os}" != "Linux" ] + then + umount /dev/${md} || exit 1 + mdconfig -d -u "${md}" || exit 1 + else + umount ${_mnt} || exit 1 + fi +# exit 0 +} + +# Clear mounted image +# $1 mounted directory +# $2 error code +clearmount () +{ + if [ $# -ne "2" ] + then + echo "Error: function ${0} takes exactly two parameters." + exit 1 + fi + if [ -z "${1}" ] + then + test -z "${2}" || exit "${2}" + else + # Ignore errors + umount "${1}" 2>/dev/null + test -z "${2}" || exit "${2}" + fi +} + +# Clear CD image allocation +# $1 os name +# $2 md +# $3 error code +clearmd () +{ + if [ $# -ne "3" ] + then + echo "Error: function ${0} takes exactly three parameters." + exit 1 + fi + if [ "${1}" != "FreeBSD" -o -z "${2}" ] + then + test -z "${3}" || exit "${3}" + else + # Ignore errors + mdconfig -d -u "${2}" 2>/dev/null + test -z "${3}" || exit "${3}" + fi +} + +## Check params +if [ $# -lt 3 ] +then + usage + echo "Error, this script should take more than two parameters." + exit 1 +fi + +# Check if zero +if [ -z "${1}" ]; then + usage + exit 1 +fi + +# Check if already exists +if [ -e "${1}" ]; then + if [ ! -f "${1}" ]; then + echo "Destination DVD image file already exists and is not a regular file." + exit 1 + fi + while echo "The ${1} file exists. Overwrite? (y/n)" + do + read line + case "${line}" in + y|Y) + rm -rf "${1}" + touch "${1}" + break + ;; + n|N) + echo "Please, run program again with a new value." + exit 1 + ;; + esac + done +fi +DVDIMAGE="${1}" + +shift + +count=0 +for i in "$@" +do + # Skip empty params. + if test -z "${i}"; then + continue + fi + if [ ! -f "${i}" -o ! -r "${i}" ] + then + echo "Error: The ${i} is not readable, do not exists or not a regular file." + exit 1 + fi + count=`expr ${count} \+ 1` +done + +# Check if we have at the least two CD images +if [ "${count}" -lt 2 ] +then + echo "Error: less than two CD images specified." +fi + +## Some useful variables +pwd=`pwd` +tmpdirin="${pwd}/tmp-$$-in" +tmpdirout="${pwd}/tmp-$$-out" +system=`uname -s` +md="" + +# set the trap options +trap 'echo ""; echo "Cleaning up"; clearmount "${tmpdirin}" ""; clearmd "${system}" "${md}" ""; rm -rf "${tmpdirin}" "${tmpdirout}";' 0 1 2 3 15 +mkdir "${tmpdirin}" || (echo "Error: failed to create tempory ${tmpdirin}"; exit 1) +mkdir "${tmpdirout}" || (echo "Error: failed to create tempory ${tmpdirout}"; exit 1) + |