2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification.
11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13 * redistribution must be conditioned upon including a substantially
14 * similar Disclaimer requirement for further binary redistribution.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
34 #include "ah_internal.h"
35 #include "ah_decode.h"
49 #define MAXREGS 5*1024
50 struct dumpreg *regs[MAXREGS];
53 static dumpregs_t state;
55 static void opdevice(const struct athregrec *r);
56 static const char* opmark(FILE *, int, const struct athregrec *);
57 static void oprw(FILE *fd, int recnum, struct athregrec *r);
60 main(int argc, char *argv[])
62 int fd, i, nrecs, same;
65 const char *filename = "/tmp/ath_hal.log";
66 struct athregrec *rprev;
70 fd = open(filename, O_RDONLY);
72 err(1, "open: %s", filename);
73 if (fstat(fd, &sb) < 0)
75 addr = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE|MAP_NOCORE, fd, 0);
76 if (addr == MAP_FAILED)
78 nrecs = sb.st_size / sizeof (struct athregrec);
79 printf("%u records", nrecs);
83 for (i = 0; i < nrecs; i++) {
84 struct athregrec *r = &((struct athregrec *) addr)[i];
85 if (rprev && bcmp(r, rprev, sizeof (*r)) == 0) {
90 printf("\t\t+%u time%s", same, same == 1 ? "" : "s");
100 opmark(stdout, i, r);
111 opmark(FILE *fd, int i, const struct athregrec *r)
113 fprintf(fd, "\n%05d: ", i);
116 fprintf(fd, "ar%uReset %s", state.chipnum,
117 r->val ? "change channel" : "no channel change");
119 case AH_MARK_RESET_LINE:
120 fprintf(fd, "ar%u_reset.c; line %u", state.chipnum, r->val);
122 case AH_MARK_RESET_DONE:
124 fprintf(fd, "ar%uReset (done), FAIL, error %u",
125 state.chipnum, r->val);
127 fprintf(fd, "ar%uReset (done), OK", state.chipnum);
129 case AH_MARK_CHIPRESET:
130 fprintf(fd, "ar%uChipReset, channel %u MHz", state.chipnum, r->val);
133 fprintf(fd, "ar%uPerCalibration, channel %u MHz", state.chipnum, r->val);
135 case AH_MARK_SETCHANNEL:
136 fprintf(fd, "ar%uSetChannel, channel %u MHz", state.chipnum, r->val);
138 case AH_MARK_ANI_RESET:
141 fprintf(fd, "ar%uAniReset, HAL_M_STA", state.chipnum);
144 fprintf(fd, "ar%uAniReset, HAL_M_IBSS", state.chipnum);
147 fprintf(fd, "ar%uAniReset, HAL_M_HOSTAP", state.chipnum);
150 fprintf(fd, "ar%uAniReset, HAL_M_MONITOR", state.chipnum);
153 fprintf(fd, "ar%uAniReset, opmode %u", state.chipnum, r->val);
157 case AH_MARK_ANI_POLL:
158 fprintf(fd, "ar%uAniPoll, listenTime %u", state.chipnum, r->val);
160 case AH_MARK_ANI_CONTROL:
162 case HAL_ANI_PRESENT:
163 fprintf(fd, "ar%uAniControl, PRESENT", state.chipnum);
165 case HAL_ANI_NOISE_IMMUNITY_LEVEL:
166 fprintf(fd, "ar%uAniControl, NOISE_IMMUNITY", state.chipnum);
168 case HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION:
169 fprintf(fd, "ar%uAniControl, OFDM_WEAK_SIGNAL", state.chipnum);
171 case HAL_ANI_CCK_WEAK_SIGNAL_THR:
172 fprintf(fd, "ar%uAniControl, CCK_WEAK_SIGNAL", state.chipnum);
174 case HAL_ANI_FIRSTEP_LEVEL:
175 fprintf(fd, "ar%uAniControl, FIRSTEP_LEVEL", state.chipnum);
177 case HAL_ANI_SPUR_IMMUNITY_LEVEL:
178 fprintf(fd, "ar%uAniControl, SPUR_IMMUNITY", state.chipnum);
181 fprintf(fd, "ar%uAniControl, MODE", state.chipnum);
183 case HAL_ANI_PHYERR_RESET:
184 fprintf(fd, "ar%uAniControl, PHYERR_RESET", state.chipnum);
187 fprintf(fd, "ar%uAniControl, cmd %u", state.chipnum, r->val);
192 fprintf(fd, "mark #%u value %u/0x%x", r->reg, r->val, r->val);
198 #include "ah_devid.h"
201 opdevice(const struct athregrec *r)
206 state.chipnum = 5210;
207 state.revs.ah_macVersion = 1;
208 state.revs.ah_macRev = 0;
214 state.chipnum = 5211;
215 state.revs.ah_macVersion = 2;
216 state.revs.ah_macRev = 0;
222 case AR5212_DEVID_IBM:
223 case AR5212_AR5312_REV2:
224 case AR5212_AR5312_REV7:
225 case AR5212_AR2313_REV8:
226 case AR5212_AR2315_REV6:
227 case AR5212_AR2315_REV7:
228 case AR5212_AR2317_REV1:
229 case AR5212_AR2317_REV2:
231 /* AR5212 compatible devid's also attach to 5212 */
232 case AR5212_DEVID_0014:
233 case AR5212_DEVID_0015:
234 case AR5212_DEVID_0016:
235 case AR5212_DEVID_0017:
236 case AR5212_DEVID_0018:
237 case AR5212_DEVID_0019:
242 case AR5212_DEVID_FF19:
243 state.chipnum = 5212;
244 state.revs.ah_macVersion = 4;
245 state.revs.ah_macRev = 5;
249 case AR5213_SREV_1_0:
250 case AR5213_SREV_REG:
251 state.chipnum = 5213;
252 state.revs.ah_macVersion = 5;
253 state.revs.ah_macRev = 9;
256 /* AR5416 compatible devid's */
257 case AR5416_DEVID_PCI:
258 case AR5416_DEVID_PCIE:
259 case AR9160_DEVID_PCI:
260 case AR9280_DEVID_PCI:
261 case AR9280_DEVID_PCIE:
262 case AR9285_DEVID_PCIE:
263 case AR9287_DEVID_PCI:
264 case AR9287_DEVID_PCIE:
265 case AR9300_DEVID_AR9330:
266 state.chipnum = 5416;
267 state.revs.ah_macVersion = 13;
268 state.revs.ah_macRev = 8;
271 printf("Unknown device id 0x%x\n", r->val);
277 regcompar(const void *a, const void *b)
279 const struct dumpreg *ra = *(const struct dumpreg **)a;
280 const struct dumpreg *rb = *(const struct dumpreg **)b;
281 return ra->addr - rb->addr;
285 register_regs(struct dumpreg *chipregs, u_int nchipregs,
286 int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max)
288 const int existing_regs = state.nregs;
291 for (i = 0; i < nchipregs; i++) {
292 struct dumpreg *nr = &chipregs[i];
293 if (nr->srevMin == 0)
294 nr->srevMin = def_srev_min;
295 if (nr->srevMax == 0)
296 nr->srevMax = def_srev_max;
298 nr->phyMin = def_phy_min;
300 nr->phyMax = def_phy_max;
301 for (j = 0; j < existing_regs; j++) {
302 struct dumpreg *r = state.regs[j];
304 * Check if we can just expand the mac+phy
305 * coverage for the existing entry.
307 if (nr->addr == r->addr &&
308 (nr->name == r->name ||
309 (nr->name != NULL && r->name != NULL &&
310 strcmp(nr->name, r->name) == 0))) {
311 if (nr->srevMin < r->srevMin &&
312 (r->srevMin <= nr->srevMax &&
313 nr->srevMax+1 <= r->srevMax)) {
314 r->srevMin = nr->srevMin;
317 if (nr->srevMax > r->srevMax &&
318 (r->srevMin <= nr->srevMin &&
319 nr->srevMin <= r->srevMax)) {
320 r->srevMax = nr->srevMax;
324 if (r->addr > nr->addr)
328 * New item, add to the end, it'll be sorted below.
330 if (state.nregs == MAXREGS)
331 errx(-1, "too many registers; bump MAXREGS");
332 state.regs[state.nregs++] = nr;
336 qsort(state.regs, state.nregs, sizeof(struct dumpreg *), regcompar);
340 register_keycache(u_int nslots,
341 int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max)
343 /* discard, no use */
347 register_range(u_int brange, u_int erange, int type,
348 int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max)
350 /* discard, no use */
353 static const struct dumpreg *
356 const HAL_REVS *revs = &state.revs;
359 for (i = 0; i < state.nregs; i++) {
360 const struct dumpreg *dr = state.regs[i];
361 if (dr->addr == reg &&
362 MAC_MATCH(dr, revs->ah_macVersion, revs->ah_macRev))
368 /* XXX cheat, 5212 has a superset of the key table defs */
369 #include "ar5212/ar5212reg.h"
370 #include "ar5212/ar5212phy.h"
372 #define PWR_TABLE_SIZE 64
375 oprw(FILE *fd, int recnum, struct athregrec *r)
377 const struct dumpreg *dr;
382 fprintf(fd, "\n%05d: [%d] ", recnum, r->threadid);
383 dr = findreg(r->reg);
384 if (dr != NULL && dr->name != NULL) {
385 snprintf(buf, sizeof (buf), "AR_%s (0x%x)", dr->name, r->reg);
387 } else if (AR_KEYTABLE(0) <= r->reg && r->reg < AR_KEYTABLE(128)) {
388 snprintf(buf, sizeof (buf), "AR_KEYTABLE%u(%u) (0x%x)",
389 ((r->reg - AR_KEYTABLE_0) >> 2) & 7,
390 (r->reg - AR_KEYTABLE_0) >> 5, r->reg);
393 } else if (AR_PHY_PCDAC_TX_POWER(0) <= r->reg && r->reg < AR_PHY_PCDAC_TX_POWER(PWR_TABLE_SIZE/2)) {
394 snprintf(buf, sizeof (buf), "AR_PHY_PCDAC_TX_POWER(%u) (0x%x)",
395 (r->reg - AR_PHY_PCDAC_TX_POWER_0) >> 2, r->reg);
398 } else if (AR_RATE_DURATION(0) <= r->reg && r->reg < AR_RATE_DURATION(32)) {
399 snprintf(buf, sizeof (buf), "AR_RATE_DURATION(0x%x) (0x%x)",
400 (r->reg - AR_RATE_DURATION_0) >> 2, r->reg);
402 } else if (AR_PHY_BASE <= r->reg) {
403 snprintf(buf, sizeof (buf), "AR_PHY(%u) (0x%x)",
404 (r->reg - AR_PHY_BASE) >> 2, r->reg);
407 snprintf(buf, sizeof (buf), "0x%x", r->reg);
410 fprintf(fd, "%-30s %s 0x%x", buf, r->op ? "<=" : "=>", r->val);
412 const char *p = bits;
415 for (tmp = 0, p++; *p;) {
417 if (r->val & (1 << (n - 1))) {
418 putc(tmp ? ',' : '<', fd);
419 for (; (n = *p) > ' '; ++p)
423 for (; *p > ' '; ++p)