Author: sam
Date: Wed Mar 11 17:15:33 2009
New Revision: 189702
URL: http://svn.freebsd.org/changeset/base/189702

Log:
  add athdecode, an app to decode register logs

Added:
  head/tools/tools/ath/athdecode/
  head/tools/tools/ath/athdecode/Makefile   (contents, props changed)
  head/tools/tools/ath/athdecode/main.c   (contents, props changed)
Modified:
  head/tools/tools/ath/Makefile

Modified: head/tools/tools/ath/Makefile
==============================================================================
--- head/tools/tools/ath/Makefile       Wed Mar 11 17:14:17 2009        
(r189701)
+++ head/tools/tools/ath/Makefile       Wed Mar 11 17:15:33 2009        
(r189702)
@@ -1,5 +1,5 @@
 #      $FreeBSD$
 
-SUBDIR=        athdebug athkey athprom athrd athregs athstats
+SUBDIR=        athdebug athdecode athkey athprom athrd athregs athstats
 
 .include <bsd.subdir.mk>

Added: head/tools/tools/ath/athdecode/Makefile
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/tools/tools/ath/athdecode/Makefile     Wed Mar 11 17:15:33 2009        
(r189702)
@@ -0,0 +1,17 @@
+#
+# $FreeBSD$
+
+PROG=  athdecode
+
+.PATH.c: ${.CURDIR}/../athregs
+CFLAGS+=-I${.CURDIR}/../athregs
+
+SRCS=  main.c
+SRCS+= dumpregs_5210.c
+SRCS+= dumpregs_5211.c
+SRCS+= dumpregs_5212.c
+SRCS+= dumpregs_5416.c
+
+.include <../Makefile.inc>
+
+.include <bsd.prog.mk>

Added: head/tools/tools/ath/athdecode/main.c
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/tools/tools/ath/athdecode/main.c       Wed Mar 11 17:15:33 2009        
(r189702)
@@ -0,0 +1,423 @@
+/*-
+ * 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 <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: ", recnum);
+       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);
+       }
+}
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to