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