xref: /dragonfly/tools/tools/ath/athpow/athpow.c (revision df052c2a)
1cde9b937SSascha Wildner /*-
2cde9b937SSascha Wildner  * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
3cde9b937SSascha Wildner  * All rights reserved.
4cde9b937SSascha Wildner  *
5cde9b937SSascha Wildner  * Redistribution and use in source and binary forms, with or without
6cde9b937SSascha Wildner  * modification, are permitted provided that the following conditions
7cde9b937SSascha Wildner  * are met:
8cde9b937SSascha Wildner  * 1. Redistributions of source code must retain the above copyright
9cde9b937SSascha Wildner  *    notice, this list of conditions and the following disclaimer,
10cde9b937SSascha Wildner  *    without modification.
11cde9b937SSascha Wildner  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12cde9b937SSascha Wildner  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13cde9b937SSascha Wildner  *    redistribution must be conditioned upon including a substantially
14cde9b937SSascha Wildner  *    similar Disclaimer requirement for further binary redistribution.
15cde9b937SSascha Wildner  *
16cde9b937SSascha Wildner  * NO WARRANTY
17cde9b937SSascha Wildner  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18cde9b937SSascha Wildner  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*df052c2aSSascha Wildner  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTABILITY
20cde9b937SSascha Wildner  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21cde9b937SSascha Wildner  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22cde9b937SSascha Wildner  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23cde9b937SSascha Wildner  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24cde9b937SSascha Wildner  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25cde9b937SSascha Wildner  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26cde9b937SSascha Wildner  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27cde9b937SSascha Wildner  * THE POSSIBILITY OF SUCH DAMAGES.
28cde9b937SSascha Wildner  *
29cde9b937SSascha Wildner  * $FreeBSD: src/tools/tools/ath/athpow/athpow.c,v 1.1 2008/12/07 19:17:33 sam Exp $
30cde9b937SSascha Wildner  */
31cde9b937SSascha Wildner #include "diag.h"
32cde9b937SSascha Wildner 
33cde9b937SSascha Wildner #include <getopt.h>
34cde9b937SSascha Wildner #include <stdlib.h>
35cde9b937SSascha Wildner #include <string.h>
36cde9b937SSascha Wildner 
37cde9b937SSascha Wildner #include "ah.h"
38cde9b937SSascha Wildner #include "ah_internal.h"
39cde9b937SSascha Wildner #include "ah_eeprom.h"
40cde9b937SSascha Wildner #include "ah_eeprom_v1.h"
41cde9b937SSascha Wildner #include "ah_eeprom_v3.h"
42cde9b937SSascha Wildner #include "ah_eeprom_v14.h"
43cde9b937SSascha Wildner #include "ar5212/ar5212reg.h"
44cde9b937SSascha Wildner #define	IS_5112(ah) \
45cde9b937SSascha Wildner 	(((ah)->ah_analog5GhzRev&0xf0) >= AR_RAD5112_SREV_MAJOR \
46cde9b937SSascha Wildner 	 && ((ah)->ah_analog5GhzRev&0xf0) < AR_RAD2316_SREV_MAJOR )
47cde9b937SSascha Wildner #define	IS_2316(ah) \
48cde9b937SSascha Wildner 	((ah)->ah_macVersion == AR_SREV_2415)
49cde9b937SSascha Wildner #define	IS_2413(ah) \
50cde9b937SSascha Wildner 	((ah)->ah_macVersion == AR_SREV_2413 || IS_2316(ah))
51cde9b937SSascha Wildner #define IS_5424(ah) \
52cde9b937SSascha Wildner 	((ah)->ah_macVersion == AR_SREV_5424 || \
53cde9b937SSascha Wildner 	((ah)->ah_macVersion == AR_SREV_5413 && \
54cde9b937SSascha Wildner 	  (ah)->ah_macRev <= AR_SREV_D2PLUS_MS))
55cde9b937SSascha Wildner #define IS_5413(ah) \
56cde9b937SSascha Wildner 	((ah)->ah_macVersion == AR_SREV_5413 || IS_5424(ah))
57cde9b937SSascha Wildner 
58cde9b937SSascha Wildner #ifndef MAX
59cde9b937SSascha Wildner #define	MAX(a,b)	((a) > (b) ? (a) : (b))
60cde9b937SSascha Wildner #endif
61cde9b937SSascha Wildner 
62cde9b937SSascha Wildner static void printPcdacTable(FILE *fd, u_int16_t pcdac[], u_int n);
63cde9b937SSascha Wildner static void printPowerPerRate(FILE *fd, u_int16_t ratesArray[], u_int n);
64cde9b937SSascha Wildner static void printRevs(FILE *fd, const HAL_REVS *revs);
65cde9b937SSascha Wildner 
66cde9b937SSascha Wildner static void
usage(const char * progname)67cde9b937SSascha Wildner usage(const char *progname)
68cde9b937SSascha Wildner {
69cde9b937SSascha Wildner 	fprintf(stderr, "usage: %s [-v] [-i dev]\n", progname);
70cde9b937SSascha Wildner 	exit(1);
71cde9b937SSascha Wildner }
72cde9b937SSascha Wildner 
73cde9b937SSascha Wildner int
main(int argc,char * argv[])74cde9b937SSascha Wildner main(int argc, char *argv[])
75cde9b937SSascha Wildner {
76cde9b937SSascha Wildner 	int s, i, verbose = 0, c;
77cde9b937SSascha Wildner 	struct ath_diag atd;
78cde9b937SSascha Wildner 	const char *ifname;
79cde9b937SSascha Wildner 	HAL_REVS revs;
80cde9b937SSascha Wildner 	u_int16_t pcdacTable[MAX(PWR_TABLE_SIZE,PWR_TABLE_SIZE_2413)];
81cde9b937SSascha Wildner 	u_int16_t ratesArray[16];
82cde9b937SSascha Wildner 	u_int nrates, npcdac;
83cde9b937SSascha Wildner 
84cde9b937SSascha Wildner 	s = socket(AF_INET, SOCK_DGRAM, 0);
85cde9b937SSascha Wildner 	if (s < 0)
86cde9b937SSascha Wildner 		err(1, "socket");
87cde9b937SSascha Wildner 	ifname = getenv("ATH");
88cde9b937SSascha Wildner 	if (!ifname)
89cde9b937SSascha Wildner 		ifname = ATH_DEFAULT;
90cde9b937SSascha Wildner 	while ((c = getopt(argc, argv, "i:v")) != -1)
91cde9b937SSascha Wildner 		switch (c) {
92cde9b937SSascha Wildner 		case 'i':
93cde9b937SSascha Wildner 			ifname = optarg;
94cde9b937SSascha Wildner 			break;
95cde9b937SSascha Wildner 		case 'v':
96cde9b937SSascha Wildner 			verbose++;
97cde9b937SSascha Wildner 			break;
98cde9b937SSascha Wildner 		default:
99cde9b937SSascha Wildner 			usage(argv[0]);
100cde9b937SSascha Wildner 		}
101cde9b937SSascha Wildner 	strncpy(atd.ad_name, ifname, sizeof (atd.ad_name));
102cde9b937SSascha Wildner 
103cde9b937SSascha Wildner 	atd.ad_id = HAL_DIAG_REVS;
104cde9b937SSascha Wildner 	atd.ad_out_data = (caddr_t) &revs;
105cde9b937SSascha Wildner 	atd.ad_out_size = sizeof(revs);
106cde9b937SSascha Wildner 	if (ioctl(s, SIOCGATHDIAG, &atd) < 0)
107cde9b937SSascha Wildner 		err(1, atd.ad_name);
108cde9b937SSascha Wildner 
109cde9b937SSascha Wildner 	if (verbose)
110cde9b937SSascha Wildner 		printRevs(stdout, &revs);
111cde9b937SSascha Wildner 
112cde9b937SSascha Wildner 	atd.ad_id = HAL_DIAG_TXRATES;
113cde9b937SSascha Wildner 	atd.ad_out_data = (caddr_t) ratesArray;
114cde9b937SSascha Wildner 	atd.ad_out_size = sizeof(ratesArray);
115cde9b937SSascha Wildner 	if (ioctl(s, SIOCGATHDIAG, &atd) < 0)
116cde9b937SSascha Wildner 		err(1, atd.ad_name);
117cde9b937SSascha Wildner 	nrates = sizeof(ratesArray) / sizeof(u_int16_t);
118cde9b937SSascha Wildner 
119cde9b937SSascha Wildner 	atd.ad_id = HAL_DIAG_PCDAC;
120cde9b937SSascha Wildner 	atd.ad_out_data = (caddr_t) pcdacTable;
121cde9b937SSascha Wildner 	atd.ad_out_size = sizeof(pcdacTable);
122cde9b937SSascha Wildner 	if (ioctl(s, SIOCGATHDIAG, &atd) < 0)
123cde9b937SSascha Wildner 		err(1, atd.ad_name);
124cde9b937SSascha Wildner 	if (IS_2413(&revs) || IS_5413(&revs))
125cde9b937SSascha Wildner 		npcdac = PWR_TABLE_SIZE_2413;
126cde9b937SSascha Wildner 	else
127cde9b937SSascha Wildner 		npcdac = PWR_TABLE_SIZE;
128cde9b937SSascha Wildner 
129cde9b937SSascha Wildner 	printf("PCDAC table:\n");
130cde9b937SSascha Wildner 	printPcdacTable(stdout, pcdacTable, npcdac);
131cde9b937SSascha Wildner 
132cde9b937SSascha Wildner 	printf("Power per rate table:\n");
133cde9b937SSascha Wildner 	printPowerPerRate(stdout, ratesArray, nrates);
134cde9b937SSascha Wildner 
135cde9b937SSascha Wildner 	return 0;
136cde9b937SSascha Wildner }
137cde9b937SSascha Wildner 
138cde9b937SSascha Wildner static void
printPcdacTable(FILE * fd,u_int16_t pcdac[],u_int n)139cde9b937SSascha Wildner printPcdacTable(FILE *fd, u_int16_t pcdac[], u_int n)
140cde9b937SSascha Wildner {
141cde9b937SSascha Wildner 	int i, halfRates = n/2;
142cde9b937SSascha Wildner 
143cde9b937SSascha Wildner 	for (i = 0; i < halfRates; i += 2)
144cde9b937SSascha Wildner 		fprintf(fd, "[%2u] %04x %04x [%2u] %04x %04x\n",
145cde9b937SSascha Wildner 			i, pcdac[2*i + 1], pcdac[2*i],
146cde9b937SSascha Wildner 			i+1, pcdac[2*(i+1) + 1], pcdac[2*(i+1)]);
147cde9b937SSascha Wildner }
148cde9b937SSascha Wildner 
149cde9b937SSascha Wildner static void
printPowerPerRate(FILE * fd,u_int16_t ratesArray[],u_int n)150cde9b937SSascha Wildner printPowerPerRate(FILE *fd, u_int16_t ratesArray[], u_int n)
151cde9b937SSascha Wildner {
152cde9b937SSascha Wildner 	const char *rateString[] = {
153cde9b937SSascha Wildner 		" 6mb OFDM", " 9mb OFDM", "12mb OFDM", "18mb OFDM",
154cde9b937SSascha Wildner 		"24mb OFDM", "36mb OFDM", "48mb OFDM", "54mb OFDM",
155cde9b937SSascha Wildner 		"1L   CCK ", "2L   CCK ", "2S   CCK ", "5.5L CCK ",
156cde9b937SSascha Wildner 		"5.5S CCK ", "11L  CCK ", "11S  CCK ", "XR       "
157cde9b937SSascha Wildner 	};
158cde9b937SSascha Wildner 	int i, halfRates = n/2;
159cde9b937SSascha Wildner 
160cde9b937SSascha Wildner 	for (i = 0; i < halfRates; i++)
161cde9b937SSascha Wildner 		fprintf(fd, " %s %3d.%1d dBm | %s %3d.%1d dBm\n",
162cde9b937SSascha Wildner 			 rateString[i], ratesArray[i]/2,
163cde9b937SSascha Wildner 			 (ratesArray[i] %2) * 5,
164cde9b937SSascha Wildner 			 rateString[i + halfRates],
165cde9b937SSascha Wildner 			 ratesArray[i + halfRates]/2,
166cde9b937SSascha Wildner 			 (ratesArray[i + halfRates] %2) *5);
167cde9b937SSascha Wildner }
168cde9b937SSascha Wildner 
169cde9b937SSascha Wildner static void
printRevs(FILE * fd,const HAL_REVS * revs)170cde9b937SSascha Wildner printRevs(FILE *fd, const HAL_REVS *revs)
171cde9b937SSascha Wildner {
172cde9b937SSascha Wildner 	const char *rfbackend;
173cde9b937SSascha Wildner 
174cde9b937SSascha Wildner 	fprintf(fd, "PCI device id 0x%x subvendor id 0x%x\n",
175cde9b937SSascha Wildner 		revs->ah_devid, revs->ah_subvendorid);
176cde9b937SSascha Wildner 	fprintf(fd, "mac %d.%d phy %d.%d"
177cde9b937SSascha Wildner 		, revs->ah_macVersion, revs->ah_macRev
178cde9b937SSascha Wildner 		, revs->ah_phyRev >> 4, revs->ah_phyRev & 0xf
179cde9b937SSascha Wildner 	);
180cde9b937SSascha Wildner 	rfbackend = IS_5413(revs) ? "5413" :
181cde9b937SSascha Wildner 		    IS_2413(revs) ? "2413" :
182cde9b937SSascha Wildner 		    IS_5112(revs) ? "5112" :
183cde9b937SSascha Wildner 				    "5111";
184cde9b937SSascha Wildner 	if (revs->ah_analog5GhzRev && revs->ah_analog2GhzRev)
185cde9b937SSascha Wildner 		fprintf(fd, " 5ghz radio %d.%d 2ghz radio %d.%d (%s)\n"
186cde9b937SSascha Wildner 			, revs->ah_analog5GhzRev >> 4
187cde9b937SSascha Wildner 			, revs->ah_analog5GhzRev & 0xf
188cde9b937SSascha Wildner 			, revs->ah_analog2GhzRev >> 4
189cde9b937SSascha Wildner 			, revs->ah_analog2GhzRev & 0xf
190cde9b937SSascha Wildner 			, rfbackend
191cde9b937SSascha Wildner 		);
192cde9b937SSascha Wildner 	else
193cde9b937SSascha Wildner 		fprintf(fd, " radio %d.%d (%s)\n"
194cde9b937SSascha Wildner 			, revs->ah_analog5GhzRev >> 4
195cde9b937SSascha Wildner 			, revs->ah_analog5GhzRev & 0xf
196cde9b937SSascha Wildner 			, rfbackend
197cde9b937SSascha Wildner 		);
198cde9b937SSascha Wildner }
199