xref: /freebsd/tools/tools/ath/athregs/dumpregs.c (revision b3e76948)
11094c01fSSam Leffler /*-
21094c01fSSam Leffler  * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
31094c01fSSam Leffler  * All rights reserved.
41094c01fSSam Leffler  *
51094c01fSSam Leffler  * Redistribution and use in source and binary forms, with or without
61094c01fSSam Leffler  * modification, are permitted provided that the following conditions
71094c01fSSam Leffler  * are met:
81094c01fSSam Leffler  * 1. Redistributions of source code must retain the above copyright
91094c01fSSam Leffler  *    notice, this list of conditions and the following disclaimer,
101094c01fSSam Leffler  *    without modification.
111094c01fSSam Leffler  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
121094c01fSSam Leffler  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
131094c01fSSam Leffler  *    redistribution must be conditioned upon including a substantially
141094c01fSSam Leffler  *    similar Disclaimer requirement for further binary redistribution.
151094c01fSSam Leffler  *
161094c01fSSam Leffler  * NO WARRANTY
171094c01fSSam Leffler  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
181094c01fSSam Leffler  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
191094c01fSSam Leffler  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
201094c01fSSam Leffler  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
211094c01fSSam Leffler  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
221094c01fSSam Leffler  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
231094c01fSSam Leffler  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
241094c01fSSam Leffler  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
251094c01fSSam Leffler  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
261094c01fSSam Leffler  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
271094c01fSSam Leffler  * THE POSSIBILITY OF SUCH DAMAGES.
281094c01fSSam Leffler  */
291094c01fSSam Leffler #include "diag.h"
301094c01fSSam Leffler 
311094c01fSSam Leffler #include "ah.h"
321094c01fSSam Leffler #include "ah_internal.h"
331094c01fSSam Leffler /* XXX cheat, 5212 has a superset of the key table defs */
341094c01fSSam Leffler #include "ar5212/ar5212reg.h"
351094c01fSSam Leffler 
361094c01fSSam Leffler #include "dumpregs.h"
371094c01fSSam Leffler 
381094c01fSSam Leffler #include <getopt.h>
391094c01fSSam Leffler #include <stdlib.h>
401094c01fSSam Leffler #include <string.h>
411094c01fSSam Leffler #include <ctype.h>
421045db19SAdrian Chadd #include <err.h>
431094c01fSSam Leffler 
44f0ea23b2SAdrian Chadd #include "ctrl.h"
45f0ea23b2SAdrian Chadd 
461094c01fSSam Leffler typedef struct {
471094c01fSSam Leffler 	HAL_REVS revs;
481094c01fSSam Leffler 	u_int32_t regdata[0xffff / sizeof(u_int32_t)];
491094c01fSSam Leffler #define	MAXREGS	5*1024
501094c01fSSam Leffler 	struct dumpreg *regs[MAXREGS];
511094c01fSSam Leffler 	u_int nregs;
521094c01fSSam Leffler 	u_int	show_names	: 1,
531094c01fSSam Leffler 		show_addrs	: 1;
541094c01fSSam Leffler } dumpregs_t;
551094c01fSSam Leffler static	dumpregs_t state;
561094c01fSSam Leffler 
571094c01fSSam Leffler #undef OS_REG_READ
581094c01fSSam Leffler #define	OS_REG_READ(ah, off)	state.regdata[(off) >> 2]
591094c01fSSam Leffler 
601094c01fSSam Leffler static	int ath_hal_anyregs(int what);
611094c01fSSam Leffler static	int ath_hal_setupregs(struct ath_diag *atd, int what);
621094c01fSSam Leffler static	u_int ath_hal_setupdiagregs(const HAL_REGRANGE regs[], u_int nr);
631094c01fSSam Leffler static	void ath_hal_dumpregs(FILE *fd, int what);
641094c01fSSam Leffler static	void ath_hal_dumprange(FILE *fd, u_int a, u_int b);
651094c01fSSam Leffler static	void ath_hal_dumpkeycache(FILE *fd, int nkeys);
661094c01fSSam Leffler static	void ath_hal_dumpint(FILE *fd, int what);
671094c01fSSam Leffler static	void ath_hal_dumpqcu(FILE *fd, int what);
681094c01fSSam Leffler static	void ath_hal_dumpdcu(FILE *fd, int what);
691094c01fSSam Leffler static	void ath_hal_dumpbb(FILE *fd, int what);
701094c01fSSam Leffler 
711094c01fSSam Leffler static void
usage(void)721094c01fSSam Leffler usage(void)
731094c01fSSam Leffler {
741094c01fSSam Leffler 	fprintf(stderr, "usage: athregs [-i interface] [-abdkmqxz]\n");
751094c01fSSam Leffler 	fprintf(stderr, "-a	display all registers\n");
761094c01fSSam Leffler 	fprintf(stderr, "-b	display baseband registers\n");
771094c01fSSam Leffler 	fprintf(stderr, "-d	display DCU registers\n");
781094c01fSSam Leffler 	fprintf(stderr, "-k	display key cache registers\n");
791094c01fSSam Leffler 	fprintf(stderr, "-m	display \"MAC\" registers (default)\n");
801094c01fSSam Leffler 	fprintf(stderr, "-q	display QCU registers\n");
811094c01fSSam Leffler 	fprintf(stderr, "-x	display XR registers\n");
821094c01fSSam Leffler 	fprintf(stderr, "-z	display interrupt registers\n");
831094c01fSSam Leffler 	fprintf(stderr, "\n");
841094c01fSSam Leffler 	fprintf(stderr, "-A	display register address\n");
851094c01fSSam Leffler 	fprintf(stderr, "-N	suppress display of register name\n");
861094c01fSSam Leffler 	exit(-1);
871094c01fSSam Leffler }
881094c01fSSam Leffler 
891094c01fSSam Leffler int
main(int argc,char * argv[])901094c01fSSam Leffler main(int argc, char *argv[])
911094c01fSSam Leffler {
921094c01fSSam Leffler 	struct ath_diag atd;
931094c01fSSam Leffler 	const char *ifname;
941094c01fSSam Leffler 	u_int32_t *data;
951094c01fSSam Leffler 	u_int32_t *dp, *ep;
96f0ea23b2SAdrian Chadd 	int what, c, i;
97f0ea23b2SAdrian Chadd 	struct ath_driver_req req;
981094c01fSSam Leffler 
99f0ea23b2SAdrian Chadd 	ath_driver_req_init(&req);
100f0ea23b2SAdrian Chadd 
1011094c01fSSam Leffler 	ifname = getenv("ATH");
1021094c01fSSam Leffler 	if (!ifname)
1031094c01fSSam Leffler 		ifname = ATH_DEFAULT;
1041094c01fSSam Leffler 
1051094c01fSSam Leffler 	what = 0;
1061094c01fSSam Leffler 	state.show_addrs = 0;
1071094c01fSSam Leffler 	state.show_names = 1;
1081094c01fSSam Leffler 	while ((c = getopt(argc, argv, "i:aAbdkmNqxz")) != -1)
1091094c01fSSam Leffler 		switch (c) {
1101094c01fSSam Leffler 		case 'a':
1111094c01fSSam Leffler 			what |= DUMP_ALL;
1121094c01fSSam Leffler 			break;
1131094c01fSSam Leffler 		case 'A':
1141094c01fSSam Leffler 			state.show_addrs = 1;
1151094c01fSSam Leffler 			break;
1161094c01fSSam Leffler 		case 'b':
1171094c01fSSam Leffler 			what |= DUMP_BASEBAND;
1181094c01fSSam Leffler 			break;
1191094c01fSSam Leffler 		case 'd':
1201094c01fSSam Leffler 			what |= DUMP_DCU;
1211094c01fSSam Leffler 			break;
1221094c01fSSam Leffler 		case 'k':
1231094c01fSSam Leffler 			what |= DUMP_KEYCACHE;
1241094c01fSSam Leffler 			break;
1251094c01fSSam Leffler 		case 'i':
1261094c01fSSam Leffler 			ifname = optarg;
1271094c01fSSam Leffler 			break;
1281094c01fSSam Leffler 		case 'm':
1291094c01fSSam Leffler 			what |= DUMP_BASIC;
1301094c01fSSam Leffler 			break;
1311094c01fSSam Leffler 		case 'N':
1321094c01fSSam Leffler 			state.show_names = 0;
1331094c01fSSam Leffler 			break;
1341094c01fSSam Leffler 		case 'q':
1351094c01fSSam Leffler 			what |= DUMP_QCU;
1361094c01fSSam Leffler 			break;
1371094c01fSSam Leffler 		case 'x':
1381094c01fSSam Leffler 			what |= DUMP_XR;
1391094c01fSSam Leffler 			break;
1401094c01fSSam Leffler 		case 'z':
1411094c01fSSam Leffler 			what |= DUMP_INTERRUPT;
1421094c01fSSam Leffler 			break;
1431094c01fSSam Leffler 		default:
1441094c01fSSam Leffler 			usage();
1451094c01fSSam Leffler 			/*NOTREACHED*/
1461094c01fSSam Leffler 		}
147f0ea23b2SAdrian Chadd 
148f0ea23b2SAdrian Chadd 	/* Initialise the driver interface */
149f0ea23b2SAdrian Chadd 	if (ath_driver_req_open(&req, ifname) < 0) {
150f0ea23b2SAdrian Chadd 		exit(127);
151f0ea23b2SAdrian Chadd 	}
152f0ea23b2SAdrian Chadd 
153f0ea23b2SAdrian Chadd 	/*
154f0ea23b2SAdrian Chadd 	 * Whilst we're doing the ath_diag pieces, we have to set this
155f0ea23b2SAdrian Chadd 	 * ourselves.
156f0ea23b2SAdrian Chadd 	 */
1571094c01fSSam Leffler 	strncpy(atd.ad_name, ifname, sizeof (atd.ad_name));
1581094c01fSSam Leffler 
1591094c01fSSam Leffler 	argc -= optind;
1601094c01fSSam Leffler 	argv += optind;
1611094c01fSSam Leffler 	if (what == 0)
1621094c01fSSam Leffler 		what = DUMP_BASIC;
1631094c01fSSam Leffler 
1641094c01fSSam Leffler 	atd.ad_id = HAL_DIAG_REVS;
1651094c01fSSam Leffler 	atd.ad_out_data = (caddr_t) &state.revs;
1661094c01fSSam Leffler 	atd.ad_out_size = sizeof(state.revs);
167f0ea23b2SAdrian Chadd 
168f0ea23b2SAdrian Chadd 	if (ath_driver_req_fetch_diag(&req, SIOCGATHDIAG, &atd) < 0)
169727d23e3SAdrian Chadd 		err(1, "%s", atd.ad_name);
1701094c01fSSam Leffler 
1711094c01fSSam Leffler 	if (ath_hal_setupregs(&atd, what) == 0)
1721094c01fSSam Leffler 		errx(-1, "no registers are known for this part "
1731094c01fSSam Leffler 		    "(devid 0x%x mac %d.%d phy %d)", state.revs.ah_devid,
1741094c01fSSam Leffler 		    state.revs.ah_macVersion, state.revs.ah_macRev,
1751094c01fSSam Leffler 		    state.revs.ah_phyRev);
1761094c01fSSam Leffler 
1771094c01fSSam Leffler 	atd.ad_out_size = ath_hal_setupdiagregs((HAL_REGRANGE *) atd.ad_in_data,
1781094c01fSSam Leffler 		atd.ad_in_size / sizeof(HAL_REGRANGE));
1791094c01fSSam Leffler 	atd.ad_out_data = (caddr_t) malloc(atd.ad_out_size);
1801094c01fSSam Leffler 	if (atd.ad_out_data == NULL) {
1811094c01fSSam Leffler 		fprintf(stderr, "Cannot malloc output buffer, size %u\n",
1821094c01fSSam Leffler 			atd.ad_out_size);
1831094c01fSSam Leffler 		exit(-1);
1841094c01fSSam Leffler 	}
1851094c01fSSam Leffler 	atd.ad_id = HAL_DIAG_REGS | ATH_DIAG_IN | ATH_DIAG_DYN;
186f0ea23b2SAdrian Chadd 
187f0ea23b2SAdrian Chadd 	if (ath_driver_req_fetch_diag(&req, SIOCGATHDIAG, &atd) < 0)
188727d23e3SAdrian Chadd 		err(1, "%s", atd.ad_name);
1891094c01fSSam Leffler 
1901094c01fSSam Leffler 	/*
1911094c01fSSam Leffler 	 * Expand register data into global space that can be
1921094c01fSSam Leffler 	 * indexed directly by register offset.
1931094c01fSSam Leffler 	 */
1941094c01fSSam Leffler 	dp = (u_int32_t *)atd.ad_out_data;
1951094c01fSSam Leffler 	ep = (u_int32_t *)(atd.ad_out_data + atd.ad_out_size);
1961094c01fSSam Leffler 	while (dp < ep) {
197fa5e9502SAdrian Chadd 		u_int r = dp[0];	/* start of range */
198fa5e9502SAdrian Chadd 		u_int e = dp[1];	/* end of range */
199fa5e9502SAdrian Chadd 		dp++;
2001094c01fSSam Leffler 		dp++;
2011094c01fSSam Leffler 		/* convert offsets to indices */
2021094c01fSSam Leffler 		r >>= 2; e >>= 2;
2031094c01fSSam Leffler 		do {
2041094c01fSSam Leffler 			if (dp >= ep) {
2051094c01fSSam Leffler 				fprintf(stderr, "Warning, botched return data;"
2061094c01fSSam Leffler 					"register at offset 0x%x not present\n",
2071094c01fSSam Leffler 					r << 2);
2081094c01fSSam Leffler 				break;
2091094c01fSSam Leffler 			}
2101094c01fSSam Leffler 			state.regdata[r++] = *dp++;
2111094c01fSSam Leffler 		} while (r <= e);
2121094c01fSSam Leffler 	}
2131094c01fSSam Leffler 
2141094c01fSSam Leffler 	if (what & DUMP_BASIC)
2151094c01fSSam Leffler 		ath_hal_dumpregs(stdout, DUMP_BASIC);
2161094c01fSSam Leffler 	if ((what & DUMP_INTERRUPT) && ath_hal_anyregs(DUMP_INTERRUPT)) {
2171094c01fSSam Leffler 		if (what & DUMP_BASIC)
2181094c01fSSam Leffler 			putchar('\n');
2191094c01fSSam Leffler 		if (state.show_addrs)
2201094c01fSSam Leffler 			ath_hal_dumpregs(stdout, DUMP_INTERRUPT);
2211094c01fSSam Leffler 		else
2221094c01fSSam Leffler 			ath_hal_dumpint(stdout, what);
2231094c01fSSam Leffler 	}
2241094c01fSSam Leffler 	if ((what & DUMP_QCU) && ath_hal_anyregs(DUMP_QCU)) {
2251094c01fSSam Leffler 		if (what & (DUMP_BASIC|DUMP_INTERRUPT))
2261094c01fSSam Leffler 			putchar('\n');
2271094c01fSSam Leffler 		if (state.show_addrs)
2281094c01fSSam Leffler 			ath_hal_dumpregs(stdout, DUMP_QCU);
2291094c01fSSam Leffler 		else
2301094c01fSSam Leffler 			ath_hal_dumpqcu(stdout, what);
2311094c01fSSam Leffler 	}
2321094c01fSSam Leffler 	if ((what & DUMP_DCU) && ath_hal_anyregs(DUMP_DCU)) {
2331094c01fSSam Leffler 		if (what & (DUMP_BASIC|DUMP_INTERRUPT|DUMP_QCU))
2341094c01fSSam Leffler 			putchar('\n');
2351094c01fSSam Leffler 		if (state.show_addrs)
2361094c01fSSam Leffler 			ath_hal_dumpregs(stdout, DUMP_DCU);
2371094c01fSSam Leffler 		else
2381094c01fSSam Leffler 			ath_hal_dumpdcu(stdout, what);
2391094c01fSSam Leffler 	}
2401094c01fSSam Leffler 	if (what & DUMP_KEYCACHE) {
2411094c01fSSam Leffler 		if (state.show_addrs) {
2421094c01fSSam Leffler 			if (what & (DUMP_BASIC|DUMP_INTERRUPT|DUMP_QCU|DUMP_DCU))
2431094c01fSSam Leffler 				putchar('\n');
2441094c01fSSam Leffler 			ath_hal_dumpregs(stdout, DUMP_KEYCACHE);
2451094c01fSSam Leffler 		} else
2461094c01fSSam Leffler 			ath_hal_dumpkeycache(stdout, 128);
2471094c01fSSam Leffler 	}
2481094c01fSSam Leffler 	if (what & DUMP_BASEBAND) {
2491094c01fSSam Leffler 		if (what &~ DUMP_BASEBAND)
2501094c01fSSam Leffler 			fprintf(stdout, "\n");
2511094c01fSSam Leffler 		ath_hal_dumpbb(stdout, what);
2521094c01fSSam Leffler 	}
253f0ea23b2SAdrian Chadd 	ath_driver_req_close(&req);
2541094c01fSSam Leffler 	return 0;
2551094c01fSSam Leffler }
2561094c01fSSam Leffler 
2571094c01fSSam Leffler static int
regcompar(const void * a,const void * b)2581094c01fSSam Leffler regcompar(const void *a, const void *b)
2591094c01fSSam Leffler {
2601094c01fSSam Leffler 	const struct dumpreg *ra = *(const struct dumpreg **)a;
2611094c01fSSam Leffler 	const struct dumpreg *rb = *(const struct dumpreg **)b;
2621094c01fSSam Leffler 	return ra->addr - rb->addr;
2631094c01fSSam Leffler }
2641094c01fSSam Leffler 
2651094c01fSSam Leffler 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)2661094c01fSSam Leffler register_regs(struct dumpreg *chipregs, u_int nchipregs,
2671094c01fSSam Leffler 	int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max)
2681094c01fSSam Leffler {
2691094c01fSSam Leffler 	const int existing_regs = state.nregs;
2701094c01fSSam Leffler 	int i, j;
2711094c01fSSam Leffler 
2721094c01fSSam Leffler 	for (i = 0; i < nchipregs; i++) {
2731094c01fSSam Leffler 		struct dumpreg *nr = &chipregs[i];
2741094c01fSSam Leffler 		if (nr->srevMin == 0)
2751094c01fSSam Leffler 			nr->srevMin = def_srev_min;
2761094c01fSSam Leffler 		if (nr->srevMax == 0)
2771094c01fSSam Leffler 			nr->srevMax = def_srev_max;
2781094c01fSSam Leffler 		if (nr->phyMin == 0)
2791094c01fSSam Leffler 			nr->phyMin = def_phy_min;
2801094c01fSSam Leffler 		if (nr->phyMax == 0)
2811094c01fSSam Leffler 			nr->phyMax = def_phy_max;
2821094c01fSSam Leffler 		for (j = 0; j < existing_regs; j++) {
2831094c01fSSam Leffler 			struct dumpreg *r = state.regs[j];
2841094c01fSSam Leffler 			/*
2851094c01fSSam Leffler 			 * Check if we can just expand the mac+phy
2861094c01fSSam Leffler 			 * coverage for the existing entry.
2871094c01fSSam Leffler 			 */
2881094c01fSSam Leffler 			if (nr->addr == r->addr &&
2891094c01fSSam Leffler 			    (nr->name == r->name ||
2901094c01fSSam Leffler 			     nr->name != NULL && r->name != NULL &&
2911094c01fSSam Leffler 			     strcmp(nr->name, r->name) == 0)) {
2921094c01fSSam Leffler 				if (nr->srevMin < r->srevMin &&
2931094c01fSSam Leffler 				    (r->srevMin <= nr->srevMax &&
2941094c01fSSam Leffler 				     nr->srevMax+1 <= r->srevMax)) {
2951094c01fSSam Leffler 					r->srevMin = nr->srevMin;
2961094c01fSSam Leffler 					goto skip;
2971094c01fSSam Leffler 				}
2981094c01fSSam Leffler 				if (nr->srevMax > r->srevMax &&
2991094c01fSSam Leffler 				    (r->srevMin <= nr->srevMin &&
3001094c01fSSam Leffler 				     nr->srevMin <= r->srevMax)) {
3011094c01fSSam Leffler 					r->srevMax = nr->srevMax;
3021094c01fSSam Leffler 					goto skip;
3031094c01fSSam Leffler 				}
3041094c01fSSam Leffler 			}
3051094c01fSSam Leffler 			if (r->addr > nr->addr)
3061094c01fSSam Leffler 				break;
3071094c01fSSam Leffler 		}
3081094c01fSSam Leffler 		/*
3091094c01fSSam Leffler 		 * New item, add to the end, it'll be sorted below.
3101094c01fSSam Leffler 		 */
3111094c01fSSam Leffler 		if (state.nregs == MAXREGS)
3121094c01fSSam Leffler 			errx(-1, "too many registers; bump MAXREGS");
3131094c01fSSam Leffler 		state.regs[state.nregs++] = nr;
3141094c01fSSam Leffler 	skip:
3151094c01fSSam Leffler 		;
3161094c01fSSam Leffler 	}
3171094c01fSSam Leffler 	qsort(state.regs, state.nregs, sizeof(struct dumpreg *), regcompar);
3181094c01fSSam Leffler }
3191094c01fSSam Leffler 
3201094c01fSSam Leffler void
register_keycache(u_int nslots,int def_srev_min,int def_srev_max,int def_phy_min,int def_phy_max)3211094c01fSSam Leffler register_keycache(u_int nslots,
3221094c01fSSam Leffler 	int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max)
3231094c01fSSam Leffler {
3241094c01fSSam Leffler #define	SET(r, a) do { \
3251094c01fSSam Leffler 	r->addr = a; r->type = DUMP_KEYCACHE; r++; \
3261094c01fSSam Leffler } while(0)
3271094c01fSSam Leffler 	struct dumpreg *keyregs, *r;
3281094c01fSSam Leffler 	int i;
3291094c01fSSam Leffler 
3301094c01fSSam Leffler 	keyregs = (struct dumpreg *) calloc(nslots, 8*sizeof(struct dumpreg));
3311094c01fSSam Leffler 	if (keyregs == NULL)
3321094c01fSSam Leffler 		errx(-1, "no space to %d keycache slots\n", nslots);
3331094c01fSSam Leffler 	r = keyregs;
3341094c01fSSam Leffler 	for (i = 0; i < nslots; i++) {
3351094c01fSSam Leffler 		SET(r, AR_KEYTABLE_KEY0(i));
3361094c01fSSam Leffler 		SET(r, AR_KEYTABLE_KEY1(i));
3371094c01fSSam Leffler 		SET(r, AR_KEYTABLE_KEY2(i));
3381094c01fSSam Leffler 		SET(r, AR_KEYTABLE_KEY3(i));
3391094c01fSSam Leffler 		SET(r, AR_KEYTABLE_KEY4(i));
3401094c01fSSam Leffler 		SET(r, AR_KEYTABLE_TYPE(i));
3411094c01fSSam Leffler 		SET(r, AR_KEYTABLE_MAC0(i));
3421094c01fSSam Leffler 		SET(r, AR_KEYTABLE_MAC1(i));
3431094c01fSSam Leffler 	}
3441094c01fSSam Leffler 	register_regs(keyregs, 8*nslots,
3451094c01fSSam Leffler 	    def_srev_min, def_srev_max, def_phy_min, def_phy_max);
3461094c01fSSam Leffler #undef SET
3471094c01fSSam Leffler }
3481094c01fSSam Leffler 
3491094c01fSSam Leffler 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)3501094c01fSSam Leffler register_range(u_int brange, u_int erange, int type,
3511094c01fSSam Leffler 	int def_srev_min, int def_srev_max, int def_phy_min, int def_phy_max)
3521094c01fSSam Leffler {
3531094c01fSSam Leffler 	struct dumpreg *bbregs, *r;
3541094c01fSSam Leffler 	int i, nregs;
3551094c01fSSam Leffler 
3561094c01fSSam Leffler 	nregs = (erange - brange) / sizeof(uint32_t);
3571094c01fSSam Leffler 	bbregs = (struct dumpreg *) calloc(nregs, sizeof(struct dumpreg));
3581094c01fSSam Leffler 	if (bbregs == NULL)
3591094c01fSSam Leffler 		errx(-1, "no space for %d register slots (type %d)\n",
3601094c01fSSam Leffler 		    nregs, type);
3611094c01fSSam Leffler 	r = bbregs;
3621094c01fSSam Leffler 	for (i = 0; i < nregs; i++) {
3631094c01fSSam Leffler 		r->addr = brange + (i<<2);
3641094c01fSSam Leffler 		r->type = type;
3651094c01fSSam Leffler 		r++;
3661094c01fSSam Leffler 	}
3671094c01fSSam Leffler 	register_regs(bbregs, nregs,
3681094c01fSSam Leffler 	    def_srev_min, def_srev_max, def_phy_min, def_phy_max);
3691094c01fSSam Leffler }
3701094c01fSSam Leffler 
3711045db19SAdrian Chadd static __inline int
match(const struct dumpreg * dr,const HAL_REVS * revs)3721094c01fSSam Leffler match(const struct dumpreg *dr, const HAL_REVS *revs)
3731094c01fSSam Leffler {
3741094c01fSSam Leffler 	if (!MAC_MATCH(dr, revs->ah_macVersion, revs->ah_macRev))
3751094c01fSSam Leffler 		return 0;
3761094c01fSSam Leffler 	if ((dr->type & DUMP_BASEBAND) && !PHY_MATCH(dr, revs->ah_phyRev))
3771094c01fSSam Leffler 		return 0;
3781094c01fSSam Leffler 	return 1;
3791094c01fSSam Leffler }
3801094c01fSSam Leffler 
3811094c01fSSam Leffler static int
ath_hal_anyregs(int what)3821094c01fSSam Leffler ath_hal_anyregs(int what)
3831094c01fSSam Leffler {
3841094c01fSSam Leffler 	const HAL_REVS *revs = &state.revs;
3851094c01fSSam Leffler 	int i;
3861094c01fSSam Leffler 
3871094c01fSSam Leffler 	for (i = 0; i < state.nregs; i++) {
3881094c01fSSam Leffler 		const struct dumpreg *dr = state.regs[i];
3891094c01fSSam Leffler 		if ((what & dr->type) && match(dr, revs))
3901094c01fSSam Leffler 			return 1;
3911094c01fSSam Leffler 	}
3921094c01fSSam Leffler 	return 0;
3931094c01fSSam Leffler }
3941094c01fSSam Leffler 
3951094c01fSSam Leffler static int
ath_hal_setupregs(struct ath_diag * atd,int what)3961094c01fSSam Leffler ath_hal_setupregs(struct ath_diag *atd, int what)
3971094c01fSSam Leffler {
3981094c01fSSam Leffler 	const HAL_REVS *revs = &state.revs;
3991094c01fSSam Leffler 	HAL_REGRANGE r;
4001094c01fSSam Leffler 	size_t space = 0;
4011094c01fSSam Leffler 	u_int8_t *cp;
4021094c01fSSam Leffler 	int i, brun, erun;
4031094c01fSSam Leffler 
4041094c01fSSam Leffler 	brun = erun = -1;
4051094c01fSSam Leffler 	for (i = 0; i < state.nregs; i++) {
4061094c01fSSam Leffler 		const struct dumpreg *dr = state.regs[i];
4071094c01fSSam Leffler 		if ((what & dr->type) && match(dr, revs)) {
4081094c01fSSam Leffler 			if (erun + 4 != dr->addr) {
4091094c01fSSam Leffler 				if (brun != -1)
4101094c01fSSam Leffler 					space += sizeof(HAL_REGRANGE);
4111094c01fSSam Leffler 				brun = erun = dr->addr;
4121094c01fSSam Leffler 			} else
4131094c01fSSam Leffler 				erun = dr->addr;
4141094c01fSSam Leffler 		}
4151094c01fSSam Leffler 	}
4161094c01fSSam Leffler 	space += sizeof(HAL_REGRANGE);
4171094c01fSSam Leffler 
4181094c01fSSam Leffler 	atd->ad_in_data = (caddr_t) malloc(space);
4191094c01fSSam Leffler 	if (atd->ad_in_data == NULL) {
4201094c01fSSam Leffler 		fprintf(stderr, "Cannot malloc memory for registers!\n");
4211094c01fSSam Leffler 		exit(-1);
4221094c01fSSam Leffler 	}
4231094c01fSSam Leffler 	atd->ad_in_size = space;
4241094c01fSSam Leffler 	cp = (u_int8_t *) atd->ad_in_data;
4251094c01fSSam Leffler 	brun = erun = -1;
4261094c01fSSam Leffler 	for (i = 0; i < state.nregs; i++) {
4271094c01fSSam Leffler 		const struct dumpreg *dr = state.regs[i];
4281094c01fSSam Leffler 		if ((what & dr->type) && match(dr, revs)) {
4291094c01fSSam Leffler 			if (erun + 4 != dr->addr) {
4301094c01fSSam Leffler 				if (brun != -1) {
4311094c01fSSam Leffler 					r.start = brun, r.end = erun;
4321094c01fSSam Leffler 					memcpy(cp, &r, sizeof(r));
4331094c01fSSam Leffler 					cp += sizeof(r);
4341094c01fSSam Leffler 				}
4351094c01fSSam Leffler 				brun = erun = dr->addr;
4361094c01fSSam Leffler 			} else
4371094c01fSSam Leffler 				erun = dr->addr;
4381094c01fSSam Leffler 		}
4391094c01fSSam Leffler 	}
4401094c01fSSam Leffler 	if (brun != -1) {
4411094c01fSSam Leffler 		r.start = brun, r.end = erun;
4421094c01fSSam Leffler 		memcpy(cp, &r, sizeof(r));
4431094c01fSSam Leffler 		cp += sizeof(r);
4441094c01fSSam Leffler 	}
4451094c01fSSam Leffler 	return space / sizeof(uint32_t);
4461094c01fSSam Leffler }
4471094c01fSSam Leffler 
4481094c01fSSam Leffler static void
ath_hal_dumpregs(FILE * fd,int what)4491094c01fSSam Leffler ath_hal_dumpregs(FILE *fd, int what)
4501094c01fSSam Leffler {
4511094c01fSSam Leffler 	const HAL_REVS *revs = &state.revs;
4521094c01fSSam Leffler 	const char *sep = "";
4531094c01fSSam Leffler 	int i, count, itemsperline;
4541094c01fSSam Leffler 
4551094c01fSSam Leffler 	count = 0;
4561094c01fSSam Leffler 	itemsperline = 4;
4571094c01fSSam Leffler 	if (state.show_names && state.show_addrs)
4581094c01fSSam Leffler 		itemsperline--;
4591094c01fSSam Leffler 	for (i = 0; i < state.nregs; i++) {
4601094c01fSSam Leffler 		const struct dumpreg *dr = state.regs[i];
4611094c01fSSam Leffler 		if ((what & dr->type) && match(dr, revs)) {
4621094c01fSSam Leffler 			if (state.show_names && dr->name != NULL) {
4631094c01fSSam Leffler 				fprintf(fd, "%s%-8s", sep, dr->name);
4641094c01fSSam Leffler 				if (state.show_addrs)
4651094c01fSSam Leffler 					fprintf(fd, " [%04x]", dr->addr);
4661094c01fSSam Leffler 			} else
4671094c01fSSam Leffler 				fprintf(fd, "%s%04x", sep, dr->addr);
4681094c01fSSam Leffler 			fprintf(fd, " %08x", OS_REG_READ(ah, dr->addr));
4691094c01fSSam Leffler 			sep = " ";
4701094c01fSSam Leffler 			if ((++count % itemsperline) == 0)
4711094c01fSSam Leffler 				sep = "\n";
4721094c01fSSam Leffler 		}
4731094c01fSSam Leffler 	}
4741094c01fSSam Leffler 	if (count)
4751094c01fSSam Leffler 		fprintf(fd, "\n");
4761094c01fSSam Leffler }
4771094c01fSSam Leffler 
4781094c01fSSam Leffler static void
ath_hal_dumprange(FILE * fd,u_int a,u_int b)4791094c01fSSam Leffler ath_hal_dumprange(FILE *fd, u_int a, u_int b)
4801094c01fSSam Leffler {
4811094c01fSSam Leffler 	u_int r;
4821094c01fSSam Leffler 
4831094c01fSSam Leffler 	for (r = a; r+16 <= b; r += 5*4)
4841094c01fSSam Leffler 		fprintf(fd,
4851094c01fSSam Leffler 			"%04x %08x  %04x %08x  %04x %08x  %04x %08x  %04x %08x\n"
4861094c01fSSam Leffler 			, r, OS_REG_READ(ah, r)
4871094c01fSSam Leffler 			, r+4, OS_REG_READ(ah, r+4)
4881094c01fSSam Leffler 			, r+8, OS_REG_READ(ah, r+8)
4891094c01fSSam Leffler 			, r+12, OS_REG_READ(ah, r+12)
4901094c01fSSam Leffler 			, r+16, OS_REG_READ(ah, r+16)
4911094c01fSSam Leffler 		);
4921094c01fSSam Leffler 	switch (b-r) {
4931094c01fSSam Leffler 	case 16:
4941094c01fSSam Leffler 		fprintf(fd
4951094c01fSSam Leffler 			, "%04x %08x  %04x %08x  %04x %08x  %04x %08x\n"
4961094c01fSSam Leffler 			, r, OS_REG_READ(ah, r)
4971094c01fSSam Leffler 			, r+4, OS_REG_READ(ah, r+4)
4981094c01fSSam Leffler 			, r+8, OS_REG_READ(ah, r+8)
4991094c01fSSam Leffler 			, r+12, OS_REG_READ(ah, r+12)
5001094c01fSSam Leffler 		);
5011094c01fSSam Leffler 		break;
5021094c01fSSam Leffler 	case 12:
5031094c01fSSam Leffler 		fprintf(fd, "%04x %08x  %04x %08x  %04x %08x\n"
5041094c01fSSam Leffler 			, r, OS_REG_READ(ah, r)
5051094c01fSSam Leffler 			, r+4, OS_REG_READ(ah, r+4)
5061094c01fSSam Leffler 			, r+8, OS_REG_READ(ah, r+8)
5071094c01fSSam Leffler 		);
5081094c01fSSam Leffler 		break;
5091094c01fSSam Leffler 	case 8:
5101094c01fSSam Leffler 		fprintf(fd, "%04x %08x  %04x %08x\n"
5111094c01fSSam Leffler 			, r, OS_REG_READ(ah, r)
5121094c01fSSam Leffler 			, r+4, OS_REG_READ(ah, r+4)
5131094c01fSSam Leffler 		);
5141094c01fSSam Leffler 		break;
5151094c01fSSam Leffler 	case 4:
5161094c01fSSam Leffler 		fprintf(fd, "%04x %08x\n"
5171094c01fSSam Leffler 			, r, OS_REG_READ(ah, r)
5181094c01fSSam Leffler 		);
5191094c01fSSam Leffler 		break;
5201094c01fSSam Leffler 	}
5211094c01fSSam Leffler }
5221094c01fSSam Leffler 
5231094c01fSSam Leffler static void
ath_hal_dumpint(FILE * fd,int what)5241094c01fSSam Leffler ath_hal_dumpint(FILE *fd, int what)
5251094c01fSSam Leffler {
5261094c01fSSam Leffler 	int i;
5271094c01fSSam Leffler 
5281094c01fSSam Leffler 	/* Interrupt registers */
5291094c01fSSam Leffler 	fprintf(fd, "IMR: %08x S0 %08x S1 %08x S2 %08x S3 %08x S4 %08x\n"
5301094c01fSSam Leffler 		, OS_REG_READ(ah, AR_IMR)
5311094c01fSSam Leffler 		, OS_REG_READ(ah, AR_IMR_S0)
5321094c01fSSam Leffler 		, OS_REG_READ(ah, AR_IMR_S1)
5331094c01fSSam Leffler 		, OS_REG_READ(ah, AR_IMR_S2)
5341094c01fSSam Leffler 		, OS_REG_READ(ah, AR_IMR_S3)
5351094c01fSSam Leffler 		, OS_REG_READ(ah, AR_IMR_S4)
5361094c01fSSam Leffler 	);
5371094c01fSSam Leffler 	fprintf(fd, "ISR: %08x S0 %08x S1 %08x S2 %08x S3 %08x S4 %08x\n"
5381094c01fSSam Leffler 		, OS_REG_READ(ah, AR_ISR)
5391094c01fSSam Leffler 		, OS_REG_READ(ah, AR_ISR_S0)
5401094c01fSSam Leffler 		, OS_REG_READ(ah, AR_ISR_S1)
5411094c01fSSam Leffler 		, OS_REG_READ(ah, AR_ISR_S2)
5421094c01fSSam Leffler 		, OS_REG_READ(ah, AR_ISR_S3)
5431094c01fSSam Leffler 		, OS_REG_READ(ah, AR_ISR_S4)
5441094c01fSSam Leffler 	);
5451094c01fSSam Leffler }
5461094c01fSSam Leffler 
5471094c01fSSam Leffler static void
ath_hal_dumpqcu(FILE * fd,int what)5481094c01fSSam Leffler ath_hal_dumpqcu(FILE *fd, int what)
5491094c01fSSam Leffler {
5501094c01fSSam Leffler 	int i;
5511094c01fSSam Leffler 
5521094c01fSSam Leffler 	/* QCU registers */
5531094c01fSSam Leffler 	fprintf(fd, "%-8s %08x  %-8s %08x  %-8s %08x\n"
5541094c01fSSam Leffler 		, "Q_TXE", OS_REG_READ(ah, AR_Q_TXE)
5551094c01fSSam Leffler 		, "Q_TXD", OS_REG_READ(ah, AR_Q_TXD)
5561094c01fSSam Leffler 		, "Q_RDYTIMSHD", OS_REG_READ(ah, AR_Q_RDYTIMESHDN)
5571094c01fSSam Leffler 	);
5581094c01fSSam Leffler 	fprintf(fd, "Q_ONESHOTARM_SC %08x  Q_ONESHOTARM_CC %08x\n"
5591094c01fSSam Leffler 		, OS_REG_READ(ah, AR_Q_ONESHOTARM_SC)
5601094c01fSSam Leffler 		, OS_REG_READ(ah, AR_Q_ONESHOTARM_CC)
5611094c01fSSam Leffler 	);
5621094c01fSSam Leffler 	for (i = 0; i < 10; i++)
5631094c01fSSam Leffler 		fprintf(fd, "Q[%u] TXDP %08x CBR %08x RDYT %08x MISC %08x STS %08x\n"
5641094c01fSSam Leffler 			, i
5651094c01fSSam Leffler 			, OS_REG_READ(ah, AR_QTXDP(i))
5661094c01fSSam Leffler 			, OS_REG_READ(ah, AR_QCBRCFG(i))
5671094c01fSSam Leffler 			, OS_REG_READ(ah, AR_QRDYTIMECFG(i))
5681094c01fSSam Leffler 			, OS_REG_READ(ah, AR_QMISC(i))
5691094c01fSSam Leffler 			, OS_REG_READ(ah, AR_QSTS(i))
5701094c01fSSam Leffler 		);
5711094c01fSSam Leffler }
5721094c01fSSam Leffler 
5731094c01fSSam Leffler static void
ath_hal_dumpdcu(FILE * fd,int what)5741094c01fSSam Leffler ath_hal_dumpdcu(FILE *fd, int what)
5751094c01fSSam Leffler {
5761094c01fSSam Leffler 	int i;
5771094c01fSSam Leffler 
5781094c01fSSam Leffler 	/* DCU registers */
5791094c01fSSam Leffler 	for (i = 0; i < 10; i++)
5801094c01fSSam Leffler 		fprintf(fd, "D[%u] MASK %08x IFS %08x RTRY %08x CHNT %08x MISC %06x\n"
5811094c01fSSam Leffler 			, i
5821094c01fSSam Leffler 			, OS_REG_READ(ah, AR_DQCUMASK(i))
5831094c01fSSam Leffler 			, OS_REG_READ(ah, AR_DLCL_IFS(i))
5841094c01fSSam Leffler 			, OS_REG_READ(ah, AR_DRETRY_LIMIT(i))
5851094c01fSSam Leffler 			, OS_REG_READ(ah, AR_DCHNTIME(i))
5861094c01fSSam Leffler 			, OS_REG_READ(ah, AR_DMISC(i))
5871094c01fSSam Leffler 		);
5881094c01fSSam Leffler }
5891094c01fSSam Leffler 
5901094c01fSSam Leffler static void
ath_hal_dumpbb(FILE * fd,int what)5911094c01fSSam Leffler ath_hal_dumpbb(FILE *fd, int what)
5921094c01fSSam Leffler {
5931094c01fSSam Leffler 	const HAL_REVS *revs = &state.revs;
5941094c01fSSam Leffler 	int i, brun, erun;
5951094c01fSSam Leffler 
5961094c01fSSam Leffler 	brun = erun = 0;
5971094c01fSSam Leffler 	for (i = 0; i < state.nregs; i++) {
5981094c01fSSam Leffler 		const struct dumpreg *dr = state.regs[i];
5991094c01fSSam Leffler 		if (!match(dr, revs))
6001094c01fSSam Leffler 			continue;
6011094c01fSSam Leffler 		if (dr->type & DUMP_BASEBAND) {
6021094c01fSSam Leffler 			if (brun == 0) {
6031094c01fSSam Leffler 				brun = erun = dr->addr;
6041094c01fSSam Leffler 			} else if (dr->addr == erun + sizeof(uint32_t)) {
6051094c01fSSam Leffler 				erun = dr->addr;
6061094c01fSSam Leffler 			} else {
6071094c01fSSam Leffler 				ath_hal_dumprange(fd, brun, erun);
6081094c01fSSam Leffler 				brun = erun = dr->addr;
6091094c01fSSam Leffler 			}
6101094c01fSSam Leffler 		} else {
6111094c01fSSam Leffler 			if (brun != 0)
6121094c01fSSam Leffler 				ath_hal_dumprange(fd, brun, erun);
6131094c01fSSam Leffler 			brun = erun = 0;
6141094c01fSSam Leffler 		}
6151094c01fSSam Leffler 	}
6161094c01fSSam Leffler 	if (brun != 0)
6171094c01fSSam Leffler 		ath_hal_dumprange(fd, brun, erun);
6181094c01fSSam Leffler }
6191094c01fSSam Leffler 
6201094c01fSSam Leffler static u_int
ath_hal_setupdiagregs(const HAL_REGRANGE regs[],u_int nr)6211094c01fSSam Leffler ath_hal_setupdiagregs(const HAL_REGRANGE regs[], u_int nr)
6221094c01fSSam Leffler {
6231094c01fSSam Leffler 	u_int space;
6241094c01fSSam Leffler 	int i;
6251094c01fSSam Leffler 
6261094c01fSSam Leffler 	space = 0;
6271094c01fSSam Leffler 	for (i = 0; i < nr; i++) {
628fa5e9502SAdrian Chadd 		u_int n = sizeof(HAL_REGRANGE) + sizeof(u_int32_t);	/* reg range + first */
6291094c01fSSam Leffler 		if (regs[i].end) {
6301094c01fSSam Leffler 			if (regs[i].end < regs[i].start) {
6311094c01fSSam Leffler 				fprintf(stderr, "%s: bad register range, "
6321094c01fSSam Leffler 					"end 0x%x < start 0x%x\n",
6331094c01fSSam Leffler 					__func__, regs[i].end, regs[i].end);
6341094c01fSSam Leffler 				exit(-1);
6351094c01fSSam Leffler 			}
6361094c01fSSam Leffler 			n += regs[i].end - regs[i].start;
6371094c01fSSam Leffler 		}
6381094c01fSSam Leffler 		space += n;
6391094c01fSSam Leffler 	}
6401094c01fSSam Leffler 	return space;
6411094c01fSSam Leffler }
6421094c01fSSam Leffler 
6431094c01fSSam Leffler /*
6441094c01fSSam Leffler  * Format an Ethernet MAC for printing.
6451094c01fSSam Leffler  */
6461094c01fSSam Leffler static const char*
ether_sprintf(const u_int8_t * mac)6471094c01fSSam Leffler ether_sprintf(const u_int8_t *mac)
6481094c01fSSam Leffler {
6491094c01fSSam Leffler 	static char etherbuf[18];
6501094c01fSSam Leffler 	snprintf(etherbuf, sizeof(etherbuf), "%02x:%02x:%02x:%02x:%02x:%02x",
6511094c01fSSam Leffler 		mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
6521094c01fSSam Leffler 	return etherbuf;
6531094c01fSSam Leffler }
6541094c01fSSam Leffler 
6551094c01fSSam Leffler #ifndef isclr
6561094c01fSSam Leffler #define	setbit(a,i)	((a)[(i)/NBBY] |= 1<<((i)%NBBY))
6571094c01fSSam Leffler #define	clrbit(a,i)	((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
6581094c01fSSam Leffler #define	isset(a,i)	((a)[(i)/NBBY] & (1<<((i)%NBBY)))
6591094c01fSSam Leffler #define	isclr(a,i)	(((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0)
6601094c01fSSam Leffler #endif
6611094c01fSSam Leffler 
6621094c01fSSam Leffler static void
ath_hal_dumpkeycache(FILE * fd,int nkeys)6631094c01fSSam Leffler ath_hal_dumpkeycache(FILE *fd, int nkeys)
6641094c01fSSam Leffler {
6651094c01fSSam Leffler 	static const char *keytypenames[] = {
6661094c01fSSam Leffler 		"WEP-40", 	/* AR_KEYTABLE_TYPE_40 */
6671094c01fSSam Leffler 		"WEP-104",	/* AR_KEYTABLE_TYPE_104 */
6681094c01fSSam Leffler 		"#2",
6691094c01fSSam Leffler 		"WEP-128",	/* AR_KEYTABLE_TYPE_128 */
6701094c01fSSam Leffler 		"TKIP",		/* AR_KEYTABLE_TYPE_TKIP */
6711094c01fSSam Leffler 		"AES-OCB",	/* AR_KEYTABLE_TYPE_AES */
6721094c01fSSam Leffler 		"AES-CCM",	/* AR_KEYTABLE_TYPE_CCM */
6731094c01fSSam Leffler 		"CLR",		/* AR_KEYTABLE_TYPE_CLR */
6741094c01fSSam Leffler 	};
6751094c01fSSam Leffler 	int micEnabled = SREV(state.revs.ah_macVersion, state.revs.ah_macRev) < SREV(4,8) ? 0 :
6761094c01fSSam Leffler 	       OS_REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_CRPT_MIC_ENABLE;
6771094c01fSSam Leffler 	u_int8_t mac[IEEE80211_ADDR_LEN];
6781094c01fSSam Leffler 	u_int8_t ismic[128/NBBY];
6791094c01fSSam Leffler 	int entry;
6801094c01fSSam Leffler 	int first = 1;
6811094c01fSSam Leffler 
6821094c01fSSam Leffler 	memset(ismic, 0, sizeof(ismic));
6831094c01fSSam Leffler 	for (entry = 0; entry < nkeys; entry++) {
6841094c01fSSam Leffler 		u_int32_t macLo, macHi, type;
6851094c01fSSam Leffler 		u_int32_t key0, key1, key2, key3, key4;
6861094c01fSSam Leffler 
6871094c01fSSam Leffler 		macHi = OS_REG_READ(ah, AR_KEYTABLE_MAC1(entry));
6881094c01fSSam Leffler 		if ((macHi & AR_KEYTABLE_VALID) == 0 && isclr(ismic, entry))
6891094c01fSSam Leffler 			continue;
6901094c01fSSam Leffler 		macLo = OS_REG_READ(ah, AR_KEYTABLE_MAC0(entry));
6911094c01fSSam Leffler 		macHi <<= 1;
6921094c01fSSam Leffler 		if (macLo & (1<<31))
6931094c01fSSam Leffler 			macHi |= 1;
6941094c01fSSam Leffler 		macLo <<= 1;
6951094c01fSSam Leffler 		mac[4] = macHi & 0xff;
6961094c01fSSam Leffler 		mac[5] = macHi >> 8;
6971094c01fSSam Leffler 		mac[0] = macLo & 0xff;
6981094c01fSSam Leffler 		mac[1] = macLo >> 8;
6991094c01fSSam Leffler 		mac[2] = macLo >> 16;
7001094c01fSSam Leffler 		mac[3] = macLo >> 24;
7011094c01fSSam Leffler 		type = OS_REG_READ(ah, AR_KEYTABLE_TYPE(entry));
7021094c01fSSam Leffler 		if ((type & 7) == AR_KEYTABLE_TYPE_TKIP && micEnabled)
7031094c01fSSam Leffler 			setbit(ismic, entry+64);
7041094c01fSSam Leffler 		key0 = OS_REG_READ(ah, AR_KEYTABLE_KEY0(entry));
7051094c01fSSam Leffler 		key1 = OS_REG_READ(ah, AR_KEYTABLE_KEY1(entry));
7061094c01fSSam Leffler 		key2 = OS_REG_READ(ah, AR_KEYTABLE_KEY2(entry));
7071094c01fSSam Leffler 		key3 = OS_REG_READ(ah, AR_KEYTABLE_KEY3(entry));
7081094c01fSSam Leffler 		key4 = OS_REG_READ(ah, AR_KEYTABLE_KEY4(entry));
7091094c01fSSam Leffler 		if (first) {
7101094c01fSSam Leffler 			fprintf(fd, "\n");
7111094c01fSSam Leffler 			first = 0;
7121094c01fSSam Leffler 		}
7131094c01fSSam Leffler 		fprintf(fd, "KEY[%03u] MAC %s %-7s %02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x\n"
7141094c01fSSam Leffler 			, entry
7151094c01fSSam Leffler 			, ether_sprintf(mac)
7161094c01fSSam Leffler 			, isset(ismic, entry) ? "MIC" : keytypenames[type & 7]
7171094c01fSSam Leffler 			, (key0 >>  0) & 0xff
7181094c01fSSam Leffler 			, (key0 >>  8) & 0xff
7191094c01fSSam Leffler 			, (key0 >> 16) & 0xff
7201094c01fSSam Leffler 			, (key0 >> 24) & 0xff
7211094c01fSSam Leffler 			, (key1 >>  0) & 0xff
7221094c01fSSam Leffler 			, (key1 >>  8) & 0xff
7231094c01fSSam Leffler 			, (key2 >>  0) & 0xff
7241094c01fSSam Leffler 			, (key2 >>  8) & 0xff
7251094c01fSSam Leffler 			, (key2 >> 16) & 0xff
7261094c01fSSam Leffler 			, (key2 >> 24) & 0xff
7271094c01fSSam Leffler 			, (key3 >>  0) & 0xff
7281094c01fSSam Leffler 			, (key3 >>  8) & 0xff
7291094c01fSSam Leffler 			, (key4 >>  0) & 0xff
7301094c01fSSam Leffler 			, (key4 >>  8) & 0xff
7311094c01fSSam Leffler 			, (key4 >> 16) & 0xff
7321094c01fSSam Leffler 			, (key4 >> 24) & 0xff
7331094c01fSSam Leffler 		);
7341094c01fSSam Leffler 	}
7351094c01fSSam Leffler }
736