ath_ee_v14_print.c revision 219355
1 2/* 3 * Copyright (c) 2010-2011 Adrian Chadd, Xenion Pty Ltd. 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 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: head/tools/tools/ath/ath_ee_v14_print/ath_ee_v14_print.c 219355 2011-03-06 23:15:24Z adrian $ 27 */ 28 29#include <stdio.h> 30#include <stdlib.h> 31#include <unistd.h> 32#include <string.h> 33#include <sys/types.h> 34#include <err.h> 35 36typedef enum { 37 AH_FALSE = 0, /* NB: lots of code assumes false is zero */ 38 AH_TRUE = 1, 39} HAL_BOOL; 40 41typedef enum { 42 HAL_OK = 0, /* No error */ 43} HAL_STATUS; 44 45struct ath_hal; 46 47#include "ah_eeprom_v14.h" 48 49void 50load_eeprom_dump(const char *file, uint16_t *buf) 51{ 52 unsigned int r[8]; 53 FILE *fp; 54 char b[1024]; 55 int i; 56 57 fp = fopen(file, "r"); 58 if (!fp) 59 err(1, "fopen"); 60 61 while (!feof(fp)) { 62 if (fgets(b, 1024, fp) == NULL) 63 break; 64 if (feof(fp)) 65 break; 66 if (strlen(b) > 0) 67 b[strlen(b)-1] = '\0'; 68 if (strlen(b) == 0) 69 break; 70 sscanf(b, "%x: %x %x %x %x %x %x %x %x\n", 71 &i, &r[0], &r[1], &r[2], &r[3], &r[4], 72 &r[5], &r[6], &r[7]); 73 buf[i++] = r[0]; 74 buf[i++] = r[1]; 75 buf[i++] = r[2]; 76 buf[i++] = r[3]; 77 buf[i++] = r[4]; 78 buf[i++] = r[5]; 79 buf[i++] = r[6]; 80 buf[i++] = r[7]; 81 } 82 fclose(fp); 83} 84 85static void 86eeprom_v14_base_print(uint16_t *buf) 87{ 88 HAL_EEPROM_v14 *eep = (HAL_EEPROM_v14 *) buf; 89 BASE_EEP_HEADER *eh = &eep->ee_base.baseEepHeader; 90 int i; 91 92 printf("| Version: 0x%.4x | Length: 0x%.4x | Checksum: 0x%.4x ", 93 eh->version, eh->length, eh->checksum); 94 printf("| CapFlags: 0x%.2x | eepMisc: 0x%.2x | RegDomain: 0x%.2x 0x%.2x | \n", 95 eh->opCapFlags, eh->eepMisc, eh->regDmn[0], eh->regDmn[1]); 96 printf("| MAC: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x ", 97 eh->macAddr[0], eh->macAddr[1], eh->macAddr[2], 98 eh->macAddr[3], eh->macAddr[4], eh->macAddr[5]); 99 printf("| RxMask: 0x%.2x | TxMask: 0x%.2x | RfSilent: 0x%.4x | btOptions: 0x%.4x |\n", 100 eh->rxMask, eh->txMask, eh->rfSilent, eh->blueToothOptions); 101 printf("| DeviceCap: 0x%.4x | binBuildNumber: %.8x | deviceType: 0x%.2x |\n", 102 eh->deviceCap, eh->binBuildNumber, eh->deviceType); 103 104 printf("| pwdclkind: 0x%.2x | fastClk5g: 0x%.2x | divChain: 0x%.2x | rxGainType: 0x%.2x |\n", 105 (int) eh->pwdclkind, (int) eh->fastClk5g, (int) eh->divChain, 106 (int) eh->rxGainType); 107 108 printf("| dacHiPwrMode_5G: 0x%.2x | openLoopPwrCntl: 0x%.2x | dacLpMode: 0x%.2x ", 109 (int) eh->dacHiPwrMode_5G, (int) eh->openLoopPwrCntl, (int) eh->dacLpMode); 110 printf("| txGainType: 0x%.2x | rcChainMask: 0x%.2x |\n", 111 (int) eh->txGainType, (int) eh->rcChainMask); 112 113 printf("| desiredScaleCCK: 0x%.2x | pwr_table_offset: 0x%.2x | frac_n_5g: %.2x\n", 114 (int) eh->desiredScaleCCK, (int) eh->pwr_table_offset, (int) eh->frac_n_5g); 115 116 /* because it's convienent */ 117 printf("| antennaGainMax[0]: 0x%.2x antennaGainMax[1]: 0x%.2x |\n", 118 eep->ee_antennaGainMax[0], eep->ee_antennaGainMax[1]); 119 120 printf(" | futureBase:"); 121 for (i = 0; i < sizeof(eh->futureBase) / sizeof(uint8_t); i++) 122 printf(" %.2x", (int) eh->futureBase[i]); 123 printf("\n"); 124} 125 126static void 127eeprom_v14_custdata_print(uint16_t *buf) 128{ 129 HAL_EEPROM_v14 *eep = (HAL_EEPROM_v14 *) buf; 130 uint8_t *custdata = (uint8_t *) &eep->ee_base.custData; 131 int i; 132 133 printf("\n| Custdata: |\n"); 134 for (i = 0; i < 64; i++) { 135 printf("%s0x%.2x %s", 136 i % 16 == 0 ? "| " : "", 137 custdata[i], 138 i % 16 == 15 ? "|\n" : ""); 139 } 140} 141 142static void 143eeprom_v14_modal_print(uint16_t *buf, int m) 144{ 145 HAL_EEPROM_v14 *eep = (HAL_EEPROM_v14 *) buf; 146 MODAL_EEP_HEADER *mh = &eep->ee_base.modalHeader[m]; 147 int i; 148 149 printf("| antCtrlCommon: 0x%.4x |\n", mh->antCtrlCommon); 150 printf("| switchSettling: 0x%.2x |\n", mh->switchSettling); 151 printf("| adcDesiredSize: %d |\n| pgaDesiredSize: %.2f dBm |\n", 152 mh->adcDesiredSize, (float) mh->pgaDesiredSize / 2.0); 153 154 printf("| antCtrlChain: 0:0x%.4x 1:0x%.4x 2:0x%.4x |\n", 155 mh->antCtrlChain[0], mh->antCtrlChain[1], mh->antCtrlChain[2]); 156 printf("| antennaGainCh: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n", 157 mh->antennaGainCh[0], mh->antennaGainCh[1], mh->antennaGainCh[2]); 158 printf("| txRxAttenCh: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n", 159 mh->txRxAttenCh[0], mh->txRxAttenCh[1], mh->txRxAttenCh[2]); 160 printf("| rxTxMarginCh: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n", 161 mh->rxTxMarginCh[0], mh->rxTxMarginCh[1], mh->rxTxMarginCh[2]); 162 printf("| noiseFloorThresCh: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n", 163 mh->noiseFloorThreshCh[0], mh->noiseFloorThreshCh[1], mh->noiseFloorThreshCh[2]); 164 printf("| xlnaGainCh: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n", 165 mh->xlnaGainCh[0], mh->xlnaGainCh[1], mh->xlnaGainCh[2]); 166 printf("| iqCalICh: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n| iqCalQCh: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n", 167 mh->iqCalICh[0], mh->iqCalICh[1], mh->iqCalICh[2], 168 mh->iqCalQCh[0], mh->iqCalQCh[1], mh->iqCalQCh[2]); 169 printf("| bswAtten: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n", 170 mh->bswAtten[0], mh->bswAtten[1], mh->bswAtten[2]); 171 printf("| bswMargin: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n", 172 mh->bswMargin[0], mh->bswMargin[1], mh->bswMargin[2]); 173 printf("| xatten2Db: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n", 174 mh->xatten2Db[0], mh->xatten2Db[1], mh->xatten2Db[2]); 175 printf("| xatten2Margin: 0:0x%.2x 1:0x%.2x 2:0x%.2x |\n", 176 mh->xatten2Margin[0], mh->xatten2Margin[1], mh->xatten2Margin[2]); 177 178 printf("| txEndToXpaOff: 0x%.2x | txEndToRxOn: 0x%.2x | txFrameToXpaOn: 0x%.2x |\n", 179 mh->txEndToXpaOff, mh->txEndToRxOn, mh->txFrameToXpaOn); 180 181 printf("| thres62: 0x%.2x\n", mh->thresh62); 182 183 printf("| xpdGain: 0x%.2x | xpd: 0x%.2x |\n", mh->xpdGain, mh->xpd); 184 printf("| xpaBiasLvlFreq: 0:0x%.4x 1:0x%.4x 2:0x%.4x |\n", 185 mh->xpaBiasLvlFreq[0], mh->xpaBiasLvlFreq[1], mh->xpaBiasLvlFreq[2]); 186 187 printf("| pdGainOverlap: 0x%.2x | ob: 0x%.2x | db: 0x%.2x | xpaBiasLvl: 0x%.2x |\n", 188 mh->pdGainOverlap, mh->ob, mh->db, mh->xpaBiasLvl); 189 190 printf("| pwrDecreaseFor2Chain: 0x%.2x | pwrDecreaseFor3Chain: 0x%.2x | txFrameToDataStart: 0x%.2x | txFrameToPaOn: 0x%.2x |\n", 191 mh->pwrDecreaseFor2Chain, mh->pwrDecreaseFor3Chain, mh->txFrameToDataStart, 192 mh->txFrameToPaOn); 193 194 printf("| ht40PowerIncForPdadc: 0x%.2x |\n", mh->ht40PowerIncForPdadc); 195 196 printf("| swSettleHt40: 0x%.2x |\n", mh->swSettleHt40); 197 198 printf("| ob_ch1: 0x%.2x | db_ch1: 0x%.2x |\n", mh->ob_ch1, mh->db_ch1); 199 200 printf("| flagBits: 0x%.2x | miscBits: 0x%.2x |\n", mh->flagBits, mh->miscBits); 201 202 203 printf("| futureModal: 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x |\n", 204 mh->futureModal[0], 205 mh->futureModal[1], 206 mh->futureModal[2], 207 mh->futureModal[3], 208 mh->futureModal[4], 209 mh->futureModal[5]); 210 211 /* and now, spur channels */ 212 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) { 213 printf("| Spur %d: spurChan: 0x%.4x spurRangeLow: 0x%.2x spurRangeHigh: 0x%.2x |\n", 214 i, mh->spurChans[i].spurChan, 215 (int) mh->spurChans[i].spurRangeLow, 216 (int) mh->spurChans[i].spurRangeHigh); 217 } 218} 219 220static void 221eeprom_v14_print_caldata_perfreq_op_loop(CAL_DATA_PER_FREQ_OP_LOOP *f) 222{ 223 int i, j; 224 for (i = 0; i < 2; i++) { 225 printf(" Gain: %d:\n", i); 226 for (j = 0; j < 5; j++) { 227 printf(" %d: pwrPdg: %d, vpdPdg: %d, pcdac: %d, empty: %d\n", 228 j, f->pwrPdg[i][j], f->vpdPdg[i][j], f->pcdac[i][j], f->empty[i][j]); 229 } 230 printf("\n"); 231 } 232} 233 234static void 235eeprom_v14_print_caldata_perfreq(CAL_DATA_PER_FREQ *f) 236{ 237 int i, j; 238 239 for (i = 0; i < AR5416_NUM_PD_GAINS; i++) { 240 printf(" Gain %d: pwr dBm/vpd: ", i); 241 for (j = 0; j < AR5416_PD_GAIN_ICEPTS; j++) { 242 /* These are stored in 0.25dBm increments */ 243 printf("%d:(%.2f/%d) ", j, (float) f->pwrPdg[i][j] / 4.00, 244 f->vpdPdg[i][j]); 245 } 246 printf("\n"); 247 } 248} 249 250static void 251eeprom_v14_calfreqpiers_print(uint16_t *buf) 252{ 253 HAL_EEPROM_v14 *eep = (HAL_EEPROM_v14 *) buf; 254 int i, n; 255 256 /* 2ghz cal piers */ 257 printf("calFreqPier2G: "); 258 for (i = 0; i < AR5416_NUM_2G_CAL_PIERS; i++) { 259 printf(" 0x%.2x ", eep->ee_base.calFreqPier2G[i]); 260 } 261 printf("|\n"); 262 263 for (i = 0; i < AR5416_NUM_2G_CAL_PIERS; i++) { 264 if (eep->ee_base.calFreqPier2G[i] == 0xff) 265 continue; 266 printf("2Ghz Cal Pier %d\n", i); 267 for (n = 0; n < AR5416_MAX_CHAINS; n++) { 268 printf(" Chain %d:\n", n); 269 if (eep->ee_base.baseEepHeader.openLoopPwrCntl) 270 eeprom_v14_print_caldata_perfreq_op_loop((void *) (&eep->ee_base.calPierData2G[n][i])); 271 else 272 eeprom_v14_print_caldata_perfreq(&eep->ee_base.calPierData2G[n][i]); 273 } 274 } 275 276 printf("\n"); 277 278 /* 5ghz cal piers */ 279 printf("calFreqPier5G: "); 280 for (i = 0; i < AR5416_NUM_5G_CAL_PIERS; i++) { 281 printf(" 0x%.2x ", eep->ee_base.calFreqPier5G[i]); 282 } 283 printf("|\n"); 284 for (i = 0; i < AR5416_NUM_5G_CAL_PIERS; i++) { 285 if (eep->ee_base.calFreqPier5G[i] == 0xff) 286 continue; 287 printf("5Ghz Cal Pier %d\n", i); 288 for (n = 0; n < AR5416_MAX_CHAINS; n++) { 289 printf(" Chain %d:\n", n); 290 if (eep->ee_base.baseEepHeader.openLoopPwrCntl) 291 eeprom_v14_print_caldata_perfreq_op_loop((void *) (&eep->ee_base.calPierData2G[n][i])); 292 else 293 eeprom_v14_print_caldata_perfreq(&eep->ee_base.calPierData2G[n][i]); 294 } 295 } 296} 297 298static void 299eeprom_v14_target_legacy_print(CAL_TARGET_POWER_LEG *l) 300{ 301 int i; 302 if (l->bChannel == 0xff) 303 return; 304 printf(" bChannel: %d;", l->bChannel); 305 for (i = 0; i < 4; i++) { 306 printf(" %.2f", (float) l->tPow2x[i] / 2.0); 307 } 308 printf(" (dBm)\n"); 309} 310 311static void 312eeprom_v14_target_ht_print(CAL_TARGET_POWER_HT *l) 313{ 314 int i; 315 if (l->bChannel == 0xff) 316 return; 317 printf(" bChannel: %d;", l->bChannel); 318 for (i = 0; i < 8; i++) { 319 printf(" %.2f", (float) l->tPow2x[i] / 2.0); 320 } 321 printf(" (dBm)\n"); 322} 323 324static void 325eeprom_v14_print_targets(uint16_t *buf) 326{ 327 HAL_EEPROM_v14 *eep = (HAL_EEPROM_v14 *) buf; 328 int i; 329 330 /* 2ghz rates */ 331 printf("2Ghz CCK:\n"); 332 for (i = 0; i < AR5416_NUM_2G_CCK_TARGET_POWERS; i++) { 333 eeprom_v14_target_legacy_print(&eep->ee_base.calTargetPowerCck[i]); 334 } 335 printf("2Ghz 11g:\n"); 336 for (i = 0; i < AR5416_NUM_2G_20_TARGET_POWERS; i++) { 337 eeprom_v14_target_legacy_print(&eep->ee_base.calTargetPower2G[i]); 338 } 339 printf("2Ghz HT20:\n"); 340 for (i = 0; i < AR5416_NUM_2G_20_TARGET_POWERS; i++) { 341 eeprom_v14_target_ht_print(&eep->ee_base.calTargetPower2GHT20[i]); 342 } 343 printf("2Ghz HT40:\n"); 344 for (i = 0; i < AR5416_NUM_2G_40_TARGET_POWERS; i++) { 345 eeprom_v14_target_ht_print(&eep->ee_base.calTargetPower2GHT40[i]); 346 } 347 348 /* 5ghz rates */ 349 printf("5Ghz 11a:\n"); 350 for (i = 0; i < AR5416_NUM_5G_20_TARGET_POWERS; i++) { 351 eeprom_v14_target_legacy_print(&eep->ee_base.calTargetPower5G[i]); 352 } 353 printf("5Ghz HT20:\n"); 354 for (i = 0; i < AR5416_NUM_5G_20_TARGET_POWERS; i++) { 355 eeprom_v14_target_ht_print(&eep->ee_base.calTargetPower5GHT20[i]); 356 } 357 printf("5Ghz HT40:\n"); 358 for (i = 0; i < AR5416_NUM_5G_40_TARGET_POWERS; i++) { 359 eeprom_v14_target_ht_print(&eep->ee_base.calTargetPower5GHT40[i]); 360 } 361 362} 363 364static void 365eeprom_v14_ctl_edge_print(CAL_CTL_DATA *ctl) 366{ 367 int i, j; 368 uint8_t pow, flag; 369 370 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 371 printf(" chain %d: ", i); 372 for (j = 0; j < AR5416_NUM_BAND_EDGES; j++) { 373 pow = ctl->ctlEdges[i][j].tPowerFlag & 0x3f; 374 flag = (ctl->ctlEdges[i][j].tPowerFlag & 0xc0) >> 6; 375 printf(" %d:pow=%d,flag=%.2x", j, pow, flag); 376 } 377 printf("\n"); 378 } 379} 380 381static void 382eeprom_v14_ctl_print(uint16_t *buf) 383{ 384 HAL_EEPROM_v14 *eep = (HAL_EEPROM_v14 *) buf; 385 int i; 386 387 for (i = 0; i < AR5416_NUM_CTLS; i++) { 388 if (eep->ee_base.ctlIndex[i] == 0) 389 continue; 390 printf("| ctlIndex: offset %d, value %d\n", i, eep->ee_base.ctlIndex[i]); 391 eeprom_v14_ctl_edge_print(&eep->ee_base.ctlData[i]); 392 } 393} 394 395static void 396eeprom_v14_print_edges(uint16_t *buf) 397{ 398 HAL_EEPROM_v14 *eep = (HAL_EEPROM_v14 *) buf; 399 int i; 400 401 printf("| eeNumCtls: %d\n", eep->ee_numCtls); 402 for (i = 0; i < NUM_EDGES*eep->ee_numCtls; i++) { 403 /* XXX is flag 8 or 32 bits? */ 404 printf("| edge %2d/%2d: rdEdge: %5d EdgePower: %.2f dBm Flag: 0x%.8x\n", 405 i / NUM_EDGES, i % NUM_EDGES, 406 eep->ee_rdEdgesPower[i].rdEdge, 407 (float) eep->ee_rdEdgesPower[i].twice_rdEdgePower / 2.0, 408 eep->ee_rdEdgesPower[i].flag); 409 410 if (i % NUM_EDGES == (NUM_EDGES -1)) 411 printf("|\n"); 412 } 413#if 0 414typedef struct { 415 uint16_t rdEdge; 416 uint16_t twice_rdEdgePower; 417 HAL_BOOL flag; 418 } RD_EDGES_POWER; 419 420#endif 421} 422 423void 424usage(char *argv[]) 425{ 426 printf("Usage: %s <eeprom dump file>\n", argv[0]); 427 printf("\n"); 428 printf(" The eeprom dump file is a text hexdump of an EEPROM.\n"); 429 printf(" The lines must be formatted as follows:\n"); 430 printf(" 0xAAAA: 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD\n"); 431 printf(" where each line must have exactly eight data bytes.\n"); 432 exit(127); 433} 434 435int 436main(int argc, char *argv[]) 437{ 438 uint16_t *eep = NULL; 439 eep = calloc(4096, sizeof(int16_t)); 440 441 if (argc < 2) 442 usage(argv); 443 444 load_eeprom_dump(argv[1], eep); 445 446 eeprom_v14_base_print(eep); 447 eeprom_v14_custdata_print(eep); 448 449 /* 2.4ghz */ 450 printf("\n2.4ghz:\n"); 451 eeprom_v14_modal_print(eep, 1); 452 /* 5ghz */ 453 printf("\n5ghz:\n"); 454 eeprom_v14_modal_print(eep, 0); 455 printf("\n"); 456 457 eeprom_v14_calfreqpiers_print(eep); 458 printf("\n"); 459 460 eeprom_v14_print_targets(eep); 461 printf("\n"); 462 463 eeprom_v14_ctl_print(eep); 464 printf("\n"); 465 466 eeprom_v14_print_edges(eep); 467 printf("\n"); 468 469 free(eep); 470 exit(0); 471} 472