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