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$
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 
36 struct ath_hal;
37 
38 #include "ar9300/ar9300eep.h"
39 
40 static void
41 eeprom_9300_hdr_print(const uint16_t *buf)
42 {
43 	const ar9300_eeprom_t *ee = (ar9300_eeprom_t *) buf;
44 
45 	printf("| Version: %d, Template: %d, MAC: %02x:%02x:%02x:%02x:%02x:%02x |\n",
46 	    ee->eeprom_version,
47 	    ee->template_version,
48 	    ee->mac_addr[0],
49 	    ee->mac_addr[1],
50 	    ee->mac_addr[2],
51 	    ee->mac_addr[3],
52 	    ee->mac_addr[4],
53 	    ee->mac_addr[5]);
54 }
55 
56 static void
57 eeprom_9300_base_print(const uint16_t *buf)
58 {
59 	const ar9300_eeprom_t *ee = (ar9300_eeprom_t *) buf;
60 	const OSPREY_BASE_EEP_HEADER *ee_base = &ee->base_eep_header;
61 
62 	printf("| RegDomain: 0x%02x 0x%02x TxRxMask: 0x%02x OpFlags: 0x%02x OpMisc: 0x%02x |\n",
63 	    ee_base->reg_dmn[0],
64 	    ee_base->reg_dmn[1],
65 	    ee_base->txrx_mask,
66 	    ee_base->op_cap_flags.op_flags,
67 	    ee_base->op_cap_flags.eepMisc);
68 
69 	printf("| RfSilent: 0x%02x BtOptions: 0x%02x DeviceCap: 0x%02x DeviceType: 0x%02x |\n",
70 	    ee_base->rf_silent,
71 	    ee_base->blue_tooth_options,
72 	    ee_base->device_cap,
73 	    ee_base->device_type);
74 
75 	printf("| pwrTableOffset: %d dB, TuningCaps=0x%02x 0x%02x feature_enable: 0x%02x MiscConfig: 0x%02x |\n",
76 	    ee_base->pwrTableOffset,
77 	    ee_base->params_for_tuning_caps[0],
78 	    ee_base->params_for_tuning_caps[1],
79 	    ee_base->feature_enable,
80 	    ee_base->misc_configuration);
81 
82 	printf("| EepromWriteGpio: %d, WlanDisableGpio: %d, WlanLedGpio: %d RxBandSelectGpio: %d |\n",
83 	    ee_base->eeprom_write_enable_gpio,
84 	    ee_base->wlan_disable_gpio,
85 	    ee_base->wlan_led_gpio,
86 	    ee_base->rx_band_select_gpio);
87 
88 	printf("| TxRxGain: %d, SwReg: %d |\n",
89 	    ee_base->txrxgain,
90 	    ee_base->swreg);
91 }
92 
93 static void
94 eeprom_9300_modal_print(const OSPREY_MODAL_EEP_HEADER *m)
95 {
96 	int i;
97 
98 	printf("| AntCtrl: 0x%08x AntCtrl2: 0x%08x |\n",
99 	    m->ant_ctrl_common,
100 	    m->ant_ctrl_common2);
101 
102 	for (i = 0; i < OSPREY_MAX_CHAINS; i++) {
103 		printf("| Ch %d: AntCtrl: 0x%08x Atten1: %d, atten1_margin: %d, NfThresh: %d |\n",
104 		    i,
105 		    m->ant_ctrl_chain[i],
106 		    m->xatten1_db[i],
107 		    m->xatten1_margin[i],
108 		    m->noise_floor_thresh_ch[i]);
109 	}
110 
111 	printf("| Spur: ");
112 	for (i = 0; i < OSPREY_EEPROM_MODAL_SPURS; i++) {
113 		printf("(%d: %d) ", i, m->spur_chans[i]);
114 	}
115 	printf("|\n");
116 
117 	printf("| TempSlope: %d, VoltSlope: %d, QuickDrop: %d, XpaBiasLvl %d |\n",
118 	    m->temp_slope,
119 	    m->voltSlope,
120 	    m->quick_drop,
121 	    m->xpa_bias_lvl);
122 
123 	printf("| txFrameToDataStart: %d, TxFrameToPaOn: %d, TxEndToXpaOff: %d, TxEndToRxOn: %d, TxFrameToXpaOn: %d |\n",
124 	    m->tx_frame_to_data_start,
125 	    m->tx_frame_to_pa_on,
126 	    m->tx_end_to_xpa_off,
127 	    m->txEndToRxOn,
128 	    m->tx_frame_to_xpa_on);
129 
130 	printf("| txClip: %d, AntGain: %d, SwitchSettling: %d, adcDesiredSize: %d |\n",
131 	    m->txClip,
132 	    m->antenna_gain,
133 	    m->switchSettling,
134 	    m->adcDesiredSize);
135 
136 	printf("| Thresh62: %d, PaprdMaskHt20: 0x%08x, PaPrdMaskHt40: 0x%08x |\n",
137 	    m->thresh62,
138 	    m->paprd_rate_mask_ht20,
139 	    m->paprd_rate_mask_ht40);
140 
141 	printf("| SwitchComSpdt: %02x, XlnaBiasStrength: %d, RfGainCap: %d, TxGainCap: %x\n",
142 	    m->switchcomspdt,
143 	    m->xLNA_bias_strength,
144 	    m->rf_gain_cap,
145 	    m->tx_gain_cap);
146 
147 #if 0
148     u_int8_t   reserved[MAX_MODAL_RESERVED];
149     u_int16_t  switchcomspdt;
150     u_int8_t   xLNA_bias_strength;                      // bit: 0,1:chain0, 2,3:chain1, 4,5:chain2
151     u_int8_t   rf_gain_cap;
152     u_int8_t   tx_gain_cap;                             // bit0:4 txgain cap, txgain index for max_txgain + 20 (10dBm higher than max txgain)
153     u_int8_t   futureModal[MAX_MODAL_FUTURE];
154     // last 12 bytes stolen and moved to newly created base extension structure
155 #endif
156 }
157 
158 static void
159 load_eeprom_dump(const char *file, uint16_t *buf)
160 {
161 	unsigned int r[8];
162 	FILE *fp;
163 	char b[1024];
164 	int i;
165 
166 	fp = fopen(file, "r");
167 	if (!fp)
168 		err(1, "fopen");
169 
170 	while (!feof(fp)) {
171 		if (fgets(b, 1024, fp) == NULL)
172 			break;
173 		if (feof(fp))
174 			break;
175 		if (strlen(b) > 0)
176 			b[strlen(b)-1] = '\0';
177 		if (strlen(b) == 0)
178 			break;
179 		sscanf(b, "%x: %x %x %x %x %x %x %x %x\n",
180 		    &i, &r[0], &r[1], &r[2], &r[3], &r[4],
181 		    &r[5], &r[6], &r[7]);
182 		buf[i++] = r[0];
183 		buf[i++] = r[1];
184 		buf[i++] = r[2];
185 		buf[i++] = r[3];
186 		buf[i++] = r[4];
187 		buf[i++] = r[5];
188 		buf[i++] = r[6];
189 		buf[i++] = r[7];
190 	}
191 	fclose(fp);
192 }
193 
194 void
195 usage(char *argv[])
196 {
197 	printf("Usage: %s <eeprom dump file>\n", argv[0]);
198 	printf("\n");
199 	printf("  The eeprom dump file is a text hexdump of an EEPROM.\n");
200 	printf("  The lines must be formatted as follows:\n");
201 	printf("  0xAAAA: 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD 0xDD\n");
202 	printf("  where each line must have exactly eight data bytes.\n");
203 	exit(127);
204 }
205 
206 int
207 main(int argc, char *argv[])
208 {
209 	uint16_t *eep = NULL;
210 	const ar9300_eeprom_t *ee;
211 
212 	eep = calloc(4096, sizeof(int16_t));
213 
214 	if (argc < 2)
215 		usage(argv);
216 
217 	load_eeprom_dump(argv[1], eep);
218 	ee = (ar9300_eeprom_t *) eep;
219 
220 	eeprom_9300_hdr_print(eep);
221 	eeprom_9300_base_print(eep);
222 
223 	printf("\n2GHz modal:\n");
224 	eeprom_9300_modal_print(&ee->modal_header_2g);
225 
226 	printf("\n5GHz modal:\n");
227 	eeprom_9300_modal_print(&ee->modal_header_5g);
228 
229 	free(eep);
230 	exit(0);
231 }
232