Initial import of binutils 2.22 on the new vendor branch
[dragonfly.git] / tools / tools / ath / athpow / athpow.c
1 /*-
2  * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
15  *
16  * NO WARRANTY
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.
28  *
29  * $FreeBSD: src/tools/tools/ath/athpow/athpow.c,v 1.1 2008/12/07 19:17:33 sam Exp $
30  */
31 #include "diag.h"
32
33 #include <getopt.h>
34 #include <stdlib.h>
35 #include <string.h>
36
37 #include "ah.h"
38 #include "ah_internal.h"
39 #include "ah_eeprom.h"
40 #include "ah_eeprom_v1.h"
41 #include "ah_eeprom_v3.h"
42 #include "ah_eeprom_v14.h"
43 #include "ar5212/ar5212reg.h"
44 #define IS_5112(ah) \
45         (((ah)->ah_analog5GhzRev&0xf0) >= AR_RAD5112_SREV_MAJOR \
46          && ((ah)->ah_analog5GhzRev&0xf0) < AR_RAD2316_SREV_MAJOR )
47 #define IS_2316(ah) \
48         ((ah)->ah_macVersion == AR_SREV_2415)
49 #define IS_2413(ah) \
50         ((ah)->ah_macVersion == AR_SREV_2413 || IS_2316(ah))
51 #define IS_5424(ah) \
52         ((ah)->ah_macVersion == AR_SREV_5424 || \
53         ((ah)->ah_macVersion == AR_SREV_5413 && \
54           (ah)->ah_macRev <= AR_SREV_D2PLUS_MS))
55 #define IS_5413(ah) \
56         ((ah)->ah_macVersion == AR_SREV_5413 || IS_5424(ah))
57
58 #ifndef MAX
59 #define MAX(a,b)        ((a) > (b) ? (a) : (b))
60 #endif
61
62 static void printPcdacTable(FILE *fd, u_int16_t pcdac[], u_int n);
63 static void printPowerPerRate(FILE *fd, u_int16_t ratesArray[], u_int n);
64 static void printRevs(FILE *fd, const HAL_REVS *revs);
65
66 static void
67 usage(const char *progname)
68 {
69         fprintf(stderr, "usage: %s [-v] [-i dev]\n", progname);
70         exit(1);
71 }
72
73 int
74 main(int argc, char *argv[])
75 {
76         int s, i, verbose = 0, c;
77         struct ath_diag atd;
78         const char *ifname;
79         HAL_REVS revs;
80         u_int16_t pcdacTable[MAX(PWR_TABLE_SIZE,PWR_TABLE_SIZE_2413)];
81         u_int16_t ratesArray[16];
82         u_int nrates, npcdac;
83
84         s = socket(AF_INET, SOCK_DGRAM, 0);
85         if (s < 0)
86                 err(1, "socket");
87         ifname = getenv("ATH");
88         if (!ifname)
89                 ifname = ATH_DEFAULT;
90         while ((c = getopt(argc, argv, "i:v")) != -1)
91                 switch (c) {
92                 case 'i':
93                         ifname = optarg;
94                         break;
95                 case 'v':
96                         verbose++;
97                         break;
98                 default:
99                         usage(argv[0]);
100                 }
101         strncpy(atd.ad_name, ifname, sizeof (atd.ad_name));
102
103         atd.ad_id = HAL_DIAG_REVS;
104         atd.ad_out_data = (caddr_t) &revs;
105         atd.ad_out_size = sizeof(revs);
106         if (ioctl(s, SIOCGATHDIAG, &atd) < 0)
107                 err(1, atd.ad_name);
108
109         if (verbose)
110                 printRevs(stdout, &revs);
111
112         atd.ad_id = HAL_DIAG_TXRATES;
113         atd.ad_out_data = (caddr_t) ratesArray;
114         atd.ad_out_size = sizeof(ratesArray);
115         if (ioctl(s, SIOCGATHDIAG, &atd) < 0)
116                 err(1, atd.ad_name);
117         nrates = sizeof(ratesArray) / sizeof(u_int16_t);
118
119         atd.ad_id = HAL_DIAG_PCDAC;
120         atd.ad_out_data = (caddr_t) pcdacTable;
121         atd.ad_out_size = sizeof(pcdacTable);
122         if (ioctl(s, SIOCGATHDIAG, &atd) < 0)
123                 err(1, atd.ad_name);
124         if (IS_2413(&revs) || IS_5413(&revs))
125                 npcdac = PWR_TABLE_SIZE_2413;
126         else
127                 npcdac = PWR_TABLE_SIZE;
128
129         printf("PCDAC table:\n");
130         printPcdacTable(stdout, pcdacTable, npcdac);
131
132         printf("Power per rate table:\n");
133         printPowerPerRate(stdout, ratesArray, nrates);
134
135         return 0;
136 }
137
138 static void
139 printPcdacTable(FILE *fd, u_int16_t pcdac[], u_int n)
140 {
141         int i, halfRates = n/2;
142
143         for (i = 0; i < halfRates; i += 2)
144                 fprintf(fd, "[%2u] %04x %04x [%2u] %04x %04x\n",
145                         i, pcdac[2*i + 1], pcdac[2*i],
146                         i+1, pcdac[2*(i+1) + 1], pcdac[2*(i+1)]);
147 }
148
149 static void
150 printPowerPerRate(FILE *fd, u_int16_t ratesArray[], u_int n)
151 {
152         const char *rateString[] = {
153                 " 6mb OFDM", " 9mb OFDM", "12mb OFDM", "18mb OFDM",
154                 "24mb OFDM", "36mb OFDM", "48mb OFDM", "54mb OFDM",
155                 "1L   CCK ", "2L   CCK ", "2S   CCK ", "5.5L CCK ",
156                 "5.5S CCK ", "11L  CCK ", "11S  CCK ", "XR       "
157         };
158         int i, halfRates = n/2;
159
160         for (i = 0; i < halfRates; i++)
161                 fprintf(fd, " %s %3d.%1d dBm | %s %3d.%1d dBm\n",
162                          rateString[i], ratesArray[i]/2,
163                          (ratesArray[i] %2) * 5,
164                          rateString[i + halfRates],
165                          ratesArray[i + halfRates]/2,
166                          (ratesArray[i + halfRates] %2) *5);
167 }
168
169 static void
170 printRevs(FILE *fd, const HAL_REVS *revs)
171 {
172         const char *rfbackend;
173
174         fprintf(fd, "PCI device id 0x%x subvendor id 0x%x\n",
175                 revs->ah_devid, revs->ah_subvendorid);
176         fprintf(fd, "mac %d.%d phy %d.%d"
177                 , revs->ah_macVersion, revs->ah_macRev
178                 , revs->ah_phyRev >> 4, revs->ah_phyRev & 0xf
179         );
180         rfbackend = IS_5413(revs) ? "5413" :
181                     IS_2413(revs) ? "2413" :
182                     IS_5112(revs) ? "5112" :
183                                     "5111";
184         if (revs->ah_analog5GhzRev && revs->ah_analog2GhzRev)
185                 fprintf(fd, " 5ghz radio %d.%d 2ghz radio %d.%d (%s)\n"
186                         , revs->ah_analog5GhzRev >> 4
187                         , revs->ah_analog5GhzRev & 0xf
188                         , revs->ah_analog2GhzRev >> 4
189                         , revs->ah_analog2GhzRev & 0xf
190                         , rfbackend
191                 );
192         else
193                 fprintf(fd, " radio %d.%d (%s)\n"
194                         , revs->ah_analog5GhzRev >> 4
195                         , revs->ah_analog5GhzRev & 0xf
196                         , rfbackend
197                 );
198 }