main.c revision 244962
1183724Ssos/*- 2230132Suqs * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 3183724Ssos * All rights reserved. 4183724Ssos * 5183724Ssos * Redistribution and use in source and binary forms, with or without 6183724Ssos * modification, are permitted provided that the following conditions 7183724Ssos * are met: 8183724Ssos * 1. Redistributions of source code must retain the above copyright 9183724Ssos * notice, this list of conditions and the following disclaimer, 10183724Ssos * without modification. 11183724Ssos * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12183724Ssos * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13183724Ssos * redistribution must be conditioned upon including a substantially 14183724Ssos * similar Disclaimer requirement for further binary redistribution. 15183724Ssos * 16183724Ssos * NO WARRANTY 17183724Ssos * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18183724Ssos * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19183724Ssos * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20183724Ssos * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21183724Ssos * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22183724Ssos * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23183724Ssos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24183724Ssos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25183724Ssos * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26183724Ssos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27183724Ssos * THE POSSIBILITY OF SUCH DAMAGES. 28183724Ssos * 29183724Ssos * $FreeBSD: head/tools/tools/ath/athdecode/main.c 244962 2013-01-02 18:09:30Z adrian $ 30183724Ssos */ 31183724Ssos#include "diag.h" 32183724Ssos 33183724Ssos#include "ah.h" 34183724Ssos#include "ah_internal.h" 35183724Ssos#include "ah_decode.h" 36183724Ssos 37183724Ssos#include "dumpregs.h" 38183724Ssos 39183724Ssos#include <stdlib.h> 40183724Ssos#include <string.h> 41183724Ssos#include <err.h> 42183724Ssos#include <sys/file.h> 43183724Ssos#include <sys/stat.h> 44183724Ssos#include <sys/mman.h> 45183724Ssos 46183724Ssostypedef struct { 47183724Ssos HAL_REVS revs; 48183724Ssos int chipnum; 49183724Ssos#define MAXREGS 5*1024 50183724Ssos struct dumpreg *regs[MAXREGS]; 51183724Ssos u_int nregs; 52183724Ssos} dumpregs_t; 53183724Ssosstatic dumpregs_t state; 54188765Smav 55183724Ssosstatic void opdevice(const struct athregrec *r); 56200171Smavstatic const char* opmark(FILE *, int, const struct athregrec *); 57188765Smavstatic void oprw(FILE *fd, int recnum, struct athregrec *r); 58188769Smav 59183724Ssosint 60183724Ssosmain(int argc, char *argv[]) 61200171Smav{ 62183724Ssos int fd, i, nrecs, same; 63183724Ssos struct stat sb; 64183724Ssos void *addr; 65183724Ssos const char *filename = "/tmp/ath_hal.log"; 66183724Ssos struct athregrec *rprev; 67183724Ssos 68183724Ssos if (argc > 1) 69183724Ssos filename = argv[1]; 70183724Ssos fd = open(filename, O_RDONLY); 71183724Ssos if (fd < 0) 72183724Ssos err(1, "open: %s", filename); 73183724Ssos if (fstat(fd, &sb) < 0) 74183724Ssos err(1, "fstat"); 75183724Ssos addr = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE|MAP_NOCORE, fd, 0); 76183724Ssos if (addr == MAP_FAILED) 77242625Sdim err(1, "mmap"); 78183724Ssos nrecs = sb.st_size / sizeof (struct athregrec); 79183724Ssos printf("%u records", nrecs); 80183724Ssos rprev = NULL; 81183724Ssos same = 0; 82183724Ssos state.chipnum = 5210; 83183724Ssos for (i = 0; i < nrecs; i++) { 84183724Ssos struct athregrec *r = &((struct athregrec *) addr)[i]; 85183724Ssos if (rprev && bcmp(r, rprev, sizeof (*r)) == 0) { 86183724Ssos same++; 87183724Ssos continue; 88183724Ssos } 89183724Ssos if (same) 90183724Ssos printf("\t\t+%u time%s", same, same == 1 ? "" : "s"); 91183724Ssos switch (r->op) { 92183724Ssos case OP_DEVICE: 93183724Ssos opdevice(r); 94183724Ssos break; 95183724Ssos case OP_READ: 96183724Ssos case OP_WRITE: 97183724Ssos oprw(stdout, i, r); 98183724Ssos break; 99183724Ssos case OP_MARK: 100281140Smav opmark(stdout, i, r); 101183724Ssos break; 102183724Ssos } 103183724Ssos rprev = r; 104183724Ssos same = 0; 105183724Ssos } 106183724Ssos putchar('\n'); 107183724Ssos return 0; 108183724Ssos} 109183724Ssos 110183724Ssosstatic const char* 111183724Ssosopmark(FILE *fd, int i, const struct athregrec *r) 112183724Ssos{ 113183724Ssos fprintf(fd, "\n%05d: ", i); 114183724Ssos switch (r->reg) { 115183724Ssos case AH_MARK_RESET: 116183724Ssos fprintf(fd, "ar%uReset %s", state.chipnum, 117183724Ssos r->val ? "change channel" : "no channel change"); 118183724Ssos break; 119183724Ssos case AH_MARK_RESET_LINE: 120183724Ssos fprintf(fd, "ar%u_reset.c; line %u", state.chipnum, r->val); 121183724Ssos break; 122183724Ssos case AH_MARK_RESET_DONE: 123183724Ssos if (r->val) 124183724Ssos fprintf(fd, "ar%uReset (done), FAIL, error %u", 125183724Ssos state.chipnum, r->val); 126183724Ssos else 127183724Ssos fprintf(fd, "ar%uReset (done), OK", state.chipnum); 128183724Ssos break; 129183724Ssos case AH_MARK_CHIPRESET: 130183724Ssos fprintf(fd, "ar%uChipReset, channel %u MHz", state.chipnum, r->val); 131183724Ssos break; 132183724Ssos case AH_MARK_PERCAL: 133183724Ssos fprintf(fd, "ar%uPerCalibration, channel %u MHz", state.chipnum, r->val); 134183724Ssos break; 135183724Ssos case AH_MARK_SETCHANNEL: 136183724Ssos fprintf(fd, "ar%uSetChannel, channel %u MHz", state.chipnum, r->val); 137183724Ssos break; 138183724Ssos case AH_MARK_ANI_RESET: 139183724Ssos switch (r->val) { 140183724Ssos case HAL_M_STA: 141183724Ssos fprintf(fd, "ar%uAniReset, HAL_M_STA", state.chipnum); 142183724Ssos break; 143183724Ssos case HAL_M_IBSS: 144188769Smav fprintf(fd, "ar%uAniReset, HAL_M_IBSS", state.chipnum); 145188765Smav break; 146188769Smav case HAL_M_HOSTAP: 147188769Smav fprintf(fd, "ar%uAniReset, HAL_M_HOSTAP", state.chipnum); 148183724Ssos break; 149183724Ssos case HAL_M_MONITOR: 150183724Ssos fprintf(fd, "ar%uAniReset, HAL_M_MONITOR", state.chipnum); 151183724Ssos break; 152200171Smav default: 153183724Ssos fprintf(fd, "ar%uAniReset, opmode %u", state.chipnum, r->val); 154183724Ssos break; 155183724Ssos } 156183724Ssos break; 157183724Ssos case AH_MARK_ANI_POLL: 158183724Ssos fprintf(fd, "ar%uAniPoll, listenTime %u", state.chipnum, r->val); 159183724Ssos break; 160183724Ssos case AH_MARK_ANI_CONTROL: 161183724Ssos switch (r->val) { 162183724Ssos case HAL_ANI_PRESENT: 163183724Ssos fprintf(fd, "ar%uAniControl, PRESENT", state.chipnum); 164183724Ssos break; 165183724Ssos case HAL_ANI_NOISE_IMMUNITY_LEVEL: 166183724Ssos fprintf(fd, "ar%uAniControl, NOISE_IMMUNITY", state.chipnum); 167188765Smav break; 168188769Smav case HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION: 169183724Ssos fprintf(fd, "ar%uAniControl, OFDM_WEAK_SIGNAL", state.chipnum); 170183724Ssos break; 171183724Ssos case HAL_ANI_CCK_WEAK_SIGNAL_THR: 172183724Ssos fprintf(fd, "ar%uAniControl, CCK_WEAK_SIGNAL", state.chipnum); 173183724Ssos break; 174183724Ssos case HAL_ANI_FIRSTEP_LEVEL: 175183724Ssos fprintf(fd, "ar%uAniControl, FIRSTEP_LEVEL", state.chipnum); 176188765Smav break; 177183724Ssos case HAL_ANI_SPUR_IMMUNITY_LEVEL: 178183724Ssos fprintf(fd, "ar%uAniControl, SPUR_IMMUNITY", state.chipnum); 179183724Ssos break; 180183724Ssos case HAL_ANI_MODE: 181183724Ssos fprintf(fd, "ar%uAniControl, MODE", state.chipnum); 182188765Smav break; 183183724Ssos case HAL_ANI_PHYERR_RESET: 184183724Ssos fprintf(fd, "ar%uAniControl, PHYERR_RESET", state.chipnum); 185183724Ssos break; 186183724Ssos default: 187183724Ssos fprintf(fd, "ar%uAniControl, cmd %u", state.chipnum, r->val); 188230627Smarius break; 189230627Smarius } 190183724Ssos break; 191183724Ssos default: 192183724Ssos fprintf(fd, "mark #%u value %u/0x%x", r->reg, r->val, r->val); 193183724Ssos break; 194183724Ssos } 195183724Ssos exit(0); 196183724Ssos} 197183724Ssos 198183724Ssos#include "ah_devid.h" 199183724Ssos 200183724Ssosstatic void 201183724Ssosopdevice(const struct athregrec *r) 202183724Ssos{ 203183724Ssos switch (r->val) { 204183724Ssos case AR5210_PROD: 205183724Ssos case AR5210_DEFAULT: 206183724Ssos state.chipnum = 5210; 207183724Ssos state.revs.ah_macVersion = 1; 208200171Smav state.revs.ah_macRev = 0; 209200171Smav break; 210183724Ssos case AR5211_DEVID: 211200171Smav case AR5311_DEVID: 212200171Smav case AR5211_DEFAULT: 213200171Smav case AR5211_FPGA11B: 214200171Smav state.chipnum = 5211; 215183724Ssos state.revs.ah_macVersion = 2; 216183724Ssos state.revs.ah_macRev = 0; 217200171Smav break; 218233282Smarius /* AR5212 */ 219233282Smarius case AR5212_DEFAULT: 220233282Smarius case AR5212_DEVID: 221233282Smarius case AR5212_FPGA: 222233282Smarius case AR5212_DEVID_IBM: 223183724Ssos case AR5212_AR5312_REV2: 224200171Smav case AR5212_AR5312_REV7: 225200171Smav case AR5212_AR2313_REV8: 226200171Smav case AR5212_AR2315_REV6: 227183724Ssos case AR5212_AR2315_REV7: 228200171Smav case AR5212_AR2317_REV1: 229200171Smav case AR5212_AR2317_REV2: 230200171Smav 231200171Smav /* AR5212 compatible devid's also attach to 5212 */ 232200171Smav case AR5212_DEVID_0014: 233200171Smav case AR5212_DEVID_0015: 234200171Smav case AR5212_DEVID_0016: 235200171Smav case AR5212_DEVID_0017: 236200171Smav case AR5212_DEVID_0018: 237183724Ssos case AR5212_DEVID_0019: 238200171Smav case AR5212_AR2413: 239200171Smav case AR5212_AR5413: 240183724Ssos case AR5212_AR5424: 241183724Ssos case AR5212_AR2417: 242183724Ssos case AR5212_DEVID_FF19: 243188765Smav state.chipnum = 5212; 244183724Ssos state.revs.ah_macVersion = 4; 245183724Ssos state.revs.ah_macRev = 5; 246183724Ssos break; 247183724Ssos 248183724Ssos /* AR5213 */ 249183724Ssos case AR5213_SREV_1_0: 250183724Ssos case AR5213_SREV_REG: 251183724Ssos state.chipnum = 5213; 252183724Ssos state.revs.ah_macVersion = 5; 253183724Ssos state.revs.ah_macRev = 9; 254183724Ssos break; 255183724Ssos 256183724Ssos /* AR5416 compatible devid's */ 257183724Ssos case AR5416_DEVID_PCI: 258183724Ssos case AR5416_DEVID_PCIE: 259183724Ssos case AR9160_DEVID_PCI: 260183724Ssos case AR9280_DEVID_PCI: 261183724Ssos case AR9280_DEVID_PCIE: 262183724Ssos case AR9285_DEVID_PCIE: 263183724Ssos state.chipnum = 5416; 264183724Ssos state.revs.ah_macVersion = 13; 265183724Ssos state.revs.ah_macRev = 8; 266183724Ssos break; 267183724Ssos default: 268183724Ssos printf("Unknown device id 0x%x\n", r->val); 269183724Ssos exit(-1); 270183724Ssos } 271183724Ssos} 272183724Ssos 273183724Ssosstatic int 274200171Smavregcompar(const void *a, const void *b) 275212145Smav{ 276183724Ssos const struct dumpreg *ra = *(const struct dumpreg **)a; 277183724Ssos const struct dumpreg *rb = *(const struct dumpreg **)b; 278183724Ssos return ra->addr - rb->addr; 279183724Ssos} 280183724Ssos 281183724Ssosvoid 282183724Ssosregister_regs(struct dumpreg *chipregs, u_int nchipregs, 283183724Ssos int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max) 284183724Ssos{ 285183724Ssos const int existing_regs = state.nregs; 286183724Ssos int i, j; 287183724Ssos 288183724Ssos for (i = 0; i < nchipregs; i++) { 289200171Smav struct dumpreg *nr = &chipregs[i]; 290200171Smav if (nr->srevMin == 0) 291216013Smarius nr->srevMin = def_srev_min; 292216013Smarius if (nr->srevMax == 0) 293216013Smarius nr->srevMax = def_srev_max; 294183724Ssos if (nr->phyMin == 0) 295183724Ssos nr->phyMin = def_phy_min; 296183724Ssos if (nr->phyMax == 0) 297183724Ssos nr->phyMax = def_phy_max; 298188769Smav for (j = 0; j < existing_regs; j++) { 299188769Smav struct dumpreg *r = state.regs[j]; 300188769Smav /* 301188769Smav * Check if we can just expand the mac+phy 302188769Smav * coverage for the existing entry. 303188769Smav */ 304188769Smav if (nr->addr == r->addr && 305188769Smav (nr->name == r->name || 306183724Ssos (nr->name != NULL && r->name != NULL && 307183724Ssos strcmp(nr->name, r->name) == 0))) { 308183724Ssos if (nr->srevMin < r->srevMin && 309183724Ssos (r->srevMin <= nr->srevMax && 310183724Ssos nr->srevMax+1 <= r->srevMax)) { 311183724Ssos r->srevMin = nr->srevMin; 312183724Ssos goto skip; 313183724Ssos } 314183724Ssos if (nr->srevMax > r->srevMax && 315183724Ssos (r->srevMin <= nr->srevMin && 316214016Smav nr->srevMin <= r->srevMax)) { 317183724Ssos r->srevMax = nr->srevMax; 318183724Ssos goto skip; 319183724Ssos } 320183724Ssos } 321183724Ssos if (r->addr > nr->addr) 322183724Ssos break; 323183724Ssos } 324183724Ssos /* 325183724Ssos * New item, add to the end, it'll be sorted below. 326183724Ssos */ 327212146Smav if (state.nregs == MAXREGS) 328209884Smav errx(-1, "too many registers; bump MAXREGS"); 329212146Smav state.regs[state.nregs++] = nr; 330212146Smav skip: 331209884Smav ; 332212146Smav } 333212146Smav qsort(state.regs, state.nregs, sizeof(struct dumpreg *), regcompar); 334212146Smav} 335212146Smav 336212146Smavvoid 337190581Smavregister_keycache(u_int nslots, 338183724Ssos int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max) 339209884Smav{ 340209884Smav /* discard, no use */ 341183724Ssos} 342183724Ssos 343200171Smavvoid 344200171Smavregister_range(u_int brange, u_int erange, int type, 345183724Ssos int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max) 346200171Smav{ 347200171Smav /* discard, no use */ 348200171Smav} 349200171Smav 350200171Smavstatic const struct dumpreg * 351200171Smavfindreg(int reg) 352200171Smav{ 353200171Smav const HAL_REVS *revs = &state.revs; 354200171Smav int i; 355200171Smav 356200171Smav for (i = 0; i < state.nregs; i++) { 357233282Smarius const struct dumpreg *dr = state.regs[i]; 358233282Smarius if (dr->addr == reg && 359233282Smarius MAC_MATCH(dr, revs->ah_macVersion, revs->ah_macRev)) 360233282Smarius return dr; 361233282Smarius } 362183724Ssos return NULL; 363200171Smav} 364183724Ssos 365200171Smav/* XXX cheat, 5212 has a superset of the key table defs */ 366209872Smav#include "ar5212/ar5212reg.h" 367209872Smav#include "ar5212/ar5212phy.h" 368183724Ssos 369200171Smav#define PWR_TABLE_SIZE 64 370200171Smav 371200171Smavstatic void 372183724Ssosoprw(FILE *fd, int recnum, struct athregrec *r) 373200171Smav{ 374200171Smav const struct dumpreg *dr; 375200171Smav char buf[64]; 376200171Smav const char* bits; 377200171Smav int i; 378183724Ssos 379200171Smav fprintf(fd, "\n%05d: [%d] ", recnum, r->threadid); 380200171Smav dr = findreg(r->reg); 381200171Smav if (dr != NULL && dr->name != NULL) { 382200171Smav snprintf(buf, sizeof (buf), "AR_%s (0x%x)", dr->name, r->reg); 383200171Smav bits = dr->bits; 384200171Smav } else if (AR_KEYTABLE(0) <= r->reg && r->reg < AR_KEYTABLE(128)) { 385200171Smav snprintf(buf, sizeof (buf), "AR_KEYTABLE%u(%u) (0x%x)", 386200171Smav ((r->reg - AR_KEYTABLE_0) >> 2) & 7, 387200171Smav (r->reg - AR_KEYTABLE_0) >> 5, r->reg); 388200171Smav bits = NULL; 389200171Smav#if 0 390200171Smav } else if (AR_PHY_PCDAC_TX_POWER(0) <= r->reg && r->reg < AR_PHY_PCDAC_TX_POWER(PWR_TABLE_SIZE/2)) { 391200171Smav snprintf(buf, sizeof (buf), "AR_PHY_PCDAC_TX_POWER(%u) (0x%x)", 392200171Smav (r->reg - AR_PHY_PCDAC_TX_POWER_0) >> 2, r->reg); 393183724Ssos bits = NULL; 394183724Ssos#endif 395183724Ssos } else if (AR_RATE_DURATION(0) <= r->reg && r->reg < AR_RATE_DURATION(32)) { 396 snprintf(buf, sizeof (buf), "AR_RATE_DURATION(0x%x) (0x%x)", 397 (r->reg - AR_RATE_DURATION_0) >> 2, r->reg); 398 bits = NULL; 399 } else if (AR_PHY_BASE <= r->reg) { 400 snprintf(buf, sizeof (buf), "AR_PHY(%u) (0x%x)", 401 (r->reg - AR_PHY_BASE) >> 2, r->reg); 402 bits = NULL; 403 } else { 404 snprintf(buf, sizeof (buf), "0x%x", r->reg); 405 bits = NULL; 406 } 407 fprintf(fd, "%-30s %s 0x%x", buf, r->op ? "<=" : "=>", r->val); 408 if (bits) { 409 const char *p = bits; 410 int tmp, n; 411 412 for (tmp = 0, p++; *p;) { 413 n = *p++; 414 if (r->val & (1 << (n - 1))) { 415 putc(tmp ? ',' : '<', fd); 416 for (; (n = *p) > ' '; ++p) 417 putc(n, fd); 418 tmp = 1; 419 } else 420 for (; *p > ' '; ++p) 421 continue; 422 } 423 if (tmp) 424 putc('>', fd); 425 } 426} 427